summary refs log tree commit diff stats
path: root/lib/core
diff options
context:
space:
mode:
authorKaushal Modi <kaushal.modi@gmail.com>2018-10-27 09:10:05 -0400
committerDominik Picheta <dominikpicheta@googlemail.com>2018-10-27 14:10:05 +0100
commitf8cef575b322d9736df369e2a33f5ade7d800f95 (patch)
tree64656b79bd130ddf281d2fcfc5733d31f7b31043 /lib/core
parentdd252ce640c7f624acc08a6702193ec15fd7359b (diff)
downloadNim-f8cef575b322d9736df369e2a33f5ade7d800f95.tar.gz
Improve dumpLisp macro (#9515)
* Improve dumpLisp macro

- Remove commas from the lisp representation of the AST.
- Make the dumpLisp output "pretty" and indented.
- Improve docs of `dumpTree` and `dumpLisp` macros.

With:

    dumpLisp:
      echo "Hello, World!"

Output before this commit:

    StmtList(Command(Ident("echo"), StrLit("Hello, World!")))

Output after this commit:

    (StmtList
     (Command
      (Ident "echo")
      (StrLit "Hello, World!")))

* Re-use the traverse proc inside treeRepr for lispRepr too

- Add module-local `treeTraverse` proc.
- Also fix treeRepr/dumpTree not printing nnkCommentStmt node contents.

* More doc string updates

* Allow unindented lispRepr output for tests

* Update a test affected by the lispRepr change

* Fix dumpTree

* Add note about lispRepr and dumpLisp to changelog [ci skip]
Diffstat (limited to 'lib/core')
-rw-r--r--lib/core/macros.nim158
1 files changed, 96 insertions, 62 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 3801adfc5..87daabb5b 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -732,72 +732,56 @@ proc nestList*(theProc: NimIdent, x: NimNode): NimNode {.compileTime, deprecated
   for i in countdown(L-3, 0):
     result = newCall(theProc, x[i], result)
 
-proc treeRepr*(n: NimNode): string {.compileTime, benign.} =
-  ## Convert the AST `n` to a human-readable tree-like string.
-  ##
-  ## See also `repr`, `lispRepr`, and `astGenRepr`.
-
-  proc traverse(res: var string, level: int, n: NimNode) {.benign.} =
-    for i in 0..level-1: res.add "  "
-    res.add(($n.kind).substr(3))
-
-    case n.kind
-    of nnkEmpty, nnkNilLit: discard # same as nil node in this representation
-    of nnkCharLit..nnkInt64Lit: res.add(" " & $n.intVal)
-    of nnkFloatLit..nnkFloat64Lit: res.add(" " & $n.floatVal)
-    of nnkStrLit..nnkTripleStrLit, nnkIdent, nnkSym:
-      res.add(" " & $n.strVal.newLit.repr)
-    of nnkNone: assert false
+proc treeTraverse(n: NimNode; res: var string; level = 0; isLisp = false, indented = false) {.benign.} =
+  if level > 0:
+    if indented:
+      res.add("\n")
+      for i in 0 .. level-1:
+        if isLisp:
+          res.add(" ")          # dumpLisp indentation
+        else:
+          res.add("  ")         # dumpTree indentation
     else:
-      for j in 0..n.len-1:
-        res.add "\n"
-        traverse(res, level + 1, n[j])
+      res.add(" ")
 
-  result = ""
-  traverse(result, 0, n)
-
-proc lispRepr*(n: NimNode): string {.compileTime, benign.} =
-  ## Convert the AST `n` to a human-readable lisp-like string,
-  ##
-  ## See also `repr`, `treeRepr`, and `astGenRepr`.
-
-  result = ($n.kind).substr(3)
-  add(result, "(")
+  if isLisp:
+    res.add("(")
+  res.add(($n.kind).substr(3))
 
   case n.kind
-  of nnkEmpty, nnkNilLit: discard # same as nil node in this representation
-  of nnkCharLit..nnkInt64Lit: add(result, $n.intVal)
-  of nnkFloatLit..nnkFloat64Lit: add(result, $n.floatVal)
-  of nnkStrLit..nnkTripleStrLit, nnkCommentStmt, nnkident, nnkSym:
-    add(result, n.strVal.newLit.repr)
-  of nnkNone: assert false
+  of nnkEmpty, nnkNilLit:
+    discard # same as nil node in this representation
+  of nnkCharLit .. nnkInt64Lit:
+    res.add(" " & $n.intVal)
+  of nnkFloatLit .. nnkFloat64Lit:
+    res.add(" " & $n.floatVal)
+  of nnkStrLit .. nnkTripleStrLit, nnkCommentStmt, nnkIdent, nnkSym:
+    res.add(" " & $n.strVal.newLit.repr)
+  of nnkNone:
+    assert false
   else:
-    if n.len > 0:
-      add(result, lispRepr(n[0]))
-      for j in 1..n.len-1:
-        add(result, ", ")
-        add(result, lispRepr(n[j]))
+    for j in 0 .. n.len-1:
+      n[j].treeTraverse(res, level+1, isLisp, indented)
 
-  add(result, ")")
+  if isLisp:
+    res.add(")")
 
-proc astGenRepr*(n: NimNode): string {.compileTime, benign.} =
-  ## Convert the AST `n` to the code required to generate that AST. So for example
-  ##
-  ## .. code-block:: nim
-  ##   astGenRepr:
-  ##     echo "Hello world"
+proc treeRepr*(n: NimNode): string {.compileTime, benign.} =
+  ## Convert the AST `n` to a human-readable tree-like string.
   ##
-  ## Would output:
+  ## See also `repr`, `lispRepr`, and `astGenRepr`.
+  n.treeTraverse(result, isLisp = false, indented = true)
+
+proc lispRepr*(n: NimNode; indented = false): string {.compileTime, benign.} =
+  ## Convert the AST ``n`` to a human-readable lisp-like string.
   ##
-  ## .. code-block:: nim
-  ##   nnkStmtList.newTree(
-  ##     nnkCommand.newTree(
-  ##       newIdentNode("echo"),
-  ##       newLit("Hello world")
-  ##     )
-  ##   )
+  ## See also ``repr``, ``treeRepr``, and ``astGenRepr``.
+  n.treeTraverse(result, isLisp = true, indented = indented)
+
+proc astGenRepr*(n: NimNode): string {.compileTime, benign.} =
+  ## Convert the AST ``n`` to the code required to generate that AST.
   ##
-  ## See also `repr`, `treeRepr`, and `lispRepr`.
+  ## See also ``repr``, ``treeRepr``, and ``lispRepr``.
 
   const
     NodeKinds = {nnkEmpty, nnkIdent, nnkSym, nnkNone, nnkCommentStmt}
@@ -842,26 +826,76 @@ proc astGenRepr*(n: NimNode): string {.compileTime, benign.} =
 
 macro dumpTree*(s: untyped): untyped = echo s.treeRepr
   ## Accepts a block of nim code and prints the parsed abstract syntax
-  ## tree using the `treeRepr` function. Printing is done *at compile time*.
+  ## tree using the ``treeRepr`` proc. Printing is done *at compile time*.
   ##
   ## You can use this as a tool to explore the Nim's abstract syntax
   ## tree and to discover what kind of nodes must be created to represent
   ## a certain expression/statement.
+  ##
+  ## For example:
+  ##
+  ## .. code-block:: nim
+  ##    dumpTree:
+  ##      echo "Hello, World!"
+  ##
+  ## Outputs:
+  ##
+  ## .. code-block::
+  ##    StmtList
+  ##      Command
+  ##        Ident "echo"
+  ##        StrLit "Hello, World!"
+  ##
+  ## Also see ``dumpAstGen`` and ``dumpLisp``.
 
-macro dumpLisp*(s: untyped): untyped = echo s.lispRepr
+macro dumpLisp*(s: untyped): untyped = echo s.lispRepr(indented = true)
   ## Accepts a block of nim code and prints the parsed abstract syntax
-  ## tree using the `lispRepr` function. Printing is done *at compile time*.
+  ## tree using the ``lispRepr`` proc. Printing is done *at compile time*.
+  ##
+  ## You can use this as a tool to explore the Nim's abstract syntax
+  ## tree and to discover what kind of nodes must be created to represent
+  ## a certain expression/statement.
   ##
-  ## See `dumpTree`.
+  ## For example:
+  ##
+  ## .. code-block:: nim
+  ##    dumpLisp:
+  ##      echo "Hello, World!"
+  ##
+  ## Outputs:
+  ##
+  ## .. code-block::
+  ##    (StmtList
+  ##     (Command
+  ##      (Ident "echo")
+  ##      (StrLit "Hello, World!")))
+  ##
+  ## Also see ``dumpAstGen`` and ``dumpTree``.
 
 macro dumpAstGen*(s: untyped): untyped = echo s.astGenRepr
   ## Accepts a block of nim code and prints the parsed abstract syntax
-  ## tree using the `astGenRepr` function. Printing is done *at compile time*.
+  ## tree using the ``astGenRepr`` proc. Printing is done *at compile time*.
   ##
   ## You can use this as a tool to write macros quicker by writing example
   ## outputs and then copying the snippets into the macro for modification.
   ##
-  ## See `dumpTree`.
+  ## For example:
+  ##
+  ## .. code-block:: nim
+  ##    dumpAstGen:
+  ##      echo "Hello, World!"
+  ##
+  ## Outputs:
+  ##
+  ## .. code-block:: nim
+  ##    nnkStmtList.newTree(
+  ##      nnkCommand.newTree(
+  ##        newIdentNode("echo"),
+  ##        newLit("Hello, World!")
+  ##      )
+  ##    )
+  ##
+  ## Also see ``dumpTree`` and ``dumpLisp``.
 
 macro dumpTreeImm*(s: untyped): untyped {.deprecated.} = echo s.treeRepr
   ## Deprecated. Use `dumpTree` instead.
2017-03-16 22:34:49 +0100 committer Dominik Picheta <dominikpicheta@gmail.com> 2017-03-16 22:34:49 +0100 Cleaned up nep1 and simplified the style choices offered by it.' href='/ahoang/Nim/commit/doc/nep1.rst?h=devel&id=b938a5b884a9f32649a8e02968b980096fd7353d'>b938a5b88 ^
9da1ee4fe ^



b938a5b88 ^

9da1ee4fe ^


9da1ee4fe ^



b938a5b88 ^

9da1ee4fe ^


b938a5b88 ^

9da1ee4fe ^
c0ea647c3 ^
b938a5b88 ^
9da1ee4fe ^


b938a5b88 ^

9da1ee4fe ^
11d026501 ^
9da1ee4fe ^

b938a5b88 ^


9da1ee4fe ^

9da1ee4fe ^
c0ea647c3 ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201