@@ -8,7 +8,9 @@ import qualified Data.List as List
88import qualified Data.Map as Map
99import qualified Data.Set as Set
1010
11+import Generate.JavaScript.Helpers
1112import qualified Generate.Cases as Case
13+import qualified Generate.JavaScript.Ports as Port
1214import qualified Generate.Markdown as MD
1315import qualified SourceSyntax.Helpers as Help
1416import SourceSyntax.Literal
@@ -20,38 +22,15 @@ import Language.ECMAScript3.Syntax
2022import Language.ECMAScript3.PrettyPrint
2123import qualified Transform.SafeNames as MakeSafe
2224
23−split :: String -> [String]
24−split = go []
25− where
26− go vars str =
27− case break (=='.') str of
28− (x,_:rest) | Help.isOp x -> vars ++ [x ++ '.' : rest]
29− | otherwise -> go (vars ++ [x]) rest
30− (x,[]) -> vars ++ [x]
31−
32−var name = Id () name
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
38−call = CallExpr ()
39−string = StringLit ()
40−
41−dotSep vars =
42− case vars of
43− x:xs -> foldl (DotRef ()) (ref x) (map var xs)
44− [] -> error "dotSep must be called on a non-empty list of variables"
45−
46−obj = dotSep . split
47−
4825varDecl :: String -> Expression () -> VarDecl ()
4926varDecl x expr =
5027 VarDecl () (var x) (Just expr)
5128
29+include :: String -> String -> VarDecl ()
5230include alias moduleName =
5331 varDecl alias (obj (moduleName ++ ".make") <| ref "_elm")
5432
33+internalImports :: String -> Statement ()
5534internalImports name =
5635 VarDeclStmt ()
5736 [ varDecl "_N" (obj "Elm.Native")
@@ -155,7 +134,7 @@ expression (L span expr) =
155134 do let (defs',e') = flattenLets defs e
156135 stmts <- concat <$> mapM definition defs'
157136 exp <- expression e'
158− return $ function [] (stmts ++ [ ReturnStmt () (Just exp) ]) `call` []
137+ return $ function [] (stmts ++ [ ret exp ]) `call` []
159138
160139 MultiIf branches ->
161140 do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
@@ -196,15 +175,13 @@ expression (L span expr) =
196175 pad = "<div style=\"height:0;width:0;\"> </div>"
197176 md = pad ++ MD.toHtml doc ++ pad
198177
199− PortIn name _ _ handler ->
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')
178+ PortIn name tipe ->
179+ return $ obj "Native.Ports.portIn" `call` [ string name, Port.incoming tipe ]
204180
205− PortOut name _ signal ->
206− do signal' <- expression signal
207− return $ obj "Native.Ports.portOut" `call` [ string name, signal' ]
181+ PortOut name tipe value ->
182+ do value' <- expression value
183+ return $ obj "Native.Ports.portOut" `call`
184+ [ string name, Port.outgoing tipe, value' ]
208185
209186definition :: Def -> State Int [Statement ()]
210187definition (Definition pattern expr@(L span _) _) = do
@@ -250,7 +227,7 @@ definition (Definition pattern expr@(L span _) _) = do
250227 toDef y = let expr = L span $ Case (mkVar "$") [(pattern, mkVar y)]
251228 in definition $ Definition (PVar y) expr Nothing
252229
253−match :: (Show a) => a -> Case.Match -> State Int [Statement ()]
230+match :: SrcSpan -> Case.Match -> State Int [Statement ()]
254231match span mtch =
255232 case mtch of
256233 Case.Match name clauses mtch' ->
@@ -272,7 +249,7 @@ match span mtch =
272249 Case.Break -> return [BreakStmt () Nothing]
273250 Case.Other e ->
274251 do e' <- expression e
275− return [ ReturnStmt () (Just e') ]
252+ return [ ret e' ]
276253 Case.Seq ms -> concat <$> mapM (match span) (dropEnd [] ms)
277254 where
278255 dropEnd acc [] = acc
@@ -281,6 +258,7 @@ match span mtch =
281258 Case.Other _ -> acc ++ [m]
282259 _ -> dropEnd (acc ++ [m]) ms
283260
261+clause :: SrcSpan -> String -> Case.Clause -> State Int (Bool, CaseClause ())
284262clause span variable (Case.Clause value vars mtch) =
285263 (,) isChar . CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
286264 where
@@ -295,6 +273,7 @@ clause span variable (Case.Clause value vars mtch) =
295273 [] -> name
296274 is -> drop (last is + 1) name
297275
276+flattenLets :: [Def] -> LExpr -> ([Def], LExpr)
298277flattenLets defs lexpr@(L _ expr) =
299278 case expr of
300279 Let ds body -> flattenLets (defs ++ ds) body
@@ -310,13 +289,13 @@ generate unsafeModule =
310289 programStmts =
311290 concat
312291 [ setup (Just "_elm") (names modul ++ ["values"])
313− , [ IfSingleStmt () thisModule (ReturnStmt () (Just thisModule)) ]
292+ , [ IfSingleStmt () thisModule (ret thisModule) ]
314293 , [ internalImports (List.intercalate "." (names modul)) ]
315294 , concatMap jsImport . Set.toList . Set.fromList . map fst $ imports modul
316295 , [ assign ["_op"] (ObjectLit () []) ]
317296 , concat $ evalState (mapM definition . fst . flattenLets [] $ program modul) 0
318297 , [ jsExports ]
319− , [ ReturnStmt () (Just thisModule) ]
298+ , [ ret thisModule ]
320299 ]
321300
322301 jsExports = assign ("_elm" : names modul ++ ["values"]) (ObjectLit () exs)
@@ -342,6 +321,7 @@ generate unsafeModule =
342321 Nothing -> tail . init $ List.inits path
343322 Just nmspc -> drop 2 . init . List.inits $ nmspc : path
344323
324+binop :: SrcSpan -> String -> LExpr -> LExpr -> State Int (Expression ())
345325binop span op e1 e2 =
346326 case op of
347327 "Basics.." ->