implements a type API for macros
This commit is contained in:
parent
9080d3a9a9
commit
752052e903
7 changed files with 194 additions and 34 deletions
|
|
@ -945,6 +945,13 @@ template `{}`*(n: PNode, i: int): expr = n[i -| n]
|
||||||
template `{}=`*(n: PNode, i: int, s: PNode): stmt =
|
template `{}=`*(n: PNode, i: int, s: PNode): stmt =
|
||||||
n.sons[i -| n] = s
|
n.sons[i -| n] = s
|
||||||
|
|
||||||
|
when defined(useNodeIds):
|
||||||
|
const nodeIdToDebug* = -1 # 884953 # 612794
|
||||||
|
#612840 # 612905 # 614635 # 614637 # 614641
|
||||||
|
# 423408
|
||||||
|
#429107 # 430443 # 441048 # 441090 # 441153
|
||||||
|
var gNodeId: int
|
||||||
|
|
||||||
proc newNode*(kind: TNodeKind): PNode =
|
proc newNode*(kind: TNodeKind): PNode =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = kind
|
result.kind = kind
|
||||||
|
|
@ -1061,13 +1068,6 @@ proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) =
|
||||||
proc discardSons*(father: PNode) =
|
proc discardSons*(father: PNode) =
|
||||||
father.sons = nil
|
father.sons = nil
|
||||||
|
|
||||||
when defined(useNodeIds):
|
|
||||||
const nodeIdToDebug* = -1 # 884953 # 612794
|
|
||||||
#612840 # 612905 # 614635 # 614637 # 614641
|
|
||||||
# 423408
|
|
||||||
#429107 # 430443 # 441048 # 441090 # 441153
|
|
||||||
var gNodeId: int
|
|
||||||
|
|
||||||
proc withInfo*(n: PNode, info: TLineInfo): PNode =
|
proc withInfo*(n: PNode, info: TLineInfo): PNode =
|
||||||
n.info = info
|
n.info = info
|
||||||
return n
|
return n
|
||||||
|
|
|
||||||
|
|
@ -332,10 +332,15 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||||
if result.typ.kind != tyGenericParam:
|
if result.typ.kind != tyGenericParam:
|
||||||
# XXX get rid of this hack!
|
# XXX get rid of this hack!
|
||||||
var oldInfo = n.info
|
var oldInfo = n.info
|
||||||
|
when defined(useNodeIds):
|
||||||
|
let oldId = n.id
|
||||||
reset(n[])
|
reset(n[])
|
||||||
|
when defined(useNodeIds):
|
||||||
|
n.id = oldId
|
||||||
n.kind = nkSym
|
n.kind = nkSym
|
||||||
n.sym = result
|
n.sym = result
|
||||||
n.info = oldInfo
|
n.info = oldInfo
|
||||||
|
n.typ = result.typ
|
||||||
else:
|
else:
|
||||||
localError(n.info, errIdentifierExpected)
|
localError(n.info, errIdentifierExpected)
|
||||||
result = errorSym(c, n)
|
result = errorSym(c, n)
|
||||||
|
|
@ -1179,11 +1184,12 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
var typeExpr = semExpr(c, n)
|
var typeExpr = semExpr(c, n)
|
||||||
if typeExpr.typ.kind != tyTypeDesc:
|
if typeExpr.typ.kind != tyTypeDesc:
|
||||||
localError(n.info, errTypeExpected)
|
localError(n.info, errTypeExpected)
|
||||||
return errorType(c)
|
result = errorType(c)
|
||||||
|
else:
|
||||||
result = typeExpr.typ.base
|
result = typeExpr.typ.base
|
||||||
if result.isMetaType:
|
if result.isMetaType:
|
||||||
var preprocessed = semGenericStmt(c, n)
|
var preprocessed = semGenericStmt(c, n)
|
||||||
return makeTypeFromExpr(c, preprocessed)
|
result = makeTypeFromExpr(c, preprocessed)
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
var s = semTypeIdent(c, n)
|
var s = semTypeIdent(c, n)
|
||||||
if s.typ == nil:
|
if s.typ == nil:
|
||||||
|
|
@ -1254,6 +1260,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
else:
|
else:
|
||||||
localError(n.info, errTypeExpected)
|
localError(n.info, errTypeExpected)
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
|
n.typ = result
|
||||||
|
|
||||||
proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
|
proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
|
||||||
m.typ.kind = kind
|
m.typ.kind = kind
|
||||||
|
|
|
||||||
|
|
@ -123,8 +123,12 @@ proc createStrKeepNode(x: var TFullReg) =
|
||||||
if x.node.isNil:
|
if x.node.isNil:
|
||||||
x.node = newNode(nkStrLit)
|
x.node = newNode(nkStrLit)
|
||||||
elif x.node.kind == nkNilLit:
|
elif x.node.kind == nkNilLit:
|
||||||
|
when defined(useNodeIds):
|
||||||
|
let id = x.node.id
|
||||||
system.reset(x.node[])
|
system.reset(x.node[])
|
||||||
x.node.kind = nkStrLit
|
x.node.kind = nkStrLit
|
||||||
|
when defined(useNodeIds):
|
||||||
|
x.node.id = id
|
||||||
elif x.node.kind notin {nkStrLit..nkTripleStrLit} or
|
elif x.node.kind notin {nkStrLit..nkTripleStrLit} or
|
||||||
nfAllConst in x.node.flags:
|
nfAllConst in x.node.flags:
|
||||||
# XXX this is hacky; tests/txmlgen triggers it:
|
# XXX this is hacky; tests/txmlgen triggers it:
|
||||||
|
|
@ -1133,7 +1137,21 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "ident")
|
stackTrace(c, tos, pc, errFieldXNotFound, "ident")
|
||||||
of opcNGetType:
|
of opcNGetType:
|
||||||
internalError(c.debug[pc], "unknown opcode " & $instr.opcode)
|
let rb = instr.regB
|
||||||
|
let rc = instr.regC
|
||||||
|
if rc == 0:
|
||||||
|
ensureKind(rkNode)
|
||||||
|
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||||
|
regs[ra].node = opMapTypeToAst(regs[rb].node.typ, c.debug[pc])
|
||||||
|
else:
|
||||||
|
stackTrace(c, tos, pc, errGenerated, "node has no type")
|
||||||
|
else:
|
||||||
|
# typeKind opcode:
|
||||||
|
ensureKind(rkInt)
|
||||||
|
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||||
|
regs[ra].intVal = ord(regs[rb].node.typ.kind)
|
||||||
|
#else:
|
||||||
|
# stackTrace(c, tos, pc, errGenerated, "node has no type")
|
||||||
of opcNStrVal:
|
of opcNStrVal:
|
||||||
decodeB(rkNode)
|
decodeB(rkNode)
|
||||||
createStr regs[ra]
|
createStr regs[ra]
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nim Compiler
|
# The Nim Compiler
|
||||||
# (c) Copyright 2013 Andreas Rumpf
|
# (c) Copyright 2015 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
import ast, types, msgs, osproc, streams, options
|
import ast, types, msgs, osproc, streams, options, idents
|
||||||
|
|
||||||
proc readOutput(p: Process): string =
|
proc readOutput(p: Process): string =
|
||||||
result = ""
|
result = ""
|
||||||
|
|
@ -19,11 +19,14 @@ proc readOutput(p: Process): string =
|
||||||
discard p.waitForExit
|
discard p.waitForExit
|
||||||
|
|
||||||
proc opGorge*(cmd, input: string): string =
|
proc opGorge*(cmd, input: string): string =
|
||||||
|
try:
|
||||||
var p = startProcess(cmd, options={poEvalCommand})
|
var p = startProcess(cmd, options={poEvalCommand})
|
||||||
if input.len != 0:
|
if input.len != 0:
|
||||||
p.inputStream.write(input)
|
p.inputStream.write(input)
|
||||||
p.inputStream.close()
|
p.inputStream.close()
|
||||||
result = p.readOutput
|
result = p.readOutput
|
||||||
|
except IOError, OSError:
|
||||||
|
result = ""
|
||||||
|
|
||||||
proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
|
proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
|
||||||
try:
|
try:
|
||||||
|
|
@ -36,3 +39,111 @@ proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
|
||||||
except IOError:
|
except IOError:
|
||||||
localError(info, errCannotOpenFile, file)
|
localError(info, errCannotOpenFile, file)
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
|
proc atomicTypeX(name: string; t: PType; info: TLineInfo): PNode =
|
||||||
|
let sym = newSym(skType, getIdent(name), t.owner, info)
|
||||||
|
result = newSymNode(sym)
|
||||||
|
result.typ = t
|
||||||
|
|
||||||
|
proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode
|
||||||
|
|
||||||
|
proc mapTypeToBracket(name: string; t: PType; info: TLineInfo): PNode =
|
||||||
|
result = newNodeIT(nkBracketExpr, info, t)
|
||||||
|
result.add atomicTypeX(name, t, info)
|
||||||
|
for i in 0 .. < t.len:
|
||||||
|
result.add mapTypeToAst(t.sons[i], info)
|
||||||
|
|
||||||
|
proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
|
||||||
|
template atomicType(name): expr = atomicTypeX(name, t, info)
|
||||||
|
|
||||||
|
case t.kind
|
||||||
|
of tyNone: result = atomicType("none")
|
||||||
|
of tyBool: result = atomicType("bool")
|
||||||
|
of tyChar: result = atomicType("char")
|
||||||
|
of tyNil: result = atomicType("nil")
|
||||||
|
of tyExpr: result = atomicType("expr")
|
||||||
|
of tyStmt: result = atomicType("stmt")
|
||||||
|
of tyEmpty: result = atomicType"void"
|
||||||
|
of tyArrayConstr, tyArray:
|
||||||
|
result = newNodeIT(nkBracketExpr, info, t)
|
||||||
|
result.add atomicType("array")
|
||||||
|
result.add mapTypeToAst(t.sons[0], info)
|
||||||
|
result.add mapTypeToAst(t.sons[1], info)
|
||||||
|
of tyTypeDesc:
|
||||||
|
if t.base != nil:
|
||||||
|
result = newNodeIT(nkBracketExpr, info, t)
|
||||||
|
result.add atomicType("typeDesc")
|
||||||
|
result.add mapTypeToAst(t.base, info)
|
||||||
|
else:
|
||||||
|
result = atomicType"typeDesc"
|
||||||
|
of tyGenericInvocation:
|
||||||
|
result = newNodeIT(nkBracketExpr, info, t)
|
||||||
|
for i in 0 .. < t.len:
|
||||||
|
result.add mapTypeToAst(t.sons[i], info)
|
||||||
|
of tyGenericInst, tyGenericBody, tyOrdinal, tyUserTypeClassInst:
|
||||||
|
result = mapTypeToAst(t.lastSon, info)
|
||||||
|
of tyGenericParam, tyDistinct, tyForward: result = atomicType(t.sym.name.s)
|
||||||
|
of tyObject:
|
||||||
|
if allowRecursion:
|
||||||
|
result = newNodeIT(nkObjectTy, info, t)
|
||||||
|
if t.sons[0] == nil:
|
||||||
|
result.add ast.emptyNode
|
||||||
|
else:
|
||||||
|
result.add mapTypeToAst(t.sons[0], info)
|
||||||
|
result.add copyTree(t.n)
|
||||||
|
else:
|
||||||
|
result = atomicType(t.sym.name.s)
|
||||||
|
of tyEnum:
|
||||||
|
result = newNodeIT(nkEnumTy, info, t)
|
||||||
|
result.add copyTree(t.n)
|
||||||
|
of tyTuple: result = mapTypeToBracket("tuple", t, info)
|
||||||
|
of tySet: result = mapTypeToBracket("set", t, info)
|
||||||
|
of tyPtr: result = mapTypeToBracket("ptr", t, info)
|
||||||
|
of tyRef: result = mapTypeToBracket("ref", t, info)
|
||||||
|
of tyVar: result = mapTypeToBracket("var", t, info)
|
||||||
|
of tySequence: result = mapTypeToBracket("sequence", t, info)
|
||||||
|
of tyProc: result = mapTypeToBracket("proc", t, info)
|
||||||
|
of tyOpenArray: result = mapTypeToBracket("openArray", t, info)
|
||||||
|
of tyRange:
|
||||||
|
result = newNodeIT(nkBracketExpr, info, t)
|
||||||
|
result.add atomicType("range")
|
||||||
|
result.add t.n.sons[0].copyTree
|
||||||
|
result.add t.n.sons[1].copyTree
|
||||||
|
of tyPointer: result = atomicType"pointer"
|
||||||
|
of tyString: result = atomicType"string"
|
||||||
|
of tyCString: result = atomicType"cstring"
|
||||||
|
of tyInt: result = atomicType"int"
|
||||||
|
of tyInt8: result = atomicType"int8"
|
||||||
|
of tyInt16: result = atomicType"int16"
|
||||||
|
of tyInt32: result = atomicType"int32"
|
||||||
|
of tyInt64: result = atomicType"int64"
|
||||||
|
of tyFloat: result = atomicType"float"
|
||||||
|
of tyFloat32: result = atomicType"float32"
|
||||||
|
of tyFloat64: result = atomicType"float64"
|
||||||
|
of tyFloat128: result = atomicType"float128"
|
||||||
|
of tyUInt: result = atomicType"uint"
|
||||||
|
of tyUInt8: result = atomicType"uint8"
|
||||||
|
of tyUInt16: result = atomicType"uint16"
|
||||||
|
of tyUInt32: result = atomicType"uint32"
|
||||||
|
of tyUInt64: result = atomicType"uint64"
|
||||||
|
of tyBigNum: result = atomicType"bignum"
|
||||||
|
of tyConst: result = mapTypeToBracket("const", t, info)
|
||||||
|
of tyMutable: result = mapTypeToBracket("mutable", t, info)
|
||||||
|
of tyVarargs: result = mapTypeToBracket("varargs", t, info)
|
||||||
|
of tyIter: result = mapTypeToBracket("iter", t, info)
|
||||||
|
of tyProxy: result = atomicType"error"
|
||||||
|
of tyBuiltInTypeClass: result = mapTypeToBracket("builtinTypeClass", t, info)
|
||||||
|
of tyUserTypeClass: result = mapTypeToBracket("userTypeClass", t, info)
|
||||||
|
of tyCompositeTypeClass: result = mapTypeToBracket("compositeTypeClass", t, info)
|
||||||
|
of tyAnd: result = mapTypeToBracket("and", t, info)
|
||||||
|
of tyOr: result = mapTypeToBracket("or", t, info)
|
||||||
|
of tyNot: result = mapTypeToBracket("not", t, info)
|
||||||
|
of tyAnything: result = atomicType"anything"
|
||||||
|
of tyStatic, tyFromExpr, tyFieldAccessor:
|
||||||
|
result = newNodeIT(nkBracketExpr, info, t)
|
||||||
|
result.add atomicType("static")
|
||||||
|
if t.n != nil:
|
||||||
|
result.add t.n.copyTree
|
||||||
|
|
||||||
|
proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode =
|
||||||
|
result = mapTypeToAst(t, info, true)
|
||||||
|
|
|
||||||
|
|
@ -950,7 +950,12 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
of mNFloatVal: genUnaryABC(c, n, dest, opcNFloatVal)
|
of mNFloatVal: genUnaryABC(c, n, dest, opcNFloatVal)
|
||||||
of mNSymbol: genUnaryABC(c, n, dest, opcNSymbol)
|
of mNSymbol: genUnaryABC(c, n, dest, opcNSymbol)
|
||||||
of mNIdent: genUnaryABC(c, n, dest, opcNIdent)
|
of mNIdent: genUnaryABC(c, n, dest, opcNIdent)
|
||||||
of mNGetType: genUnaryABC(c, n, dest, opcNGetType)
|
of mNGetType:
|
||||||
|
let tmp = c.genx(n.sons[1])
|
||||||
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
|
c.gABC(n, opcNGetType, dest, tmp, if n[0].sym.name.s == "typeKind": 1 else: 0)
|
||||||
|
c.freeTemp(tmp)
|
||||||
|
#genUnaryABC(c, n, dest, opcNGetType)
|
||||||
of mNStrVal: genUnaryABC(c, n, dest, opcNStrVal)
|
of mNStrVal: genUnaryABC(c, n, dest, opcNStrVal)
|
||||||
of mNSetIntVal:
|
of mNSetIntVal:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,13 @@ type
|
||||||
ntySequence, ntyProc, ntyPointer, ntyOpenArray,
|
ntySequence, ntyProc, ntyPointer, ntyOpenArray,
|
||||||
ntyString, ntyCString, ntyForward, ntyInt,
|
ntyString, ntyCString, ntyForward, ntyInt,
|
||||||
ntyInt8, ntyInt16, ntyInt32, ntyInt64,
|
ntyInt8, ntyInt16, ntyInt32, ntyInt64,
|
||||||
ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128
|
ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128,
|
||||||
|
ntyUInt, ntyUInt8, ntyUInt16, ntyUInt32, ntyUInt64,
|
||||||
|
ntyBigNum,
|
||||||
|
ntyConst, ntyMutable, ntyVarargs,
|
||||||
|
ntyIter,
|
||||||
|
ntyError
|
||||||
|
|
||||||
TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
|
TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
|
||||||
NimSymKind* = enum
|
NimSymKind* = enum
|
||||||
nskUnknown, nskConditional, nskDynLib, nskParam,
|
nskUnknown, nskConditional, nskDynLib, nskParam,
|
||||||
|
|
@ -100,7 +106,7 @@ type
|
||||||
NimIdent* = object of RootObj
|
NimIdent* = object of RootObj
|
||||||
## represents a Nim identifier in the AST
|
## represents a Nim identifier in the AST
|
||||||
|
|
||||||
NimSymObj {.final.} = object # hidden
|
NimSymObj = object # hidden
|
||||||
NimSym* = ref NimSymObj
|
NimSym* = ref NimSymObj
|
||||||
## represents a Nim *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*.
|
||||||
|
|
@ -125,16 +131,16 @@ proc `!`*(s: string): NimIdent {.magic: "StrToIdent", noSideEffect.}
|
||||||
## constructs an identifier from the string `s`
|
## constructs an identifier from the string `s`
|
||||||
|
|
||||||
proc `$`*(i: NimIdent): string {.magic: "IdentToStr", noSideEffect.}
|
proc `$`*(i: NimIdent): string {.magic: "IdentToStr", noSideEffect.}
|
||||||
## converts a Nimrod identifier to a string
|
## converts a Nim identifier to a string
|
||||||
|
|
||||||
proc `$`*(s: NimSym): string {.magic: "IdentToStr", noSideEffect.}
|
proc `$`*(s: NimSym): string {.magic: "IdentToStr", noSideEffect.}
|
||||||
## converts a Nimrod symbol to a string
|
## converts a Nim symbol to a string
|
||||||
|
|
||||||
proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
|
proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
|
||||||
## compares two Nimrod identifiers
|
## compares two Nim identifiers
|
||||||
|
|
||||||
proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.}
|
proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.}
|
||||||
## compares two Nimrod nodes
|
## compares two Nim nodes
|
||||||
|
|
||||||
proc len*(n: PNimrodNode): int {.magic: "NLen", noSideEffect.}
|
proc len*(n: PNimrodNode): int {.magic: "NLen", noSideEffect.}
|
||||||
## returns the number of children of `n`.
|
## returns the number of children of `n`.
|
||||||
|
|
@ -159,7 +165,19 @@ 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): NimSym {.magic: "NSymbol", noSideEffect.}
|
proc symbol*(n: PNimrodNode): NimSym {.magic: "NSymbol", noSideEffect.}
|
||||||
proc ident*(n: PNimrodNode): NimIdent {.magic: "NIdent", noSideEffect.}
|
proc ident*(n: PNimrodNode): NimIdent {.magic: "NIdent", noSideEffect.}
|
||||||
proc typ*(n: PNimrodNode): typedesc {.magic: "NGetType", noSideEffect.}
|
|
||||||
|
proc getType*(n: PNimrodNode): PNimrodNode {.magic: "NGetType", noSideEffect.}
|
||||||
|
## with 'getType' you can access the node's `type`:idx:. A Nim type is
|
||||||
|
## mapped to a Nim AST too, so it's slightly confusing but it means the same
|
||||||
|
## API can be used to traverse types. Recursive types are flattened for you
|
||||||
|
## so there is no danger of infinite recursions during traversal. To
|
||||||
|
## resolve recursive types, you have to call 'getType' again. To see what
|
||||||
|
## kind of type it is, call `typeKind` on getType's result.
|
||||||
|
|
||||||
|
proc typeKind*(n: PNimrodNode): NimTypeKind {.magic: "NGetType", noSideEffect.}
|
||||||
|
## Returns the type kind of the node 'n' that should represent a type, that
|
||||||
|
## means the node should have been obtained via `getType`.
|
||||||
|
|
||||||
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.}
|
||||||
|
|
@ -216,7 +234,7 @@ proc newIdentNode*(i: string): PNimrodNode {.compileTime.} =
|
||||||
result.ident = !i
|
result.ident = !i
|
||||||
|
|
||||||
type
|
type
|
||||||
TBindSymRule* = enum ## specifies how ``bindSym`` behaves
|
BindSymRule* = enum ## specifies how ``bindSym`` behaves
|
||||||
brClosed, ## only the symbols in current scope are bound
|
brClosed, ## only the symbols in current scope are bound
|
||||||
brOpen, ## open wrt overloaded symbols, but may be a single
|
brOpen, ## open wrt overloaded symbols, but may be a single
|
||||||
## symbol if not ambiguous (the rules match that of
|
## symbol if not ambiguous (the rules match that of
|
||||||
|
|
@ -225,7 +243,9 @@ type
|
||||||
## if not ambiguous (this cannot be achieved with
|
## if not ambiguous (this cannot be achieved with
|
||||||
## any other means in the language currently)
|
## any other means in the language currently)
|
||||||
|
|
||||||
proc bindSym*(ident: string, rule: TBindSymRule = brClosed): PNimrodNode {.
|
{.deprecated: [TBindSymRule: BindSymRule].}
|
||||||
|
|
||||||
|
proc bindSym*(ident: string, rule: BindSymRule = brClosed): PNimrodNode {.
|
||||||
magic: "NBindSym", noSideEffect.}
|
magic: "NBindSym", noSideEffect.}
|
||||||
## creates a node that binds `ident` to a symbol node. The bound symbol
|
## creates a node that binds `ident` to a symbol node. The bound symbol
|
||||||
## may be an overloaded symbol.
|
## may be an overloaded symbol.
|
||||||
|
|
@ -236,7 +256,7 @@ proc bindSym*(ident: string, rule: TBindSymRule = brClosed): PNimrodNode {.
|
||||||
## If ``rule == brForceOpen`` always an ``nkOpenSymChoice`` tree is
|
## If ``rule == brForceOpen`` always an ``nkOpenSymChoice`` tree is
|
||||||
## returned even if the symbol is not ambiguous.
|
## returned even if the symbol is not ambiguous.
|
||||||
|
|
||||||
proc genSym*(kind: TNimrodSymKind = nskLet; ident = ""): PNimrodNode {.
|
proc genSym*(kind: NimSymKind = nskLet; ident = ""): PNimrodNode {.
|
||||||
magic: "NGenSym", noSideEffect.}
|
magic: "NGenSym", noSideEffect.}
|
||||||
## generates a fresh symbol that is guaranteed to be unique. The symbol
|
## generates a fresh symbol that is guaranteed to be unique. The symbol
|
||||||
## needs to occur in a declaration context.
|
## needs to occur in a declaration context.
|
||||||
|
|
@ -245,7 +265,7 @@ proc callsite*(): PNimrodNode {.magic: "NCallSite", benign.}
|
||||||
## returns the AST of the invocation expression that invoked this macro.
|
## returns the AST of the invocation expression that invoked this macro.
|
||||||
|
|
||||||
proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
## converts the AST `n` to the concrete Nimrod code and wraps that
|
## converts the AST `n` to the concrete Nim code and wraps that
|
||||||
## in a string literal node
|
## in a string literal node
|
||||||
return newStrLitNode(repr(n))
|
return newStrLitNode(repr(n))
|
||||||
|
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -74,7 +74,6 @@ version 0.9.X
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- macros as type pragmas
|
- macros as type pragmas
|
||||||
- implement type API for macros
|
|
||||||
- lazy overloading resolution:
|
- lazy overloading resolution:
|
||||||
* special case ``tyStmt``
|
* special case ``tyStmt``
|
||||||
- document NimMain and check whether it works for threading
|
- document NimMain and check whether it works for threading
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue