git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Fix a bug involving let bindings and unused variable removal. Support extended let in do-notation.
abd72b6Phil Freeman
examples/passing/Do.purs+10−2
@@ -35,8 +35,10 @@ test5 mx my mz = do
35 Just (z + sum + 1)
35 Just (z + sum + 1)
36
36
37test6 mx = \_ -> do
37test6 mx = \_ -> do
38+ let
39+ f :: forall a. Maybe a -> a
38− let Just x = mx
40+ f (Just x) = x
39− Just x
41+ Just (f mx)
40
42
41test8 = \_ -> do
43test8 = \_ -> do
42 Just (do
44 Just (do
@@ -44,4 +46,10 @@ test8 = \_ -> do
44
46
45test9 = \_ -> (+) <$> Just 1 <*> Just 2
47test9 = \_ -> (+) <$> Just 1 <*> Just 2
46
48
49+test10 _ = do
50+ let
51+ f x = g x * 3
52+ g x = f x / 2
53+ Just (f 10)
54+
47main = Debug.Trace.trace "Done"
55main = Debug.Trace.trace "Done"
examples/passing/Let.purs+7−1
@@ -24,7 +24,7 @@ test5 = let
24 f x | x > 0 = g (x / 2) + 1
24 f x | x > 0 = g (x / 2) + 1
25 f x = 0
25 f x = 0
26 g x = f (x - 1) + 1
26 g x = f (x - 1) + 1
27− in g 10
27+ in f 10
28
28
29test6 = runPure (runST (do
29test6 = runPure (runST (do
30 r <- newSTRef 0
30 r <- newSTRef 0
@@ -47,6 +47,12 @@ test8 x = let
47 go y = go $ (y + x / y) / 2
47 go y = go $ (y + x / y) / 2
48 in go x
48 in go x
49
49
50+test10 _ =
51+ let
52+ f x = g x * 3
53+ g x = f x / 2
54+ in f 10
55+
50main = do
56main = do
51 Debug.Trace.print (test1 1)
57 Debug.Trace.print (test1 1)
52 Debug.Trace.print (test2 1 2)
58 Debug.Trace.print (test2 1 2)
purescript.cabal+1−1
@@ -1,5 +1,5 @@
1name: purescript
1name: purescript
2−version: 0.4.12.1
2+version: 0.4.13
3cabal-version: >=1.8
3cabal-version: >=1.8
4build-type: Custom
4build-type: Custom
5license: MIT
5license: MIT
src/Language/PureScript/Declarations.hs+1−1
@@ -378,7 +378,7 @@ data DoNotationElement
378 -- |
378 -- |
379 -- A let statement, i.e. a pure value with a binder
379 -- A let statement, i.e. a pure value with a binder
380 --
380 --
381− | DoNotationLet Binder Value
381+ | DoNotationLet [Declaration]
382 -- |
382 -- |
383 -- A do notation element with source position information
383 -- A do notation element with source position information
384 --
384 --
src/Language/PureScript/Optimizer/Unused.hs+7−5
@@ -24,12 +24,14 @@ import Language.PureScript.CodeGen.JS.AST
24import Language.PureScript.Optimizer.Common
24import Language.PureScript.Optimizer.Common
25
25
26removeUnusedVariables :: JS -> JS
26removeUnusedVariables :: JS -> JS
27−removeUnusedVariables = everywhere (mkT $ removeFromBlock go)
27+removeUnusedVariables = everywhere (mkT $ removeFromBlock withBlock)
28 where
28 where
29+ withBlock :: [JS] -> [JS]
30+ withBlock sts = go sts sts
29− go :: [JS] -> [JS]
31+ go :: [JS] -> [JS] -> [JS]
30− go [] = []
32+ go _ [] = []
31− go (JSVariableIntroduction var _ : sts) | not (isUsed var sts) = go sts
33+ go sts (JSVariableIntroduction var _ : rest) | not (isUsed var sts) = go sts rest
32− go (s:sts) = s : go sts
34+ go sts (s : rest) = s : go sts rest
33
35
34removeCodeAfterReturnStatements :: JS -> JS
36removeCodeAfterReturnStatements :: JS -> JS
35removeCodeAfterReturnStatements = everywhere (mkT $ removeFromBlock go)
37removeCodeAfterReturnStatements = everywhere (mkT $ removeFromBlock go)
src/Language/PureScript/Parser/Declarations.hs+1−2
@@ -306,8 +306,7 @@ parseDo = do
306 Do <$> C.mark (P.many (C.same *> C.mark parseDoNotationElement))
306 Do <$> C.mark (P.many (C.same *> C.mark parseDoNotationElement))
307
307
308parseDoNotationLet :: P.Parsec String ParseState DoNotationElement
308parseDoNotationLet :: P.Parsec String ParseState DoNotationElement
309−parseDoNotationLet = DoNotationLet <$> (C.reserved "let" *> C.indented *> parseBinder)
309+parseDoNotationLet = DoNotationLet <$> (C.reserved "let" *> C.indented *> C.mark (P.many1 (C.same *> parseLocalDeclaration)))
310− <*> (C.indented *> C.reservedOp "=" *> parseValue)
311
310
312parseDoNotationBind :: P.Parsec String ParseState DoNotationElement
311parseDoNotationBind :: P.Parsec String ParseState DoNotationElement
313parseDoNotationBind = DoNotationBind <$> parseBinder <*> (C.indented *> C.reservedOp "<-" *> parseValue)
312parseDoNotationBind = DoNotationBind <$> parseBinder <*> (C.indented *> C.reservedOp "<-" *> parseValue)
src/Language/PureScript/Pretty/Values.hs+2−4
@@ -104,12 +104,10 @@ prettyPrintDoNotationElement (DoNotationBind binder val) =
104 , return " <- "
104 , return " <- "
105 , prettyPrintValue' val
105 , prettyPrintValue' val
106 ]
106 ]
107−prettyPrintDoNotationElement (DoNotationLet binder val) =
107+prettyPrintDoNotationElement (DoNotationLet ds) =
108 fmap concat $ sequence
108 fmap concat $ sequence
109 [ return "let "
109 [ return "let "
110− , prettyPrintBinder' binder
110+ , withIndent $ prettyPrintMany prettyPrintDeclaration ds
111− , return " = "
112− , prettyPrintValue' val
113 ]
111 ]
114prettyPrintDoNotationElement (PositionedDoNotationElement _ el) = prettyPrintDoNotationElement el
112prettyPrintDoNotationElement (PositionedDoNotationElement _ el) = prettyPrintDoNotationElement el
115
113
src/Language/PureScript/Sugar/DoNotation.hs+3−3
@@ -59,8 +59,8 @@ desugarDo = everywhereM (mkM replace)
59 rest' <- go rest
59 rest' <- go rest
60 let ident = head $ unusedNames rest'
60 let ident = head $ unusedNames rest'
61 return $ App (App bind val) (Abs (Left ident) (Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] Nothing rest']))
61 return $ App (App bind val) (Abs (Left ident) (Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] Nothing rest']))
62− go [DoNotationLet _ _] = Left $ mkErrorStack "Let statement cannot be the last statement in a do block" Nothing
62+ go [DoNotationLet _] = Left $ mkErrorStack "Let statement cannot be the last statement in a do block" Nothing
63− go (DoNotationLet binder val : rest) = do
63+ go (DoNotationLet ds : rest) = do
64 rest' <- go rest
64 rest' <- go rest
65− return $ Case [val] [CaseAlternative [binder] Nothing rest']
65+ return $ Let ds rest'
66 go (PositionedDoNotationElement pos el : rest) = PositionedValue pos <$> go (el : rest)
66 go (PositionedDoNotationElement pos el : rest) = PositionedValue pos <$> go (el : rest)