mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
macros.PNimrodNode is now NimNode
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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))``.
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user