diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index dc6469563c..c62c212fbd 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -14,6 +14,20 @@ const declarativeDefs = {nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef} procDefs = nkLambdaKinds + declarativeDefs +type + TCapture = seq[PSym] + + TLLShared {.final.} = object + transformedInnerProcs: TIntSet + c: PTransf + + TLLContext {.final.} = object + outerProc, innerProc: PSym + mapping: TIdNodeTable # mapping from symbols to nodes + shared: ref TLLShared + + PLLContext = ref TLLContext + proc indirectAccess(a, b: PSym, info: TLineInfo): PNode = # returns a[].b as a node let x = newSymNode(a) @@ -27,9 +41,6 @@ proc indirectAccess(a, b: PSym, info: TLineInfo): PNode = addSon(result, newSymNode(field)) result.typ = field.typ -type - TCapture = seq[PSym] - proc Capture(cap: var TCapture, s: PSym) = for x in cap: if x.name.id == s.name.id: return @@ -52,18 +63,21 @@ proc interestingVar(s: PSym): bool {.inline.} = result = s.kind in {skVar, skLet, skTemp, skForVar, skParam, skResult} and sfGlobal notin s.flags -proc gatherVars(c: PTransf, n: PNode, outerProc: PSym, cap: var TCapture) = +proc gatherVars(c: PLLContext, n: PNode, cap: var TCapture) = # gather used vars for closure generation into 'cap' case n.kind of nkSym: var s = n.sym - if interestingVar(s) and outerProc.id == s.owner.id: + if interestingVar(s) and c.innerProc.id != s.owner.id: + # we need to compute the path here: + var + #echo "captured: ", s.name.s Capture(cap, s) of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: nil else: for i in countup(0, sonsLen(n) - 1): - gatherVars(c, n.sons[i], outerProc, cap) + gatherVars(c, n.sons[i], cap) proc replaceVars(c: PTransf, n: PNode, outerProc, env: PSym) = for i in countup(0, safeLen(n) - 1): diff --git a/compiler/transf.nim b/compiler/transf.nim index 0ab8bc8d32..c056270392 100755 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -279,7 +279,7 @@ proc transformBreak(c: PTransf, n: PNode): PTransNode = result[0] = newSymNode(labl).PTransNode proc transformLoopBody(c: PTransf, n: PNode): PTransNode = - # XXX BUG: What if it contains "continue" and "break"? "break" needs + # What if it contains "continue" and "break"? "break" needs # an explicit label too, but not the same! # We fix this here by making every 'break' belong to its enclosing loop @@ -638,17 +638,7 @@ proc transform(c: PTransf, n: PNode): PTransNode = # nothing to be done for leaves: result = PTransNode(n) of nkBracketExpr: result = transformArrayAccess(c, n) - of procDefs: - if c.nestedProcs == 0: - inc c.nestedProcs - result = transformProc(c, n) - dec c.nestedProcs - else: - result = PTransNode(n) - if n.sons[namePos].kind == nkSym: - let x = transformSym(c, n.sons[namePos]) - if x.pnode.kind == nkClosure: result = x - of nkMacroDef: + of procDefs, nkMacroDef: # XXX no proper closure support yet: if n.sons[genericParamsPos].kind == nkEmpty: var s = n.sons[namePos].sym diff --git a/todo.txt b/todo.txt index 6bdfefc0d2..62e4d85aed 100755 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ version 0.9.0 ============= -- implement 'gorge' - implement a warning message for shadowed 'result' variable - make templates hygienic by default: try to gensym() everything in the 'block' of a template @@ -39,6 +38,8 @@ version 0.9.0 Bugs ---- +- result.tzname = if local: getTzname()[if result.isDST: 0 else: 1] else: "UTC" + Crashes the compiler. - bug: stress testing basic method example (eval example) without ``-d:release`` leaks memory? - bug: pragma statements in combination with symbol files are evaluated twice