on 856ac59 help sign in
elk/src/Generate/JavaScript.hs
89 lines 2.4 kB history raw
1module Generate.JavaScript (generate) where
3import qualified Control.Monad.State as State
4import qualified Language.ECMAScript3.PrettyPrint as ES
5import qualified Language.ECMAScript3.Syntax as JS
6import qualified Text.PrettyPrint.Leijen as PP
8import qualified AST.Effects as Effects
9import qualified AST.Module as Module
10import qualified AST.Module.Name as ModuleName
11import qualified Generate.JavaScript.Expression as JS
12import qualified Generate.JavaScript.Helpers as JS
13import qualified Generate.JavaScript.Variable as Var
17-- GENERATE JAVASCRIPT
20generate :: Module.Optimized -> String
21generate (Module.Module moduleName _ info) =
22 let
23 genBody =
24 do defsList <- mapM JS.generateDef (Module.program info)
25 let managerStmts = generateEffectManager moduleName (Module.effects info)
26 return (concat (defsList ++ [managerStmts]))
28 body =
29 State.evalState genBody 0
30 in
31 PP.displayS (PP.renderPretty 1 160 (ES.prettyPrint body)) ""
35-- GENERATE EFFECT MANAGER
38generateEffectManager :: ModuleName.Canonical -> Effects.Canonical -> [JS.Statement ()]
39generateEffectManager moduleName effects =
40 case effects of
41 Effects.None ->
42 []
44 Effects.Foreign _ ->
45 []
47 Effects.Manager (Effects.Info _ _ _ _ managerType) ->
48 let
49 managers =
50 Var.native (ModuleName.inCore ["Native","Platform"]) "globalManagerInfo"
52 managerName =
53 JS.StringLit () (ModuleName.canonicalToString moduleName)
55 entry name =
56 ( JS.PropId () (JS.Id () name)
57 , JS.ref (Var.qualified moduleName name)
58 )
60 managerEntries =
61 [ entry "init"
62 , entry "onEffects"
63 , entry "onSelfMsg"
64 ]
66 otherEntries =
67 case managerType of
68 Effects.CmdManager _ ->
69 [ tagEntry "cmd", entry "cmdMap" ]
71 Effects.SubManager _ ->
72 [ tagEntry "sub", entry "subMap" ]
74 Effects.FxManager _ _ ->
75 [ tagEntry "fx", entry "cmdMap", entry "subMap" ]
77 addManager =
78 JS.AssignExpr () JS.OpAssign
79 (JS.LBracket () managers managerName)
80 (JS.ObjectLit () (managerEntries ++ otherEntries))
81 in
82 [ JS.ExprStmt () addManager ]
85tagEntry :: String -> ( JS.Prop (), JS.Expression () )
86tagEntry tag =
87 ( JS.PropId () (JS.Id () "tag")
88 , JS.StringLit () tag
89 )