diff options
-rwxr-xr-x | compiler/ast.nim | 2 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 7 | ||||
-rwxr-xr-x | lib/core/macros.nim | 33 | ||||
-rwxr-xr-x | tests/accept/compile/tdumpast.nim | 23 |
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: |