@@ -1,6 +1,6 @@
11{-# OPTIONS -Wall #-}
22
3−module Generate.JavaScript where
3+module Generate.JavaScript (generate) where
44
55import Control.Arrow (first,(***))
66import Control.Applicative ((<$>),(<*>))
@@ -11,31 +11,27 @@ import qualified Data.Set as Set
1111
1212import qualified Generate.Cases as Case
1313import qualified Generate.Markdown as MD
14−import SourceSyntax.Everything
14+import qualified SourceSyntax.Helpers as Help
15+import SourceSyntax.Literal
16+import SourceSyntax.Pattern
1517import SourceSyntax.Location
18+import SourceSyntax.Expression
19+import SourceSyntax.Module
1620import qualified Transform.SortDefinitions as SD
1721import Language.ECMAScript3.Syntax
1822import Language.ECMAScript3.PrettyPrint
19−import Parse.Helpers (jsReserveds)
20−
21−makeSafe :: String -> String
22−makeSafe = List.intercalate "." . map dereserve . split . deprime
23− where
24− deprime = map (\c -> if c == '\'' then '$' else c)
25− dereserve x = case Set.member x jsReserveds of
26− False -> x
27− True -> "$" ++ x
23+import qualified Transform.SafeNames as MakeSafe
2824
2925split :: String -> [String]
3026split = go []
3127 where
3228 go vars str =
3329 case break (=='.') str of
34− (x,'.':rest) | isOp x -> vars ++ [x ++ '.' : rest]
30+ (x,'.':rest) | Help.isOp x -> vars ++ [x ++ '.' : rest]
3531 | otherwise -> go (vars ++ [x]) rest
3632 (x,[]) -> vars ++ [x]
3733
38−var name = Id () (makeSafe name)
34+var name = Id () name
3935ref name = VarRef () (var name)
4036prop name = PropId () (var name)
4137f <| x = CallExpr () f [x]
@@ -160,14 +156,15 @@ expression (L span expr) =
160156 return $ function [] (stmts ++ [ ReturnStmt () (Just exp) ]) `call` []
161157
162158 MultiIf branches ->
163− do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
164− return $ case last branches of
165− (L _ (Var "Basics.otherwise"), e) -> ifs (init branches') (snd (last branches'))
166− _ -> ifs branches'
167− (obj "_E.If" `call` [ ref "$moduleName", string (show span) ])
168− where
169− ifs branches finally = foldr iff finally branches
170− iff (if', then') else' = CondExpr () if' then' else'
159+ do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
160+ return $ case last branches of
161+ (L _ (Var "Basics.otherwise"), _) -> safeIfs branches'
162+ (L _ (Literal (Boolean True)), _) -> safeIfs branches'
163+ _ -> ifs branches' (obj "_E.If" `call` [ ref "$moduleName", string (show span) ])
164+ where
165+ safeIfs branches = ifs (init branches) (snd (last branches))
166+ ifs branches finally = foldr iff finally branches
167+ iff (if', then') else' = CondExpr () if' then' else'
171168
172169 Case e cases ->
173170 do (tempVar,initialMatch) <- Case.toMatch cases
@@ -187,7 +184,7 @@ expression (L span expr) =
187184 do es' <- mapM expression es
188185 return $ ObjectLit () (ctor : fields es')
189186 where
190− ctor = (prop "ctor", string (makeSafe name))
187+ ctor = (prop "ctor", string name)
191188 fields = zipWith (\n e -> (prop ("_" ++ show n), e)) [0..]
192189
193190 Markdown uid doc es ->
@@ -211,7 +208,7 @@ definition def =
211208 let assign x = varDecl x expr'
212209 case pattern of
213210 PVar x
214− | isOp x ->
211+ | Help.isOp x ->
215212 let op = LBracket () (ref "_op") (string x) in
216213 return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
217214 | otherwise ->
@@ -234,11 +231,11 @@ definition def =
234231
235232 decl x n = varDecl x (dotSep ["$","_" ++ show n])
236233 setup vars
237− | isTuple name = assign "$" : vars
238− | otherwise = safeAssign : vars
234+ | Help.isTuple name = assign "$" : vars
235+ | otherwise = assign "$raw" : safeAssign : vars
239236
240− safeAssign = varDecl "$" (CondExpr () if' expr' exception)
241− if' = InfixExpr () OpStrictEq (obj "$.ctor") (string name)
237+ safeAssign = varDecl "$" (CondExpr () if' (obj "$raw") exception)
238+ if' = InfixExpr () OpStrictEq (obj "$raw.ctor") (string name)
242239 exception = obj "_E.Case" `call` [ref "$moduleName", string (show span)]
243240
244241 _ ->
@@ -297,10 +294,11 @@ clause span variable (Case.Clause value vars mtch) =
297294
298295
299296generate :: MetadataModule () () -> String
300−generate modul =
297+generate unsafeModule =
301298 show . prettyPrint $ setup (Just "Elm") (names modul ++ ["make"]) ++
302299 [ assign ("Elm" : names modul ++ ["make"]) (function ["_elm"] programStmts) ]
303300 where
301+ modul = MakeSafe.metadataModule unsafeModule
304302 thisModule = dotSep ("_elm" : names modul ++ ["values"])
305303 programStmts =
306304 concat [ setup (Just "_elm") (names modul ++ ["values"])
@@ -317,7 +315,7 @@ generate modul =
317315
318316 jsExports = assign ("_elm" : names modul ++ ["values"]) (ObjectLit () exs)
319317 where
320− exs = map entry . filter (not . isOp) $ "_op" : exports modul
318+ exs = map entry . filter (not . Help.isOp) $ "_op" : exports modul
321319 entry x = (PropId () (var x), ref x)
322320
323321 assign path expr =
@@ -393,7 +391,7 @@ binop span op e1 e2 =
393391 js1 = expression e1
394392 js2 = expression e2
395393
396− func | isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)
394+ func | Help.isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)
397395 | otherwise = dotSep parts
398396 where
399397 parts = split op