@@ -1,6 +1,6 @@
1{-# OPTIONS -Wall #-}
1{-# OPTIONS -Wall #-}
3−module Generate.JavaScript where
3+module Generate.JavaScript (generate) where
5import Control.Arrow (first,(***))
5import Control.Arrow (first,(***))
6import Control.Applicative ((<$>),(<*>))
6import Control.Applicative ((<$>),(<*>))
@@ -11,31 +11,27 @@ import qualified Data.Set as Set
12import qualified Generate.Cases as Case
12import qualified Generate.Cases as Case
13import qualified Generate.Markdown as MD
13import qualified Generate.Markdown as MD
14+import qualified SourceSyntax.Helpers as Help
15+import SourceSyntax.Literal
14−import SourceSyntax.Everything
16+import SourceSyntax.Pattern
15import SourceSyntax.Location
17import SourceSyntax.Location
18+import SourceSyntax.Expression
19+import SourceSyntax.Module
16import qualified Transform.SortDefinitions as SD
20import qualified Transform.SortDefinitions as SD
17import Language.ECMAScript3.Syntax
21import Language.ECMAScript3.Syntax
18import Language.ECMAScript3.PrettyPrint
22import Language.ECMAScript3.PrettyPrint
19−import Parse.Helpers (jsReserveds)
23+import qualified Transform.SafeNames as MakeSafe
21−makeSafe :: String -> String
22−makeSafe = List.intercalate "." . map dereserve . split . deprime
24− deprime = map (\c -> if c == '\'' then '$' else c)
25− dereserve x = case Set.member x jsReserveds of
29split :: String -> [String]
25split :: String -> [String]
30split = go []
26split = go []
32 go vars str =
28 go vars str =
33 case break (=='.') str of
29 case break (=='.') str of
34− (x,'.':rest) | isOp x -> vars ++ [x ++ '.' : rest]
30+ (x,'.':rest) | Help.isOp x -> vars ++ [x ++ '.' : rest]
35 | otherwise -> go (vars ++ [x]) rest
31 | otherwise -> go (vars ++ [x]) rest
36 (x,[]) -> vars ++ [x]
32 (x,[]) -> vars ++ [x]
38−var name = Id () (makeSafe name)
34+var name = Id () name
39ref name = VarRef () (var name)
35ref name = VarRef () (var name)
40prop name = PropId () (var name)
36prop name = PropId () (var name)
41f <| x = CallExpr () f [x]
37f <| x = CallExpr () f [x]
@@ -160,14 +156,15 @@ expression (L span expr) =
160 return $ function [] (stmts ++ [ ReturnStmt () (Just exp) ]) `call` []
156 return $ function [] (stmts ++ [ ReturnStmt () (Just exp) ]) `call` []
162 MultiIf branches ->
158 MultiIf branches ->
163− do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
159+ do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
164− return $ case last branches of
160+ return $ case last branches of
165− (L _ (Var "Basics.otherwise"), e) -> ifs (init branches') (snd (last branches'))
161+ (L _ (Var "Basics.otherwise"), _) -> safeIfs branches'
166− _ -> ifs branches'
162+ (L _ (Literal (Boolean True)), _) -> safeIfs branches'
167− (obj "_E.If" `call` [ ref "$moduleName", string (show span) ])
163+ _ -> ifs branches' (obj "_E.If" `call` [ ref "$moduleName", string (show span) ])
165+ safeIfs branches = ifs (init branches) (snd (last branches))
169− ifs branches finally = foldr iff finally branches
166+ ifs branches finally = foldr iff finally branches
170− iff (if', then') else' = CondExpr () if' then' else'
167+ iff (if', then') else' = CondExpr () if' then' else'
172 Case e cases ->
169 Case e cases ->
173 do (tempVar,initialMatch) <- Case.toMatch cases
170 do (tempVar,initialMatch) <- Case.toMatch cases
@@ -187,7 +184,7 @@ expression (L span expr) =
187 do es' <- mapM expression es
184 do es' <- mapM expression es
188 return $ ObjectLit () (ctor : fields es')
185 return $ ObjectLit () (ctor : fields es')
190− ctor = (prop "ctor", string (makeSafe name))
187+ ctor = (prop "ctor", string name)
191 fields = zipWith (\n e -> (prop ("_" ++ show n), e)) [0..]
188 fields = zipWith (\n e -> (prop ("_" ++ show n), e)) [0..]
193 Markdown uid doc es ->
190 Markdown uid doc es ->
@@ -211,7 +208,7 @@ definition def =
211 let assign x = varDecl x expr'
208 let assign x = varDecl x expr'
212 case pattern of
209 case pattern of
214− | isOp x ->
211+ | Help.isOp x ->
215 let op = LBracket () (ref "_op") (string x) in
212 let op = LBracket () (ref "_op") (string x) in
216 return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
213 return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
217 | otherwise ->
214 | otherwise ->
@@ -234,11 +231,11 @@ definition def =
235 decl x n = varDecl x (dotSep ["$","_" ++ show n])
232 decl x n = varDecl x (dotSep ["$","_" ++ show n])
236 setup vars
233 setup vars
237− | isTuple name = assign "$" : vars
234+ | Help.isTuple name = assign "$" : vars
238− | otherwise = safeAssign : vars
235+ | otherwise = assign "$raw" : safeAssign : vars
240− safeAssign = varDecl "$" (CondExpr () if' expr' exception)
237+ safeAssign = varDecl "$" (CondExpr () if' (obj "$raw") exception)
241− if' = InfixExpr () OpStrictEq (obj "$.ctor") (string name)
238+ if' = InfixExpr () OpStrictEq (obj "$raw.ctor") (string name)
242 exception = obj "_E.Case" `call` [ref "$moduleName", string (show span)]
239 exception = obj "_E.Case" `call` [ref "$moduleName", string (show span)]
@@ -297,10 +294,11 @@ clause span variable (Case.Clause value vars mtch) =
299generate :: MetadataModule () () -> String
296generate :: MetadataModule () () -> String
300−generate modul =
297+generate unsafeModule =
301 show . prettyPrint $ setup (Just "Elm") (names modul ++ ["make"]) ++
298 show . prettyPrint $ setup (Just "Elm") (names modul ++ ["make"]) ++
302 [ assign ("Elm" : names modul ++ ["make"]) (function ["_elm"] programStmts) ]
299 [ assign ("Elm" : names modul ++ ["make"]) (function ["_elm"] programStmts) ]
301+ modul = MakeSafe.metadataModule unsafeModule
304 thisModule = dotSep ("_elm" : names modul ++ ["values"])
302 thisModule = dotSep ("_elm" : names modul ++ ["values"])
305 programStmts =
303 programStmts =
306 concat [ setup (Just "_elm") (names modul ++ ["values"])
304 concat [ setup (Just "_elm") (names modul ++ ["values"])
@@ -317,7 +315,7 @@ generate modul =
318 jsExports = assign ("_elm" : names modul ++ ["values"]) (ObjectLit () exs)
316 jsExports = assign ("_elm" : names modul ++ ["values"]) (ObjectLit () exs)
320− exs = map entry . filter (not . isOp) $ "_op" : exports modul
318+ exs = map entry . filter (not . Help.isOp) $ "_op" : exports modul
321 entry x = (PropId () (var x), ref x)
319 entry x = (PropId () (var x), ref x)
323 assign path expr =
321 assign path expr =
@@ -393,7 +391,7 @@ binop span op e1 e2 =
393 js1 = expression e1
391 js1 = expression e1
394 js2 = expression e2
392 js2 = expression e2
396− func | isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)
394+ func | Help.isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)
397 | otherwise = dotSep parts
395 | otherwise = dotSep parts
399 parts = split op
397 parts = split op