macros
nimony/lib/std/macros.nim
This module implements Nim's macro system for Nimony. It provides the NimNode type and operations for AST manipulation.
type NimNodeKind = enum nnkNone = (0, "nnkNone") nnkEmpty = (1, "nnkEmpty") nnkIdent = (2, "nnkIdent") nnkSym = (3, "nnkSym") nnkClosedSymChoice = (4, "nnkClosedSymChoice") nnkOpenSymChoice = (5, "nnkOpenSymChoice") nnkIntLit = (6, "nnkIntLit") nnkInt8Lit = (7, "nnkInt8Lit") nnkInt16Lit = (8, "nnkInt16Lit") nnkInt32Lit = (9, "nnkInt32Lit") nnkInt64Lit = (10, "nnkInt64Lit") nnkUIntLit = (11, "nnkUIntLit") nnkUInt8Lit = (12, "nnkUInt8Lit") nnkUInt16Lit = (13, "nnkUInt16Lit") nnkUInt32Lit = (14, "nnkUInt32Lit") nnkUInt64Lit = (15, "nnkUInt64Lit") nnkFloatLit = (16, "nnkFloatLit") nnkFloat32Lit = (17, "nnkFloat32Lit") nnkFloat64Lit = (18, "nnkFloat64Lit") nnkStrLit = (19, "nnkStrLit") nnkRStrLit = (20, "nnkRStrLit") nnkTripleStrLit = (21, "nnkTripleStrLit") nnkCharLit = (22, "nnkCharLit") nnkNilLit = (23, "nnkNilLit") nnkCall = (24, "nnkCall") nnkCommand = (25, "nnkCommand") nnkCallStrLit = (26, "nnkCallStrLit") nnkInfix = (27, "nnkInfix") nnkPrefix = (28, "nnkPrefix") nnkPostfix = (29, "nnkPostfix") nnkHiddenCallConv = (30, "nnkHiddenCallConv") nnkExprEqExpr = (31, "nnkExprEqExpr") nnkExprColonExpr = (32, "nnkExprColonExpr") nnkPar = (33, "nnkPar") nnkBracket = (34, "nnkBracket") nnkCurly = (35, "nnkCurly") nnkTupleConstr = (36, "nnkTupleConstr") nnkObjConstr = (37, "nnkObjConstr") nnkTableConstr = (38, "nnkTableConstr") nnkBracketExpr = (39, "nnkBracketExpr") nnkCurlyExpr = (40, "nnkCurlyExpr") nnkDotExpr = (41, "nnkDotExpr") nnkDerefExpr = (42, "nnkDerefExpr") nnkHiddenDeref = (43, "nnkHiddenDeref") nnkAddr = (44, "nnkAddr") nnkHiddenAddr = (45, "nnkHiddenAddr") nnkCast = (46, "nnkCast") nnkConv = (47, "nnkConv") nnkHiddenStdConv = (48, "nnkHiddenStdConv") nnkHiddenSubConv = (49, "nnkHiddenSubConv") nnkIfExpr = (50, "nnkIfExpr") nnkWhenExpr = (51, "nnkWhenExpr") nnkStmtList = (52, "nnkStmtList") nnkStmtListExpr = (53, "nnkStmtListExpr") nnkBlockExpr = (54, "nnkBlockExpr") nnkBlockStmt = (55, "nnkBlockStmt") nnkAsgn = (56, "nnkAsgn") nnkFastAsgn = (57, "nnkFastAsgn") nnkVarSection = (58, "nnkVarSection") nnkLetSection = (59, "nnkLetSection") nnkConstSection = (60, "nnkConstSection") nnkIdentDefs = (61, "nnkIdentDefs") nnkVarTuple = (62, "nnkVarTuple") nnkIfStmt = (63, "nnkIfStmt") nnkWhenStmt = (64, "nnkWhenStmt") nnkElifBranch = (65, "nnkElifBranch") nnkElse = (66, "nnkElse") nnkCaseStmt = (67, "nnkCaseStmt") nnkOfBranch = (68, "nnkOfBranch") nnkWhileStmt = (69, "nnkWhileStmt") nnkForStmt = (70, "nnkForStmt") nnkTryStmt = (71, "nnkTryStmt") nnkExceptBranch = (72, "nnkExceptBranch") nnkFinally = (73, "nnkFinally") nnkReturnStmt = (74, "nnkReturnStmt") nnkBreakStmt = (75, "nnkBreakStmt") nnkContinueStmt = (76, "nnkContinueStmt") nnkYieldStmt = (77, "nnkYieldStmt") nnkRaiseStmt = (78, "nnkRaiseStmt") nnkDiscardStmt = (79, "nnkDiscardStmt") nnkProcDef = (80, "nnkProcDef") nnkFuncDef = (81, "nnkFuncDef") nnkMethodDef = (82, "nnkMethodDef") nnkIteratorDef = (83, "nnkIteratorDef") nnkMacroDef = (84, "nnkMacroDef") nnkTemplateDef = (85, "nnkTemplateDef") nnkConverterDef = (86, "nnkConverterDef") nnkFormalParams = (87, "nnkFormalParams") nnkGenericParams = (88, "nnkGenericParams") nnkPragma = (89, "nnkPragma") nnkPragmaExpr = (90, "nnkPragmaExpr") nnkTypeSection = (91, "nnkTypeSection") nnkTypeDef = (92, "nnkTypeDef") nnkObjectTy = (93, "nnkObjectTy") nnkTupleTy = (94, "nnkTupleTy") nnkEnumTy = (95, "nnkEnumTy") nnkEnumFieldDef = (96, "nnkEnumFieldDef") nnkRecList = (97, "nnkRecList") nnkRecCase = (98, "nnkRecCase") nnkRecWhen = (99, "nnkRecWhen") nnkDistinctTy = (100, "nnkDistinctTy") nnkRefTy = (101, "nnkRefTy") nnkPtrTy = (102, "nnkPtrTy") nnkVarTy = (103, "nnkVarTy") nnkProcTy = (104, "nnkProcTy") nnkIteratorTy = (105, "nnkIteratorTy") nnkRange = (106, "nnkRange") nnkImportStmt = (107, "nnkImportStmt") nnkExportStmt = (108, "nnkExportStmt") nnkIncludeStmt = (109, "nnkIncludeStmt") nnkFromImport = (110, "nnkFromImport") nnkImportExcept = (111, "nnkImportExcept") nnkBind = (112, "nnkBind") nnkMixin = (113, "nnkMixin") nnkUsing = (114, "nnkUsing") nnkCommentStmt = (115, "nnkCommentStmt") nnkStaticStmt = (116, "nnkStaticStmt") nnkDefer = (117, "nnkDefer") nnkAsm = (118, "nnkAsm") nnkDo = (119, "nnkDo") nnkAccQuoted = (120, "nnkAccQuoted") nnkError = (121, "nnkError") nnkType = (122, "nnkType")
func dollar`.NimNodeKind(e: NimNodeKind): stringtype NimNode = ref NimNode.Objtype NimNode.Obj = object kindField: NimNodeKind kids: seq strValField: string intValField: int64 floatValField: float64
template isNilNode(n: ref NimNode.Obj): boolfunc kind(n: ref NimNode.Obj): NimNodeKindfunc kind=(n: ref NimNode.Obj; k: NimNodeKind)func len(n: ref NimNode.Obj): int64func [](n: ref NimNode.Obj; i: int64): ref NimNode.Objfunc [](n: ref NimNode.Obj; i: BackwardsIndex): ref NimNode.Objfunc []=(n: ref NimNode.Obj; i: int64; child: ref NimNode.Obj)func []=(n: ref NimNode.Obj; i: BackwardsIndex; child: ref NimNode.Obj)func add(n: ref NimNode.Obj; child: ref NimNode.Obj)iterator items(n: ref NimNode.Obj): ref NimNode.Objiterator pairs(n: ref NimNode.Obj): tuple[int64, ref NimNode.Obj]proc strVal(n: ref NimNode.Obj): stringfunc strVal=(n: ref NimNode.Obj; s: string)proc intVal(n: ref NimNode.Obj): int64func intVal=(n: ref NimNode.Obj; i: int64)proc floatVal(n: ref NimNode.Obj): float64func floatVal=(n: ref NimNode.Obj; f: float64)func newNimNode(kind: NimNodeKind): ref NimNode.Objfunc newEmptyNode(): ref NimNode.Objfunc newIdentNode(ident: string): ref NimNode.Objfunc newStrLitNode(s: string): ref NimNode.Objfunc newIntLitNode(i: int64): ref NimNode.Objfunc newFloatLitNode(f: float64): ref NimNode.Objfunc newNilLit(): ref NimNode.Objfunc newSymNode(fullName: string): ref NimNode.ObjConstruct a
NimNodeof kindnnkSymcarrying a fully-qualified symbol name. The serialiser emits this as a NIF Symbol token, which sem treats as already-resolved — so any name lookup at the macro call site is bypassed. Used as the runtime form ofbindSym(the magic resolves the name at the macro's def-site and rewritesbindSym "foo"tonewSymNode "<full.foo.suffix>").type BindSymRule = enum brClosed = (0, "brClosed") brOpen = (1, "brOpen") brForceOpen = (2, "brForceOpen")
func dollar`.BindSymRule(e: BindSymRule): stringfunc newSymChoiceNode(rule: BindSymRule; fullNames: openArray): ref NimNode.ObjMulti-symbol bundle: returns a NimNode of kind
nnkClosedSymChoiceornnkOpenSymChoicewhose children are individualnnkSymnodes for eachfullName. The serialiser emits this as(cchoice …)/(ochoice …). Used bybindSymwhen the looked-up identifier matches more than one symbol.func newTree(kind: NimNodeKind; children: openArray): ref NimNode.Objfunc newCall(fn: ref NimNode.Obj; args: openArray): ref NimNode.Objfunc newCall(fn: ref NimNode.Obj): ref NimNode.Objfunc newCall(fn: string; args: openArray): ref NimNode.Objfunc newCall(fn: string): ref NimNode.Objfunc newDotExpr(a: ref NimNode.Obj; b: ref NimNode.Obj): ref NimNode.Objfunc newColonExpr(a: ref NimNode.Obj; b: ref NimNode.Obj): ref NimNode.Objfunc newStmtList(stmts: openArray): ref NimNode.Objfunc newStmtList(): ref NimNode.Objfunc newBlockStmt(label: ref NimNode.Obj; body: ref NimNode.Obj): ref NimNode.Objfunc newBlockStmt(body: ref NimNode.Obj): ref NimNode.Objfunc newVarStmt(name: ref NimNode.Obj; value: ref NimNode.Obj): ref NimNode.Objfunc newLetStmt(name: ref NimNode.Obj; value: ref NimNode.Obj): ref NimNode.Objfunc newConstStmt(name: ref NimNode.Obj; value: ref NimNode.Obj): ref NimNode.Objfunc newAssignment(lhs: ref NimNode.Obj; rhs: ref NimNode.Obj): ref NimNode.Objfunc newIfStmt(cond: ref NimNode.Obj; body: ref NimNode.Obj): ref NimNode.ObjConstruct a single-branch if statement. Add more branches with
add.proc $(n: ref NimNode.Obj): stringBasic tree repr for debugging
proc treeRepr(n: ref NimNode.Obj): stringfunc copy(n: ref NimNode.Obj): ref NimNode.ObjDeep copy a NimNode tree
func copyNimTree(n: ref NimNode.Obj): ref NimNode.Objfunc ident(s: string): ref NimNode.Objproc fromNif(r: var Reader): ref NimNode.Objproc toNif(b: var Builder; n: ref NimNode.Obj)proc loadInput(): ref NimNode.Objproc saveOutput(n: ref NimNode.Obj)template macroMain(body: untyped)proc parseStmt(code: string): ref NimNode.Objcodeas a statement list. A syntax error is annnkErrornode, which becomes a compile error once it is part of the macro's result.proc parseExpr(code: string): ref NimNode.Objcodeas exactly one expression; errors as forparseStmt.proc expectKind(n: ref NimNode.Obj; k: NimNodeKind)proc expectLen(n: ref NimNode.Obj; len: int64)proc expectMinLen(n: ref NimNode.Obj; len: int64)func ==(a: ref NimNode.Obj; b: ref NimNode.Obj): boolStructural equality
func sameTree(a: ref NimNode.Obj; b: ref NimNode.Obj): boolfunc eqIdent(a: ref NimNode.Obj; b: string): boolCompare ident or sym to string (case insensitive)
func eqIdent(a: ref NimNode.Obj; b: ref NimNode.Obj): boolfunc basename(n: ref NimNode.Obj): ref NimNode.Obj