diff options
author | Zahary Karadjov <zahary@gmail.com> | 2011-11-04 04:56:40 +0200 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2011-11-04 04:56:40 +0200 |
commit | b72480ec88fa2826853b281a0c14054b51bd6c3b (patch) | |
tree | 6e385992ccf426eb0901dd9f3aa82a746f5b4465 /lib/core/macros.nim | |
parent | 4a436120bd235b7c91e5ef2a6ccdad5edb3f2daf (diff) | |
download | Nim-b72480ec88fa2826853b281a0c14054b51bd6c3b.tar.gz |
new kind of AST printer that prints indented trees
AST-to-string conversion procs renamed to repr, treeRepr and lispRepr for better consistency new dumpTree and dumpLisp procs for quick AST inspection of arbitrary nimrod blocks
Diffstat (limited to 'lib/core/macros.nim')
-rwxr-xr-x | lib/core/macros.nim | 109 |
1 files changed, 73 insertions, 36 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 8a589896d..2e75e8d5d 100755 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -189,40 +189,8 @@ proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} = return newStrLitNode(repr(n)) proc lineinfo*(n: PNimrodNode): string {.magic: "NLineInfo".} - -proc toLisp*(n: PNimrodNode): string {.compileTime.} = - ## Convert the AST `n` to a human-readable string - ## - ## You can use this as a tool to explore the Nimrod's abstract syntax - ## tree and to discover what kind of nodes must be created to represent - ## a certain expression/statement - - if n == nil: return "nil" - - result = $n.kind - add(result, "(") - - case n.kind - of nnkEmpty: nil # same as nil node in this representation - of nnkNilLit: add(result, "nil") - of nnkCharLit..nnkInt64Lit: add(result, $n.intVal) - of nnkFloatLit..nnkFloat64Lit: add(result, $n.floatVal) - of nnkStrLit..nnkTripleStrLit: add(result, $n.strVal) - of nnkIdent: add(result, $n.ident) - of nnkSym, nnkNone: assert false - else: - add(result, toLisp(n[0])) - for j in 1..n.len-1: - add(result, ", ") - add(result, toLisp(n[j])) - - add(result, ")") - -proc toYaml*(n: PNimrodNode): string {.magic: "AstToYaml".} - ## Converts the AST `n` to an YAML string - ## - ## Provides more detailed, potentially harder to digest information - ## than `toLisp` + ## returns the position the node appears in the original source file + ## in the form filename(line, col) proc parseExpr*(s: string): expr {.magic: "ParseExprToAst".} ## Compiles the passed string to its AST representation. @@ -275,8 +243,8 @@ proc newCall*(theProc: string, result.add(newIdentNode(theProc)) result.add(args) -proc nestList*(theProc: TNimrodIdent, - x: PNimrodNode): PNimrodNode {.compileTime.} = +proc nestList*(theProc: TNimrodIdent, + x: PNimrodNode): PNimrodNode {.compileTime.} = ## nests the list `x` into a tree of call expressions: ## ``[a, b, c]`` is transformed into ``theProc(a, theProc(c, d))`` var L = x.len @@ -285,3 +253,72 @@ proc nestList*(theProc: TNimrodIdent, for i in countdown(L-3, 0): a = newCall(theProc, x[i], copyNimTree(a)) +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 " " + + if n == nil: + res.add "nil" + 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]) + + result = "" + traverse(result, 0, n) + +proc lispRepr*(n: PNimrodNode): string {.compileTime.} = + ## Convert the AST `n` to a human-readable lisp-like string + ## + ## see also `repr` and `treeRepr` + + if n == nil: return "nil" + + result = ($n.kind).substr(3) + add(result, "(") + + case n.kind + of nnkEmpty: nil # same as nil node in this representation + of nnkNilLit: add(result, "nil") + of nnkCharLit..nnkInt64Lit: add(result, $n.intVal) + of nnkFloatLit..nnkFloat64Lit: add(result, $n.floatVal) + of nnkStrLit..nnkTripleStrLit: add(result, $n.strVal) + of nnkIdent: add(result, $n.ident) + of nnkSym, nnkNone: assert false + else: + add(result, lispRepr(n[0])) + for j in 1..n.len-1: + add(result, ", ") + add(result, lispRepr(n[j])) + + add(result, ")") + +macro dumpTree*(s: stmt): stmt = echo s[1].treeRepr + ## Accepts a block of nimrod code and prints the parsed abstract syntax + ## tree using the `toTree` function. + ## + ## You can use this as a tool to explore the Nimrod's abstract syntax + ## 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 + ## Accepts a block of nimrod code and prints the parsed abstract syntax + ## tree using the `toLisp` function. + ## + ## see `dumpTree` + |