summary refs log tree commit diff stats
path: root/compiler/semmagic.nim
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2017-08-30 23:14:33 +0200
committerAndreas Rumpf <rumpf_a@web.de>2017-08-30 23:14:33 +0200
commit8d714d2b02458553234869d7139afb73621f6d7d (patch)
tree331d8f00e6f832984fee7496ecf93ca4abfc1acd /compiler/semmagic.nim
parent786f9315e381406181843d245b5ac1f8553b6fa2 (diff)
downloadNim-8d714d2b02458553234869d7139afb73621f6d7d.tar.gz
low/high/of are now overloadable operations
Diffstat (limited to 'compiler/semmagic.nim')
-rw-r--r--compiler/semmagic.nim36
1 files changed, 36 insertions, 0 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index c664f735c..8b3d9c014 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -200,6 +200,41 @@ proc isStrangeArray(t: PType): bool =
   let t = t.skipTypes(abstractInst)
   result = t.kind == tyArray and t.firstOrd != 0
 
+proc semOf(c: PContext, n: PNode): PNode =
+  if sonsLen(n) == 3:
+    n.sons[1] = semExprWithType(c, n.sons[1])
+    n.sons[2] = semExprWithType(c, n.sons[2], {efDetermineType})
+    #restoreOldStyleType(n.sons[1])
+    #restoreOldStyleType(n.sons[2])
+    let a = skipTypes(n.sons[1].typ, abstractPtrs)
+    let b = skipTypes(n.sons[2].typ, abstractPtrs)
+    let x = skipTypes(n.sons[1].typ, abstractPtrs-{tyTypeDesc})
+    let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc})
+
+    if x.kind == tyTypeDesc or y.kind != tyTypeDesc:
+      localError(n.info, errXExpectsObjectTypes, "of")
+    elif b.kind != tyObject or a.kind != tyObject:
+      localError(n.info, errXExpectsObjectTypes, "of")
+    else:
+      let diff = inheritanceDiff(a, b)
+      # | returns: 0 iff `a` == `b`
+      # | returns: -x iff `a` is the x'th direct superclass of `b`
+      # | returns: +x iff `a` is the x'th direct subclass of `b`
+      # | returns: `maxint` iff `a` and `b` are not compatible at all
+      if diff <= 0:
+        # optimize to true:
+        message(n.info, hintConditionAlwaysTrue, renderTree(n))
+        result = newIntNode(nkIntLit, 1)
+        result.info = n.info
+        result.typ = getSysType(tyBool)
+        return result
+      elif diff == high(int):
+        localError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a))
+  else:
+    localError(n.info, errXExpectsTwoArguments, "of")
+  n.typ = getSysType(tyBool)
+  result = n
+
 proc magicsAfterOverloadResolution(c: PContext, n: PNode,
                                    flags: TExprFlags): PNode =
   case n[0].sym.magic
@@ -219,6 +254,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
     result.typ = getSysType(tyString)
   of mInstantiationInfo: result = semInstantiationInfo(c, n)
   of mOrd: result = semOrd(c, n)
+  of mOf: result = semOf(c, n)
   of mHigh, mLow: result = semLowHigh(c, n, n[0].sym.magic)
   of mShallowCopy: result = semShallowCopy(c, n, flags)
   of mNBindSym: result = semBindSym(c, n)