diff --git a/src/Language/Fay.hs b/src/Language/Fay.hs index a81a468..a37cc5a 100644 --- a/src/Language/Fay.hs +++ b/src/Language/Fay.hs @@ -631,15 +631,8 @@ constructorName = fromString . ("$_" ++) . qname compileFunCase :: Bool -> [Match] -> Compile [JsStmt] compileFunCase _toplevel [] = return [] compileFunCase toplevel matches@(Match _ name argslen _ _ _:_) = do - tco <- config configTCO - pats <- fmap optimizePatConditions $ forM matches $ \match@(Match _ _ pats _ rhs wheres) -> do - unless (noBinds wheres) $ do _ <- throwError (UnsupportedWhereInMatch match) -- TODO: Support `where'. - return () - exp <- compileRhs rhs - foldM (\inner (arg,pat) -> - compilePat (JsName arg) pat inner) - [JsEarlyReturn exp] - (zip args pats) + tco <- config configTCO + pats <- fmap optimizePatConditions (mapM compileCase matches) bind <- bindToplevel toplevel (UnQual name) (foldr (\arg inner -> JsFun [arg] [] (Just inner)) @@ -650,14 +643,32 @@ compileFunCase toplevel matches@(Match _ name argslen _ _ _:_) = do args) return [bind] where args = zipWith const uniqueNames argslen + + isWildCardMatch (Match _ _ pats _ _ _) = all isWildCardPat pats + + compileCase :: Match -> Compile [JsStmt] + compileCase match@(Match _ _ pats _ rhs _) = do + whereDecls' <- whereDecls match + exp <- compileRhs rhs + body <- if null whereDecls' + then return exp + else do + binds <- mapM compileLetDecl whereDecls' + return (JsApp (JsFun [] (concat binds) (Just exp)) []) + foldM (\inner (arg,pat) -> + compilePat (JsName arg) pat inner) + [JsEarlyReturn body] + (zip args pats) + + whereDecls :: Match -> Compile [Decl] + whereDecls (Match _ _ _ _ _ (BDecls decls)) = return decls + whereDecls match = throwError (UnsupportedWhereInMatch match) + + basecase :: [JsStmt] basecase = if any isWildCardMatch matches then [] else [throw ("unhandled case in " ++ show name) (JsList (map JsName args))] - isWildCardMatch (Match _ _ pats _ _ _) = all isWildCardPat pats - noBinds (BDecls []) = True - noBinds (IPBinds []) = True - noBinds _ = False -- | Optimize functions in tail-call form. optimizeTailCalls :: [JsParam] -- ^ The function parameters. diff --git a/tests/whereBind b/tests/whereBind new file mode 100644 index 0000000..64bb6b7 --- /dev/null +++ b/tests/whereBind @@ -0,0 +1 @@ +30 diff --git a/tests/whereBind.hs b/tests/whereBind.hs new file mode 100644 index 0000000..e38f748 --- /dev/null +++ b/tests/whereBind.hs @@ -0,0 +1,10 @@ +{-# LANGUAGE NoImplicitPrelude #-} + +main :: IO () +main = + let x = 10 + in print $ show (x + y) + where y = 20 + +print :: String -> Fay () +print = ffi "console.log(%1)" diff --git a/tests/whereBind2 b/tests/whereBind2 new file mode 100644 index 0000000..9b17b28 --- /dev/null +++ b/tests/whereBind2 @@ -0,0 +1,2 @@ +ok +nop diff --git a/tests/whereBind2.hs b/tests/whereBind2.hs new file mode 100644 index 0000000..35e99c5 --- /dev/null +++ b/tests/whereBind2.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE NoImplicitPrelude #-} + +someFun x = fun x + where fun x | x < 50 = "ok" + | otherwise = "nop" + +main :: IO () +main = do + print (someFun 30) + print (someFun 100) + +print :: String -> Fay () +print = ffi "console.log(%1)" diff --git a/tests/whereBind3 b/tests/whereBind3 new file mode 100644 index 0000000..a27663f --- /dev/null +++ b/tests/whereBind3 @@ -0,0 +1 @@ +my friends and family diff --git a/tests/whereBind3.hs b/tests/whereBind3.hs new file mode 100644 index 0000000..4439465 --- /dev/null +++ b/tests/whereBind3.hs @@ -0,0 +1,11 @@ +{-# LANGUAGE NoImplicitPrelude #-} + +f :: String -> String +f x = friends ++ family + where friends = x + family = " and family" + +main = print (f "my friends") + +print :: String -> Fay () +print = ffi "console.log(%1)"