macros.PNimrodNode is now NimNode

This commit is contained in:
Araq 2015-02-23 10:16:20 +01:00
commit 1e6aef62ba
9 changed files with 62 additions and 50 deletions

View file

@ -89,6 +89,7 @@ proc initDefines*() =
defineSymbol("nimparsebiggestfloatmagic") defineSymbol("nimparsebiggestfloatmagic")
defineSymbol("nimalias") defineSymbol("nimalias")
defineSymbol("nimlocks") defineSymbol("nimlocks")
defineSymbol("nimnode")
# add platform specific symbols: # add platform specific symbols:
for c in low(CPU)..high(CPU): for c in low(CPU)..high(CPU):

View file

@ -1512,7 +1512,9 @@ proc semExpandToAst(c: PContext, n: PNode): PNode =
# Preserve the magic symbol in order to be handled in evals.nim # Preserve the magic symbol in order to be handled in evals.nim
internalAssert n.sons[0].sym.magic == mExpandToAst internalAssert n.sons[0].sym.magic == mExpandToAst
n.typ = getSysSym("PNimrodNode").typ # expandedSym.getReturnType #n.typ = getSysSym("PNimrodNode").typ # expandedSym.getReturnType
n.typ = if getCompilerProc("NimNode") != nil: sysTypeFromName"NimNode"
else: sysTypeFromName"PNimrodNode"
result = n result = n
proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym, proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym,

View file

@ -672,8 +672,9 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
elif param.typ.kind == tyTypeDesc: elif param.typ.kind == tyTypeDesc:
addDecl(c, param) addDecl(c, param)
else: else:
# within a macro, every param has the type PNimrodNode! # within a macro, every param has the type NimNode!
let nn = getSysSym"PNimrodNode" let nn = if getCompilerProc("NimNode") != nil: getSysSym"NimNode"
else: getSysSym"PNimrodNode"
var a = copySym(param) var a = copySym(param)
a.typ = nn.typ a.typ = nn.typ
addDecl(c, a) addDecl(c, a)

View file

@ -154,7 +154,7 @@ proc moveConst(x: var TFullReg, y: TFullReg) =
of rkNodeAddr: x.nodeAddr = y.nodeAddr of rkNodeAddr: x.nodeAddr = y.nodeAddr
# this seems to be the best way to model the reference semantics # this seems to be the best way to model the reference semantics
# of PNimrodNode: # of system.NimNode:
template asgnRef(x, y: expr) = moveConst(x, y) template asgnRef(x, y: expr) = moveConst(x, y)
proc copyValue(src: PNode): PNode = proc copyValue(src: PNode): PNode =

View file

@ -1247,7 +1247,7 @@ proc genGlobalInit(c: PCtx; n: PNode; s: PSym) =
s.position = c.globals.len s.position = c.globals.len
# This is rather hard to support, due to the laziness of the VM code # This is rather hard to support, due to the laziness of the VM code
# generator. See tests/compile/tmacro2 for why this is necessary: # generator. See tests/compile/tmacro2 for why this is necessary:
# var decls{.compileTime.}: seq[PNimrodNode] = @[] # var decls{.compileTime.}: seq[NimNode] = @[]
let dest = c.getTemp(s.typ) let dest = c.getTemp(s.typ)
c.gABx(n, opcLdGlobal, dest, s.position) c.gABx(n, opcLdGlobal, dest, s.position)
let tmp = c.genx(s.ast) let tmp = c.genx(s.ast)

View file

@ -1,14 +1,14 @@
The AST in Nim The AST in Nim
================= =================
This section describes how the AST is modelled with Nim's type system. This section describes how the AST is modelled with Nim's type system.
The AST consists of nodes (``PNimrodNode``) with a variable number of The AST consists of nodes (``NimNode``) with a variable number of
children. Each node has a field named ``kind`` which describes what the node children. Each node has a field named ``kind`` which describes what the node
contains: contains:
.. code-block:: nim .. code-block:: nim
type type
TNimrodNodeKind = enum ## kind of a node; only explanatory NimNodeKind = enum ## kind of a node; only explanatory
nnkNone, ## invalid node kind nnkNone, ## invalid node kind
nnkEmpty, ## empty node nnkEmpty, ## empty node
nnkIdent, ## node contains an identifier nnkIdent, ## node contains an identifier
@ -18,11 +18,11 @@ contains:
nnkCaseStmt, ## node represents a case statement nnkCaseStmt, ## node represents a case statement
... ## many more ... ## many more
PNimrodNode = ref TNimrodNode NimNode = ref NimNodeObj
TNimrodNode {.final.} = object NimNodeObj = object
case kind: TNimrodNodeKind ## the node's kind case kind: NimNodeKind ## the node's kind
of nnkNone, nnkEmpty, nnkNilLit: of nnkNone, nnkEmpty, nnkNilLit:
nil ## node contains no additional fields discard ## node contains no additional fields
of nnkCharLit..nnkInt64Lit: of nnkCharLit..nnkInt64Lit:
intVal: biggestInt ## the int literal intVal: biggestInt ## the int literal
of nnkFloatLit..nnkFloat64Lit: of nnkFloatLit..nnkFloat64Lit:
@ -30,13 +30,13 @@ contains:
of nnkStrLit..nnkTripleStrLit: of nnkStrLit..nnkTripleStrLit:
strVal: string ## the string literal strVal: string ## the string literal
of nnkIdent: of nnkIdent:
ident: TNimrodIdent ## the identifier ident: NimIdent ## the identifier
of nnkSym: of nnkSym:
symbol: PNimrodSymbol ## the symbol (after symbol lookup phase) symbol: NimSymbol ## the symbol (after symbol lookup phase)
else: else:
sons: seq[PNimrodNode] ## the node's sons (or children) sons: seq[NimNode] ## the node's sons (or children)
For the ``PNimrodNode`` type, the ``[]`` operator has been overloaded: For the ``NimNode`` type, the ``[]`` operator has been overloaded:
``n[i]`` is ``n``'s ``i``-th child. ``n[i]`` is ``n``'s ``i``-th child.
To specify the AST for the different Nim constructs, the notation To specify the AST for the different Nim constructs, the notation
@ -73,10 +73,7 @@ Nim expression corresponding AST
----------------- --------------------------------------------- ----------------- ---------------------------------------------
Identifiers are ``nnkIdent`` nodes. After the name lookup pass these nodes Identifiers are ``nnkIdent`` nodes. After the name lookup pass these nodes
get transferred into ``nnkSym`` nodes. However, a macro receives an AST that get transferred into ``nnkSym`` nodes.
has not been checked for semantics and thus the identifiers have not been
looked up. Macros should deal with ``nnkIdent`` nodes and do not need to deal
with ``nnkSym`` nodes.
Calls/expressions Calls/expressions
@ -171,13 +168,13 @@ AST:
nnkStrLit("hallo")) nnkStrLit("hallo"))
Dereference operator ``^`` Dereference operator ``[]``
-------------------------- ---------------------------
Concrete syntax: Concrete syntax:
.. code-block:: nim .. code-block:: nim
x^ x[]
AST: AST:
@ -573,4 +570,3 @@ Other node kinds are especially designed to make AST manipulations easier.
These are explained here. These are explained here.
To be written. To be written.

View file

@ -15,7 +15,7 @@ include "system/inclrtl"
## .. include:: ../doc/astspec.txt ## .. include:: ../doc/astspec.txt
type type
TNimrodNodeKind* = enum NimNodeKind* = enum
nnkNone, nnkEmpty, nnkIdent, nnkSym, nnkNone, nnkEmpty, nnkIdent, nnkSym,
nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit, nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit, nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit,
@ -72,8 +72,8 @@ type
nnkEnumFieldDef, nnkEnumFieldDef,
nnkArglist, nnkPattern nnkArglist, nnkPattern
nnkReturnToken nnkReturnToken
TNimNodeKinds* = set[TNimrodNodeKind] NimNodeKinds* = set[NimNodeKind]
TNimrodTypeKind* = enum NimTypeKind* = enum
ntyNone, ntyBool, ntyChar, ntyEmpty, ntyNone, ntyBool, ntyChar, ntyEmpty,
ntyArrayConstr, ntyNil, ntyExpr, ntyStmt, ntyArrayConstr, ntyNil, ntyExpr, ntyStmt,
ntyTypeDesc, ntyGenericInvocation, ntyGenericBody, ntyGenericInst, ntyTypeDesc, ntyGenericInvocation, ntyGenericBody, ntyGenericInst,
@ -84,8 +84,8 @@ type
ntyString, ntyCString, ntyForward, ntyInt, ntyString, ntyCString, ntyForward, ntyInt,
ntyInt8, ntyInt16, ntyInt32, ntyInt64, ntyInt8, ntyInt16, ntyInt32, ntyInt64,
ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128 ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128
TNimTypeKinds* = set[TNimrodTypeKind] TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
TNimrodSymKind* = enum NimSymKind* = enum
nskUnknown, nskConditional, nskDynLib, nskParam, nskUnknown, nskConditional, nskDynLib, nskParam,
nskGenericParam, nskTemp, nskModule, nskType, nskVar, nskLet, nskGenericParam, nskTemp, nskModule, nskType, nskVar, nskLet,
nskConst, nskResult, nskConst, nskResult,
@ -94,17 +94,21 @@ type
nskEnumField, nskForVar, nskLabel, nskEnumField, nskForVar, nskLabel,
nskStub nskStub
TNimSymKinds* = set[TNimrodSymKind] TNimSymKinds* {.deprecated.} = set[NimSymKind]
type type
TNimrodIdent* = object of RootObj NimIdent* = object of RootObj
## represents a Nimrod identifier in the AST ## represents a Nim identifier in the AST
TNimrodSymbol {.final.} = object # hidden NimSymObj {.final.} = object # hidden
PNimrodSymbol* {.compilerproc.} = ref TNimrodSymbol NimSym* = ref NimSymObj
## represents a Nimrod *symbol* in the compiler; a *symbol* is a looked-up ## represents a Nim *symbol* in the compiler; a *symbol* is a looked-up
## *ident*. ## *ident*.
{.deprecated: [TNimrodNodeKind: NimNodeKind, TNimNodeKinds: NimNodeKinds,
TNimrodTypeKind: NimTypeKind, TNimrodSymKind: NimSymKind,
TNimrodIdent: NimIdent, PNimrodSymbol: NimSym].}
const const
nnkLiterals* = {nnkCharLit..nnkNilLit} nnkLiterals* = {nnkCharLit..nnkNilLit}
nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand, nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
@ -117,16 +121,16 @@ proc `[]=`*(n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild",
noSideEffect.} noSideEffect.}
## set `n`'s `i`'th child to `child`. ## set `n`'s `i`'th child to `child`.
proc `!`*(s: string): TNimrodIdent {.magic: "StrToIdent", noSideEffect.} proc `!`*(s: string): NimIdent {.magic: "StrToIdent", noSideEffect.}
## constructs an identifier from the string `s` ## constructs an identifier from the string `s`
proc `$`*(i: TNimrodIdent): string {.magic: "IdentToStr", noSideEffect.} proc `$`*(i: NimIdent): string {.magic: "IdentToStr", noSideEffect.}
## converts a Nimrod identifier to a string ## converts a Nimrod identifier to a string
proc `$`*(s: PNimrodSymbol): string {.magic: "IdentToStr", noSideEffect.} proc `$`*(s: NimSym): string {.magic: "IdentToStr", noSideEffect.}
## converts a Nimrod symbol to a string ## converts a Nimrod symbol to a string
proc `==`*(a, b: TNimrodIdent): bool {.magic: "EqIdent", noSideEffect.} proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
## compares two Nimrod identifiers ## compares two Nimrod identifiers
proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.} proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.}
@ -153,15 +157,15 @@ proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind", noSideEffect.}
proc intVal*(n: PNimrodNode): BiggestInt {.magic: "NIntVal", noSideEffect.} proc intVal*(n: PNimrodNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
proc floatVal*(n: PNimrodNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.} proc floatVal*(n: PNimrodNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
proc symbol*(n: PNimrodNode): PNimrodSymbol {.magic: "NSymbol", noSideEffect.} proc symbol*(n: PNimrodNode): NimSym {.magic: "NSymbol", noSideEffect.}
proc ident*(n: PNimrodNode): TNimrodIdent {.magic: "NIdent", noSideEffect.} proc ident*(n: PNimrodNode): NimIdent {.magic: "NIdent", noSideEffect.}
proc typ*(n: PNimrodNode): typedesc {.magic: "NGetType", noSideEffect.} proc typ*(n: PNimrodNode): typedesc {.magic: "NGetType", noSideEffect.}
proc strVal*(n: PNimrodNode): string {.magic: "NStrVal", noSideEffect.} proc strVal*(n: PNimrodNode): string {.magic: "NStrVal", noSideEffect.}
proc `intVal=`*(n: PNimrodNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.} proc `intVal=`*(n: PNimrodNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.}
proc `floatVal=`*(n: PNimrodNode, val: BiggestFloat) {.magic: "NSetFloatVal", noSideEffect.} proc `floatVal=`*(n: PNimrodNode, val: BiggestFloat) {.magic: "NSetFloatVal", noSideEffect.}
proc `symbol=`*(n: PNimrodNode, val: PNimrodSymbol) {.magic: "NSetSymbol", noSideEffect.} proc `symbol=`*(n: PNimrodNode, val: NimSym) {.magic: "NSetSymbol", noSideEffect.}
proc `ident=`*(n: PNimrodNode, val: TNimrodIdent) {.magic: "NSetIdent", noSideEffect.} proc `ident=`*(n: PNimrodNode, val: NimIdent) {.magic: "NSetIdent", noSideEffect.}
#proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".} #proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".}
# this is not sound! Unfortunately forbidding 'typ=' is not enough, as you # this is not sound! Unfortunately forbidding 'typ=' is not enough, as you
# can easily do: # can easily do:
@ -201,7 +205,7 @@ proc newFloatLitNode*(f: BiggestFloat): PNimrodNode {.compileTime.} =
result = newNimNode(nnkFloatLit) result = newNimNode(nnkFloatLit)
result.floatVal = f result.floatVal = f
proc newIdentNode*(i: TNimrodIdent): PNimrodNode {.compileTime.} = proc newIdentNode*(i: NimIdent): PNimrodNode {.compileTime.} =
## creates an identifier node from `i` ## creates an identifier node from `i`
result = newNimNode(nnkIdent) result = newNimNode(nnkIdent)
result.ident = i result.ident = i
@ -339,7 +343,7 @@ proc newCall*(theProc: PNimrodNode,
result.add(theProc) result.add(theProc)
result.add(args) result.add(args)
proc newCall*(theProc: TNimrodIdent, proc newCall*(theProc: NimIdent,
args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} = args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
## produces a new call node. `theProc` is the proc that is called with ## produces a new call node. `theProc` is the proc that is called with
## the arguments ``args[0..]``. ## the arguments ``args[0..]``.
@ -375,7 +379,7 @@ proc newLit*(s: string): PNimrodNode {.compileTime.} =
result = newNimNode(nnkStrLit) result = newNimNode(nnkStrLit)
result.strVal = s result.strVal = s
proc nestList*(theProc: TNimrodIdent, proc nestList*(theProc: NimIdent,
x: PNimrodNode): PNimrodNode {.compileTime.} = x: PNimrodNode): PNimrodNode {.compileTime.} =
## nests the list `x` into a tree of call expressions: ## nests the list `x` into a tree of call expressions:
## ``[a, b, c]`` is transformed into ``theProc(a, theProc(c, d))``. ## ``[a, b, c]`` is transformed into ``theProc(a, theProc(c, d))``.

View file

@ -3126,8 +3126,16 @@ proc shallow*(s: var string) {.noSideEffect, inline.} =
s.reserved = s.reserved or seqShallowFlag s.reserved = s.reserved or seqShallowFlag
type type
TNimrodNode {.final.} = object NimNodeObj = object
PNimrodNode* {.magic: "PNimrodNode".} = ref TNimrodNode
when defined(nimnode):
type
NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj
## represents a Nim AST node. Macros operate on this type.
{.deprecated: [PNimrodNode: NimNode].}
else:
type
PNimrodNode* {.magic: "PNimrodNode".} = ref NimNodeObj
## represents a Nim AST node. Macros operate on this type. ## represents a Nim AST node. Macros operate on this type.
when false: when false:

View file

@ -18,8 +18,8 @@ Commercial support includes:
.. container:: standout .. container:: standout
Features Requests Feature Requests
----------------- ----------------
Suggest to us any feature that you might need, we will examine your request with Suggest to us any feature that you might need, we will examine your request with
care and provide a proper answer about its potential for inclusion. care and provide a proper answer about its potential for inclusion.