Macros can build code node by node: newCall(ident"echo", newLit("hi")) equals echo "hi".
Nim Expert · Lesson 1 · On the house
Building ASTs in macros
Construct NimNodes with newTree, newCall, ident, and newLit, and walk typed arguments. Lesson 1 is free — on the house.
Lessons · Nim Expert · Lesson 1 of 10 · On the house
Building ASTs in macros
Construct NimNodes with newTree, newCall, ident, and newLit, and walk typed arguments.

newTree(nnkInfix, ident"+", a, b) builds a + b; newStmtList() collects statements; result.add appends.
Iterate children with for child in node: and inspect node.kind, node.len, node[i], node.strVal, node.intVal.
typed parameters are semantically checked first, so you can call getType/getTypeImpl to read object fields.
expandMacros: or echo result.repr at the end of a macro shows the generated code while debugging.
AST building
import std/macros
macro sumLits(args: varargs[untyped]): untyped =
result = newLit(0)
for a in args:
result = newTree(nnkInfix, ident"+", result, a)
macro fieldNames(T: typedesc): untyped =
let impl = T.getTypeInst[1].getImpl
var names = newSeq[string]()
for def in impl[2][2]:
for i in 0 ..< def.len - 2:
names.add $def[i]
newLit(names)
macro echoEach(args: varargs[untyped]): untyped =
result = newStmtList()
for a in args:
result.add newCall(ident"echo", newLit(a.repr & " = "), a)
type Order = object
id: int
total, tax: float
echo sumLits(1, 2, 3, 4)
echo fieldNames(Order)
let x = 6
echoEach(x * 7, x div 4)
Quiz
Quiz
Quiz
Quiz
Check
Match the still for: Building ASTs in macros.
Open-book: the answers are on this page. Pass every quiz and check (5) to mark the lesson done. This visit: 0/5.