summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/lambdalifting.nim26
-rwxr-xr-xcompiler/transf.nim14
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