summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/msgs.nim4
-rw-r--r--compiler/semstmts.nim19
-rw-r--r--compiler/vm.nim13
-rw-r--r--compiler/vmdef.nim3
-rw-r--r--compiler/vmgen.nim28
5 files changed, 41 insertions, 26 deletions
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 895ba71f3..2a7d54d4e 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -700,11 +700,9 @@ type
 
 proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
   template maybeTrace =
-    if defined(debug) or gVerbosity >= 3:
+    if defined(debug) or gVerbosity >= 3 or msg == errInternal:
       writeStackTrace()
 
-  if msg == errInternal:
-    writeStackTrace() # we always want a stack trace here
   if msg >= fatalMin and msg <= fatalMax: 
     maybeTrace()
     quit(1)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index cd714ef6e..6f0cc3c8b 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1168,13 +1168,18 @@ proc semPragmaBlock(c: PContext, n: PNode): PNode =
 
 proc semStaticStmt(c: PContext, n: PNode): PNode =
   let a = semStmt(c, n.sons[0])
-  result = evalStaticExpr(c.module, a, c.p.owner)
-  if result.isNil:
-    LocalError(n.info, errCannotInterpretNodeX, renderTree(n))
-    result = emptyNode
-  elif result.kind == nkEmpty:
-    result = newNodeI(nkDiscardStmt, n.info, 1)
-    result.sons[0] = emptyNode
+  n.sons[0] = a
+  evalStaticStmt(c.module, a, c.p.owner)
+  result = newNodeI(nkDiscardStmt, n.info, 1)
+  result.sons[0] = emptyNode
+  when false:
+    result = evalStaticStmt(c.module, a, c.p.owner)
+    if result.isNil:
+      LocalError(n.info, errCannotInterpretNodeX, renderTree(n))
+      result = emptyNode
+    elif result.kind == nkEmpty:
+      result = newNodeI(nkDiscardStmt, n.info, 1)
+      result.sons[0] = emptyNode
 
 proc usesResult(n: PNode): bool =
   # nkStmtList(expr) properly propagates the void context,
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 019397bbc..a6cdc81b2 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -515,7 +515,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
                              regs[rb].sons == regs[rc].sons)
     of opcEqNimrodNode:
       decodeBC(nkIntLit)
-      regs[ra].intVal = ord(regs[rb].uast == regs[rc].uast)
+      regs[ra].intVal = ord(regs[rb].skipMeta == regs[rc].skipMeta)
     of opcXor:
       decodeBC(nkIntLit)
       regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
@@ -746,7 +746,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
       decodeB(nkStrLit)
       regs[ra].strVal = renderTree(regs[rb].skipMeta, {renderNoComments})
     of opcQuit:
-      if c.mode in {emRepl, emStatic}:
+      if c.mode in {emRepl, emStaticExpr, emStaticStmt}:
         Message(c.debug[pc], hintQuitCalled)
         quit(int(getOrdValue(regs[ra])))
       else:
@@ -1036,7 +1036,7 @@ proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode =
   setupGlobalCtx(module)
   var c = globalCtx
   c.mode = mode
-  let start = genExpr(c, n)
+  let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
   assert c.code[start].opcode != opcEof
   var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil)
   newSeq(tos.slots, c.prc.maxSlots)
@@ -1047,8 +1047,11 @@ proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode =
 proc evalConstExpr*(module: PSym, e: PNode): PNode = 
   result = evalConstExprAux(module, nil, e, emConst)
 
-proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode = 
-  result = evalConstExprAux(module, prc, e, emStatic)
+proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode =
+  result = evalConstExprAux(module, prc, e, emStaticExpr)
+
+proc evalStaticStmt*(module: PSym, e: PNode, prc: PSym) =
+  discard evalConstExprAux(module, prc, e, emStaticStmt)
 
 proc setupMacroParam(x: PNode): PNode =
   result = x
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 15ea9767b..1869b69c4 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -134,8 +134,9 @@ type
     emConst,                  ## evaluate for 'const' according to spec
     emOptimize,               ## evaluate for optimization purposes (same as
                               ## emConst?)
-    emStatic                  ## evaluate for enforced compile time eval
+    emStaticExpr,             ## evaluate for enforced compile time eval
                               ## ('static' context)
+    emStaticStmt              ## 'static' as an expression
 
   TSandboxFlag* = enum        ## what the evaluation engine should allow
     allowCast,                ## allow unsafe language feature: 'cast'
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index cc395f6c5..802fa1706 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -314,6 +314,11 @@ proc genLiteral(c: PCtx; n: PNode): int =
     if sameConstant(c.constants[i], n): return i
   result = rawGenLiteral(c, n)
 
+proc unused(n: PNode; x: TDest) {.inline.} =
+  if x >= 0: 
+    #debug(n)
+    InternalError(n.info, "not unused")
+
 proc genCase(c: PCtx; n: PNode; dest: var TDest) =
   #  if (!expr1) goto L1;
   #    thenPart
@@ -325,7 +330,10 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) =
   #  L2:
   #    elsePart
   #  Lend:
-  if dest < 0 and not isEmptyType(n.typ): dest = getTemp(c, n.typ)
+  if not isEmptyType(n.typ):
+    if dest < 0: dest = getTemp(c, n.typ)
+  else:
+    unused(n, dest)
   var endings: seq[TPosition] = @[]
   withTemp(tmp, n.sons[0].typ):
     c.gen(n.sons[0], tmp)
@@ -503,11 +511,6 @@ proc genAddSubInt(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
   else:
     genBinaryABC(c, n, dest, opc)
 
-proc unused(n: PNode; x: TDest) {.inline.} =
-  if x >= 0: 
-    #debug(n)
-    InternalError(n.info, "not unused")
-
 proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) =  
   let tmp = c.genx(arg)
   c.gABx(n, opcSetType, tmp, genType(c, arg.typ))
@@ -1168,7 +1171,10 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) =
       c.gABx(n, opcLdImmInt, dest, n.intVal.int)
     else:
       genLit(c, n, dest)
-  of nkUIntLit..nkNilLit: genLit(c, n, dest)
+  of nkUIntLit..pred(nkNilLit): genLit(c, n, dest)
+  of nkNilLit:
+    if not n.typ.isEmptyType: genLit(c, n, dest)
+    else: unused(n, dest)
   of nkAsgn, nkFastAsgn: 
     unused(n, dest)
     genAsgn(c, n.sons[0], n.sons[1], n.kind == nkAsgn)
@@ -1253,14 +1259,16 @@ proc genStmt*(c: PCtx; n: PNode): int =
   var d: TDest = -1
   c.gen(n, d)
   c.gABC(n, opcEof)
-  InternalAssert d < 0
+  if d >= 0: internalError(n.info, "some destination set")
 
-proc genExpr*(c: PCtx; n: PNode): int =
+proc genExpr*(c: PCtx; n: PNode, requiresValue = true): int =
   c.removeLastEof
   result = c.code.len
   var d: TDest = -1
   c.gen(n, d)
-  InternalAssert d >= 0
+  if d < 0:
+    if requiresValue: internalError(n.info, "no destination set")
+    d = 0
   c.gABC(n, opcEof, d)
 
 proc genParams(c: PCtx; params: PNode) =