@@ -12,7 +12,7 @@ import Language.ECMAScript3.Syntax
13import AST.Module
13import AST.Module
14import AST.Expression.General as Expr
14import AST.Expression.General as Expr
15−import qualified AST.Expression.Canonical as Canonical
15+import qualified AST.Expression.Optimized as Opt
16import qualified AST.Helpers as Help
16import qualified AST.Helpers as Help
17import AST.Literal
17import AST.Literal
18import qualified AST.Module as Module
18import qualified AST.Module as Module
@@ -26,7 +26,6 @@ import qualified Generate.JavaScript.Port as Port
26import qualified Generate.JavaScript.Variable as Var
26import qualified Generate.JavaScript.Variable as Var
27import qualified Reporting.Annotation as A
27import qualified Reporting.Annotation as A
28import qualified Reporting.Crash as Crash
28import qualified Reporting.Crash as Crash
29−import qualified Reporting.Region as R
32internalImports :: Module.Name -> [VarDecl ()]
31internalImports :: Module.Name -> [VarDecl ()]
@@ -117,13 +116,13 @@ toExpr code =
118-- EXPRESSIONS
117-- EXPRESSIONS
120−exprToJsExpr :: Canonical.Expr -> State Int (Expression ())
119+exprToJsExpr :: Opt.Expr -> State Int (Expression ())
121exprToJsExpr canonicalExpr =
120exprToJsExpr canonicalExpr =
122 toExpr <$> exprToCode canonicalExpr
121 toExpr <$> exprToCode canonicalExpr
125−exprToCode :: Canonical.Expr -> State Int Code
124+exprToCode :: Opt.Expr -> State Int Code
126−exprToCode annotatedExpr@(A.A region expr) =
125+exprToCode annotatedExpr@(A.A _ expr) =
127 case expr of
126 case expr of
128 Var var ->
127 Var var ->
129 jsExpr $ Var.canonical var
128 jsExpr $ Var.canonical var
@@ -179,7 +178,7 @@ exprToCode annotatedExpr@(A.A region expr) =
179 map (first prop) (Map.toList (Map.map head fs))
178 map (first prop) (Map.toList (Map.map head fs))
181 Binop op leftExpr rightExpr ->
180 Binop op leftExpr rightExpr ->
182− binop region op leftExpr rightExpr
181+ binop op leftExpr rightExpr
184 Lambda _ _ ->
183 Lambda _ _ ->
185 generateFunction (Expr.collectLambdas annotatedExpr)
184 generateFunction (Expr.collectLambdas annotatedExpr)
@@ -207,7 +206,7 @@ exprToCode annotatedExpr@(A.A region expr) =
207 generateIf branches finally
206 generateIf branches finally
209 Case expr branches ->
208 Case expr branches ->
210− generateCase region expr branches
209+ generateCase expr branches
212 ExplicitList elements ->
211 ExplicitList elements ->
213 do jsElements <- mapM exprToJsExpr elements
212 do jsElements <- mapM exprToJsExpr elements
@@ -238,12 +237,12 @@ exprToCode annotatedExpr@(A.A region expr) =
238 jsExpr (Port.task name expr' portType)
237 jsExpr (Port.task name expr' portType)
240 Crash details ->
239 Crash details ->
241− jsExpr $ Crash.crash region details
240+ jsExpr $ Crash.crash details
244-- FUNCTIONS
243-- FUNCTIONS
246−generateFunction :: ([P.CanonicalPattern], Canonical.Expr) -> State Int Code
245+generateFunction :: ([P.Optimized], Opt.Expr) -> State Int Code
247generateFunction (args, initialBody) =
246generateFunction (args, initialBody) =
248 do (argVars, patternDefs) <- destructuredArgs args
247 do (argVars, patternDefs) <- destructuredArgs args
249 code <- generateLet patternDefs initialBody
248 code <- generateLet patternDefs initialBody
@@ -268,13 +267,13 @@ generateFunctionWithArity args code =
268 foldl (\body arg -> function [arg] [ret body]) innerBody otherArgs
267 foldl (\body arg -> function [arg] [ret body]) innerBody otherArgs
271−destructuredArgs :: [P.CanonicalPattern] -> State Int ([String], [Canonical.Def])
270+destructuredArgs :: [P.Optimized] -> State Int ([String], [Opt.Def])
272destructuredArgs args =
271destructuredArgs args =
273 do (argVars, maybePatternDefs) <- unzip <$> mapM destructPattern args
272 do (argVars, maybePatternDefs) <- unzip <$> mapM destructPattern args
274 return (argVars, Maybe.catMaybes maybePatternDefs)
273 return (argVars, Maybe.catMaybes maybePatternDefs)
277−destructPattern :: P.CanonicalPattern -> State Int (String, Maybe Canonical.Def)
276+destructPattern :: P.Optimized -> State Int (String, Maybe Opt.Def)
278destructPattern pattern@(A.A ann pat) =
277destructPattern pattern@(A.A ann pat) =
279 case pat of
278 case pat of
280 P.Var x ->
279 P.Var x ->
@@ -284,15 +283,15 @@ destructPattern pattern@(A.A ann pat) =
284 do arg <- Case.newVar
283 do arg <- Case.newVar
287− , Just $ Canonical.Definition pattern (A.A ann (localVar arg)) Nothing
286+ , Just $ Opt.Definition Opt.dummyFacts pattern (A.A ann (localVar arg))
291-- LET EXPRESSIONS
290-- LET EXPRESSIONS
293generateLet
292generateLet
294− :: [Canonical.Def]
293+ :: [Opt.Def]
295− -> Canonical.Expr
294+ -> Opt.Expr
296 -> State Int Code
295 -> State Int Code
297generateLet givenDefs givenBody =
296generateLet givenDefs givenBody =
298 do let (defs, body) = flattenLets givenDefs givenBody
297 do let (defs, body) = flattenLets givenDefs givenBody
@@ -308,7 +307,7 @@ generateLet givenDefs givenBody =
309-- GENERATE IFS
308-- GENERATE IFS
311−generateIf :: [(Canonical.Expr, Canonical.Expr)] -> Canonical.Expr -> State Int Code
310+generateIf :: [(Opt.Expr, Opt.Expr)] -> Opt.Expr -> State Int Code
312generateIf givenBranches givenFinally =
311generateIf givenBranches givenFinally =
314 (branches, finally) =
313 (branches, finally) =
@@ -334,18 +333,18 @@ generateIf givenBranches givenFinally =
337− :: [(Canonical.Expr, Canonical.Expr)]
336+ :: [(Opt.Expr, Opt.Expr)]
338− -> Canonical.Expr
337+ -> Opt.Expr
339− -> ([(Canonical.Expr, Canonical.Expr)], Canonical.Expr)
338+ -> ([(Opt.Expr, Opt.Expr)], Opt.Expr)
340crushIfs branches finally =
339crushIfs branches finally =
341 crushIfsHelp [] branches finally
340 crushIfsHelp [] branches finally
344crushIfsHelp
343crushIfsHelp
345− :: [(Canonical.Expr, Canonical.Expr)]
344+ :: [(Opt.Expr, Opt.Expr)]
346− -> [(Canonical.Expr, Canonical.Expr)]
345+ -> [(Opt.Expr, Opt.Expr)]
347− -> Canonical.Expr
346+ -> Opt.Expr
348− -> ([(Canonical.Expr, Canonical.Expr)], Canonical.Expr)
347+ -> ([(Opt.Expr, Opt.Expr)], Opt.Expr)
349crushIfsHelp visitedBranches unvisitedBranches finally =
348crushIfsHelp visitedBranches unvisitedBranches finally =
350 case unvisitedBranches of
349 case unvisitedBranches of
@@ -369,13 +368,22 @@ crushIfsHelp visitedBranches unvisitedBranches finally =
370-- DEFINITIONS
369-- DEFINITIONS
372−defToStatements :: Canonical.Def -> State Int [Statement ()]
371+defToStatements :: Opt.Def -> State Int [Statement ()]
373−defToStatements (Canonical.Definition pattern expr _) =
372+defToStatements (Opt.Definition facts pattern expr) =
374− defToStatementsHelp pattern =<< exprToJsExpr expr
373+ case Opt.tailRecursionDetails facts of
374+ Just (name, arity) ->
375+ error "TODO" name arity
378+ defToStatementsHelp facts pattern =<< exprToJsExpr expr
377−defToStatementsHelp :: P.CanonicalPattern -> Expression () -> State Int [Statement ()]
381+defToStatementsHelp
385+ -> State Int [Statement ()]
378−defToStatementsHelp annPattern@(A.A patternRegion pattern) jsExpr =
386+defToStatementsHelp facts annPattern@(A.A _ pattern) jsExpr =
380 define x =
388 define x =
381 varDecl x jsExpr
389 varDecl x jsExpr
@@ -417,25 +425,25 @@ defToStatementsHelp annPattern@(A.A patternRegion pattern) jsExpr =
418 safeAssign = varDecl "$" (CondExpr () if' (ref "_raw") exception)
426 safeAssign = varDecl "$" (CondExpr () if' (ref "_raw") exception)
419 if' = InfixExpr () OpStrictEq (obj ["_raw","ctor"]) (string name)
427 if' = InfixExpr () OpStrictEq (obj ["_raw","ctor"]) (string name)
420− exception = Crash.crash patternRegion Crash.IncompletePatternMatch
428+ exception = Crash.crash (Crash.IncompletePatternMatch (error "TODO"))
423 do defs' <- concat <$> mapM toDef vars
431 do defs' <- concat <$> mapM toDef vars
424 return (VarDeclStmt () [define "_"] : defs')
432 return (VarDeclStmt () [define "_"] : defs')
426 vars = P.boundVarList annPattern
434 vars = P.boundVarList annPattern
427− mkVar = A.A patternRegion . localVar
435+ mkVar = A.A () . localVar
428 toDef y =
436 toDef y =
429− let expr = A.A patternRegion $ Case (mkVar "_") [(annPattern, mkVar y)]
437+ let expr = A.A () $ Case (mkVar "_") [(annPattern, mkVar y)]
430− pat = A.A patternRegion (P.Var y)
438+ pat = A.A () (P.Var y)
432− defToStatements (Canonical.Definition pat expr Nothing)
440+ defToStatements (Opt.Definition facts pat expr)
435-- CASE EXPRESSIONS
443-- CASE EXPRESSIONS
437−generateCase :: R.Region -> Canonical.Expr -> [(P.CanonicalPattern, Canonical.Expr)] -> State Int Code
445+generateCase :: Opt.Expr -> [(P.Optimized, Opt.Expr)] -> State Int Code
438−generateCase region expr branches =
446+generateCase expr branches =
439 do (tempVar, initialMatch) <-
447 do (tempVar, initialMatch) <-
440 Case.toMatch branches
448 Case.toMatch branches
@@ -447,17 +455,17 @@ generateCase region expr branches =
447 do expr' <- exprToJsExpr expr
455 do expr' <- exprToJsExpr expr
448 return (initialMatch, [VarDeclStmt () [varDecl tempVar expr']])
456 return (initialMatch, [VarDeclStmt () [varDecl tempVar expr']])
450− match' <- match region revisedMatch
458+ match' <- match revisedMatch
452 jsBlock (stmt ++ match')
460 jsBlock (stmt ++ match')
455−match :: R.Region -> Case.Match -> State Int [Statement ()]
463+match :: Case.Match -> State Int [Statement ()]
456−match region mtch =
464+match mtch =
457 case mtch of
465 case mtch of
458 Case.Match name clauses mtch' ->
466 Case.Match name clauses mtch' ->
459− do (isChars, clauses') <- unzip <$> mapM (clause region name) clauses
467+ do (isChars, clauses') <- unzip <$> mapM (clause name) clauses
460− mtch'' <- match region mtch'
468+ mtch'' <- match mtch'
461 return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
469 return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
463 isLiteral p =
471 isLiteral p =
@@ -480,7 +488,7 @@ match region mtch =
482 Case.Fail ->
490 Case.Fail ->
483− return [ ExprStmt () (Crash.crash region Crash.IncompletePatternMatch) ]
491+ return [ ExprStmt () (Crash.crash (Crash.IncompletePatternMatch (error "TODO"))) ]
485 Case.Break ->
493 Case.Break ->
486 return [BreakStmt () Nothing]
494 return [BreakStmt () Nothing]
@@ -489,7 +497,7 @@ match region mtch =
489 toStatementList <$> exprToCode expr
497 toStatementList <$> exprToCode expr
491 Case.Seq ms ->
499 Case.Seq ms ->
492− concat <$> mapM (match region) (dropEnd [] ms)
500+ concat <$> mapM match (dropEnd [] ms)
494 dropEnd acc [] = acc
502 dropEnd acc [] = acc
495 dropEnd acc (m:ms) =
503 dropEnd acc (m:ms) =
@@ -498,9 +506,9 @@ match region mtch =
498 _ -> dropEnd (acc ++ [m]) ms
506 _ -> dropEnd (acc ++ [m]) ms
501−clause :: R.Region -> String -> Case.Clause -> State Int (Bool, CaseClause ())
509+clause :: String -> Case.Clause -> State Int (Bool, CaseClause ())
502−clause region variable (Case.Clause value vars mtch) =
510+clause variable (Case.Clause value vars mtch) =
503− (,) isChar . CaseClause () pattern <$> match region (Case.matchSubst (zip vars vars') mtch)
511+ (,) isChar . CaseClause () pattern <$> match (Case.matchSubst (zip vars vars') mtch)
506 map (\n -> variable ++ "._" ++ show n) [0..]
514 map (\n -> variable ++ "._" ++ show n) [0..]
@@ -517,14 +525,14 @@ clause region variable (Case.Clause value vars mtch) =
517 string name
525 string name
520−flattenLets :: [Canonical.Def] -> Canonical.Expr -> ([Canonical.Def], Canonical.Expr)
528+flattenLets :: [Opt.Def] -> Opt.Expr -> ([Opt.Def], Opt.Expr)
521flattenLets defs lexpr@(A.A _ expr) =
529flattenLets defs lexpr@(A.A _ expr) =
522 case expr of
530 case expr of
523 Let ds body -> flattenLets (defs ++ ds) body
531 Let ds body -> flattenLets (defs ++ ds) body
524 _ -> (defs, lexpr)
532 _ -> (defs, lexpr)
527−generate :: Module.CanonicalModule -> String
535+generate :: Module.Optimized -> String
528generate modul =
536generate modul =
529 show . prettyPrint $ setup "Elm" (names ++ ["make"]) ++
537 show . prettyPrint $ setup "Elm" (names ++ ["make"]) ++
530 [ assign ("Elm" : names ++ ["make"]) (function [localRuntime] programStmts) ]
538 [ assign ("Elm" : names ++ ["make"]) (function [localRuntime] programStmts) ]
@@ -613,14 +621,13 @@ generate modul =
613-- BINARY OPERATORS
621-- BINARY OPERATORS
617− -> Var.Canonical
624+ :: Var.Canonical
618− -> Canonical.Expr
625+ -> Opt.Expr
619− -> Canonical.Expr
626+ -> Opt.Expr
620 -> State Int Code
627 -> State Int Code
621−binop region func left right
628+binop func left right
622 | func == Var.Canonical Var.BuiltIn "::" =
629 | func == Var.Canonical Var.BuiltIn "::" =
623− exprToCode (A.A region (Data "::" [left,right]))
630+ exprToCode (A.A () (Data "::" [left,right]))
625 | func == forwardCompose =
632 | func == forwardCompose =
626 compose (collectLeftAssoc forwardCompose left right)
633 compose (collectLeftAssoc forwardCompose left right)
@@ -647,13 +654,13 @@ apply arg func =
647 func <| arg
654 func <| arg
650−compose :: [Canonical.Expr] -> State Int Code
657+compose :: [Opt.Expr] -> State Int Code
651compose functions =
658compose functions =
652 do jsFunctions <- mapM exprToJsExpr functions
659 do jsFunctions <- mapM exprToJsExpr functions
653 jsExpr $ ["$"] ==> List.foldl' apply (ref "$") jsFunctions
660 jsExpr $ ["$"] ==> List.foldl' apply (ref "$") jsFunctions
656−pipe :: [Canonical.Expr] -> State Int Code
663+pipe :: [Opt.Expr] -> State Int Code
657pipe expressions =
664pipe expressions =
658 do (value:functions) <- mapM exprToJsExpr expressions
665 do (value:functions) <- mapM exprToJsExpr expressions
659 jsExpr $ List.foldl' apply value functions
666 jsExpr $ List.foldl' apply value functions
@@ -740,12 +747,12 @@ cmp op n a b =
740-- BINARY OPERATOR COLLECTORS
747-- BINARY OPERATOR COLLECTORS
742-- (h << g << f) becomes [f, g, h] which is the order you want for doing stuff
749-- (h << g << f) becomes [f, g, h] which is the order you want for doing stuff
743−collectRightAssoc :: Var.Canonical -> Canonical.Expr -> Canonical.Expr -> [Canonical.Expr]
750+collectRightAssoc :: Var.Canonical -> Opt.Expr -> Opt.Expr -> [Opt.Expr]
744collectRightAssoc desiredOp left right =
751collectRightAssoc desiredOp left right =
745 collectRightAssocHelp desiredOp [left] right
752 collectRightAssocHelp desiredOp [left] right
748−collectRightAssocHelp :: Var.Canonical -> [Canonical.Expr] -> Canonical.Expr -> [Canonical.Expr]
755+collectRightAssocHelp :: Var.Canonical -> [Opt.Expr] -> Opt.Expr -> [Opt.Expr]
749collectRightAssocHelp desiredOp exprList expr =
756collectRightAssocHelp desiredOp exprList expr =
750 case expr of
757 case expr of
751 A.A _ (Binop op left right) | op == desiredOp ->
758 A.A _ (Binop op left right) | op == desiredOp ->
@@ -756,12 +763,12 @@ collectRightAssocHelp desiredOp exprList expr =
758-- (f >> g >> h) becomes [f, g, h] which is the order you want for doing stuff
765-- (f >> g >> h) becomes [f, g, h] which is the order you want for doing stuff
759−collectLeftAssoc :: Var.Canonical -> Canonical.Expr -> Canonical.Expr -> [Canonical.Expr]
766+collectLeftAssoc :: Var.Canonical -> Opt.Expr -> Opt.Expr -> [Opt.Expr]
760collectLeftAssoc desiredOp left right =
767collectLeftAssoc desiredOp left right =
761 collectLeftAssocHelp desiredOp [right] left
768 collectLeftAssocHelp desiredOp [right] left
764−collectLeftAssocHelp :: Var.Canonical -> [Canonical.Expr] -> Canonical.Expr -> [Canonical.Expr]
771+collectLeftAssocHelp :: Var.Canonical -> [Opt.Expr] -> Opt.Expr -> [Opt.Expr]
765collectLeftAssocHelp desiredOp exprList expr =
772collectLeftAssocHelp desiredOp exprList expr =
766 case expr of
773 case expr of
767 A.A _ (Binop op left right) | op == desiredOp ->
774 A.A _ (Binop op left right) | op == desiredOp ->