macros.PNimrodNode is now NimNode

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

View File

@@ -89,6 +89,7 @@ proc initDefines*() =
defineSymbol("nimparsebiggestfloatmagic")
defineSymbol("nimalias")
defineSymbol("nimlocks")
defineSymbol("nimnode")
# add platform specific symbols:
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
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
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:
addDecl(c, param)
else:
# within a macro, every param has the type PNimrodNode!
let nn = getSysSym"PNimrodNode"
# within a macro, every param has the type NimNode!
let nn = if getCompilerProc("NimNode") != nil: getSysSym"NimNode"
else: getSysSym"PNimrodNode"
var a = copySym(param)
a.typ = nn.typ
addDecl(c, a)

View File

@@ -154,7 +154,7 @@ proc moveConst(x: var TFullReg, y: TFullReg) =
of rkNodeAddr: x.nodeAddr = y.nodeAddr
# 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)
proc copyValue(src: PNode): PNode =

View File

@@ -1247,7 +1247,7 @@ proc genGlobalInit(c: PCtx; n: PNode; s: PSym) =
s.position = c.globals.len
# This is rather hard to support, due to the laziness of the VM code
# 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)
c.gABx(n, opcLdGlobal, dest, s.position)
let tmp = c.genx(s.ast)

View File

@@ -1,14 +1,14 @@
The AST in Nim
=================
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
contains:
.. code-block:: nim
type
TNimrodNodeKind = enum ## kind of a node; only explanatory
NimNodeKind = enum ## kind of a node; only explanatory
nnkNone, ## invalid node kind
nnkEmpty, ## empty node
nnkIdent, ## node contains an identifier
@@ -18,11 +18,11 @@ contains:
nnkCaseStmt, ## node represents a case statement
... ## many more
PNimrodNode = ref TNimrodNode
TNimrodNode {.final.} = object
case kind: TNimrodNodeKind ## the node's kind
NimNode = ref NimNodeObj
NimNodeObj = object
case kind: NimNodeKind ## the node's kind
of nnkNone, nnkEmpty, nnkNilLit:
nil ## node contains no additional fields
discard ## node contains no additional fields
of nnkCharLit..nnkInt64Lit:
intVal: biggestInt ## the int literal
of nnkFloatLit..nnkFloat64Lit:
@@ -30,13 +30,13 @@ contains:
of nnkStrLit..nnkTripleStrLit:
strVal: string ## the string literal
of nnkIdent:
ident: TNimrodIdent ## the identifier
ident: NimIdent ## the identifier
of nnkSym:
symbol: PNimrodSymbol ## the symbol (after symbol lookup phase)
symbol: NimSymbol ## the symbol (after symbol lookup phase)
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.
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
get transferred into ``nnkSym`` nodes. However, a macro receives an AST that
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.
get transferred into ``nnkSym`` nodes.
Calls/expressions
@@ -171,13 +168,13 @@ AST:
nnkStrLit("hallo"))
Dereference operator ``^``
--------------------------
Dereference operator ``[]``
---------------------------
Concrete syntax:
.. code-block:: nim
x^
x[]
AST:
@@ -573,4 +570,3 @@ Other node kinds are especially designed to make AST manipulations easier.
These are explained here.
To be written.

View File

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

View File

@@ -3126,9 +3126,17 @@ proc shallow*(s: var string) {.noSideEffect, inline.} =
s.reserved = s.reserved or seqShallowFlag
type
TNimrodNode {.final.} = object
PNimrodNode* {.magic: "PNimrodNode".} = ref TNimrodNode
## represents a Nim AST node. Macros operate on this type.
NimNodeObj = object
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.
when false:
template eval*(blk: stmt): stmt =

View File

@@ -18,8 +18,8 @@ Commercial support includes:
.. container:: standout
Features Requests
-----------------
Feature Requests
----------------
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.