diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/lambdalifting.nim | 26 | ||||
-rwxr-xr-x | compiler/transf.nim | 14 |
2 files changed, 22 insertions, 18 deletions
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index dc6469563..c62c212fb 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 0ab8bc8d3..c05627039 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 |