@@ -2,11 +2,13 @@ module Generate.JavaScript (generate) where
3import Control.Applicative ((<$>),(<*>))
3import Control.Applicative ((<$>),(<*>))
4import Control.Arrow (first, second, (***))
4import Control.Arrow (first, second, (***))
5−import Control.Monad.State
5+import Control.Monad.State as State
6import qualified Data.List as List
6import qualified Data.List as List
7import qualified Data.Map as Map
7import qualified Data.Map as Map
8import qualified Data.Maybe as Maybe
8import qualified Data.Maybe as Maybe
9+import Language.ECMAScript3.PrettyPrint as ES
9import Language.ECMAScript3.Syntax
10import Language.ECMAScript3.Syntax
11+import qualified Text.PrettyPrint.Leijen as PP
11import AST.Expression.General as Expr
13import AST.Expression.General as Expr
12import qualified AST.Expression.Optimized as Opt
14import qualified AST.Expression.Optimized as Opt
@@ -28,8 +30,15 @@ import qualified Reporting.Crash as Crash
30generate :: Module.Optimized -> String
32generate :: Module.Optimized -> String
31−generate modul =
33+generate module_ =
32− error "TODO" modul exprToCode
34+ let
36+ flattenLets [] (Module.program (Module.body module_))
39+ concat (State.evalState (mapM defToStatements definitions) 0)
41+ PP.displayS (PP.renderPretty 0.4 120 (ES.prettyPrint stmts)) ""
35-- CODE CHUNKS
44-- CODE CHUNKS
@@ -222,7 +231,7 @@ generateFunction (args, initialBody) =
222generateTailFunction :: String -> ([P.Optimized], Opt.Expr) -> State Int (Expression ())
231generateTailFunction :: String -> ([P.Optimized], Opt.Expr) -> State Int (Expression ())
223generateTailFunction name (args, initialBody) =
232generateTailFunction name (args, initialBody) =
224 do (argVars, patternDefs) <- destructuredArgs args
233 do (argVars, patternDefs) <- destructuredArgs args
225− label <- Id () <$> Case.newVar
234+ label <- Id () <$> Var.fresh
226 code <- generateLet (Just (name, argVars, label)) patternDefs initialBody
235 code <- generateLet (Just (name, argVars, label)) patternDefs initialBody
227 let whileLoop =
236 let whileLoop =
228 JsBlock [ LabelledStmt () label (WhileStmt () (BoolLit () True) (toStatement code)) ]
237 JsBlock [ LabelledStmt () label (WhileStmt () (BoolLit () True) (toStatement code)) ]
@@ -260,7 +269,7 @@ destructPattern pattern@(A.A ann pat) =
260 return (Var.safe x, Nothing)
269 return (Var.safe x, Nothing)
263− do arg <- Case.newVar
272+ do arg <- Var.fresh
266 , Just $ Opt.Definition Opt.dummyFacts pattern (A.A ann (localVar arg))
275 , Just $ Opt.Definition Opt.dummyFacts pattern (A.A ann (localVar arg))
@@ -287,7 +296,7 @@ generateApplication tcc expr =
287 case isTailCall tcc func arity of
296 case isTailCall tcc func arity of
288 Just (argNames, label) ->
297 Just (argNames, label) ->
289 do args' <- mapM toJsExpr args
298 do args' <- mapM toJsExpr args
290− tempNames <- mapM (\_ -> Case.newVar) args
299+ tempNames <- mapM (\_ -> Var.fresh) args
291 jsBlock $
300 jsBlock $
292 VarDeclStmt () (zipWith varDecl tempNames args')
301 VarDeclStmt () (zipWith varDecl tempNames args')
293 : zipWith reassign argNames tempNames
302 : zipWith reassign argNames tempNames
@@ -336,6 +345,13 @@ generateLet tcc givenDefs givenBody =
336 jsBlock (stmts ++ toStatementList code)
345 jsBlock (stmts ++ toStatementList code)
348+flattenLets :: [Opt.Def] -> Opt.Expr -> ([Opt.Def], Opt.Expr)
349+flattenLets defs lexpr@(A.A _ expr) =
351+ Let ds body -> flattenLets (defs ++ ds) body
339-- GENERATE IFS
355-- GENERATE IFS
341generateIf :: TailCallContext -> [(Opt.Expr, Opt.Expr)] -> Opt.Expr -> State Int Code
357generateIf :: TailCallContext -> [(Opt.Expr, Opt.Expr)] -> Opt.Expr -> State Int Code
@@ -473,97 +489,7 @@ defToStatementsHelp facts annPattern@(A.A _ pattern) jsExpr =
474generateCase :: TailCallContext -> Opt.Expr -> [(P.Optimized, Opt.Expr)] -> State Int Code
490generateCase :: TailCallContext -> Opt.Expr -> [(P.Optimized, Opt.Expr)] -> State Int Code
475generateCase tcc expr branches =
491generateCase tcc expr branches =
476− do (tempVar, initialMatch) <-
492+ error "TODO" tcc expr branches
477− Case.toMatch branches
479− (revisedMatch, stmt) <-
481− A.A _ (Var (Var.Canonical Var.Local x)) ->
482− return (Case.matchSubst [(tempVar, Var.safe x)] initialMatch, [])
484− A.A _ (Var (Var.Canonical (Var.TopLevel _) x)) ->
485− return (Case.matchSubst [(tempVar, Var.safe x)] initialMatch, [])
488− do expr' <- toJsExpr expr
489− return (initialMatch, [VarDeclStmt () [varDecl tempVar expr']])
491− match' <- match tcc revisedMatch
493− jsBlock (stmt ++ match')
496−match :: TailCallContext -> Case.Match -> State Int [Statement ()]
499− Case.Match name clauses mtch' ->
500− do (isChars, clauses') <- unzip <$> mapM (clause tcc name) clauses
501− mtch'' <- match tcc mtch'
502− return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
506− Case.Clause (Right _) _ _ ->
512− if any isLiteral clauses then
515− obj (Help.splitDots name ++ ["ctor"])
517− format isChars expr =
519− InfixExpr () OpAdd expr (string "")
524− return [ ExprStmt () (Crash.crash (Crash.IncompletePatternMatch (error "TODO"))) ]
527− return [BreakStmt () Nothing]
530− toStatementList <$> exprToCode tcc expr
533− concat <$> mapM (match tcc) (dropEnd [] ms)
535− dropEnd acc [] = acc
536− dropEnd acc (m:ms) =
538− Case.Other _ -> acc ++ [m]
539− _ -> dropEnd (acc ++ [m]) ms
542−clause :: TailCallContext -> String -> Case.Clause -> State Int (Bool, CaseClause ())
543−clause tcc variable (Case.Clause value vars mtch) =
544− do statemens <- match tcc (Case.matchSubst (zip vars vars') mtch)
545− return ((,) isChar (CaseClause () pattern statemens))
548− map (\n -> variable ++ "._" ++ show n) [0..]
552− Right (Chr c) -> (True, string [c])
556− Right (Boolean b) -> BoolLit () b
557− Right lit -> Literal.literal lit
558− Left (Var.Canonical _ name) ->
562−flattenLets :: [Opt.Def] -> Opt.Expr -> ([Opt.Def], Opt.Expr)
563−flattenLets defs lexpr@(A.A _ expr) =
565− Let ds body -> flattenLets (defs ++ ds) body
569-- BINARY OPERATORS
495-- BINARY OPERATORS