mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-02 11:12:37 +00:00
macros: Introduce sameType(a, b) for node types
Previously introduced node comparison `==` was working somehow wrong on nodes
returned from getType(a), comparing just ids of the symbols.
Recently introduced `==` change 47dce26886
started comparing symbol nodes pointer-wise, thus strictly. Since getType(a)
always creates new symbol pointing to the type, comparing two such nodes using
`==` always returns false, even they point to the same type.
That is why we need a new sameType macro to be able to tell if these nodes
point to the same type.
This commit is contained in:
@@ -587,7 +587,8 @@ type
|
||||
mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo,
|
||||
mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr,
|
||||
mNBindSym, mLocals, mNCallSite,
|
||||
mEqIdent, mEqNimrodNode, mNHint, mNWarning, mNError,
|
||||
mEqIdent, mEqNimrodNode, mSameNodeType,
|
||||
mNHint, mNWarning, mNError,
|
||||
mInstantiationInfo, mGetTypeInfo, mNGenSym
|
||||
|
||||
# things that we can evaluate safely at compile time, even if not asked for it:
|
||||
|
||||
@@ -692,6 +692,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
regs[ra].intVal =
|
||||
ord(exprStructuralEquivalent(regs[rb].node, regs[rc].node,
|
||||
strictSymEquality=true))
|
||||
of opcSameNodeType:
|
||||
decodeBC(rkInt)
|
||||
regs[ra].intVal = ord(regs[rb].node.typ.sameTypeOrNil regs[rc].node.typ)
|
||||
of opcXor:
|
||||
decodeBC(rkInt)
|
||||
regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
|
||||
|
||||
@@ -60,8 +60,9 @@ type
|
||||
opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat, opcShrInt, opcShlInt,
|
||||
opcBitandInt, opcBitorInt, opcBitxorInt, opcAddu, opcSubu, opcMulu,
|
||||
opcDivu, opcModu, opcEqInt, opcLeInt, opcLtInt, opcEqFloat,
|
||||
opcLeFloat, opcLtFloat, opcLeu, opcLtu, opcEqRef, opcEqNimrodNode, opcXor,
|
||||
opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt,
|
||||
opcLeFloat, opcLtFloat, opcLeu, opcLtu,
|
||||
opcEqRef, opcEqNimrodNode, opcSameNodeType,
|
||||
opcXor, opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt,
|
||||
opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet,
|
||||
opcMulSet, opcPlusSet, opcMinusSet, opcSymdiffSet, opcConcatStr,
|
||||
opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq,
|
||||
|
||||
@@ -991,6 +991,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||
of mIdentToStr: genUnaryABC(c, n, dest, opcIdentToStr)
|
||||
of mEqIdent: genBinaryABC(c, n, dest, opcEqIdent)
|
||||
of mEqNimrodNode: genBinaryABC(c, n, dest, opcEqNimrodNode)
|
||||
of mSameNodeType: genBinaryABC(c, n, dest, opcSameNodeType)
|
||||
of mNLineInfo: genUnaryABC(c, n, dest, opcNLineInfo)
|
||||
of mNHint:
|
||||
unused(n, dest)
|
||||
|
||||
@@ -144,6 +144,10 @@ proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
|
||||
proc `==`*(a, b: NimNode): bool {.magic: "EqNimrodNode", noSideEffect.}
|
||||
## compares two Nim nodes
|
||||
|
||||
proc sameType*(a, b: NimNode): bool {.magic: "SameNodeType", noSideEffect.}
|
||||
## compares two Nim nodes' types. Return true if the types are the same,
|
||||
## eg. true when comparing alias with original type.
|
||||
|
||||
proc len*(n: NimNode): int {.magic: "NLen", noSideEffect.}
|
||||
## returns the number of children of `n`.
|
||||
|
||||
|
||||
41
tests/macros/tsametype.nim
Normal file
41
tests/macros/tsametype.nim
Normal file
@@ -0,0 +1,41 @@
|
||||
discard """
|
||||
output: '''1
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
0'''
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
macro same(a: typedesc, b: typedesc): expr =
|
||||
newLit(a.getType[1].sameType b.getType[1])
|
||||
|
||||
echo same(int, int)
|
||||
echo same(int, float)
|
||||
|
||||
type
|
||||
SomeInt = int
|
||||
DistinctInt = distinct int
|
||||
SomeFloat = float
|
||||
DistinctFloat = distinct float
|
||||
|
||||
echo same(int, SomeInt)
|
||||
echo same(int, DistinctInt)
|
||||
echo same(float, SomeFloat)
|
||||
echo same(float, DistinctFloat)
|
||||
|
||||
type
|
||||
Obj = object of RootObj
|
||||
SubObj = object of Obj
|
||||
Other = object of RootObj
|
||||
|
||||
echo same(Obj, Obj)
|
||||
echo same(int, Obj)
|
||||
echo same(SubObj, SubObj)
|
||||
echo same(Other, Obj)
|
||||
Reference in New Issue
Block a user