From dd6d3e90082978ffc07f38c99f46b17e564f56ff Mon Sep 17 00:00:00 2001 From: Basile Pesin Date: Mon, 15 Jun 2020 19:32:29 +0200 Subject: [PATCH] Fixed lambda capture in presence of let bindings --- examples/nested_lambdas.carp | 15 ++++++++++++++- src/Concretize.hs | 14 +++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/examples/nested_lambdas.carp b/examples/nested_lambdas.carp index 33731d0b..f0f15b20 100644 --- a/examples/nested_lambdas.carp +++ b/examples/nested_lambdas.carp @@ -1,5 +1,18 @@ (defn my-curry [f] (fn [x] (fn [y] (f x y)))) (defn double-curry [f] (fn [x] (fn [y] (fn [z] (f x y z))))) +(defn make-cb [] + ((fn [] + (let [x "hi"] + (fn [] (IO.println x)))))) + +(defn make-cb2 [] + ((fn [] + (let [x "hello" + f (fn [] (IO.println x))] + f)))) + (defn main [] - (do (((my-curry (fn [x y] (Int.+ x y))) 1) 2))) \ No newline at end of file + (do ((make-cb)) + ((make-cb2)) + (((my-curry (fn [x y] (Int.+ x y))) 1) 2))) diff --git a/src/Concretize.hs b/src/Concretize.hs index f7eae2a0..2b0e4574 100644 --- a/src/Concretize.hs +++ b/src/Concretize.hs @@ -326,14 +326,26 @@ collectCapturedVars root = removeDuplicates (map decreaseCaptureLevel (visit roo else LookupLocal (Capture (n-1)))) (Just dummyInfo) ty + pairBindings :: [XObj] -> [(XObj, XObj)] + pairBindings [] = [] + pairBindings (k:v:tl) = (k, v):pairBindings tl + visit xobj = case obj xobj of -- don't peek inside lambdas, trust their capture lists: (Lst [XObj (Fn _ captures) _ _, _, _]) -> Set.toList captures + (Lst [XObj Let _ _, XObj (Arr bindings) _ _, body]) -> + let (bound, bindingsCaptured) = foldl + (\(bound, captured) (XObj sym _ ty, expr) -> + let capt = filter (\x -> Set.notMember x bound) (visit expr) in + (Set.insert (XObj sym (Just dummyInfo) ty) bound, capt++captured)) + (Set.empty, []) (pairBindings bindings) in + let bodyCaptured = filter (\x -> Set.notMember x bound) (visit body) in + bindingsCaptured++bodyCaptured (Lst _) -> visitList xobj (Arr _) -> visitArray xobj -- TODO: Static Arrays! - (Sym path (LookupLocal (Capture _))) -> [xobj] + sym@(Sym path (LookupLocal (Capture _))) -> [XObj sym (Just dummyInfo) (ty xobj)] _ -> [] visitList :: XObj -> [XObj]