@@ -8,7 +8,9 @@ import qualified Data.List as List
8import qualified Data.Map as Map
8import qualified Data.Map as Map
9import qualified Data.Set as Set
9import qualified Data.Set as Set
11+import Generate.JavaScript.Helpers
11import qualified Generate.Cases as Case
12import qualified Generate.Cases as Case
13+import qualified Generate.JavaScript.Ports as Port
12import qualified Generate.Markdown as MD
14import qualified Generate.Markdown as MD
13import qualified SourceSyntax.Helpers as Help
15import qualified SourceSyntax.Helpers as Help
14import SourceSyntax.Literal
16import SourceSyntax.Literal
@@ -20,38 +22,15 @@ import Language.ECMAScript3.Syntax
20import Language.ECMAScript3.PrettyPrint
22import Language.ECMAScript3.PrettyPrint
21import qualified Transform.SafeNames as MakeSafe
23import qualified Transform.SafeNames as MakeSafe
23−split :: String -> [String]
27− case break (=='.') str of
28− (x,_:rest) | Help.isOp x -> vars ++ [x ++ '.' : rest]
29− | otherwise -> go (vars ++ [x]) rest
30− (x,[]) -> vars ++ [x]
33−ref name = VarRef () (var name)
34−prop name = PropId () (var name)
35−f <| x = CallExpr () f [x]
36−args ==> e = FuncExpr () Nothing (map var args) [ ReturnStmt () (Just e) ]
37−function args stmts = FuncExpr () Nothing (map var args) stmts
43− x:xs -> foldl (DotRef ()) (ref x) (map var xs)
44− [] -> error "dotSep must be called on a non-empty list of variables"
48varDecl :: String -> Expression () -> VarDecl ()
25varDecl :: String -> Expression () -> VarDecl ()
49varDecl x expr =
26varDecl x expr =
50 VarDecl () (var x) (Just expr)
27 VarDecl () (var x) (Just expr)
29+include :: String -> String -> VarDecl ()
52include alias moduleName =
30include alias moduleName =
53 varDecl alias (obj (moduleName ++ ".make") <| ref "_elm")
31 varDecl alias (obj (moduleName ++ ".make") <| ref "_elm")
33+internalImports :: String -> Statement ()
55internalImports name =
34internalImports name =
56 VarDeclStmt ()
35 VarDeclStmt ()
57 [ varDecl "_N" (obj "Elm.Native")
36 [ varDecl "_N" (obj "Elm.Native")
@@ -155,7 +134,7 @@ expression (L span expr) =
155 do let (defs',e') = flattenLets defs e
134 do let (defs',e') = flattenLets defs e
156 stmts <- concat <$> mapM definition defs'
135 stmts <- concat <$> mapM definition defs'
157 exp <- expression e'
136 exp <- expression e'
158− return $ function [] (stmts ++ [ ReturnStmt () (Just exp) ]) `call` []
137+ return $ function [] (stmts ++ [ ret exp ]) `call` []
160 MultiIf branches ->
139 MultiIf branches ->
161 do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
140 do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
@@ -196,15 +175,13 @@ expression (L span expr) =
196 pad = "<div style=\"height:0;width:0;\"> </div>"
175 pad = "<div style=\"height:0;width:0;\"> </div>"
197 md = pad ++ MD.toHtml doc ++ pad
176 md = pad ++ MD.toHtml doc ++ pad
199− PortIn name _ _ handler ->
178+ PortIn name tipe ->
200− do handler' <- case handler of
201− Nothing -> return []
202− Just h -> (:[]) `fmap` expression h
203− return $ obj "Native.Ports.portIn" `call` ([ string name ] ++ handler')
179+ return $ obj "Native.Ports.portIn" `call` [ string name, Port.incoming tipe ]
205− PortOut name _ signal ->
181+ PortOut name tipe value ->
206− do signal' <- expression signal
182+ do value' <- expression value
207− return $ obj "Native.Ports.portOut" `call` [ string name, signal' ]
183+ return $ obj "Native.Ports.portOut" `call`
184+ [ string name, Port.outgoing tipe, value' ]
209definition :: Def -> State Int [Statement ()]
186definition :: Def -> State Int [Statement ()]
210definition (Definition pattern expr@(L span _) _) = do
187definition (Definition pattern expr@(L span _) _) = do
@@ -250,7 +227,7 @@ definition (Definition pattern expr@(L span _) _) = do
250 toDef y = let expr = L span $ Case (mkVar "$") [(pattern, mkVar y)]
227 toDef y = let expr = L span $ Case (mkVar "$") [(pattern, mkVar y)]
251 in definition $ Definition (PVar y) expr Nothing
228 in definition $ Definition (PVar y) expr Nothing
253−match :: (Show a) => a -> Case.Match -> State Int [Statement ()]
230+match :: SrcSpan -> Case.Match -> State Int [Statement ()]
254match span mtch =
231match span mtch =
255 case mtch of
232 case mtch of
256 Case.Match name clauses mtch' ->
233 Case.Match name clauses mtch' ->
@@ -272,7 +249,7 @@ match span mtch =
272 Case.Break -> return [BreakStmt () Nothing]
249 Case.Break -> return [BreakStmt () Nothing]
273 Case.Other e ->
250 Case.Other e ->
274 do e' <- expression e
251 do e' <- expression e
275− return [ ReturnStmt () (Just e') ]
252+ return [ ret e' ]
276 Case.Seq ms -> concat <$> mapM (match span) (dropEnd [] ms)
253 Case.Seq ms -> concat <$> mapM (match span) (dropEnd [] ms)
278 dropEnd acc [] = acc
255 dropEnd acc [] = acc
@@ -281,6 +258,7 @@ match span mtch =
281 Case.Other _ -> acc ++ [m]
258 Case.Other _ -> acc ++ [m]
282 _ -> dropEnd (acc ++ [m]) ms
259 _ -> dropEnd (acc ++ [m]) ms
261+clause :: SrcSpan -> String -> Case.Clause -> State Int (Bool, CaseClause ())
284clause span variable (Case.Clause value vars mtch) =
262clause span variable (Case.Clause value vars mtch) =
285 (,) isChar . CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
263 (,) isChar . CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
@@ -295,6 +273,7 @@ clause span variable (Case.Clause value vars mtch) =
295 [] -> name
273 [] -> name
296 is -> drop (last is + 1) name
274 is -> drop (last is + 1) name
276+flattenLets :: [Def] -> LExpr -> ([Def], LExpr)
298flattenLets defs lexpr@(L _ expr) =
277flattenLets defs lexpr@(L _ expr) =
299 case expr of
278 case expr of
300 Let ds body -> flattenLets (defs ++ ds) body
279 Let ds body -> flattenLets (defs ++ ds) body
@@ -310,13 +289,13 @@ generate unsafeModule =
310 programStmts =
289 programStmts =
312 [ setup (Just "_elm") (names modul ++ ["values"])
291 [ setup (Just "_elm") (names modul ++ ["values"])
313− , [ IfSingleStmt () thisModule (ReturnStmt () (Just thisModule)) ]
292+ , [ IfSingleStmt () thisModule (ret thisModule) ]
314 , [ internalImports (List.intercalate "." (names modul)) ]
293 , [ internalImports (List.intercalate "." (names modul)) ]
315 , concatMap jsImport . Set.toList . Set.fromList . map fst $ imports modul
294 , concatMap jsImport . Set.toList . Set.fromList . map fst $ imports modul
316 , [ assign ["_op"] (ObjectLit () []) ]
295 , [ assign ["_op"] (ObjectLit () []) ]
317 , concat $ evalState (mapM definition . fst . flattenLets [] $ program modul) 0
296 , concat $ evalState (mapM definition . fst . flattenLets [] $ program modul) 0
318 , [ jsExports ]
297 , [ jsExports ]
319− , [ ReturnStmt () (Just thisModule) ]
298+ , [ ret thisModule ]
322 jsExports = assign ("_elm" : names modul ++ ["values"]) (ObjectLit () exs)
301 jsExports = assign ("_elm" : names modul ++ ["values"]) (ObjectLit () exs)
@@ -342,6 +321,7 @@ generate unsafeModule =
342 Nothing -> tail . init $ List.inits path
321 Nothing -> tail . init $ List.inits path
343 Just nmspc -> drop 2 . init . List.inits $ nmspc : path
322 Just nmspc -> drop 2 . init . List.inits $ nmspc : path
324+binop :: SrcSpan -> String -> LExpr -> LExpr -> State Int (Expression ())
345binop span op e1 e2 =
325binop span op e1 e2 =
346 case op of
326 case op of
347 "Basics.." ->
327 "Basics.." ->