← Back to AILP Home

Debugging Macros with --expand-macros

The --expand-macros flag dumps the compiler's macro expansion trace to stdout and exits. Use it to inspect what each macro call expands to before type-checking and code generation.

Usage

npkc myfile.npk --expand-macros

The flag parses and type-checks the file (triggering macro expansion), then prints the expansion log and exits with code 0. No binary is produced.

Output Format

For each macro invocation in the file, the trace shows:

// macro expansion at <file>:<line>:<column>
// call:     <macro-name>!(<argument-AST>)
// expanded: <expanded-AST>

Followed by a total count:

// total: N expansion(s)

If the file contains no macro invocations:

// no macro invocations found in <file>

Example

Given example.npk:

macro:double = (x) {
    x + x;
};

func:main = int32() {
    int32:val = double!(5i32);
    assert!(true);
    exit(0);
};
func:failsafe = int32(tbb32:e) { exit(1); };

Running:

$ npkc example.npk --expand-macros
// macro expansion at example.npk:6:17
// call:     double!(Literal(5:i32))
// expanded: Block([ExprStmt(Binary(Literal(5:i32) PLUS Literal(5:i32)))])

// macro expansion at example.npk:7:5
// call:     assert!(Literal(true))
// expanded: AssertStatic(Literal(true))

// total: 2 expansion(s)

Reading the Output

Combining with Other Flags

--expand-macros cannot be combined with --tokens or --ast-dump. Use each flag independently.

Exit Code

--expand-macros always exits 0 on a well-formed file. If the file has a syntax or type error, it exits non-zero with the diagnostic on stderr.