summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semexprs.nim3
-rw-r--r--compiler/semfold.nim46
-rw-r--r--compiler/vmdef.nim2
-rw-r--r--compiler/vmdeps.nim57
-rw-r--r--compiler/vmgen.nim16
-rw-r--r--lib/pure/encodings.nim10
6 files changed, 54 insertions, 80 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 78d828e43..13bfddab7 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -780,6 +780,7 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
   #semLazyOpAux(c, n)
   result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
   if result != nil: result = afterCallActions(c, result, nOrig, flags)
+  else: result = errorNode(c, n)
 
 proc buildStringify(c: PContext, arg: PNode): PNode = 
   if arg.typ != nil and 
@@ -1839,7 +1840,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     # don't have to check the symbol for semantics here again!
     result = semSym(c, n, n.sym, flags)
   of nkEmpty, nkNone, nkCommentStmt: 
-    nil
+    discard
   of nkNilLit: 
     result.typ = getSysType(tyNil)
   of nkIntLit:
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index ca06ea1b6..fb1816f9c 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -229,6 +229,33 @@ discard """
   mShrI, mShrI64, mAddF64, mSubF64, mMulF64, mDivF64, mMaxF64, mMinF64
 """
 
+proc evalIs(n, a: PNode): PNode =
+  internalAssert a.kind == nkSym and a.sym.kind == skType
+  internalAssert n.sonsLen == 3 and
+    n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
+  
+  let t1 = a.sym.typ
+
+  if n[2].kind in {nkStrLit..nkTripleStrLit}:
+    case n[2].strVal.normalize
+    of "closure":
+      let t = skipTypes(t1, abstractRange)
+      result = newIntNode(nkIntLit, ord(t.kind == tyProc and
+                                        t.callConv == ccClosure and 
+                                        tfIterator notin t.flags))
+    of "iterator":
+      let t = skipTypes(t1, abstractRange)
+      result = newIntNode(nkIntLit, ord(t.kind == tyProc and
+                                        t.callConv == ccClosure and 
+                                        tfIterator in t.flags))
+  else:
+    # XXX semexprs.isOpImpl is slightly different and requires a context. yay.
+    let t2 = n[2].typ
+    var match = if t2.kind == tyTypeClass: matchTypeClass(t2, t1)
+                else: sameType(t1, t2)
+    result = newIntNode(nkIntLit, ord(match))
+  result.typ = n.typ
+
 proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = 
   # b and c may be nil
   result = nil
@@ -372,7 +399,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
      mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq, 
      mParseExprToAst, mParseStmtToAst, mExpandToAst, mTypeTrait,
      mNLen..mNError, mEqRef, mSlurp, mStaticExec, mNGenSym: 
-    nil
+    discard
   of mRand:
     result = newIntNodeT(math.random(a.getInt.int), n)
   else: InternalError(a.info, "evalOp(" & $m & ')')
@@ -446,8 +473,6 @@ proc magicCall(m: PSym, n: PNode): PNode =
     if sonsLen(n) > 3: 
       c = getConstExpr(m, n.sons[3])
       if c == nil: return 
-  else: 
-    b = nil
   result = evalOp(s.magic, n, a, b, c)
   
 proc getAppType(n: PNode): PNode =
@@ -485,7 +510,7 @@ proc foldConv*(n, a: PNode; check = false): PNode =
       result = a
       result.typ = n.typ
   of tyOpenArray, tyVarargs, tyProc: 
-    nil
+    discard
   else: 
     result = a
     result.typ = n.typ
@@ -523,7 +548,7 @@ proc foldArrayAccess(m: PSym, n: PNode): PNode =
       nil
     else: 
       LocalError(n.info, errIndexOutOfBounds)
-  else: nil
+  else: discard
   
 proc foldFieldAccess(m: PSym, n: PNode): PNode =
   # a real field access; proc calls have already been transformed
@@ -592,7 +617,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
         result.typ = s.typ.sons[0]
       else:
         result = newSymNodeTypeDesc(s, n.info)
-    else: nil
+    else: discard
   of nkCharLit..nkNilLit: 
     result = copyNode(n)
   of nkIfExpr: 
@@ -604,7 +629,8 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
     try:
       case s.magic
       of mNone:
-        return # XXX: if it has no sideEffect, it should be evaluated
+        # If it has no sideEffect, it should be evaluated. But not here.
+        return
       of mSizeOf:
         var a = n.sons[1]
         if computeSize(a.typ) < 0: 
@@ -644,6 +670,10 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
         result = newStrNodeT(renderTree(n[1], {renderNoComments}), n)
       of mConStrStr:
         result = foldConStrStr(m, n)
+      of mIs:
+        let a = getConstExpr(m, n[1])
+        if a != nil and a.kind == nkSym and a.sym.kind == skType:
+          result = evalIs(n, a)
       else:
         result = magicCall(m, n)
     except EOverflow: 
@@ -727,4 +757,4 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
   of nkBracketExpr: result = foldArrayAccess(m, n)
   of nkDotExpr: result = foldFieldAccess(m, n)
   else:
-    nil
+    discard
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 1869b69c4..290dfd38c 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -60,7 +60,7 @@ type
     opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet,
     opcMulSet, opcPlusSet, opcMinusSet, opcSymdiffSet, opcConcatStr,
     opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq,
-    opcSwap, opcIsNil, opcOf,
+    opcSwap, opcIsNil, opcOf, 
     opcSubStr, opcConv, opcCast, opcQuit, opcReset,
     
     opcAddStrCh,
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
index 5b1a028b1..07100897b 100644
--- a/compiler/vmdeps.nim
+++ b/compiler/vmdeps.nim
@@ -34,60 +34,3 @@ proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
   except EIO:
     LocalError(info, errCannotOpenFile, file)
     result = ""
-
-when false:
-  proc opExpandToAst*(c: PEvalContext, original: PNode): PNode =
-    var
-      n = original.copyTree
-      macroCall = n.sons[1]
-      expandedSym = macroCall.sons[0].sym
-
-    for i in countup(1, macroCall.sonsLen - 1):
-      macroCall.sons[i] = evalAux(c, macroCall.sons[i], {})
-
-    case expandedSym.kind
-    of skTemplate:
-      let genSymOwner = if c.tos != nil and c.tos.prc != nil:
-                          c.tos.prc 
-                        else:
-                          c.module
-      result = evalTemplate(macroCall, expandedSym, genSymOwner)
-    of skMacro:
-      # At this point macroCall.sons[0] is nkSym node.
-      # To be completely compatible with normal macro invocation,
-      # we want to replace it with nkIdent node featuring
-      # the original unmangled macro name.
-      macroCall.sons[0] = newIdentNode(expandedSym.name, expandedSym.info)
-      result = evalMacroCall(c, macroCall, original, expandedSym)
-    else:
-      InternalError(macroCall.info,
-        "ExpandToAst: expanded symbol is no macro or template")
-      result = emptyNode
-
-  proc opIs*(n: PNode): PNode =
-    InternalAssert n.sonsLen == 3 and
-      n[1].kind == nkSym and n[1].sym.kind == skType and
-      n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
-    
-    let t1 = n[1].sym.typ
-
-    if n[2].kind in {nkStrLit..nkTripleStrLit}:
-      case n[2].strVal.normalize
-      of "closure":
-        let t = skipTypes(t1, abstractRange)
-        result = newIntNode(nkIntLit, ord(t.kind == tyProc and
-                                          t.callConv == ccClosure and 
-                                          tfIterator notin t.flags))
-      of "iterator":
-        let t = skipTypes(t1, abstractRange)
-        result = newIntNode(nkIntLit, ord(t.kind == tyProc and
-                                          t.callConv == ccClosure and 
-                                          tfIterator in t.flags))
-    else:
-      let t2 = n[2].typ
-      var match = if t2.kind == tyTypeClass: matchTypeClass(t2, t1)
-                  else: sameType(t1, t2)
-      result = newIntNode(nkIntLit, ord(match))
-
-    result.typ = n.typ
-
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 300ef2d71..62b9e7d1e 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -16,17 +16,17 @@ import
 when hasFFI:
   import evalffi
 
-proc codeListing(c: PCtx, result: var string) =
+proc codeListing(c: PCtx, result: var string, start=0) =
   # first iteration: compute all necessary labels:
   var jumpTargets = initIntSet()
   
-  for i in 0.. < c.code.len:
+  for i in start.. < c.code.len:
     let x = c.code[i]
     if x.opcode in relativeJumps:
       jumpTargets.incl(i+x.regBx-wordExcess)
 
   # for debugging purposes
-  var i = 0
+  var i = start
   while i < c.code.len:
     if i in jumpTargets: result.addf("L$1:\n", i)
     let x = c.code[i]
@@ -48,9 +48,9 @@ proc codeListing(c: PCtx, result: var string) =
     result.add("\n")
     inc i
 
-proc echoCode*(c: PCtx) {.deprecated.} =
+proc echoCode*(c: PCtx, start=0) {.deprecated.} =
   var buf = ""
-  codeListing(c, buf)
+  codeListing(c, buf, start)
   echo buf
 
 proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) =
@@ -846,7 +846,7 @@ proc whichAsgnOpc(n: PNode): TOpcode =
     opcAsgnStr
   of tyFloat..tyFloat128:
     opcAsgnFloat
-  of tyRef, tyNil:
+  of tyRef, tyNil, tyVar:
     opcAsgnRef
   else:
     opcAsgnComplex
@@ -1371,8 +1371,8 @@ proc genProc(c: PCtx; s: PSym): int =
     c.gABC(body, opcEof, eofInstr.regA)
     c.optimizeJumps(result)
     s.offset = c.prc.maxSlots
-    #if s.name.s == "innerProc":
-    #  c.echoCode
+    #if s.name.s == "treeRepr" or s.name.s == "traverse":
+    #  c.echoCode(result)
     #  echo renderTree(body)
     c.prc = oldPrc
   else:
diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim
index ce4238409..bc849bfe8 100644
--- a/lib/pure/encodings.nim
+++ b/lib/pure/encodings.nim
@@ -14,15 +14,15 @@ import os, parseutils, strutils
 
 when not defined(windows):
   type
-    TConverter = object {.pure, final.}
+    TConverter = object
     PConverter* = ptr TConverter ## can convert between two character sets
-    
+
 else:
   type
     TCodePage = distinct int32
-    PConverter* = object {.pure.}
+    PConverter* = object
       dest, src: TCodePage
-    
+
 type
   EInvalidEncoding* = object of EInvalidValue ## exception that is raised
                                               ## for encoding errors
@@ -425,7 +425,7 @@ else:
           dst = cast[cstring](cast[int](cstring(result)) + offset)
           outLen = len(result) - offset
         else:
-          OSError()
+          OSError(lerr.TOSErrorCode)
     # iconv has a buffer that needs flushing, specially if the last char is 
     # not '\0'
     discard iconv(c, nil, nil, dst, outlen)