diff options
-rwxr-xr-x | compiler/ccgstmts.nim | 4 | ||||
-rwxr-xr-x | compiler/evals.nim | 45 | ||||
-rwxr-xr-x | compiler/sem.nim | 2 | ||||
-rwxr-xr-x | compiler/transf.nim | 2 | ||||
-rwxr-xr-x | todo.txt | 8 |
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 ========= |