Macros
LuneScript macros are a powerful feature that expands and generates code (AST) at compile time.
Definition
Defined using the macro keyword. By convention, macro names begin with an underscore
_.
macro _dprint( exp: __exp ) {
print( "DEBUG:", ,,exp );
}
Arguments
In addition to regular types, you can specify macro-specific types for macro arguments.
__exp: Receives the expression itself. The most versatile type.sym: Receives a symbol (variable name, function name, etc.).__block: Receives a code block{ ... }.
macro _assign( symbol: sym, val: int ) {
,,symbol = ,,val;
}
let mut val = 0;
_assign( val, 10 ); // Expanded as val = 10;
Quoting (Expansion Operators)
When using arguments in the macro body (expand-statement), use the following operators to control expansion.
| Operator | Description |
|---|---|
,, |
Expands the value of the argument directly as code. |
,,, |
Expands the string value of the argument as a symbol name. |
,,,, |
Converts the symbol name of the argument into a string literal and expands it. |
pub macro _hello( name: str ) {
print( "Hello, ", ,,name );
}
Macro Statement
A macro definition consists of a macro-statement (the first {}) for calculations
and preparation, and an expand-statement (the latter part) for generating actual code.
Within the macro-statement, standard LuneScript calculation features can be used to determine
the content of the expanded code dynamically. Furthermore, by using the `{} operator, fragments
of code (of type stat) can be stored into variables and listed.
Example of Dynamic Code Generation
The following example automatically defines a series of variables by the specified count.
macro _GenVars( prefix: str, count: int ) {
{
// macro-statement: Create a list of code to expand
let mut stats: List<stat> = [];
for i = 1, count {
let varName = "%s%d" (prefix, i);
stats.insert( `{
let ,,,"v_%s"(varName)~~ = ,,i;
} );
}
}
// expand-statement: Expand the generated list all at once
,,stats;
}
_GenVars( "val", 3 );
// Expanded as let v_val1 = 1; let v_val2 = 2; let v_val3 = 3;
print( v_val1, v_val2, v_val3 ); // 1 2 3
Constraints within macro-statement
- Available functions are only LuneScript standard functions (
print,os.clock,io.open, etc.). - You cannot call regular functions defined within the same file (since those functions do not exist yet at compile time).
- The special operator
~~is used to explicitly indicate the end of the expression targeted by the,,,operator.
Caution: Conflict with Lua Reserved Words
If a variable name in the code expanded by a macro conflicts with a Lua reserved word (such asend), an error will occur after transcompilation. Be careful with variable names used inside
macros.