1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Generate.JavaScript (generate) where
5import qualified Control.Monad.State as State
6import Data.Monoid ((<>))
7import qualified Data.List as List
8import qualified Data.Map as Map
9import qualified Data.Set as Set
10import Data.Text (Text)
11import qualified Data.ByteString.Builder as BS
13import qualified AST.Effects as Effects
14import qualified AST.Expression.Optimized as Opt
15import qualified AST.Module.Name as ModuleName
16import qualified AST.Variable as Var
17import qualified Elm.Package as Pkg
18import qualified Generate.JavaScript.Builder as JS
19import qualified Generate.JavaScript.Expression as JS
20import qualified Generate.JavaScript.Helpers as JS
21import qualified Generate.JavaScript.Variable as JS
29 Map.Map Var.Global Opt.Decl
32generate :: Graph -> [Var.Global] -> (Set.Set ModuleName.Canonical, BS.Builder)
35 (State builders _ natives effects) =
36 List.foldl' (crawl graph) empty roots
39 Map.foldrWithKey addManager "" effects
42 List.foldl' (\rest js -> js <> rest) managers builders
48-- DEAD CODE ELIMINATION
54 , _seen :: Set.Set Var.Global
55 , _natives :: Set.Set ModuleName.Canonical
56 , _effects :: Map.Map ModuleName.Canonical Effects.ManagerType
62 State [] Set.empty Set.empty Map.empty
66-- DEAD CODE ELIMINATION
69crawl :: Graph -> State -> Var.Global -> State
70crawl graph state@(State js seen natives effects) name@(Var.Global home _) =
71 if Set.member name seen then
75 case Map.lookup name graph of
77 crawlDecl graph name decl state
80 if ModuleName.canonicalIsNative home then
81 State js seen (Set.insert home natives) effects
83 error "TODO something went wrong"
86crawlDecl :: Graph -> Var.Global -> Opt.Decl -> State -> State
87crawlDecl graph name@(Var.Global home _) (Opt.Decl deps mfx body) state =
90 state { _seen = Set.insert name (_seen state) }
92 (State js seen natives effects) =
93 Set.foldl' (crawl graph) newState deps
98 Just fx -> Map.insert home fx effects
101 { _js = generateDecl name body : js
104 , _effects = newEffects
108generateDecl :: Var.Global -> Opt.Def -> BS.Builder
109generateDecl (Var.Global home name) def =
112 JS.generateDef (Just home) name def
114 JS.encodeUtf8 (State.evalState genBody 0)
121addManager :: ModuleName.Canonical -> Effects.ManagerType -> BS.Builder -> BS.Builder
122addManager name manager builder =
123 JS.encodeUtf8 [genManager name manager] <> builder
126genManager :: ModuleName.Canonical -> Effects.ManagerType -> JS.Stmt
127genManager moduleName@(ModuleName.Canonical pkg _) manager =
130 JS.coreNative "Platform" "effectManagers"
133 JS.String (ModuleName.canonicalToText moduleName)
136 ( JS.IdProp (JS.Id name)
137 , JS.ref (JS.qualified moduleName name)
141 [ "pkg" ==> Pkg.toText pkg
149 Effects.Cmds -> [ "tag" ==> "cmd", entry "cmdMap" ]
150 Effects.Subs -> [ "tag" ==> "sub", entry "subMap" ]
151 Effects.Both -> [ "tag" ==> "fx", entry "cmdMap", entry "subMap" ]
155 (JS.LBracket managers managerName)
156 (JS.Object (managerEntries ++ otherEntries))
159(==>) :: Text -> Text -> ( JS.Prop, JS.Expr )
161 ( JS.IdProp (JS.Id key)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list