summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ccgstmts.nim5
-rw-r--r--compiler/nimsets.nim27
-rw-r--r--compiler/vm.nim7
-rw-r--r--compiler/vmdeps.nim30
-rw-r--r--compiler/vmgen.nim49
5 files changed, 69 insertions, 49 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index c3374a354..6f362a615 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -322,6 +322,7 @@ proc genComputedGoto(p: BProc; n: PNode) =
   gotoArray.appf("&&TMP$#};$n", (id+arraySize).toRope)
   line(p, cpsLocals, gotoArray)
   
+  for j in 0 .. casePos-1: genStmts(p, n.sons[j])
   let caseStmt = n.sons[casePos]
   var a: TLoc
   initLocExpr(p, caseStmt.sons[0], a)
@@ -329,6 +330,7 @@ proc genComputedGoto(p: BProc; n: PNode) =
   lineF(p, cpsStmts, "goto *$#[$#];$n", tmp, a.rdLoc)
   
   for i in 1 .. <caseStmt.len:
+    startBlock(p)
     let it = caseStmt.sons[i]
     for j in 0 .. it.len-2:
       if it.sons[j].kind == nkRange:
@@ -336,12 +338,13 @@ proc genComputedGoto(p: BProc; n: PNode) =
         return
       let val = getOrdValue(it.sons[j])
       lineF(p, cpsStmts, "TMP$#:$n", intLiteral(val+id+1))
-    for j in 0 .. casePos-1: genStmts(p, n.sons[j])
     genStmts(p, it.lastSon)
     for j in casePos+1 .. <n.len: genStmts(p, n.sons[j])
+    for j in 0 .. casePos-1: genStmts(p, n.sons[j])
     var a: TLoc
     initLocExpr(p, caseStmt.sons[0], a)
     lineF(p, cpsStmts, "goto *$#[$#];$n", tmp, a.rdLoc)
+    endBlock(p)
 
 proc genWhileStmt(p: BProc, t: PNode) =
   # we don't generate labels here as for example GCC would produce
diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim
index f874ccdca..34f79e14b 100644
--- a/compiler/nimsets.nim
+++ b/compiler/nimsets.nim
@@ -117,32 +117,17 @@ proc ToTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode =
       e = b
     Inc(e)
 
-type 
-  TSetOP = enum 
-    soUnion, soDiff, soSymDiff, soIntersect
-
-proc nodeSetOp(a, b: PNode, op: TSetOp): PNode = 
+template nodeSetOp(a, b: PNode, op: expr) {.dirty.} = 
   var x, y: TBitSet
   toBitSet(a, x)
   toBitSet(b, y)
-  case op
-  of soUnion: BitSetUnion(x, y)
-  of soDiff: BitSetDiff(x, y)
-  of soSymDiff: BitSetSymDiff(x, y)
-  of soIntersect: BitSetIntersect(x, y)
+  op(x, y)
   result = toTreeSet(x, a.typ, a.info)
 
-proc unionSets(a, b: PNode): PNode = 
-  result = nodeSetOp(a, b, soUnion)
-
-proc diffSets(a, b: PNode): PNode = 
-  result = nodeSetOp(a, b, soDiff)
-
-proc intersectSets(a, b: PNode): PNode = 
-  result = nodeSetOp(a, b, soIntersect)
-
-proc symdiffSets(a, b: PNode): PNode = 
-  result = nodeSetOp(a, b, soSymDiff)
+proc unionSets(a, b: PNode): PNode = nodeSetOp(a, b, BitSetUnion)
+proc diffSets(a, b: PNode): PNode = nodeSetOp(a, b, BitSetDiff)
+proc intersectSets(a, b: PNode): PNode = nodeSetOp(a, b, BitSetIntersect)
+proc symdiffSets(a, b: PNode): PNode = nodeSetOp(a, b, BitSetSymDiff)
 
 proc containsSets(a, b: PNode): bool = 
   var x, y: TBitSet
diff --git a/compiler/vm.nim b/compiler/vm.nim
index b02de405e..e13d91e77 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -352,7 +352,6 @@ proc execute(c: PCtx, start: int) =
       if not inSet(regs[ra], regs[rb]): addSon(regs[ra], copyTree(regs[rb]))
     of opcExcl:
       decodeB(nkCurly)
-      # XXX arg we need types here :-(
       var b = newNodeIT(nkCurly, regs[rb].info, regs[rb].typ)
       addSon(b, regs[rb])
       var r = diffSets(regs[ra], b)
@@ -834,6 +833,12 @@ proc execute(c: PCtx, start: int) =
       regs[ra] = newSymNode(newSym(k.TSymKind, name.getIdent, c.module,
                             c.debug[pc]))
       incl(regs[ra].sym.flags, sfGenSym)
+    of opcTypeTrait:
+      # XXX only supports 'name' for now; we can use regC to encode the
+      # type trait operation
+      decodeB(nkStrLit)
+      let typ = regs[rb].sym.typ.skipTypes({tyTypeDesc})
+      regs[ra].strVal = typ.typeToString(preferExported)
     inc pc
 
 proc evalStmt*(c: PCtx, n: PNode) =
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
index 919cd5f9d..0e90a9b14 100644
--- a/compiler/vmdeps.nim
+++ b/compiler/vmdeps.nim
@@ -35,6 +35,21 @@ proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
     result = ""
     LocalError(info, errCannotOpenFile, file)
 
+proc opTypeTrait*(n: PNode, context: PSym): PNode =
+  ## XXX: This should be pretty much guaranteed to be true
+  # by the type traits procs' signatures, but until the
+  # code is more mature it doesn't hurt to be extra safe
+  internalAssert n.len >= 2 and n.sons[1].kind == nkSym
+
+  let typ = n.sons[1].sym.typ.skipTypes({tyTypeDesc})
+  case n.sons[0].sym.name.s.normalize
+  of "name":
+    result = newStrNode(nkStrLit, typ.typeToString(preferExported))
+    result.typ = newType(tyString, context)
+    result.info = n.info
+  else:
+    internalAssert false
+
 when false:
   proc opExpandToAst*(c: PEvalContext, original: PNode): PNode =
     var
@@ -64,21 +79,6 @@ when false:
         "ExpandToAst: expanded symbol is no macro or template")
       result = emptyNode
 
-  proc opTypeTrait*(n: PNode, context: PSym): PNode =
-    ## XXX: This should be pretty much guaranteed to be true
-    # by the type traits procs' signatures, but until the
-    # code is more mature it doesn't hurt to be extra safe
-    internalAssert n.len >= 2 and n.sons[1].kind == nkSym
-
-    let typ = n.sons[1].sym.typ.skipTypes({tyTypeDesc})
-    case n.sons[0].sym.name.s.normalize
-    of "name":
-      result = newStrNode(nkStrLit, typ.typeToString(preferExported))
-      result.typ = newType(tyString, context)
-      result.info = n.info
-    else:
-      internalAssert false
-
   proc opIs*(n: PNode): PNode =
     InternalAssert n.sonsLen == 3 and
       n[1].kind == nkSym and n[1].sym.kind == skType and
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index f7df31c0c..84d82e117 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -439,6 +439,22 @@ proc genBinaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
   c.freeTemp(tmp)
   c.freeTemp(tmp2)
 
+proc genSetType(c: PCtx; n: PNode; dest: TRegister) =
+  let t = skipTypes(n.typ, abstractInst)
+  if t.kind == tySet:
+    c.gABx(n, opcSetType, dest, c.genType(t))
+
+proc genBinarySet(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
+  let
+    tmp = c.genx(n.sons[1])
+    tmp2 = c.genx(n.sons[2])
+  if dest < 0: dest = c.getTemp(n.typ)
+  c.genSetType(n.sons[1], tmp)
+  c.genSetType(n.sons[2], tmp2)
+  c.gABC(n, opc, dest, tmp, tmp2)
+  c.freeTemp(tmp)
+  c.freeTemp(tmp2)
+
 proc genBinaryStmt(c: PCtx; n: PNode; opc: TOpcode) =
   let
     dest = c.genx(n.sons[1])
@@ -488,6 +504,13 @@ proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) =
   c.gABx(n, opc, 0, genType(c, n.typ))
   c.freeTemp(tmp)
 
+proc genCard(c: PCtx; n: PNode; dest: var TDest) =
+  let tmp = c.genx(n.sons[1])
+  if dest < 0: dest = c.getTemp(n.typ)
+  c.genSetType(n.sons[1], tmp)
+  c.gABC(n, opc, dest, tmp)
+  c.freeTemp(tmp)
+
 proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
   let m = n.sons[0].sym.magic
   case m
@@ -532,10 +555,11 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
     unused(n, dest)
     var d = c.genx(n.sons[1])
     var tmp = c.genx(n.sons[2])
+    c.genSetType(n.sons[1], d)
     c.gABC(n, if m == mIncl: opcIncl else: opcExcl, d, tmp)
     c.freeTemp(d)
     c.freeTemp(tmp)
-  of mCard: genUnaryABC(c, n, dest, opcCard)
+  of mCard: genCard(c, n, dest)
   of mMulI, mMulI64: genBinaryABC(c, n, dest, opcMulInt)
   of mDivI, mDivI64: genBinaryABC(c, n, dest, opcDivInt)
   of mModI, mModI64: genBinaryABC(c, n, dest, opcModInt)
@@ -580,15 +604,15 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
   of mEqStr: genBinaryABC(c, n, dest, opcEqStr)
   of mLeStr: genBinaryABC(c, n, dest, opcLeStr)
   of mLtStr: genBinaryABC(c, n, dest, opcLtStr)
-  of mEqSet: genBinaryABC(c, n, dest, opcEqSet)
-  of mLeSet: genBinaryABC(c, n, dest, opcLeSet)
-  of mLtSet: genBinaryABC(c, n, dest, opcLtSet)
-  of mMulSet: genBinaryABC(c, n, dest, opcMulSet)
-  of mPlusSet: genBinaryABC(c, n, dest, opcPlusSet)
-  of mMinusSet: genBinaryABC(c, n, dest, opcMinusSet)
-  of mSymDiffSet: genBinaryABC(c, n, dest, opcSymdiffSet)
+  of mEqSet: genBinarySet(c, n, dest, opcEqSet)
+  of mLeSet: genBinarySet(c, n, dest, opcLeSet)
+  of mLtSet: genBinarySet(c, n, dest, opcLtSet)
+  of mMulSet: genBinarySet(c, n, dest, opcMulSet)
+  of mPlusSet: genBinarySet(c, n, dest, opcPlusSet)
+  of mMinusSet: genBinarySet(c, n, dest, opcMinusSet)
+  of mSymDiffSet: genBinarySet(c, n, dest, opcSymdiffSet)
   of mConStrStr: genVarargsABC(c, n, dest, opcConcatStr)
-  of mInSet: genBinaryABC(c, n, dest, opcContainsSet)
+  of mInSet: genBinarySet(c, n, dest, opcContainsSet)
   of mRepr: genUnaryABC(c, n, dest, opcRepr)
   of mExit:
     unused(n, dest)
@@ -675,8 +699,11 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
   of mExpandToAst:
     InternalError(n.info, "cannot generate code for: " & $m)
   of mTypeTrait: 
-    
-    InternalError(n.info, "cannot generate code for: " & $m)
+    let tmp = c.genx(n.sons[1])
+    if dest < 0: dest = c.getTemp(n.typ)
+    c.gABx(n, opcSetType, tmp, c.genType(n.sons[1]))
+    c.gABC(n, opcTypeTrait, dest, tmp)
+    c.freeTemp(tmp)
   of mIs:
     InternalError(n.info, "cannot generate code for: " & $m)
   of mSlurp: genUnaryABC(c, n, dest, opcSlurp)