diff options
author | Araq <rumpf_a@web.de> | 2012-08-28 22:15:29 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-08-28 22:15:29 +0200 |
commit | b4844a189d88655394080f765076a7d85fe6185d (patch) | |
tree | 466be4d35d50e7928cbef25a416e2c97f50c2490 /lib/core | |
parent | 6bcdb9c8f429b48e534c50d3dadf7b31783aa0bf (diff) | |
download | Nim-b4844a189d88655394080f765076a7d85fe6185d.tar.gz |
parameter passing works the same for macros and templates; use callsite magic to access the invokation AST
Diffstat (limited to 'lib/core')
-rwxr-xr-x | lib/core/macros.nim | 66 |
1 files changed, 26 insertions, 40 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim index fac935430..610360fb2 100755 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -96,27 +96,25 @@ const nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand, nnkCallStrLit} -# Nodes should be reference counted to make the `copy` operation very fast! -# However, this is difficult to achieve: modify(n[0][1]) should propagate to -# its father. How to do this without back references? Hm, BS, it works without -# them. - -proc `[]`* (n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".} +proc `[]`*(n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".} ## get `n`'s `i`'th child. -proc `[]=`* (n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild".} +proc `[]=`*(n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild".} ## set `n`'s `i`'th child to `child`. -proc `!` *(s: string): TNimrodIdent {.magic: "StrToIdent".} +proc `!`*(s: string): TNimrodIdent {.magic: "StrToIdent".} ## constructs an identifier from the string `s` proc `$`*(i: TNimrodIdent): string {.magic: "IdentToStr".} ## converts a Nimrod identifier to a string -proc `==`* (a, b: TNimrodIdent): bool {.magic: "EqIdent", noSideEffect.} +proc `$`*(s: PNimrodSymbol): string {.magic: "IdentToStr".} + ## converts a Nimrod symbol to a string + +proc `==`*(a, b: TNimrodIdent): bool {.magic: "EqIdent", noSideEffect.} ## compares two Nimrod identifiers -proc `==`* (a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.} +proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.} ## compares two Nimrod nodes proc len*(n: PNimrodNode): int {.magic: "NLen".} @@ -209,6 +207,9 @@ proc bindSym*(ident: string, rule: TBindSymRule = brClosed): PNimrodNode {. ## returned or ``nkSym`` if the symbol is not ambiguous. ## If ``rule == brForceOpen`` always an ``nkOpenSymChoice`` tree is ## returned even if the symbol is not ambiguous. + +proc callsite*(): PNimrodNode {.magic: "NCallSite".} + ## returns the AST if the invokation expression that invoked this macro. proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} = ## converts the AST `n` to the concrete Nimrod code and wraps that @@ -246,15 +247,6 @@ template emit*(s: expr): stmt = block: const evaluated = s eval: result = evaluated.parseStmt - when false: - template once(x: expr): expr = - block: - const y = x - y - - macro `payload`(x: stmt): stmt = result = once(s).parseStmt - `payload`() - proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} = ## checks that `n` is of kind `k`. If this is not the case, @@ -312,27 +304,23 @@ proc treeRepr*(n: PNimrodNode): string {.compileTime.} = ## Convert the AST `n` to a human-readable tree-like string. ## ## See also `repr` and `lispRepr`. - proc traverse(res: var string, level: int, n: PNimrodNode) = for i in 0..level-1: res.add " " + res.add(($n.kind).substr(3)) - if n == nil: - res.add "nil" + case n.kind + of nnkEmpty: nil # same as nil node in this representation + of nnkNilLit: res.add(" nil") + of nnkCharLit..nnkInt64Lit: res.add(" " & $n.intVal) + of nnkFloatLit..nnkFloat64Lit: res.add(" " & $n.floatVal) + of nnkStrLit..nnkTripleStrLit: res.add(" " & $n.strVal) + of nnkIdent: res.add(" !\"" & $n.ident & '"') + of nnkSym: res.add(" \"" & $n.symbol & '"') + of nnkNone: assert false else: - res.add(($n.kind).substr(3)) - - case n.kind - of nnkEmpty: nil # same as nil node in this representation - of nnkNilLit: res.add(" nil") - of nnkCharLit..nnkInt64Lit: res.add(" " & $n.intVal) - of nnkFloatLit..nnkFloat64Lit: res.add(" " & $n.floatVal) - of nnkStrLit..nnkTripleStrLit: res.add(" " & $n.strVal) - of nnkIdent: res.add(" !\"" & $n.ident & '"') - of nnkSym, nnkNone: assert false - else: - for j in 0..n.len-1: - res.add "\n" - traverse(res, level + 1, n[j]) + for j in 0..n.len-1: + res.add "\n" + traverse(res, level + 1, n[j]) result = "" traverse(result, 0, n) @@ -342,8 +330,6 @@ proc lispRepr*(n: PNimrodNode): string {.compileTime.} = ## ## See also `repr` and `treeRepr`. - if n == nil: return "nil" - result = ($n.kind).substr(3) add(result, "(") @@ -363,7 +349,7 @@ proc lispRepr*(n: PNimrodNode): string {.compileTime.} = add(result, ")") -macro dumpTree*(s: stmt): stmt = echo s[1].treeRepr +macro dumpTree*(s: stmt): stmt = echo s.treeRepr ## Accepts a block of nimrod code and prints the parsed abstract syntax ## tree using the `toTree` function. Printing is done *at compile time*. ## @@ -371,7 +357,7 @@ macro dumpTree*(s: stmt): stmt = echo s[1].treeRepr ## tree and to discover what kind of nodes must be created to represent ## a certain expression/statement. -macro dumpLisp*(s: stmt): stmt = echo s[1].lispRepr +macro dumpLisp*(s: stmt): stmt = echo s.lispRepr ## Accepts a block of nimrod code and prints the parsed abstract syntax ## tree using the `toLisp` function. Printing is done *at compile time*. ## |