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:
Adam Strzelecki
2015-07-01 20:11:09 +02:00
parent 60ac5e3e76
commit 1a0417fbe0
6 changed files with 54 additions and 3 deletions

View File

@@ -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:

View File

@@ -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)

View File

@@ -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,

View File

@@ -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)

View File

@@ -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`.

View 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)