summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rwxr-xr-xlib/core/macros.nim666
1 files changed, 330 insertions, 336 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index b43105f44..8fdaf7a6c 100755
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -1,194 +1,188 @@
-#

-#

-#            Nimrod's Runtime Library

-#        (c) Copyright 2012 Andreas Rumpf

-#

-#    See the file "copying.txt", included in this

-#    distribution, for details about the copyright.

-#

-

-

-## This module contains the interface to the compiler's abstract syntax 

-## tree (`AST`:idx:). Macros operate on this tree.

-

-## .. include:: ../doc/astspec.txt

-

-type

-  TNimrodNodeKind* = enum

-    nnkNone, nnkEmpty, nnkIdent, nnkSym, 

-    nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit, 

-    nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit, 

-    nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit, 

-    nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit, 

-    nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall, 

-    nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr, 

-    nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix, 

-    nnkPrefix, nnkPostfix, nnkPar, nnkCurly, nnkCurlyExpr,

-    nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange, 

-    nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr, 

-    nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkAccQuoted, 

+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2012 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+
+## This module contains the interface to the compiler's abstract syntax
+## tree (`AST`:idx:). Macros operate on this tree.
+
+## .. include:: ../doc/astspec.txt
+
+type
+  TNimrodNodeKind* = enum
+    nnkNone, nnkEmpty, nnkIdent, nnkSym,
+    nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
+    nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit,
+    nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
+    nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
+    nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall,
+    nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr,
+    nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix,
+    nnkPrefix, nnkPostfix, nnkPar, nnkCurly, nnkCurlyExpr,
+    nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange,
+    nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr,
+    nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkAccQuoted,
     nnkTableConstr, nnkBind,
     nnkClosedSymChoice,
     nnkOpenSymChoice,
-    nnkHiddenStdConv,

-    nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, nnkStaticExpr,

-    nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv, 

-    nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange, 

-    nnkStringToCString, nnkCStringToString, nnkAsgn, 

-    nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit, 

-    nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef, 

-    nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch, 

-    nnkElifBranch, nnkExceptBranch, nnkElse, nnkMacroStmt, 

-    nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt, 

-    nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt, 

-    nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection, 

-    nnkConstDef, nnkTypeDef, 

-    nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt, 

-    nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt,

-    nnkDiscardStmt, nnkStmtList, nnkImportStmt, nnkFromStmt, 

-    nnkIncludeStmt, nnkBindStmt, nnkMixinStmt,

-    nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, 

-    nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy, 

-    nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen, 

-    nnkRefTy, nnkPtrTy, nnkVarTy, 

-    nnkConstTy, nnkMutableTy,

-    nnkDistinctTy, 

-    nnkProcTy, nnkEnumTy, 
-    nnkEnumFieldDef, 
+    nnkHiddenStdConv,
+    nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, nnkStaticExpr,
+    nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,
+    nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
+    nnkStringToCString, nnkCStringToString, nnkAsgn,
+    nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit,
+    nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef,
+    nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,
+    nnkElifBranch, nnkExceptBranch, nnkElse, nnkMacroStmt,
+    nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt,
+    nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt,
+    nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection,
+    nnkConstDef, nnkTypeDef,
+    nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt,
+    nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt,
+    nnkDiscardStmt, nnkStmtList, nnkImportStmt, nnkFromStmt,
+    nnkIncludeStmt, nnkBindStmt, nnkMixinStmt,
+    nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr,
+    nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy,
+    nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen,
+    nnkRefTy, nnkPtrTy, nnkVarTy,
+    nnkConstTy, nnkMutableTy,
+    nnkDistinctTy,
+    nnkProcTy, nnkEnumTy,
+    nnkEnumFieldDef,
     nnkArglist, nnkPattern
-    nnkReturnToken

-  TNimNodeKinds* = set[TNimrodNodeKind]

-  TNimrodTypeKind* = enum

-    ntyNone, ntyBool, ntyChar, ntyEmpty, 

-    ntyArrayConstr, ntyNil, ntyExpr, ntyStmt, 

-    ntyTypeDesc, ntyGenericInvokation, ntyGenericBody, ntyGenericInst, 

-    ntyGenericParam, ntyDistinct, ntyEnum, ntyOrdinal, 

-    ntyArray, ntyObject, ntyTuple, ntySet, 

-    ntyRange, ntyPtr, ntyRef, ntyVar, 

-    ntySequence, ntyProc, ntyPointer, ntyOpenArray, 

-    ntyString, ntyCString, ntyForward, ntyInt, 

-    ntyInt8, ntyInt16, ntyInt32, ntyInt64, 

-    ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128

-  TNimTypeKinds* = set[TNimrodTypeKind]

-  TNimrodSymKind* = enum

-    nskUnknown, nskConditional, nskDynLib, nskParam, 

-    nskGenericParam, nskTemp, nskType, nskConst, 

-    nskVar, nskProc, nskMethod, nskIterator, 

-    nskConverter, nskMacro, nskTemplate, nskField, 

-    nskEnumField, nskForVar, nskModule, nskLabel, 

-    nskStub

-  TNimSymKinds* = set[TNimrodSymKind]

-

-type

-  TNimrodIdent* = object of TObject

-    ## represents a Nimrod identifier in the AST

-

-  TNimrodSymbol {.final.} = object # hidden

-  TNimrodType {.final.} = object   # hidden

-  

-  PNimrodType* {.compilerproc.} = ref TNimrodType

-    ## represents a Nimrod type in the compiler; currently this is not very

-    ## useful as there is no API to deal with Nimrod types.

-  

-  PNimrodSymbol* {.compilerproc.} = ref TNimrodSymbol

-    ## represents a Nimrod *symbol* in the compiler; a *symbol* is a looked-up

-    ## *ident*.

-  

-const

-  nnkLiterals* = {nnkCharLit..nnkNilLit}

-  nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,

-                   nnkCallStrLit}

-

-proc `[]`*(n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".}

-  ## get `n`'s `i`'th child.

-

-proc `[]=`*(n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild".}

-  ## set `n`'s `i`'th child to `child`.

-

-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 `$`*(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.}

-  ## compares two Nimrod nodes

-

-proc len*(n: PNimrodNode): int {.magic: "NLen".}

-  ## returns the number of children of `n`.

-

-proc add*(father, child: PNimrodNode) {.magic: "NAdd".}

-  ## adds the `child` to the `father` node

-

-proc add*(father: PNimrodNode, children: varargs[PNimrodNode]) {.

-  magic: "NAddMultiple".}

-  ## adds each child of `children` to the `father` node

-

-proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel".}

-  ## deletes `n` children of `father` starting at index `idx`. 

-

-proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind".}

-  ## returns the `kind` of the node `n`.

-

-proc intVal*(n: PNimrodNode): biggestInt {.magic: "NIntVal".}

-proc floatVal*(n: PNimrodNode): biggestFloat {.magic: "NFloatVal".}

-proc symbol*(n: PNimrodNode): PNimrodSymbol {.magic: "NSymbol".}

-proc ident*(n: PNimrodNode): TNimrodIdent {.magic: "NIdent".}

-proc typ*(n: PNimrodNode): PNimrodType {.magic: "NGetType".}

-proc strVal*(n: PNimrodNode): string  {.magic: "NStrVal".}

-

-proc `intVal=`*(n: PNimrodNode, val: biggestInt) {.magic: "NSetIntVal".}

-proc `floatVal=`*(n: PNimrodNode, val: biggestFloat) {.magic: "NSetFloatVal".}

-proc `symbol=`*(n: PNimrodNode, val: PNimrodSymbol) {.magic: "NSetSymbol".}

-proc `ident=`*(n: PNimrodNode, val: TNimrodIdent) {.magic: "NSetIdent".}

-proc `typ=`*(n: PNimrodNode, typ: PNimrodType) {.magic: "NSetType".}

-proc `strVal=`*(n: PNimrodNode, val: string) {.magic: "NSetStrVal".}

-

-proc newNimNode*(kind: TNimrodNodeKind,

-                 n: PNimrodNode=nil): PNimrodNode {.magic: "NNewNimNode".}

-

-proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode".}

-proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree".}

-

-proc error*(msg: string) {.magic: "NError".}

-  ## writes an error message at compile time

-

-proc warning*(msg: string) {.magic: "NWarning".}

-  ## writes a warning message at compile time

-

-proc hint*(msg: string) {.magic: "NHint".}

-  ## writes a hint message at compile time

-

-proc newStrLitNode*(s: string): PNimrodNode {.compileTime.} =

-  ## creates a string literal node from `s`

-  result = newNimNode(nnkStrLit)

-  result.strVal = s

-

-proc newIntLitNode*(i: biggestInt): PNimrodNode {.compileTime.} =

-  ## creates a int literal node from `i`

-  result = newNimNode(nnkIntLit)

-  result.intVal = i

-

-proc newFloatLitNode*(f: biggestFloat): PNimrodNode {.compileTime.} =

-  ## creates a float literal node from `f`

-  result = newNimNode(nnkFloatLit)

-  result.floatVal = f

-

-proc newIdentNode*(i: TNimrodIdent): PNimrodNode {.compileTime.} =

-  ## creates an identifier node from `i`

-  result = newNimNode(nnkIdent)

-  result.ident = i

-

-proc newIdentNode*(i: string): PNimrodNode {.compileTime.} =

-  ## creates an identifier node from `i`

-  result = newNimNode(nnkIdent)

-  result.ident = !i

+    nnkReturnToken
+  TNimNodeKinds* = set[TNimrodNodeKind]
+  TNimrodTypeKind* = enum
+    ntyNone, ntyBool, ntyChar, ntyEmpty,
+    ntyArrayConstr, ntyNil, ntyExpr, ntyStmt,
+    ntyTypeDesc, ntyGenericInvokation, ntyGenericBody, ntyGenericInst,
+    ntyGenericParam, ntyDistinct, ntyEnum, ntyOrdinal,
+    ntyArray, ntyObject, ntyTuple, ntySet,
+    ntyRange, ntyPtr, ntyRef, ntyVar,
+    ntySequence, ntyProc, ntyPointer, ntyOpenArray,
+    ntyString, ntyCString, ntyForward, ntyInt,
+    ntyInt8, ntyInt16, ntyInt32, ntyInt64,
+    ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128
+  TNimTypeKinds* = set[TNimrodTypeKind]
+  TNimrodSymKind* = enum
+    nskUnknown, nskConditional, nskDynLib, nskParam,
+    nskGenericParam, nskTemp, nskType, nskConst,
+    nskVar, nskProc, nskMethod, nskIterator,
+    nskConverter, nskMacro, nskTemplate, nskField,
+    nskEnumField, nskForVar, nskModule, nskLabel,
+    nskStub
+  TNimSymKinds* = set[TNimrodSymKind]
+
+type
+  TNimrodIdent* = object of TObject
+    ## represents a Nimrod identifier in the AST
+
+  TNimrodSymbol {.final.} = object # hidden
+  PNimrodSymbol* {.compilerproc.} = ref TNimrodSymbol
+    ## represents a Nimrod *symbol* in the compiler; a *symbol* is a looked-up
+    ## *ident*.
+
+const
+  nnkLiterals* = {nnkCharLit..nnkNilLit}
+  nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
+                   nnkCallStrLit}
+
+proc `[]`*(n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".}
+  ## get `n`'s `i`'th child.
+
+proc `[]=`*(n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild".}
+  ## set `n`'s `i`'th child to `child`.
+
+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 `$`*(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.}
+  ## compares two Nimrod nodes
+
+proc len*(n: PNimrodNode): int {.magic: "NLen".}
+  ## returns the number of children of `n`.
+
+proc add*(father, child: PNimrodNode) {.magic: "NAdd".}
+  ## adds the `child` to the `father` node
+
+proc add*(father: PNimrodNode, children: varargs[PNimrodNode]) {.
+  magic: "NAddMultiple".}
+  ## adds each child of `children` to the `father` node
+
+proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel".}
+  ## deletes `n` children of `father` starting at index `idx`.
+
+proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind".}
+  ## returns the `kind` of the node `n`.
+
+proc intVal*(n: PNimrodNode): biggestInt {.magic: "NIntVal".}
+proc floatVal*(n: PNimrodNode): biggestFloat {.magic: "NFloatVal".}
+proc symbol*(n: PNimrodNode): PNimrodSymbol {.magic: "NSymbol".}
+proc ident*(n: PNimrodNode): TNimrodIdent {.magic: "NIdent".}
+proc typ*(n: PNimrodNode): typedesc {.magic: "NGetType".}
+proc strVal*(n: PNimrodNode): string  {.magic: "NStrVal".}
+
+proc `intVal=`*(n: PNimrodNode, val: biggestInt) {.magic: "NSetIntVal".}
+proc `floatVal=`*(n: PNimrodNode, val: biggestFloat) {.magic: "NSetFloatVal".}
+proc `symbol=`*(n: PNimrodNode, val: PNimrodSymbol) {.magic: "NSetSymbol".}
+proc `ident=`*(n: PNimrodNode, val: TNimrodIdent) {.magic: "NSetIdent".}
+proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".}
+proc `strVal=`*(n: PNimrodNode, val: string) {.magic: "NSetStrVal".}
+
+proc newNimNode*(kind: TNimrodNodeKind,
+                 n: PNimrodNode=nil): PNimrodNode {.magic: "NNewNimNode".}
+
+proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode".}
+proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree".}
+
+proc error*(msg: string) {.magic: "NError".}
+  ## writes an error message at compile time
+
+proc warning*(msg: string) {.magic: "NWarning".}
+  ## writes a warning message at compile time
+
+proc hint*(msg: string) {.magic: "NHint".}
+  ## writes a hint message at compile time
+
+proc newStrLitNode*(s: string): PNimrodNode {.compileTime.} =
+  ## creates a string literal node from `s`
+  result = newNimNode(nnkStrLit)
+  result.strVal = s
+
+proc newIntLitNode*(i: biggestInt): PNimrodNode {.compileTime.} =
+  ## creates a int literal node from `i`
+  result = newNimNode(nnkIntLit)
+  result.intVal = i
+
+proc newFloatLitNode*(f: biggestFloat): PNimrodNode {.compileTime.} =
+  ## creates a float literal node from `f`
+  result = newNimNode(nnkFloatLit)
+  result.floatVal = f
+
+proc newIdentNode*(i: TNimrodIdent): PNimrodNode {.compileTime.} =
+  ## creates an identifier node from `i`
+  result = newNimNode(nnkIdent)
+  result.ident = i
+
+proc newIdentNode*(i: string): PNimrodNode {.compileTime.} =
+  ## creates an identifier node from `i`
+  result = newNimNode(nnkIdent)
+  result.ident = !i
 
 type
   TBindSymRule* = enum   ## specifies how ``bindSym`` behaves
@@ -212,157 +206,157 @@ proc bindSym*(ident: string, rule: TBindSymRule = brClosed): PNimrodNode {.
   ## 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

-  ## in a string literal node

-  return newStrLitNode(repr(n))

-

-proc lineinfo*(n: PNimrodNode): string {.magic: "NLineInfo".}

-  ## returns the position the node appears in the original source file

-  ## in the form filename(line, col)

-

-proc parseExpr*(s: string): PNimrodNode {.magic: "ParseExprToAst".}

-  ## Compiles the passed string to its AST representation.

-  ## Expects a single expression.

-

-proc parseStmt*(s: string): PNimrodNode {.magic: "ParseStmtToAst".}

-  ## Compiles the passed string to its AST representation.

-  ## Expects one or more statements.

-

-proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst".}

-  ## Obtains the AST nodes returned from a macro or template invocation.

-  ## Example:

-  ## 

-  ## .. code-block:: nimrod

-  ##

-  ##   macro FooMacro() = 

-  ##     var ast = getAst(BarTemplate())

-

-template emit*(s: expr): stmt =

-  ## accepts a single string argument and treats it as nimrod code

-  ## that should be inserted verbatim in the program

-  ## Example:

-  ## 

-  ##   emit("echo " & '"' & "hello world".toUpper & '"')

+  ## 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
+  ## in a string literal node
+  return newStrLitNode(repr(n))
+
+proc lineinfo*(n: PNimrodNode): string {.magic: "NLineInfo".}
+  ## returns the position the node appears in the original source file
+  ## in the form filename(line, col)
+
+proc parseExpr*(s: string): PNimrodNode {.magic: "ParseExprToAst".}
+  ## Compiles the passed string to its AST representation.
+  ## Expects a single expression.
+
+proc parseStmt*(s: string): PNimrodNode {.magic: "ParseStmtToAst".}
+  ## Compiles the passed string to its AST representation.
+  ## Expects one or more statements.
+
+proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst".}
+  ## Obtains the AST nodes returned from a macro or template invocation.
+  ## Example:
+  ##
+  ## .. code-block:: nimrod
+  ##
+  ##   macro FooMacro() =
+  ##     var ast = getAst(BarTemplate())
+
+template emit*(s: expr): stmt =
+  ## accepts a single string argument and treats it as nimrod code
+  ## that should be inserted verbatim in the program
+  ## Example:
+  ##
+  ##   emit("echo " & '"' & "hello world".toUpper & '"')
   ##
   block:
     const evaluated = s
     eval: result = evaluated.parseStmt
-

-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

-  ## macros that check the AST that is passed to them.

-  if n.kind != k: error("macro expects a node of kind: " & repr(k))

-

-proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} =

-  ## checks that `n` has at least `min` children. If this is not the case,

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

-  ## macros that check its number of arguments. 

-  if n.len < min: error("macro expects a node with " & $min & " children")

-

-proc expectLen*(n: PNimrodNode, len: int) {.compileTime.} =

-  ## checks that `n` has exactly `len` children. If this is not the case,

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

-  ## macros that check its number of arguments. 

-  if n.len != len: error("macro expects a node with " & $len & " children")

-
-proc newCall*(theProc: PNimrodNode,

-              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =

-  ## produces a new call node. `theProc` is the proc that is called with

-  ## the arguments ``args[0..]``.

-  result = newNimNode(nnkCall)

-  result.add(theProc)

-  result.add(args)

-

-proc newCall*(theProc: TNimrodIdent,

-              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =

-  ## produces a new call node. `theProc` is the proc that is called with

-  ## the arguments ``args[0..]``.

-  result = newNimNode(nnkCall)

-  result.add(newIdentNode(theProc))

-  result.add(args)

-  

-proc newCall*(theProc: string,

-              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =

-  ## produces a new call node. `theProc` is the proc that is called with

-  ## the arguments ``args[0..]``.

-  result = newNimNode(nnkCall)

-  result.add(newIdentNode(theProc))

-  result.add(args)

-

-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

-  result = newCall(theProc, x[L-2], x[L-1])

-  var a = result

-  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 "  "

-    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 & '"')

+
+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
+  ## macros that check the AST that is passed to them.
+  if n.kind != k: error("macro expects a node of kind: " & repr(k))
+
+proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} =
+  ## checks that `n` has at least `min` children. If this is not the case,
+  ## compilation aborts with an error message. This is useful for writing
+  ## macros that check its number of arguments.
+  if n.len < min: error("macro expects a node with " & $min & " children")
+
+proc expectLen*(n: PNimrodNode, len: int) {.compileTime.} =
+  ## checks that `n` has exactly `len` children. If this is not the case,
+  ## compilation aborts with an error message. This is useful for writing
+  ## macros that check its number of arguments.
+  if n.len != len: error("macro expects a node with " & $len & " children")
+
+proc newCall*(theProc: PNimrodNode,
+              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
+  ## produces a new call node. `theProc` is the proc that is called with
+  ## the arguments ``args[0..]``.
+  result = newNimNode(nnkCall)
+  result.add(theProc)
+  result.add(args)
+
+proc newCall*(theProc: TNimrodIdent,
+              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
+  ## produces a new call node. `theProc` is the proc that is called with
+  ## the arguments ``args[0..]``.
+  result = newNimNode(nnkCall)
+  result.add(newIdentNode(theProc))
+  result.add(args)
+
+proc newCall*(theProc: string,
+              args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
+  ## produces a new call node. `theProc` is the proc that is called with
+  ## the arguments ``args[0..]``.
+  result = newNimNode(nnkCall)
+  result.add(newIdentNode(theProc))
+  result.add(args)
+
+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
+  result = newCall(theProc, x[L-2], x[L-1])
+  var a = result
+  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 "  "
+    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: res.add(" \"" & $n.symbol & '"')
-    of 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`.

-  

-  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.treeRepr

-  ## Accepts a block of nimrod code and prints the parsed abstract syntax

-  ## tree using the `toTree` function. Printing is done *at compile time*.

-  ##

-  ## 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.lispRepr

-  ## Accepts a block of nimrod code and prints the parsed abstract syntax

-  ## tree using the `toLisp` function. Printing is done *at compile time*.

-  ##

-  ## See `dumpTree`.

-

+    of 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`.
+
+  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.treeRepr
+  ## Accepts a block of nimrod code and prints the parsed abstract syntax
+  ## tree using the `toTree` function. Printing is done *at compile time*.
+  ##
+  ## 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.lispRepr
+  ## Accepts a block of nimrod code and prints the parsed abstract syntax
+  ## tree using the `toLisp` function. Printing is done *at compile time*.
+  ##
+  ## See `dumpTree`.
+