Add isInstanceOf for generic procs to the macros module (#9730)
This commit is contained in:
parent
1cc8b7814d
commit
086676782a
8 changed files with 46 additions and 3 deletions
|
|
@ -61,6 +61,10 @@ proc enumToString*(enums: openArray[enum]): string =
|
||||||
- Added `system.typeof` for more control over how `type` expressions
|
- Added `system.typeof` for more control over how `type` expressions
|
||||||
can be deduced.
|
can be deduced.
|
||||||
|
|
||||||
|
- Added `macros.isInstantiationOf` for checking if the proc symbol
|
||||||
|
is instantiation of generic proc symbol.
|
||||||
|
|
||||||
|
|
||||||
### Library changes
|
### Library changes
|
||||||
|
|
||||||
- The string output of `macros.lispRepr` proc has been tweaked
|
- The string output of `macros.lispRepr` proc has been tweaked
|
||||||
|
|
|
||||||
|
|
@ -656,7 +656,8 @@ type
|
||||||
mNHint, mNWarning, mNError,
|
mNHint, mNWarning, mNError,
|
||||||
mInstantiationInfo, mGetTypeInfo,
|
mInstantiationInfo, mGetTypeInfo,
|
||||||
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
|
mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
|
||||||
mException, mBuiltinType, mSymOwner, mUncheckedArray, mGetImplTransf
|
mException, mBuiltinType, mSymOwner, mUncheckedArray, mGetImplTransf,
|
||||||
|
mSymIsInstantiationOf
|
||||||
|
|
||||||
# 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
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ proc initDefines*(symbols: StringTableRef) =
|
||||||
defineSymbol("nimUncheckedArrayTyp")
|
defineSymbol("nimUncheckedArrayTyp")
|
||||||
defineSymbol("nimHasTypeof")
|
defineSymbol("nimHasTypeof")
|
||||||
defineSymbol("nimErrorProcCanHaveBody")
|
defineSymbol("nimErrorProcCanHaveBody")
|
||||||
|
defineSymbol("nimHasInstantiationOfInMacro")
|
||||||
defineSymbol("nimHasNilSeqs")
|
defineSymbol("nimHasNilSeqs")
|
||||||
for f in low(Feature)..high(Feature):
|
for f in low(Feature)..high(Feature):
|
||||||
defineSymbol("nimHas" & $f)
|
defineSymbol("nimHas" & $f)
|
||||||
|
|
|
||||||
|
|
@ -960,6 +960,17 @@ 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 opcSymIsInstantiationOf:
|
||||||
|
decodeBC(rkInt)
|
||||||
|
let a = regs[rb].node
|
||||||
|
let b = regs[rc].node
|
||||||
|
if a.kind == nkSym and a.sym.kind in skProcKinds and
|
||||||
|
b.kind == nkSym and b.sym.kind in skProcKinds:
|
||||||
|
regs[ra].intVal =
|
||||||
|
if sfFromGeneric in a.sym.flags and a.sym.owner == b.sym: 1
|
||||||
|
else: 0
|
||||||
|
else:
|
||||||
|
stackTrace(c, tos, pc, "node is not a proc symbol")
|
||||||
of opcEcho:
|
of opcEcho:
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
if rb == 1:
|
if rb == 1:
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,8 @@ type
|
||||||
opcTypeTrait,
|
opcTypeTrait,
|
||||||
opcMarshalLoad, opcMarshalStore,
|
opcMarshalLoad, opcMarshalStore,
|
||||||
opcToNarrowInt,
|
opcToNarrowInt,
|
||||||
opcSymOwner
|
opcSymOwner,
|
||||||
|
opcSymIsInstantiationOf
|
||||||
|
|
||||||
TBlock* = object
|
TBlock* = object
|
||||||
label*: PSym
|
label*: PSym
|
||||||
|
|
|
||||||
|
|
@ -1148,6 +1148,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||||
of mGetImpl: genUnaryABC(c, n, dest, opcGetImpl)
|
of mGetImpl: genUnaryABC(c, n, dest, opcGetImpl)
|
||||||
of mGetImplTransf: genUnaryABC(c, n, dest, opcGetImplTransf)
|
of mGetImplTransf: genUnaryABC(c, n, dest, opcGetImplTransf)
|
||||||
of mSymOwner: genUnaryABC(c, n, dest, opcSymOwner)
|
of mSymOwner: genUnaryABC(c, n, dest, opcSymOwner)
|
||||||
|
of mSymIsInstantiationOf: genBinaryABC(c, n, dest, opcSymIsInstantiationOf)
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,12 @@ when defined(nimHasSymOwnerInMacro):
|
||||||
## result is also mnde of kind nnkSym if owner exists otherwise
|
## result is also mnde of kind nnkSym if owner exists otherwise
|
||||||
## nnkNilLit is returned
|
## nnkNilLit is returned
|
||||||
|
|
||||||
|
when defined(nimHasInstantiationOfInMacro):
|
||||||
|
proc isInstantiationOf*(instanceProcSym, genProcSym: NimNode): bool {.magic: "SymIsInstantiationOf", noSideEffect.}
|
||||||
|
## check if proc symbol is instance of the generic proc symbol
|
||||||
|
## useful to check proc symbols against generic symbols
|
||||||
|
## returned by `bindSym`
|
||||||
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,22 @@ static:
|
||||||
doAssert isSameOwner(foo, poo)
|
doAssert isSameOwner(foo, poo)
|
||||||
doAssert isSameOwner(foo, echo) == false
|
doAssert isSameOwner(foo, echo) == false
|
||||||
doAssert isSameOwner(poo, len) == false
|
doAssert isSameOwner(poo, len) == false
|
||||||
|
|
||||||
|
#---------------------------------------------------------------
|
||||||
|
|
||||||
|
macro check_gen_proc(ex: typed): (bool, bool) =
|
||||||
|
let lenChoice = bindsym"len"
|
||||||
|
var is_equal = false
|
||||||
|
var is_instance_of = false
|
||||||
|
for child in lenChoice:
|
||||||
|
if not is_equal:
|
||||||
|
is_equal = ex[0] == child
|
||||||
|
if not is_instance_of:
|
||||||
|
is_instance_of = isInstantiationOf(ex[0], child)
|
||||||
|
|
||||||
|
result = nnkTupleConstr.newTree(newLit(is_equal), newLit(is_instance_of))
|
||||||
|
|
||||||
|
# check that len(seq[int]) is not equal to bindSym"len", but is instance of it
|
||||||
|
let a = @[1,2,3]
|
||||||
|
assert: check_gen_proc(len(a)) == (false, true)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue