Add sym owner to macros (#8253)
This commit is contained in:
parent
1abef2dc59
commit
e63c66b810
7 changed files with 50 additions and 3 deletions
|
|
@ -657,7 +657,7 @@ type
|
||||||
mNHint, mNWarning, mNError,
|
mNHint, mNWarning, mNError,
|
||||||
mInstantiationInfo, mGetTypeInfo,
|
mInstantiationInfo, mGetTypeInfo,
|
||||||
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
|
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
|
||||||
mException, mBuiltinType
|
mException, mBuiltinType, mSymOwner
|
||||||
|
|
||||||
# things that we can evaluate safely at compile time, even if not asked for it:
|
# things that we can evaluate safely at compile time, even if not asked for it:
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ proc initDefines*(symbols: StringTableRef) =
|
||||||
defineSymbol("nimNoZeroTerminator")
|
defineSymbol("nimNoZeroTerminator")
|
||||||
defineSymbol("nimNotNil")
|
defineSymbol("nimNotNil")
|
||||||
defineSymbol("nimVmExportFixed")
|
defineSymbol("nimVmExportFixed")
|
||||||
|
defineSymbol("nimHasSymOwnerInMacro")
|
||||||
defineSymbol("nimNewRuntime")
|
defineSymbol("nimNewRuntime")
|
||||||
defineSymbol("nimIncrSeqV3")
|
defineSymbol("nimIncrSeqV3")
|
||||||
defineSymbol("nimAshr")
|
defineSymbol("nimAshr")
|
||||||
|
|
|
||||||
|
|
@ -920,6 +920,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
regs[ra].node.flags.incl nfIsRef
|
regs[ra].node.flags.incl nfIsRef
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, "node is not a symbol")
|
stackTrace(c, tos, pc, "node is not a symbol")
|
||||||
|
of opcSymOwner:
|
||||||
|
decodeB(rkNode)
|
||||||
|
let a = regs[rb].node
|
||||||
|
if a.kind == nkSym:
|
||||||
|
regs[ra].node = if a.sym.owner.isNil: newNode(nkNilLit)
|
||||||
|
else: newSymNode(a.sym.skipGenericOwner)
|
||||||
|
regs[ra].node.flags.incl nfIsRef
|
||||||
|
else:
|
||||||
|
stackTrace(c, tos, pc, "node is not a symbol")
|
||||||
of opcEcho:
|
of opcEcho:
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
if rb == 1:
|
if rb == 1:
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,8 @@ type
|
||||||
opcSetType, # dest.typ = types[Bx]
|
opcSetType, # dest.typ = types[Bx]
|
||||||
opcTypeTrait,
|
opcTypeTrait,
|
||||||
opcMarshalLoad, opcMarshalStore,
|
opcMarshalLoad, opcMarshalStore,
|
||||||
opcToNarrowInt
|
opcToNarrowInt,
|
||||||
|
opcSymOwner
|
||||||
|
|
||||||
TBlock* = object
|
TBlock* = object
|
||||||
label*: PSym
|
label*: PSym
|
||||||
|
|
|
||||||
|
|
@ -1118,6 +1118,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||||
of mStaticExec: genBinaryABCD(c, n, dest, opcGorge)
|
of mStaticExec: genBinaryABCD(c, n, dest, opcGorge)
|
||||||
of mNLen: genUnaryABI(c, n, dest, opcLenSeq, nimNodeFlag)
|
of mNLen: genUnaryABI(c, n, dest, opcLenSeq, nimNodeFlag)
|
||||||
of mGetImpl: genUnaryABC(c, n, dest, opcGetImpl)
|
of mGetImpl: genUnaryABC(c, n, dest, opcGetImpl)
|
||||||
|
of mSymOwner: genUnaryABC(c, n, dest, opcSymOwner)
|
||||||
of mNChild: genBinaryABC(c, n, dest, opcNChild)
|
of mNChild: genBinaryABC(c, n, dest, opcNChild)
|
||||||
of mNSetChild: genVoidABC(c, n, dest, opcNSetChild)
|
of mNSetChild: genVoidABC(c, n, dest, opcNSetChild)
|
||||||
of mNDel: genVoidABC(c, n, dest, opcNDel)
|
of mNDel: genVoidABC(c, n, dest, opcNDel)
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,12 @@ else: # bootstrapping substitute
|
||||||
else:
|
else:
|
||||||
n.strValOld
|
n.strValOld
|
||||||
|
|
||||||
|
when defined(nimHasSymOwnerInMacro):
|
||||||
|
proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.}
|
||||||
|
## accepts node of kind nnkSym and returns its owner's symbol.
|
||||||
|
## result is also mnde of kind nnkSym if owner exists otherwise
|
||||||
|
## nnkNilLit is returned
|
||||||
|
|
||||||
proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
||||||
## with 'getType' you can access the node's `type`:idx:. A Nim type is
|
## 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
|
## mapped to a Nim AST too, so it's slightly confusing but it means the same
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
msg: '''"muhaha"
|
msg: '''"muhaha"
|
||||||
proc poo(x, y: int) =
|
proc poo(x, y: int) =
|
||||||
|
let y = x
|
||||||
echo ["poo"]'''
|
echo ["poo"]'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -10,11 +11,39 @@ const
|
||||||
foo = "muhaha"
|
foo = "muhaha"
|
||||||
|
|
||||||
proc poo(x, y: int) =
|
proc poo(x, y: int) =
|
||||||
|
let y = x
|
||||||
echo "poo"
|
echo "poo"
|
||||||
|
|
||||||
macro m(x: typed): untyped =
|
macro m(x: typed): untyped =
|
||||||
echo repr x.symbol.getImpl
|
echo repr x.getImpl
|
||||||
result = x
|
result = x
|
||||||
|
|
||||||
discard m foo
|
discard m foo
|
||||||
discard m poo
|
discard m poo
|
||||||
|
|
||||||
|
#------------
|
||||||
|
|
||||||
|
macro checkOwner(x: typed, check_id: static[int]): untyped =
|
||||||
|
let sym = case check_id:
|
||||||
|
of 0: x
|
||||||
|
of 1: x.getImpl.body[0][0][0]
|
||||||
|
of 2: x.getImpl.body[0][0][^1]
|
||||||
|
of 3: x.getImpl.body[1][0]
|
||||||
|
else: x
|
||||||
|
result = newStrLitNode($sym.owner.symKind)
|
||||||
|
|
||||||
|
macro isSameOwner(x, y: typed): untyped =
|
||||||
|
result =
|
||||||
|
if x.owner == y.owner: bindSym"true"
|
||||||
|
else: bindSym"false"
|
||||||
|
|
||||||
|
|
||||||
|
static:
|
||||||
|
doAssert checkOwner(foo, 0) == "nskModule"
|
||||||
|
doAssert checkOwner(poo, 0) == "nskModule"
|
||||||
|
doAssert checkOwner(poo, 1) == "nskProc"
|
||||||
|
doAssert checkOwner(poo, 2) == "nskProc"
|
||||||
|
doAssert checkOwner(poo, 3) == "nskModule"
|
||||||
|
doAssert isSameOwner(foo, poo)
|
||||||
|
doAssert isSameOwner(foo, echo) == false
|
||||||
|
doAssert isSameOwner(poo, len) == false
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue