macros.PNimrodNode is now NimNode
This commit is contained in:
parent
fb46785969
commit
1e6aef62ba
9 changed files with 62 additions and 50 deletions
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))``.
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue