summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/ast.nim2
-rwxr-xr-xcompiler/semexprs.nim7
-rwxr-xr-xlib/core/macros.nim33
-rwxr-xr-xtests/accept/compile/tdumpast.nim23
4 files changed, 44 insertions, 21 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index bb9803830..485639a01 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -312,7 +312,7 @@ type
 
   TMagic* = enum # symbols that require compiler magic:
     mNone, mDefined, mDefinedInScope, mLow, mHigh, mSizeOf, mIs, mOf,
-    mEcho, mShallowCopy, mSlurp,
+    mEcho, mAstToYaml, mShallowCopy, mSlurp,
     mUnaryLt, mSucc, 
     mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray, 
     mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref, 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index f86a4f60d..36211fbe9 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -8,6 +8,7 @@
 #
 
 # this module does the semantic checking for expressions
+
 const 
   ConstAbstractTypes = {tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128, 
     tyArrayConstr, tyTuple, tySet}
@@ -883,6 +884,11 @@ proc setMs(n: PNode, s: PSym): PNode =
   n.sons[0] = newSymNode(s)
   n.sons[0].info = n.info
 
+proc semAstToYaml(c: PContext, n: PNode): PNode =
+  result = newStrNode(nkStrLit, n.treeToYaml.ropeToStr)
+  result.typ = getSysType(tyString)
+  result.info = n.info
+
 proc semSlurp(c: PContext, n: PNode, flags: TExprFlags): PNode = 
   if sonsLen(n) == 2:
     var a = c.semConstExpr(c, n.sons[1])
@@ -921,6 +927,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
     else:
       result = semDirectOp(c, n, flags)
   of mSlurp: result = semSlurp(c, n, flags)
+  of mAstToYaml: result = semAstToYaml(c, n)
   else: result = semDirectOp(c, n, flags)
 
 proc semIfExpr(c: PContext, n: PNode): PNode = 
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 3b11e774c..173caa347 100755
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -184,6 +184,39 @@ proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
   ## in a string literal node

   return newStrLitNode(repr(n))

 

+proc prettyPrint*(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, prettyPrint(n[0]))

+    for j in 1..n.len-1:

+      add(result, ", ")

+      add(result, prettyPrint(n[j]))

+

+  add(result, ")")

+

+proc toYaml*(n: PNimrodNode) {.magic: "AstToYaml".}

+  ## Converts the AST `n` to an YAML string

+  ##

+  ## Provides more detailed, potentially harder to digest information

+  ## than `prettyPrint`

+

 proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} =

   ## checks that `n` is of kind `k`. If this is not the case,

   ## compilation aborts with an error message. This is useful for writing

diff --git a/tests/accept/compile/tdumpast.nim b/tests/accept/compile/tdumpast.nim
index fb31af0ec..a56438773 100755
--- a/tests/accept/compile/tdumpast.nim
+++ b/tests/accept/compile/tdumpast.nim
@@ -1,29 +1,12 @@
 # Dump the contents of a PNimrodNode
 
 import macros
-
-proc dumpit(n: PNimrodNode): string {.compileTime.} = 
-  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, dumpit(n[0]))
-    for j in 1..n.len-1:
-      add(result, ", ")
-      add(result, dumpit(n[j]))
-  add(result, ")")
   
 macro dumpAST(n: stmt): stmt = 
   # dump AST as a side-effect and return the inner node
-  echo dumpit(n)
+  echo n.prettyPrint
+  echo n.toYaml
+
   result = n[1]
   
 dumpAST: