-
Notifications
You must be signed in to change notification settings - Fork 14
7. Preprocessor
Before the file is compiled Clue analyzes the source code (checks if comments and strings have an end, checks if all characters are valid, etc) using its preprocessor.
This preprocessor can be controlled with directives to modify the source code before it is compiled:
If the OS from where the code is being compiled matches target_os
(case sensitive, it must be all lowercase) the code block will be kept, otherwise it will be discarded.
This directive can be used when the source uses code that is platform dependent.
If the --target
flag was specified and matches target_lua
, the code block will be kept, otherwise it will be discarded.
This directive can be used when the source uses code that changes based on the version of Lua.
If env_var
matches the name of any environment variable, the code block will be kept, otherwise it will be discarded.
With this environment variables can be used as custom flags for the source, to define these variables simply add NAME="..."
to the command.
Example: STR="This is a string" clue main.clue
Works the same way as @ifdef
, but in reverse, keeping the code block if env_var
is not the name of any environment variable.
If env_var
is equal (or not equal, based on what operation is used) to compared
the code block will be kept, otherwise it will be discarded.
A more general directive for more complex checks, condition has to be a call to any of these 6 functions:
-
all(<cond1>, <cond2>, ...)
: If every condition passed is true, this will also return true, otherwise it will return false. -
any(<cond1>, <cond2>, ...)
: If at least one condition passed is true, this will also return true, otherwise it will return false. -
os(<target_os>)
: The same as@ifos
. -
def(<env_var>)
: The same as@ifdef
. -
ndef(<env_var>)
: The same as@ifndef
. -
cmp(<env_var> ==/!= <compared>)
: The same as@ifcmp
. -
not(<condition>)
: Returns the opposite of the result ofcondition
.
Example:
@if any(not(def(A)), all(def(B), def(C))) {
foo()
}
If either A is not defined or both B and C are defined then foo()
will be kept, otherwise it will be discarded.
If the previous "if" directive (@if
, @ifdef
, etc) discarded its block (so if its condition returned false), the code block will be kept, otherwise it will be discarded.
Merges @else
and @<if_name>
into a directive that does both at once, <if_name>
has to be one of the "if" directives "if" (@if
, @ifos
, etc)
Imports path
(if a valid file path) and stores it in a variable matching the name of the file. (works with both .lua
and .clue
files)
path
is written similarly to Lua's require(...)
paths (dir.file
, no extension), and the path is not relative to this file, but relative to the compiled directory.
Example:
dir1
|---dir2
| |---file1.clue
|
|---file2.clue
If dir1
is the compiled directory (by running clue dir1
):
- To import
file2
fromfile1
:@import "file2"
- To import
file1
from "file2":@import "dir2.file1"
To import a Lua file, simply make sure that path
points to a file with the .lua
extensione (but don't include it in the path!), and the preprocessor will automatically handle it.
If name
is specified, the value returned from the file will be named name
instead of the file's name
Example:
@import "file"
print(file)
@import "file" => something_else
print(something_else)
Note: if a variable was previously defined that shares the same name as an imported file, that variable will be overwritten!
local thing = 3
@import "thing"
print(thing) //will NOT print 3
Terminates compilation if Clue's version doesn't match clue_version
.
To only allow a specific version, add =
before the error.
*
can also be used to not specify a version number.
Examples:
-
@version 3.3.0
will cause an error if Clue's version is 3.2 or below. -
@import =3.3.1
will cause an error if Clue's version is anything but 3.3.1. -
@import =3.3.*
will cause an error if Clue's version is not 3.3, ignoring the patch number.
Defines a preprocessor constant variable that can be used anywhere else in the code. These variables only exist when preprocessing:
@define FOO 10
assert($FOO == 10)
print(FOO)
The above will be compiled into:
assert(10==10);
print(FOO);
Defines a preprocessor macro that can be called anywhere else in the code.
The arguments that are passed to it are treated as constant variables like the ones defined with @define
.
You can think of macros as functions that are called at compile time that return code:
@macro mul(x, y) {
$x * $y
}
@macro double(x) {
$mul!($x, 2)
}
print($double!(4))
The above will be compiled into:
print(4*2);
If @define
or @macro
are used inside a macro, the resulting variables will be only usable inside of it.
If the last (or only) argument name in the macro definition is ...
, it will be able to accept any amount of arguments:
@macro sum(...) {
local a = 0
${a += $vararg}
}
$sum!(2, 4, 3, 5)
The above will be compiled into:
local a = 0;
a = a + 2;
a = a + 4;
a = a + 3;
a = a + 5;
Once the preprocessor reads this directive it will halt and return an error (with <msg>
as the error message), terminating the compilation.
This directive should only be used inside an "if" directive (@if
, @ifcmp
, etc), as otherwise Clue will always error.
Works similarly to @error
, but instead of erroring and terminating the program it simply prints <msg>
and resumes normally.
These are mostly defined with other directives (@define
and @macro
) and only exist during preprocessing.
To use them $
must be used:
Returns the value of the constant (defined with @define
) named <name>
.
Returns the value of the environment variable named <env_var>
inside a string.
Note: if both a constant and env variable share the same name, the env variable will be used.
Calls the macro named <macro_name>
with the given arguments (can be any sort of code or text).
Note: if <macro_name>
is actually the name of a constant, it will assume !(...)
is part of the source and not error.