summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/ccgstmts.nim4
-rwxr-xr-xcompiler/evals.nim45
-rwxr-xr-xcompiler/sem.nim2
-rwxr-xr-xcompiler/transf.nim2
-rwxr-xr-xtodo.txt8
5 files changed, 40 insertions, 21 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 605440fc3..edda1997c 100755
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -22,7 +22,7 @@ proc genVarTuple(p: BProc, n: PNode) =
   var t = tup.t
   for i in countup(0, L-3): 
     var v = n.sons[i].sym
-    if sfGlobal in v.flags: 
+    if sfGlobal in v.flags and v.kind != skForVar: 
       assignGlobalVar(p, v)
       genObjectInit(p, cpsInit, v.typ, v.loc, true)
     else:
@@ -47,7 +47,7 @@ proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
 proc genSingleVar(p: BProc, a: PNode) =
   var v = a.sons[0].sym
   var immediateAsgn = a.sons[2].kind != nkEmpty
-  if sfGlobal in v.flags: 
+  if sfGlobal in v.flags and v.kind != skForVar: 
     assignGlobalVar(p, v)
     genObjectInit(p, cpsInit, v.typ, v.loc, true)
   else:
diff --git a/compiler/evals.nim b/compiler/evals.nim
index 886738704..3519e2e4d 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -27,11 +27,18 @@ type
     next*: PStackFrame        # for stacking
     params*: TNodeSeq         # parameters passed to the proc
   
+  TEvalMode* = enum           ## reason for evaluation
+    emRepl,                   ## evaluate because in REPL mode
+    emConst,                  ## evaluate for 'const' according to spec
+    emOptimize,               ## evaluate for optimization purposes (same as
+                              ## emConst?)
+    emStatic                  ## evaluate for enforced compile time eval
+                              ## ('static' context)
   TEvalContext* = object of passes.TPassContext
     module*: PSym
     tos*: PStackFrame         # top of stack
     lastException*: PNode
-    optEval*: bool            # evaluation done for optimization purposes
+    mode*: TEvalMode
     globals*: TIdNodeTable    # state of global vars
   
   PEvalContext* = ref TEvalContext
@@ -53,10 +60,10 @@ proc newStackFrame*(): PStackFrame =
   result.params = @[]
 
 proc newEvalContext*(module: PSym, filename: string, 
-                     optEval: bool): PEvalContext = 
+                     mode: TEvalMode): PEvalContext = 
   new(result)
   result.module = module
-  result.optEval = optEval
+  result.mode = mode
   initIdNodeTable(result.globals)
 
 proc pushStackFrame*(c: PEvalContext, t: PStackFrame) {.inline.} = 
@@ -342,18 +349,21 @@ proc evalVariable(c: PStackFrame, sym: PSym, flags: TEvalFlags): PNode =
   #result = emptyNode
 
 proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
-  result = IdNodeTableGet(c.globals, s)
-  if result != nil: 
-    if not aliasNeeded(result, flags): 
-      result = copyTree(result)
-  else:
-    result = s.ast
-    if result == nil or result.kind == nkEmpty:
-      result = getNullValue(s.typ, s.info)
+  if sfCompileTime in s.flags or c.mode == emRepl:
+    result = IdNodeTableGet(c.globals, s)
+    if result != nil: 
+      if not aliasNeeded(result, flags): 
+        result = copyTree(result)
     else:
-      result = evalAux(c, result, {})
-      if isSpecial(result): return
-    IdNodeTablePut(c.globals, s, result)
+      result = s.ast
+      if result == nil or result.kind == nkEmpty:
+        result = getNullValue(s.typ, s.info)
+      else:
+        result = evalAux(c, result, {})
+        if isSpecial(result): return
+      IdNodeTablePut(c.globals, s, result)
+  else:
+    result = raiseCannotEval(nil, s.info)
 
 proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = 
   result = evalAux(c, n.sons[0], flags)
@@ -540,7 +550,8 @@ proc evalAnd(c: PEvalContext, n: PNode): PNode =
   if result.intVal != 0: result = evalAux(c, n.sons[2], {})
   
 proc evalNew(c: PEvalContext, n: PNode): PNode = 
-  if c.optEval: return raiseCannotEval(c, n.info)
+  #if c.mode == emOptimize: return raiseCannotEval(c, n.info)
+  
   # we ignore the finalizer for now and most likely forever :-)
   result = evalAux(c, n.sons[1], {efLValue})
   if isSpecial(result): return 
@@ -1269,7 +1280,7 @@ proc eval*(c: PEvalContext, n: PNode): PNode =
       stackTrace(c, n, errCannotInterpretNodeX, renderTree(n))
 
 proc evalConstExpr*(module: PSym, e: PNode): PNode = 
-  var p = newEvalContext(module, "", true)
+  var p = newEvalContext(module, "", emConst)
   var s = newStackFrame()
   s.call = e
   pushStackFrame(p, s)
@@ -1296,7 +1307,7 @@ proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode =
   dec(evalTemplateCounter)
 
 proc myOpen(module: PSym, filename: string): PPassContext = 
-  var c = newEvalContext(module, filename, false)
+  var c = newEvalContext(module, filename, emRepl)
   pushStackFrame(c, newStackFrame())
   result = c
 
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 58a73a3a8..8bb8758b7 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -125,7 +125,7 @@ proc semMacroExpr(c: PContext, n: PNode, sym: PSym,
                   semCheck: bool = true): PNode = 
   markUsed(n, sym)
   if c.evalContext == nil:
-    c.evalContext = newEvalContext(c.module, "", false)
+    c.evalContext = newEvalContext(c.module, "", emStatic)
   result = evalMacroCall(c.evalContext, n, sym)
   if semCheck: result = semAfterMacroCall(c, result, sym)
 
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 986d5311d..ba74323be 100755
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -199,7 +199,7 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode =
     elif it.kind == nkIdentDefs: 
       if it.sons[0].kind != nkSym: InternalError(it.info, "transformVarSection")
       var newVar = copySym(it.sons[0].sym)
-      incl(newVar.flags, sfFromGeneric) 
+      incl(newVar.flags, sfFromGeneric)
       # fixes a strange bug for rodgen:
       #include(it.sons[0].sym.flags, sfFromGeneric);
       newVar.owner = getCurrOwner(c)
diff --git a/todo.txt b/todo.txt
index f7a545e70..50fc080b9 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,7 @@
 version 0.9.0
 =============
 
+- implement 'static' vs. 'const'
 - ``=`` should be overloadable; requires specialization for ``=``
 - fix remaining generics bugs
 - fix remaining closure bugs:
@@ -139,6 +140,13 @@ Low priority
 - implement closures that support nesting > 1
 
 
+Further optimization ideas
+==========================
+
+- To optimize further copies away, you want to gather the additional
+  information inlining would provide, but don't inline for code size reasons.
+
+
 Version 2
 =========