added getTypeInst which includes generic parameters

This commit is contained in:
James Osborn 2016-04-16 12:16:58 -05:00
commit d462cca21f
4 changed files with 62 additions and 23 deletions

View file

@ -1185,19 +1185,28 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcNGetType: of opcNGetType:
let rb = instr.regB let rb = instr.regB
let rc = instr.regC let rc = instr.regC
if rc == 0: case rc:
ensureKind(rkNode) of 0:
if regs[rb].kind == rkNode and regs[rb].node.typ != nil: # getType opcode:
regs[ra].node = opMapTypeToAst(regs[rb].node.typ, c.debug[pc]) 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")
of 1:
# 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")
else: else:
stackTrace(c, tos, pc, errGenerated, "node has no type") # getTypeInst opcode:
else: ensureKind(rkNode)
# typeKind opcode: if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
ensureKind(rkInt) regs[ra].node = opMapTypeInstToAst(regs[rb].node.typ, c.debug[pc])
if regs[rb].kind == rkNode and regs[rb].node.typ != nil: else:
regs[ra].intVal = ord(regs[rb].node.typ.kind) stackTrace(c, tos, pc, errGenerated, "node has no type")
#else:
# stackTrace(c, tos, pc, errGenerated, "node has no type")
of opcNStrVal: of opcNStrVal:
decodeB(rkNode) decodeB(rkNode)
createStr regs[ra] createStr regs[ra]

View file

@ -67,9 +67,11 @@ proc atomicTypeX(name: string; t: PType; info: TLineInfo): PNode =
result = newSymNode(sym) result = newSymNode(sym)
result.typ = t result.typ = t
proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode proc mapTypeToAstImpl(t: PType; info: TLineInfo;
inst=false; allowRecursion=false): PNode
proc mapTypeToBracket(name: string; t: PType; info: TLineInfo): PNode = proc mapTypeToBracketImpl(name: string; t: PType; info: TLineInfo;
inst=false): PNode =
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicTypeX(name, t, info) result.add atomicTypeX(name, t, info)
for i in 0 .. < t.len: for i in 0 .. < t.len:
@ -78,10 +80,14 @@ proc mapTypeToBracket(name: string; t: PType; info: TLineInfo): PNode =
void.typ = newType(tyEmpty, t.owner) void.typ = newType(tyEmpty, t.owner)
result.add void result.add void
else: else:
result.add mapTypeToAst(t.sons[i], info) result.add mapTypeToAstImpl(t.sons[i], info, inst)
proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode = proc mapTypeToAstImpl(t: PType; info: TLineInfo;
inst=false; allowRecursion=false): PNode =
template atomicType(name): expr = atomicTypeX(name, t, info) template atomicType(name): expr = atomicTypeX(name, t, info)
template mapTypeToAst(t,info): expr = mapTypeToAstImpl(t, info, inst)
template mapTypeToBracket(name,t,info): expr =
mapTypeToBracketImpl(name, t, info, inst)
case t.kind case t.kind
of tyNone: result = atomicType("none") of tyNone: result = atomicType("none")
@ -107,7 +113,14 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
for i in 0 .. < t.len: for i in 0 .. < t.len:
result.add mapTypeToAst(t.sons[i], info) result.add mapTypeToAst(t.sons[i], info)
of tyGenericInst, tyGenericBody, tyOrdinal, tyUserTypeClassInst: of tyGenericInst:
if inst:
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
for i in 0 .. < t.len-1:
result.add mapTypeToAst(t.sons[i], info)
else:
result = mapTypeToAst(t.lastSon, info)
of tyGenericBody, tyOrdinal, tyUserTypeClassInst:
result = mapTypeToAst(t.lastSon, info) result = mapTypeToAst(t.lastSon, info)
of tyDistinct: of tyDistinct:
if allowRecursion: if allowRecursion:
@ -174,10 +187,17 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
of tyNot: result = mapTypeToBracket("not", t, info) of tyNot: result = mapTypeToBracket("not", t, info)
of tyAnything: result = atomicType"anything" of tyAnything: result = atomicType"anything"
of tyStatic, tyFromExpr, tyFieldAccessor: of tyStatic, tyFromExpr, tyFieldAccessor:
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t) if inst:
result.add atomicType("static") if t.n != nil: result = t.n.copyTree
if t.n != nil: else: result = atomicType "void"
result.add t.n.copyTree else:
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicType("static")
if t.n != nil:
result.add t.n.copyTree
proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode = proc opMapTypeToAst*(t: PType; info: TLineInfo): PNode =
result = mapTypeToAst(t, info, true) result = mapTypeToAstImpl(t, info, false, true)
proc opMapTypeInstToAst*(t: PType; info: TLineInfo): PNode =
result = mapTypeToAstImpl(t, info, true, true)

View file

@ -983,7 +983,11 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mNGetType: of mNGetType:
let tmp = c.genx(n.sons[1]) let tmp = c.genx(n.sons[1])
if dest < 0: dest = c.getTemp(n.typ) if dest < 0: dest = c.getTemp(n.typ)
c.gABC(n, opcNGetType, dest, tmp, if n[0].sym.name.s == "typeKind": 1 else: 0) let rc = case n[0].sym.name.s:
of "getType": 0
of "typeKind": 1
else: 2 # "getTypeInst"
c.gABC(n, opcNGetType, dest, tmp, rc)
c.freeTemp(tmp) c.freeTemp(tmp)
#genUnaryABC(c, n, dest, opcNGetType) #genUnaryABC(c, n, dest, opcNGetType)
of mNStrVal: genUnaryABC(c, n, dest, opcNStrVal) of mNStrVal: genUnaryABC(c, n, dest, opcNStrVal)

View file

@ -197,6 +197,12 @@ proc typeKind*(n: NimNode): NimTypeKind {.magic: "NGetType", noSideEffect.}
## Returns the type kind of the node 'n' that should represent a type, that ## Returns the type kind of the node 'n' that should represent a type, that
## means the node should have been obtained via `getType`. ## means the node should have been obtained via `getType`.
proc getTypeInst*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
## Like getType except it includes generic parameters for a specific instance
proc getTypeInst*(n: typedesc): NimNode {.magic: "NGetType", noSideEffect.}
## Like getType except it includes generic parameters for a specific instance
proc strVal*(n: NimNode): string {.magic: "NStrVal", noSideEffect.} proc strVal*(n: NimNode): string {.magic: "NStrVal", noSideEffect.}
proc `intVal=`*(n: NimNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.} proc `intVal=`*(n: NimNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.}