@@ -1,25 +1,164 @@
1module Generate.JavaScript (generate) where
1module Generate.JavaScript (generate) where
3import Control.Monad.State as State
3import Control.Monad.State as State
4+import qualified Data.List as List
4import Language.ECMAScript3.PrettyPrint as ES
5import Language.ECMAScript3.PrettyPrint as ES
5import Language.ECMAScript3.Syntax
6import Language.ECMAScript3.Syntax
6import qualified Text.PrettyPrint.Leijen as PP
7import qualified Text.PrettyPrint.Leijen as PP
9+import qualified AST.Expression.Optimized as Optimized
10+import qualified AST.Helpers as Help
8import qualified AST.Module as Module
11import qualified AST.Module as Module
12+import qualified AST.Module.Name as ModuleName
13+import qualified AST.Variable as Variable
9import qualified Generate.JavaScript.Expression as JS
14import qualified Generate.JavaScript.Expression as JS
15+import Generate.JavaScript.Helpers (call, function, localRuntime, obj, prop, ref, varDecl)
10import qualified Generate.JavaScript.Variable as Var
16import qualified Generate.JavaScript.Variable as Var
13generate :: Module.Optimized -> String
19generate :: Module.Optimized -> String
14generate module_ =
20generate module_ =
16− definitions =
22+ (ModuleName.Canonical _ name) =
17− Module.program (Module.body module_)
23+ Module.name module_
28+ , checkForCachedVersion name
29+ , imports (Module.imports module_)
30+ , definitions (Module.program (Module.body module_))
31+ , exports name (Module.exports module_)
35+ "Elm" : name ++ ["make"]
38+ buildIntermediateObjects make
40+ [ assign make (function [localRuntime] body)
43+ PP.displayS (PP.renderPretty 0.4 160 (ES.prettyPrint javascript)) ""
50+useStrict :: [Statement ()]
52+ [ ExprStmt () (StringLit () "use strict")
56+checkForCachedVersion :: ModuleName.Raw -> [Statement ()]
57+checkForCachedVersion name =
60+ localRuntime : name ++ ["values"]
65+ buildIntermediateObjects values
67+ [ IfSingleStmt () valuesObject (ReturnStmt () (Just valuesObject))
71+buildIntermediateObjects :: [String] -> [Statement ()]
72+buildIntermediateObjects path =
75+ assign name (InfixExpr () OpLOr (obj name) (ObjectLit () []))
78+ drop 2 (init (List.inits path))
83+assign :: [String] -> Expression () -> Statement ()
87+ VarDeclStmt () [ varDecl x expr ]
91+ AssignExpr () OpAssign (LDot () (obj (init path)) (last path)) expr
98+imports :: [ModuleName.Raw] -> [Statement ()]
105+ [ VarDeclStmt () (map jsImport rawImports)
109+jsImport :: ModuleName.Raw -> VarDecl ()
113+ obj ("Elm" : name ++ ["make"])
115+ varDecl (Var.modulePrefix name) (call make [ref localRuntime])
122+definitions :: [Optimized.Def] -> [Statement ()]
20− Var.define "_op" (ObjectLit () [])
126+ Var.define "_op" (ObjectLit () [])
128+ setup : State.evalState (mapM JS.generateDef defs) 0
135+exports :: ModuleName.Raw -> [Variable.Value] -> [Statement ()]
136+exports name exportedValues =
139+ map toField ("_op" : concatMap extract exportedValues)
156+ Variable.Union _ (Variable.Listing ctors _) ->
23− State.evalState (mapM JS.generateDef definitions) 0
160+ LDot () (obj (localRuntime : name)) "values"
25− PP.displayS (PP.renderPretty 0.4 160 (ES.prettyPrint (setup:stmts))) ""
162+ [ ReturnStmt () $ Just $
163+ AssignExpr () OpAssign values (ObjectLit () exportedFields)