@@ -20,7 +20,7 @@ module Language.PureScript.CodeGen.JS (
20import Data.Maybe (mapMaybe)
20import Data.Maybe (mapMaybe)
21import qualified Data.Map as M
21import qualified Data.Map as M
22import Control.Arrow (second)
22import Control.Arrow (second)
23−import Control.Monad (forM)
23+import Control.Monad (replicateM, forM)
25import Language.PureScript.TypeChecker (Environment, names)
25import Language.PureScript.TypeChecker (Environment, names)
26import Language.PureScript.Values
26import Language.PureScript.Values
@@ -73,7 +73,7 @@ valueToJs m e (ObjectLiteral ps) = JSObjectLiteral (map (second (valueToJs m e))
73valueToJs m e (ObjectUpdate o ps) = JSApp (JSAccessor "extend" (JSVar (Ident "Object"))) [ valueToJs m e o, JSObjectLiteral (map (second (valueToJs m e)) ps)]
73valueToJs m e (ObjectUpdate o ps) = JSApp (JSAccessor "extend" (JSVar (Ident "Object"))) [ valueToJs m e o, JSObjectLiteral (map (second (valueToJs m e)) ps)]
74valueToJs _ _ (Constructor name) = qualifiedToJS runProperName name
74valueToJs _ _ (Constructor name) = qualifiedToJS runProperName name
75valueToJs m e (Block sts) = JSApp (JSFunction Nothing [] (JSBlock (map (statementToJs m e) sts))) []
75valueToJs m e (Block sts) = JSApp (JSFunction Nothing [] (JSBlock (map (statementToJs m e) sts))) []
76−valueToJs m e (Case value binders) = runGen (bindersToJs m e binders (valueToJs m e value))
76+valueToJs m e (Case values binders) = runGen (bindersToJs m e binders (map (valueToJs m e) values))
77valueToJs m e (IfThenElse cond th el) = JSConditional (valueToJs m e cond) (valueToJs m e th) (valueToJs m e el)
77valueToJs m e (IfThenElse cond th el) = JSConditional (valueToJs m e cond) (valueToJs m e th) (valueToJs m e el)
78valueToJs m e (Accessor prop val) = JSAccessor prop (valueToJs m e val)
78valueToJs m e (Accessor prop val) = JSAccessor prop (valueToJs m e val)
79valueToJs m e (Indexer index val) = JSIndexer (valueToJs m e index) (valueToJs m e val)
79valueToJs m e (Indexer index val) = JSIndexer (valueToJs m e index) (valueToJs m e val)
@@ -94,12 +94,20 @@ qualifiedToJS f (Qualified (ModulePath parts) a) =
94 delimited (part:parts') = JSAccessor part (delimited parts')
94 delimited (part:parts') = JSAccessor part (delimited parts')
95 delimited _ = error "Invalid argument to delimited"
95 delimited _ = error "Invalid argument to delimited"
97−bindersToJs :: ModulePath -> Environment -> [(Binder, Value)] -> JS -> Gen JS
97+bindersToJs :: ModulePath -> Environment -> [([Binder], Maybe Guard, Value)] -> [JS] -> Gen JS
98−bindersToJs m e binders val = do
98+bindersToJs m e binders vals = do
99− valName <- fresh
99+ valNames <- replicateM (length vals) fresh
100− jss <- forM binders $ \(binder, result) -> binderToJs m e valName [JSReturn (valueToJs m e result)] binder
100+ jss <- forM binders $ \(bs, grd, result) -> go valNames [JSReturn (valueToJs m e result)] bs grd
101− return $ JSApp (JSFunction Nothing [Ident valName] (JSBlock (concat jss ++ [JSThrow (JSStringLiteral "Failed pattern match")])))
101+ return $ JSApp (JSFunction Nothing (map Ident valNames) (JSBlock (concat jss ++ [JSThrow (JSStringLiteral "Failed pattern match")])))
104+ go :: [String] -> [JS] -> [Binder] -> Maybe Guard -> Gen [JS]
105+ go _ done [] Nothing = return done
106+ go _ done [] (Just cond) = return [JSIfElse (valueToJs m e cond) (JSBlock done) Nothing]
107+ go (v:vs) done' (b:bs) grd = do
108+ done'' <- go vs done' bs grd
109+ binderToJs m e v done'' b
110+ go _ _ _ _ = error "Invalid arguments to bindersToJs"
104binderToJs :: ModulePath -> Environment -> String -> [JS] -> Binder -> Gen [JS]
112binderToJs :: ModulePath -> Environment -> String -> [JS] -> Binder -> Gen [JS]
105binderToJs _ _ _ done NullBinder = return done
113binderToJs _ _ _ done NullBinder = return done
@@ -152,9 +160,6 @@ binderToJs m e varName done (ConsBinder headBinder tailBinder) = do
152binderToJs m e varName done (NamedBinder ident binder) = do
160binderToJs m e varName done (NamedBinder ident binder) = do
153 js <- binderToJs m e varName done binder
161 js <- binderToJs m e varName done binder
154 return (JSVariableIntroduction ident (Just (JSVar (Ident varName))) : js)
162 return (JSVariableIntroduction ident (Just (JSVar (Ident varName))) : js)
155−binderToJs m e varName done (GuardedBinder cond binder) = binderToJs m e varName done' binder
157− done' = [JSIfElse (valueToJs m e cond) (JSBlock done) Nothing]
159statementToJs :: ModulePath -> Environment -> Statement -> JS
164statementToJs :: ModulePath -> Environment -> Statement -> JS
160statementToJs m e (VariableIntroduction ident value) = JSVariableIntroduction ident (Just (valueToJs m e value))
165statementToJs m e (VariableIntroduction ident value) = JSVariableIntroduction ident (Just (valueToJs m e value))