@@ -12,7 +12,7 @@ import Language.ECMAScript3.Syntax
1212
1313import AST.Module
1414import AST.Expression.General as Expr
15−import qualified AST.Expression.Canonical as Canonical
15+import qualified AST.Expression.Optimized as Opt
1616import qualified AST.Helpers as Help
1717import AST.Literal
1818import qualified AST.Module as Module
@@ -26,7 +26,6 @@ import qualified Generate.JavaScript.Port as Port
2626import qualified Generate.JavaScript.Variable as Var
2727import qualified Reporting.Annotation as A
2828import qualified Reporting.Crash as Crash
29−import qualified Reporting.Region as R
3029
3130
3231internalImports :: Module.Name -> [VarDecl ()]
@@ -117,13 +116,13 @@ toExpr code =
117116
118117-- EXPRESSIONS
119118
120−exprToJsExpr :: Canonical.Expr -> State Int (Expression ())
119+exprToJsExpr :: Opt.Expr -> State Int (Expression ())
121120exprToJsExpr canonicalExpr =
122121 toExpr <$> exprToCode canonicalExpr
123122
124123
125−exprToCode :: Canonical.Expr -> State Int Code
126−exprToCode annotatedExpr@(A.A region expr) =
124+exprToCode :: Opt.Expr -> State Int Code
125+exprToCode annotatedExpr@(A.A _ expr) =
127126 case expr of
128127 Var var ->
129128 jsExpr $ Var.canonical var
@@ -179,7 +178,7 @@ exprToCode annotatedExpr@(A.A region expr) =
179178 map (first prop) (Map.toList (Map.map head fs))
180179
181180 Binop op leftExpr rightExpr ->
182− binop region op leftExpr rightExpr
181+ binop op leftExpr rightExpr
183182
184183 Lambda _ _ ->
185184 generateFunction (Expr.collectLambdas annotatedExpr)
@@ -207,7 +206,7 @@ exprToCode annotatedExpr@(A.A region expr) =
207206 generateIf branches finally
208207
209208 Case expr branches ->
210− generateCase region expr branches
209+ generateCase expr branches
211210
212211 ExplicitList elements ->
213212 do jsElements <- mapM exprToJsExpr elements
@@ -238,12 +237,12 @@ exprToCode annotatedExpr@(A.A region expr) =
238237 jsExpr (Port.task name expr' portType)
239238
240239 Crash details ->
241− jsExpr $ Crash.crash region details
240+ jsExpr $ Crash.crash details
242241
243242
244243-- FUNCTIONS
245244
246−generateFunction :: ([P.CanonicalPattern], Canonical.Expr) -> State Int Code
245+generateFunction :: ([P.Optimized], Opt.Expr) -> State Int Code
247246generateFunction (args, initialBody) =
248247 do (argVars, patternDefs) <- destructuredArgs args
249248 code <- generateLet patternDefs initialBody
@@ -268,13 +267,13 @@ generateFunctionWithArity args code =
268267 foldl (\body arg -> function [arg] [ret body]) innerBody otherArgs
269268
270269
271−destructuredArgs :: [P.CanonicalPattern] -> State Int ([String], [Canonical.Def])
270+destructuredArgs :: [P.Optimized] -> State Int ([String], [Opt.Def])
272271destructuredArgs args =
273272 do (argVars, maybePatternDefs) <- unzip <$> mapM destructPattern args
274273 return (argVars, Maybe.catMaybes maybePatternDefs)
275274
276275
277−destructPattern :: P.CanonicalPattern -> State Int (String, Maybe Canonical.Def)
276+destructPattern :: P.Optimized -> State Int (String, Maybe Opt.Def)
278277destructPattern pattern@(A.A ann pat) =
279278 case pat of
280279 P.Var x ->
@@ -284,15 +283,15 @@ destructPattern pattern@(A.A ann pat) =
284283 do arg <- Case.newVar
285284 return
286285 ( arg
287− , Just $ Canonical.Definition pattern (A.A ann (localVar arg)) Nothing
286+ , Just $ Opt.Definition Opt.dummyFacts pattern (A.A ann (localVar arg))
288287 )
289288
290289
291290-- LET EXPRESSIONS
292291
293292generateLet
294− :: [Canonical.Def]
295− -> Canonical.Expr
293+ :: [Opt.Def]
294+ -> Opt.Expr
296295 -> State Int Code
297296generateLet givenDefs givenBody =
298297 do let (defs, body) = flattenLets givenDefs givenBody
@@ -308,7 +307,7 @@ generateLet givenDefs givenBody =
308307
309308-- GENERATE IFS
310309
311−generateIf :: [(Canonical.Expr, Canonical.Expr)] -> Canonical.Expr -> State Int Code
310+generateIf :: [(Opt.Expr, Opt.Expr)] -> Opt.Expr -> State Int Code
312311generateIf givenBranches givenFinally =
313312 let
314313 (branches, finally) =
@@ -334,18 +333,18 @@ generateIf givenBranches givenFinally =
334333
335334
336335crushIfs
337− :: [(Canonical.Expr, Canonical.Expr)]
338− -> Canonical.Expr
339− -> ([(Canonical.Expr, Canonical.Expr)], Canonical.Expr)
336+ :: [(Opt.Expr, Opt.Expr)]
337+ -> Opt.Expr
338+ -> ([(Opt.Expr, Opt.Expr)], Opt.Expr)
340339crushIfs branches finally =
341340 crushIfsHelp [] branches finally
342341
343342
344343crushIfsHelp
345− :: [(Canonical.Expr, Canonical.Expr)]
346− -> [(Canonical.Expr, Canonical.Expr)]
347− -> Canonical.Expr
348− -> ([(Canonical.Expr, Canonical.Expr)], Canonical.Expr)
344+ :: [(Opt.Expr, Opt.Expr)]
345+ -> [(Opt.Expr, Opt.Expr)]
346+ -> Opt.Expr
347+ -> ([(Opt.Expr, Opt.Expr)], Opt.Expr)
349348crushIfsHelp visitedBranches unvisitedBranches finally =
350349 case unvisitedBranches of
351350 [] ->
@@ -369,13 +368,22 @@ crushIfsHelp visitedBranches unvisitedBranches finally =
369368
370369-- DEFINITIONS
371370
372−defToStatements :: Canonical.Def -> State Int [Statement ()]
373−defToStatements (Canonical.Definition pattern expr _) =
374− defToStatementsHelp pattern =<< exprToJsExpr expr
371+defToStatements :: Opt.Def -> State Int [Statement ()]
372+defToStatements (Opt.Definition facts pattern expr) =
373+ case Opt.tailRecursionDetails facts of
374+ Just (name, arity) ->
375+ error "TODO" name arity
375376
377+ Nothing ->
378+ defToStatementsHelp facts pattern =<< exprToJsExpr expr
376379
377−defToStatementsHelp :: P.CanonicalPattern -> Expression () -> State Int [Statement ()]
378−defToStatementsHelp annPattern@(A.A patternRegion pattern) jsExpr =
380+
381+defToStatementsHelp
382+ :: Opt.Facts
383+ -> P.Optimized
384+ -> Expression ()
385+ -> State Int [Statement ()]
386+defToStatementsHelp facts annPattern@(A.A _ pattern) jsExpr =
379387 let
380388 define x =
381389 varDecl x jsExpr
@@ -417,25 +425,25 @@ defToStatementsHelp annPattern@(A.A patternRegion pattern) jsExpr =
417425
418426 safeAssign = varDecl "$" (CondExpr () if' (ref "_raw") exception)
419427 if' = InfixExpr () OpStrictEq (obj ["_raw","ctor"]) (string name)
420− exception = Crash.crash patternRegion Crash.IncompletePatternMatch
428+ exception = Crash.crash (Crash.IncompletePatternMatch (error "TODO"))
421429
422430 _ ->
423431 do defs' <- concat <$> mapM toDef vars
424432 return (VarDeclStmt () [define "_"] : defs')
425433 where
426434 vars = P.boundVarList annPattern
427− mkVar = A.A patternRegion . localVar
435+ mkVar = A.A () . localVar
428436 toDef y =
429− let expr = A.A patternRegion $ Case (mkVar "_") [(annPattern, mkVar y)]
430− pat = A.A patternRegion (P.Var y)
437+ let expr = A.A () $ Case (mkVar "_") [(annPattern, mkVar y)]
438+ pat = A.A () (P.Var y)
431439 in
432− defToStatements (Canonical.Definition pat expr Nothing)
440+ defToStatements (Opt.Definition facts pat expr)
433441
434442
435443-- CASE EXPRESSIONS
436444
437−generateCase :: R.Region -> Canonical.Expr -> [(P.CanonicalPattern, Canonical.Expr)] -> State Int Code
438−generateCase region expr branches =
445+generateCase :: Opt.Expr -> [(P.Optimized, Opt.Expr)] -> State Int Code
446+generateCase expr branches =
439447 do (tempVar, initialMatch) <-
440448 Case.toMatch branches
441449
@@ -447,17 +455,17 @@ generateCase region expr branches =
447455 do expr' <- exprToJsExpr expr
448456 return (initialMatch, [VarDeclStmt () [varDecl tempVar expr']])
449457
450− match' <- match region revisedMatch
458+ match' <- match revisedMatch
451459
452460 jsBlock (stmt ++ match')
453461
454462
455−match :: R.Region -> Case.Match -> State Int [Statement ()]
456−match region mtch =
463+match :: Case.Match -> State Int [Statement ()]
464+match mtch =
457465 case mtch of
458466 Case.Match name clauses mtch' ->
459− do (isChars, clauses') <- unzip <$> mapM (clause region name) clauses
460− mtch'' <- match region mtch'
467+ do (isChars, clauses') <- unzip <$> mapM (clause name) clauses
468+ mtch'' <- match mtch'
461469 return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
462470 where
463471 isLiteral p =
@@ -480,7 +488,7 @@ match region mtch =
480488 expr
481489
482490 Case.Fail ->
483− return [ ExprStmt () (Crash.crash region Crash.IncompletePatternMatch) ]
491+ return [ ExprStmt () (Crash.crash (Crash.IncompletePatternMatch (error "TODO"))) ]
484492
485493 Case.Break ->
486494 return [BreakStmt () Nothing]
@@ -489,7 +497,7 @@ match region mtch =
489497 toStatementList <$> exprToCode expr
490498
491499 Case.Seq ms ->
492− concat <$> mapM (match region) (dropEnd [] ms)
500+ concat <$> mapM match (dropEnd [] ms)
493501 where
494502 dropEnd acc [] = acc
495503 dropEnd acc (m:ms) =
@@ -498,9 +506,9 @@ match region mtch =
498506 _ -> dropEnd (acc ++ [m]) ms
499507
500508
501−clause :: R.Region -> String -> Case.Clause -> State Int (Bool, CaseClause ())
502−clause region variable (Case.Clause value vars mtch) =
503− (,) isChar . CaseClause () pattern <$> match region (Case.matchSubst (zip vars vars') mtch)
509+clause :: String -> Case.Clause -> State Int (Bool, CaseClause ())
510+clause variable (Case.Clause value vars mtch) =
511+ (,) isChar . CaseClause () pattern <$> match (Case.matchSubst (zip vars vars') mtch)
504512 where
505513 vars' =
506514 map (\n -> variable ++ "._" ++ show n) [0..]
@@ -517,14 +525,14 @@ clause region variable (Case.Clause value vars mtch) =
517525 string name
518526
519527
520−flattenLets :: [Canonical.Def] -> Canonical.Expr -> ([Canonical.Def], Canonical.Expr)
528+flattenLets :: [Opt.Def] -> Opt.Expr -> ([Opt.Def], Opt.Expr)
521529flattenLets defs lexpr@(A.A _ expr) =
522530 case expr of
523531 Let ds body -> flattenLets (defs ++ ds) body
524532 _ -> (defs, lexpr)
525533
526534
527−generate :: Module.CanonicalModule -> String
535+generate :: Module.Optimized -> String
528536generate modul =
529537 show . prettyPrint $ setup "Elm" (names ++ ["make"]) ++
530538 [ assign ("Elm" : names ++ ["make"]) (function [localRuntime] programStmts) ]
@@ -613,14 +621,13 @@ generate modul =
613621-- BINARY OPERATORS
614622
615623binop
616− :: R.Region
617− -> Var.Canonical
618− -> Canonical.Expr
619− -> Canonical.Expr
624+ :: Var.Canonical
625+ -> Opt.Expr
626+ -> Opt.Expr
620627 -> State Int Code
621−binop region func left right
628+binop func left right
622629 | func == Var.Canonical Var.BuiltIn "::" =
623− exprToCode (A.A region (Data "::" [left,right]))
630+ exprToCode (A.A () (Data "::" [left,right]))
624631
625632 | func == forwardCompose =
626633 compose (collectLeftAssoc forwardCompose left right)
@@ -647,13 +654,13 @@ apply arg func =
647654 func <| arg
648655
649656
650−compose :: [Canonical.Expr] -> State Int Code
657+compose :: [Opt.Expr] -> State Int Code
651658compose functions =
652659 do jsFunctions <- mapM exprToJsExpr functions
653660 jsExpr $ ["$"] ==> List.foldl' apply (ref "$") jsFunctions
654661
655662
656−pipe :: [Canonical.Expr] -> State Int Code
663+pipe :: [Opt.Expr] -> State Int Code
657664pipe expressions =
658665 do (value:functions) <- mapM exprToJsExpr expressions
659666 jsExpr $ List.foldl' apply value functions
@@ -740,12 +747,12 @@ cmp op n a b =
740747-- BINARY OPERATOR COLLECTORS
741748
742749-- (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]
744751collectRightAssoc desiredOp left right =
745752 collectRightAssocHelp desiredOp [left] right
746753
747754
748−collectRightAssocHelp :: Var.Canonical -> [Canonical.Expr] -> Canonical.Expr -> [Canonical.Expr]
755+collectRightAssocHelp :: Var.Canonical -> [Opt.Expr] -> Opt.Expr -> [Opt.Expr]
749756collectRightAssocHelp desiredOp exprList expr =
750757 case expr of
751758 A.A _ (Binop op left right) | op == desiredOp ->
@@ -756,12 +763,12 @@ collectRightAssocHelp desiredOp exprList expr =
756763
757764
758765-- (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]
760767collectLeftAssoc desiredOp left right =
761768 collectLeftAssocHelp desiredOp [right] left
762769
763770
764−collectLeftAssocHelp :: Var.Canonical -> [Canonical.Expr] -> Canonical.Expr -> [Canonical.Expr]
771+collectLeftAssocHelp :: Var.Canonical -> [Opt.Expr] -> Opt.Expr -> [Opt.Expr]
765772collectLeftAssocHelp desiredOp exprList expr =
766773 case expr of
767774 A.A _ (Binop op left right) | op == desiredOp ->