diff options
-rw-r--r-- | lib/core/macros.nim | 31 | ||||
-rw-r--r-- | tests/pragmas/tcustom_pragma.nim | 2 |
2 files changed, 19 insertions, 14 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 05c54df91..8cbcc54df 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -1027,7 +1027,10 @@ const nnkCallStrLit, nnkHiddenCallConv} proc expectKind*(n: NimNode; k: set[NimNodeKind]) {.compileTime.} = - assert n.kind in k, "Expected one of " & $k & ", got " & $n.kind + ## checks that `n` is of kind `k`. If this is not the case, + ## compilation aborts with an error message. This is useful for writing + ## macros that check the AST that is passed to them. + if n.kind notin k: error("Expected one of " & $k & ", got " & $n.kind, n) proc newProc*(name = newEmptyNode(); params: openArray[NimNode] = [newEmptyNode()]; body: NimNode = newStmtList(), procType = nnkProcDef): NimNode {.compileTime.} = @@ -1035,7 +1038,8 @@ proc newProc*(name = newEmptyNode(); params: openArray[NimNode] = [newEmptyNode( ## ## The ``params`` array must start with the return type of the proc, ## followed by a list of IdentDefs which specify the params. - assert procType in RoutineNodes + if procType notin RoutineNodes: + error("Expected one of " & $RoutineNodes & ", got " & $procType) result = newNimNode(procType).add( name, newEmptyNode(), @@ -1077,7 +1081,8 @@ proc newEnum*(name: NimNode, fields: openArray[NimNode], ## expectKind name, nnkIdent - doAssert len(fields) > 0, "Enum must contain at least one field" + if len(fields) < 1: + error("Enum must contain at least one field") for field in fields: expectKind field, {nnkIdent, nnkEnumFieldDef} @@ -1133,7 +1138,7 @@ proc params*(someProc: NimNode): NimNode {.compileTime.} = result = someProc[3] proc `params=`* (someProc: NimNode; params: NimNode) {.compileTime.}= someProc.expectRoutine - assert params.kind == nnkFormalParams + expectKind(params, nnkFormalParams) someProc[3] = params proc pragma*(someProc: NimNode): NimNode {.compileTime.} = @@ -1144,7 +1149,7 @@ proc pragma*(someProc: NimNode): NimNode {.compileTime.} = proc `pragma=`*(someProc: NimNode; val: NimNode){.compileTime.}= ## Set the pragma of a proc type someProc.expectRoutine - assert val.kind in {nnkEmpty, nnkPragma} + expectKind(val, {nnkEmpty, nnkPragma}) someProc[4] = val proc addPragma*(someProc, pragma: NimNode) {.compileTime.} = @@ -1156,8 +1161,8 @@ proc addPragma*(someProc, pragma: NimNode) {.compileTime.} = someProc.pragma = pragmaNode pragmaNode.add(pragma) -template badNodeKind(k, f) = - assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`" +template badNodeKind(n, f) = + error("Invalid node kind " & $n.kind & " for macros.`" & $f & "`", n) proc body*(someProc: NimNode): NimNode {.compileTime.} = case someProc.kind: @@ -1168,7 +1173,7 @@ proc body*(someProc: NimNode): NimNode {.compileTime.} = of nnkForStmt: return someProc.last else: - badNodeKind someProc.kind, "body" + badNodeKind someProc, "body" proc `body=`*(someProc: NimNode, val: NimNode) {.compileTime.} = case someProc.kind @@ -1179,7 +1184,7 @@ proc `body=`*(someProc: NimNode, val: NimNode) {.compileTime.} = of nnkForStmt: someProc[len(someProc)-1] = val else: - badNodeKind someProc.kind, "body=" + badNodeKind someProc, "body=" proc basename*(a: NimNode): NimNode {.compiletime, benign.} @@ -1195,7 +1200,7 @@ proc `$`*(node: NimNode): string {.compileTime.} = of nnkAccQuoted: result = $node[0] else: - badNodeKind node.kind, "$" + badNodeKind node, "$" proc ident*(name: string): NimNode {.magic: "StrToIdent", noSideEffect.} ## Create a new ident node from a string @@ -1281,7 +1286,7 @@ proc unpackPrefix*(node: NimNode): tuple[node: NimNode; op: string] {. proc unpackInfix*(node: NimNode): tuple[left: NimNode; op: string; right: NimNode] {.compileTime.} = - assert node.kind == nnkInfix + expectKind(node, nnkInfix) result = (node[1], $node[0], node[2]) proc copy*(node: NimNode): NimNode {.compileTime.} = @@ -1342,7 +1347,7 @@ else: proc hasArgOfName*(params: NimNode; name: string): bool {.compiletime.}= ## Search nnkFormalParams for an argument. - assert params.kind == nnkFormalParams + expectKind(params, nnkFormalParams) for i in 1 ..< params.len: template node: untyped = params[i] if name.eqIdent( $ node[0]): @@ -1451,7 +1456,7 @@ proc customPragmaNode(n: NimNode): NimNode = if varName.kind == nnkPostfix: # This is a public field. We are skipping the postfix * varName = varName[1] - if eqIdent(varName.strVal, name): + if eqIdent($varName, name): return varNode[1] if obj[1].kind == nnkOfInherit: # explore the parent object diff --git a/tests/pragmas/tcustom_pragma.nim b/tests/pragmas/tcustom_pragma.nim index 7f781f6f1..0dc85cf67 100644 --- a/tests/pragmas/tcustom_pragma.nim +++ b/tests/pragmas/tcustom_pragma.nim @@ -22,7 +22,7 @@ import custom_pragma block: # A bit more advanced case type Subfield {.defaultValue: "catman".} = object - c* {.serializationKey: "cc".}: float + `c`* {.serializationKey: "cc".}: float MySerializable = object a {.serializationKey"asdf", defaultValue: 5.} : int |