← Back to AILP Home

Basic Macros

Declaration

Use macro:name = (params) { body }; to declare a macro:

// zero-argument macro
macro:greet = () {
    println("hello");
};

// one-argument macro
macro:double = (x) {
    x + x;
};

// two-argument macro
macro:add_and_print = (a, b) {
    println(`sum: &{a + b}`);
};

A macro body is a block { ... } containing statements and expressions. The last expression in the body (without a trailing ;) becomes the expansion result in expression position.

Invocation

Invoke a macro with name!(args):

// expression position — result used as a value
int32:n = double!(5i32);        // expands to: 5 + 5

// statement position — result discarded
greet!();                       // expands to: println("hello");
add_and_print!(10i32, 20i32);   // expands to: println(...)

Rules

Scope

Macros are file-scoped. They are not exported from modules and cannot be imported with use. To share a macro across files, define it in a shared include or duplicate it.

Example: min macro

macro:min = (a, b) {
    if (a < b) { a } else { b }
};

func:main = int32() {
    int32:x = min!(10i32, 20i32);   // expands to: if (10 < 20) { 10 } else { 20 }
    println(`min = &{x}`);
    exit(0);
};
func:failsafe = int32(tbb32:e) { exit(1); };