-
Notifications
You must be signed in to change notification settings - Fork 14
1. Code blocks
Code blocks in Clue start with {
and end with }
.
Note that {
and }
are also used for defining tables:
local x = {} //x is a table, not a code block
{
//while this is a code block
}
Below is a list of all code blocks in Clue and their differences with Lua's.
These work pretty much the same way as Lua's:
if condition {
//code
} elseif other {
//more code
} else {
//even more code
}
Match blocks compare an expression and run the code block corresponding to a value matching the expression:
match expr {
1 => {
//this code block will be run if expr equals to 1
}
2 || 3 => {
//this other code block will be run instead if expr equals to either 2 or 3
}
}
This code will be converted to:
local _match = expr;
if (_match == 1) then
elseif (_match == 2) or (_match == 3) then
end
If the expression does not match with any other block, a special case can be set:
match expr {
1 => {
//this code block will be run if expr equals to 1
}
2 || 3 => {
//this other code block will be run instead if expr equals to either 2 or 3
}
default => {
//this last code block will be run if expr does not match with any other value
}
}
This code will be converted to:
local _match = expr;
if (_match == 1) then
elseif (_match == 2) or (_match == 3) then
else
end
The try
block will run the given code block in protected mode: if the code errors your program will still continue:
try {
//code
}
(Note: try blocks are converted into pcall
calls, but they should not always be used instead of pcall
: try blocks create a new function for pcall every time the block is ran in the code (this is to keep the scope working), if your try block only calls functions use pcall
directly!)
After a try block a catch
block can be added, the catch block will only be ran if the try block resulted in an error:
try {
error("error message");
} catch {
print("an error happened!");
}
If you want to know the error message you can supply a variable name to the catch block:
try {
error("error message");
} catch msg {
print(msg); //will print "error message"
}
This will be converted to:
local _check, msg = pcall(function()
error("error message");
end)
if not _check then
print(msg);
end
--you can also use _check and msg outside of the try catch block if you need to
These ones don't use the do
keyword anymore, they only need {
and }
:
{
//code
}
Clue's functions work the exact same way as Lua's but with a different keyword (fn
) and some additions:
These remain the exact same as Lua's:
local fn foo() {
//code
}
These must be defined with the global
keyword:
global fn bar() {
//code
}
These must be defined with the static
keyword.
Just like static variables these functions will be at file scope in the output file, so they will be available to only all Clue files.
Static functions also count towards the 200 locals limit that the file scope can have.
While you can define static functions anywhere, they should be put in the Clue code's file scope as they will always be put at file scope in the output file too: if you define a static function inside another function the static function will not be able to use the other function's locals (unless they are passed as arguments when calling the static function).
static fn fizz() {
//code
}
Methods work the same way but are defined and called with ::
instead of :
.
To define methods/functions inside tables the method
keyword has to be used:
local t = {}
method t::foo() {
//code
}
t::foo()
A function's arguments can have default values, if that argument is nil it will set to the default value.
The arguments are checked from last to first:
local fn foo(x = 3, y = 5) {
//code
}
This code will be converted to:
local function foo(x, y)
if y == nil then
y = 5
end
if x == nil then
x = 3
end
end
Like in Lua functions can be used as values and as arguments in other functions:
local foo = fn(x, y) {/*...*/}
bar(fn {
//if an anonymous function does not have any arguments the () can be omitted
})
Clue has all Lua's loops, but adds a few more loops.
These loops remain unchanged from Lua:
for i = 1, 10 {
print(i) //will print from 1 to 10
}
for i = 10, 1, -1 {
print(i) //will print from 10 to 1
}
These loops are slightly changed and now use the keywords of
, in
and with
:
for k, v of t {
//uses the iterator pairs with the table t
}
for k, v in t {
//uses the iterator ipairs with the table t
}
for k, v with myiter(...) {
//uses any custom iterator function with any amount of arguments
//it's pretty much Lua's for loop but with a different keyword
}
These loops remain unchanged from Lua:
while condition {
//code
}
These loops are the opposite of a while loop, looping until the condition is true
until condition {
//code
}
Lua's repeat until loops work the same way in Clue but use a different keyword:
loop {
//code
} until x
These loops with a funny name will iterate forever until something external (like break
) ends the loop:
local x = 1
loop {
x += 1
if x == 5 {break}
}
continue
is obviously not a loop itself but it can be used inside them, it works like break
but instead of ending the loop it skips to the next iteration:
for i = 1, 10 {
if i == 5 {continue}
print(i) //this will print from 1 to 10 except 5
}
Clue will assume the version of Lua you're compiling to also has a continue
keyword and it will use it in the output, if your Lua version doesn't have that keyword the --continue
flag can be used to alter the output:
If your Lua has goto
you can tell Clue to use a ::continue::
label and goto continue;
with the --continue=luajit
flag:
--without the flag enabled
for i = 1, 10, 1 do
if i==5 then
continue;
end
print(i)
end
--with the flag enabled
for i = 1, 10, 1 do
if i==5 then
goto continue;
end
print(i)
::continue::
end
Otheriwise, --continue=moonscript
can be used:
for i = 1, 10, 1 do
local _internal0 = false;
repeat
if i==5 then
_internal0 = true;
break;
end
print(i);
_internal0 = true;
until true
if not _internal0 then
break;
end
end