@@ -1,25 +1,27 @@
1{-# OPTIONS_GHC -W #-}
1{-# OPTIONS_GHC -W #-}
2module Generate.JavaScript (generate) where
2module Generate.JavaScript (generate) where
4−import Control.Arrow (first,(***))
5import Control.Applicative ((<$>),(<*>))
4import Control.Applicative ((<$>),(<*>))
5+import Control.Arrow (first,(***))
6import Control.Monad.State
6import Control.Monad.State
7import qualified Data.List as List
7import 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
10+import Language.ECMAScript3.PrettyPrint
11+import Language.ECMAScript3.Syntax
11import Generate.JavaScript.Helpers
13import Generate.JavaScript.Helpers
12import qualified Generate.Cases as Case
14import qualified Generate.Cases as Case
13import qualified Generate.JavaScript.Ports as Port
15import qualified Generate.JavaScript.Ports as Port
14import qualified Generate.Markdown as MD
16import qualified Generate.Markdown as MD
17+import SourceSyntax.Annotation
18+import SourceSyntax.Expression
15import qualified SourceSyntax.Helpers as Help
19import qualified SourceSyntax.Helpers as Help
16import SourceSyntax.Literal
20import SourceSyntax.Literal
17−import SourceSyntax.Pattern as Pattern
18−import SourceSyntax.Location
19−import SourceSyntax.Expression
20import SourceSyntax.Module
21import SourceSyntax.Module
21−import Language.ECMAScript3.Syntax
22+import qualified SourceSyntax.Pattern as P
22−import Language.ECMAScript3.PrettyPrint
23+import SourceSyntax.PrettyPrint (renderPretty)
24+import qualified SourceSyntax.Variable as V
23import qualified Transform.SafeNames as MakeSafe
25import qualified Transform.SafeNames as MakeSafe
25varDecl :: String -> Expression () -> VarDecl ()
27varDecl :: String -> Expression () -> VarDecl ()
@@ -50,10 +52,10 @@ literal lit =
50 FloatNum n -> NumLit () n
52 FloatNum n -> NumLit () n
51 Boolean b -> BoolLit () b
53 Boolean b -> BoolLit () b
53−expression :: LExpr -> State Int (Expression ())
55+expression :: Expr -> State Int (Expression ())
54−expression (L span expr) =
56+expression (A region expr) =
55 case expr of
57 case expr of
56− Var x -> return $ ref x
58+ Var (V.Raw x) -> return $ ref x
57 Literal lit -> return $ literal lit
59 Literal lit -> return $ literal lit
59 Range lo hi ->
61 Range lo hi ->
@@ -93,9 +95,9 @@ expression (L span expr) =
93 Map.toList . Map.filter (not . null) $ Map.map tail fs
95 Map.toList . Map.filter (not . null) $ Map.map tail fs
94 visible fs = map (first prop) . Map.toList $ Map.map head fs
96 visible fs = map (first prop) . Map.toList $ Map.map head fs
96− Binop op e1 e2 -> binop span op e1 e2
98+ Binop op e1 e2 -> binop region op e1 e2
98− Lambda p e@(L s _) ->
100+ Lambda p e@(A ann _) ->
99 do (args, body) <- foldM depattern ([], innerBody) (reverse patterns)
101 do (args, body) <- foldM depattern ([], innerBody) (reverse patterns)
100 body' <- expression body
102 body' <- expression body
101 return $ case length args < 2 || length args > 9 of
103 return $ case length args < 2 || length args > 9 of
@@ -104,13 +106,14 @@ expression (L span expr) =
105 depattern (args, body) pattern =
107 depattern (args, body) pattern =
106 case pattern of
108 case pattern of
107− PVar x -> return (args ++ [x], body)
109+ P.Var x -> return (args ++ [x], body)
108 _ -> do arg <- Case.newVar
110 _ -> do arg <- Case.newVar
111+ return ( args ++ [arg]
109− return (args ++ [arg], L s (Case (L s (Var arg)) [(pattern, body)]))
112+ , A ann (Case (A ann (rawVar arg)) [(pattern, body)]))
111 (patterns, innerBody) = collect [p] e
114 (patterns, innerBody) = collect [p] e
113− collect patterns lexpr@(L _ expr) =
116+ collect patterns lexpr@(A _ expr) =
114 case expr of
117 case expr of
115 Lambda p e -> collect (p:patterns) e
118 Lambda p e -> collect (p:patterns) e
116 _ -> (patterns, lexpr)
119 _ -> (patterns, lexpr)
@@ -127,7 +130,7 @@ expression (L span expr) =
127 (func, args) = getArgs e1 [e2]
130 (func, args) = getArgs e1 [e2]
128 getArgs func args =
131 getArgs func args =
129 case func of
132 case func of
130− (L _ (App f arg)) -> getArgs f (arg : args)
133+ (A _ (App f arg)) -> getArgs f (arg : args)
131 _ -> (func, args)
134 _ -> (func, args)
133 Let defs e ->
136 Let defs e ->
@@ -139,9 +142,9 @@ expression (L span expr) =
139 MultiIf branches ->
142 MultiIf branches ->
140 do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
143 do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
141 return $ case last branches of
144 return $ case last branches of
142− (L _ (Var "Basics.otherwise"), _) -> safeIfs branches'
145+ (A _ (Var (V.Raw "Basics.otherwise")), _) -> safeIfs branches'
143− (L _ (Literal (Boolean True)), _) -> safeIfs branches'
146+ (A _ (Literal (Boolean True)), _) -> safeIfs branches'
144− _ -> ifs branches' (obj "_E.If" `call` [ ref "$moduleName", string (show span) ])
147+ _ -> ifs branches' (obj "_E.If" `call` [ ref "$moduleName", string (renderPretty region) ])
146 safeIfs branches = ifs (init branches) (snd (last branches))
149 safeIfs branches = ifs (init branches) (snd (last branches))
147 ifs branches finally = foldr iff finally branches
150 ifs branches finally = foldr iff finally branches
@@ -151,10 +154,12 @@ expression (L span expr) =
151 do (tempVar,initialMatch) <- Case.toMatch cases
154 do (tempVar,initialMatch) <- Case.toMatch cases
152 (revisedMatch, stmt) <-
155 (revisedMatch, stmt) <-
153 case e of
156 case e of
157+ A _ (Var (V.Raw x)) ->
154− L _ (Var x) -> return (Case.matchSubst [(tempVar,x)] initialMatch, [])
158+ return (Case.matchSubst [(tempVar,x)] initialMatch, [])
155− _ -> do e' <- expression e
160+ do e' <- expression e
156− return (initialMatch, [VarDeclStmt () [varDecl tempVar e']])
161+ return (initialMatch, [VarDeclStmt () [varDecl tempVar e']])
157− match' <- match span revisedMatch
162+ match' <- match region revisedMatch
158 return (function [] (stmt ++ match') `call` [])
163 return (function [] (stmt ++ match') `call` [])
160 ExplicitList es ->
165 ExplicitList es ->
@@ -184,28 +189,28 @@ expression (L span expr) =
184 [ string name, Port.outgoing tipe, value' ]
189 [ string name, Port.outgoing tipe, value' ]
186definition :: Def -> State Int [Statement ()]
191definition :: Def -> State Int [Statement ()]
187−definition (Definition pattern expr@(L span _) _) = do
192+definition (Definition pattern expr@(A region _) _) = do
188 expr' <- expression expr
193 expr' <- expression expr
189 let assign x = varDecl x expr'
194 let assign x = varDecl x expr'
190 case pattern of
195 case pattern of
192 | Help.isOp x ->
197 | Help.isOp x ->
193 let op = LBracket () (ref "_op") (string x) in
198 let op = LBracket () (ref "_op") (string x) in
194 return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
199 return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
195 | otherwise ->
200 | otherwise ->
196 return [ VarDeclStmt () [ assign x ] ]
201 return [ VarDeclStmt () [ assign x ] ]
198− PRecord fields ->
203+ P.Record fields ->
199 let setField f = varDecl f (dotSep ["$",f]) in
204 let setField f = varDecl f (dotSep ["$",f]) in
200 return [ VarDeclStmt () (assign "$" : map setField fields) ]
205 return [ VarDeclStmt () (assign "$" : map setField fields) ]
202− PData name patterns | vars /= Nothing ->
207+ P.Data name patterns | vars /= Nothing ->
203 return [ VarDeclStmt () (setup (zipWith decl (maybe [] id vars) [0..])) ]
208 return [ VarDeclStmt () (setup (zipWith decl (maybe [] id vars) [0..])) ]
205 vars = getVars patterns
210 vars = getVars patterns
206 getVars patterns =
211 getVars patterns =
207 case patterns of
212 case patterns of
208− PVar x : rest -> (x:) `fmap` getVars rest
213+ P.Var x : rest -> (x:) `fmap` getVars rest
209 [] -> Just []
214 [] -> Just []
210 _ -> Nothing
215 _ -> Nothing
@@ -216,23 +221,23 @@ definition (Definition pattern expr@(L span _) _) = do
217 safeAssign = varDecl "$" (CondExpr () if' (obj "$raw") exception)
222 safeAssign = varDecl "$" (CondExpr () if' (obj "$raw") exception)
218 if' = InfixExpr () OpStrictEq (obj "$raw.ctor") (string name)
223 if' = InfixExpr () OpStrictEq (obj "$raw.ctor") (string name)
219− exception = obj "_E.Case" `call` [ref "$moduleName", string (show span)]
224+ exception = obj "_E.Case" `call` [ref "$moduleName", string (renderPretty region)]
222 do defs' <- concat <$> mapM toDef vars
227 do defs' <- concat <$> mapM toDef vars
223 return (VarDeclStmt () [assign "$"] : defs')
228 return (VarDeclStmt () [assign "$"] : defs')
225− vars = Set.toList $ Pattern.boundVars pattern
230+ vars = P.boundVarList pattern
226− mkVar = L span . Var
231+ mkVar = A region . rawVar
227− toDef y = let expr = L span $ Case (mkVar "$") [(pattern, mkVar y)]
232+ toDef y = let expr = A region $ Case (mkVar "$") [(pattern, mkVar y)]
228− in definition $ Definition (PVar y) expr Nothing
233+ in definition $ Definition (P.Var y) expr Nothing
230−match :: SrcSpan -> Case.Match -> State Int [Statement ()]
235+match :: Region -> Case.Match -> State Int [Statement ()]
231−match span mtch =
236+match region mtch =
232 case mtch of
237 case mtch of
233 Case.Match name clauses mtch' ->
238 Case.Match name clauses mtch' ->
234− do (isChars, clauses') <- unzip <$> mapM (clause span name) clauses
239+ do (isChars, clauses') <- unzip <$> mapM (clause region name) clauses
235− mtch'' <- match span mtch'
240+ mtch'' <- match region mtch'
236 return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
241 return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
238 isLiteral p = case p of
243 isLiteral p = case p of
@@ -244,13 +249,13 @@ match span mtch =
244 | otherwise = e
249 | otherwise = e
246 Case.Fail ->
251 Case.Fail ->
247− return [ ExprStmt () (obj "_E.Case" `call` [ref "$moduleName", string (show span)]) ]
252+ return [ ExprStmt () (obj "_E.Case" `call` [ref "$moduleName", string (renderPretty region)]) ]
249 Case.Break -> return [BreakStmt () Nothing]
254 Case.Break -> return [BreakStmt () Nothing]
250 Case.Other e ->
255 Case.Other e ->
251 do e' <- expression e
256 do e' <- expression e
252 return [ ret e' ]
257 return [ ret e' ]
253− Case.Seq ms -> concat <$> mapM (match span) (dropEnd [] ms)
258+ Case.Seq ms -> concat <$> mapM (match region) (dropEnd [] ms)
255 dropEnd acc [] = acc
260 dropEnd acc [] = acc
256 dropEnd acc (m:ms) =
261 dropEnd acc (m:ms) =
@@ -258,9 +263,9 @@ match span mtch =
258 Case.Other _ -> acc ++ [m]
263 Case.Other _ -> acc ++ [m]
259 _ -> dropEnd (acc ++ [m]) ms
264 _ -> dropEnd (acc ++ [m]) ms
261−clause :: SrcSpan -> String -> Case.Clause -> State Int (Bool, CaseClause ())
266+clause :: Region -> String -> Case.Clause -> State Int (Bool, CaseClause ())
262−clause span variable (Case.Clause value vars mtch) =
267+clause region variable (Case.Clause value vars mtch) =
263− (,) isChar . CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
268+ (,) isChar . CaseClause () pattern <$> match region (Case.matchSubst (zip vars vars') mtch)
265 vars' = map (\n -> variable ++ "._" ++ show n) [0..]
270 vars' = map (\n -> variable ++ "._" ++ show n) [0..]
266 (isChar, pattern) =
271 (isChar, pattern) =
@@ -273,8 +278,8 @@ clause span variable (Case.Clause value vars mtch) =
273 [] -> name
278 [] -> name
274 is -> drop (last is + 1) name
279 is -> drop (last is + 1) name
276−flattenLets :: [Def] -> LExpr -> ([Def], LExpr)
281+flattenLets :: [Def] -> Expr -> ([Def], Expr)
277−flattenLets defs lexpr@(L _ expr) =
282+flattenLets defs lexpr@(A _ expr) =
278 case expr of
283 case expr of
279 Let ds body -> flattenLets (defs ++ ds) body
284 Let ds body -> flattenLets (defs ++ ds) body
280 _ -> (defs, lexpr)
285 _ -> (defs, lexpr)
@@ -321,8 +326,8 @@ generate unsafeModule =
321 Nothing -> tail . init $ List.inits path
326 Nothing -> tail . init $ List.inits path
322 Just nmspc -> drop 2 . init . List.inits $ nmspc : path
327 Just nmspc -> drop 2 . init . List.inits $ nmspc : path
324−binop :: SrcSpan -> String -> LExpr -> LExpr -> State Int (Expression ())
329+binop :: Region -> String -> Expr -> Expr -> State Int (Expression ())
325−binop span op e1 e2 =
330+binop region op e1 e2 =
326 case op of
331 case op of
327 "Basics.." ->
332 "Basics.." ->
328 do es <- mapM expression (e1 : collect [] e2)
333 do es <- mapM expression (e1 : collect [] e2)
@@ -335,7 +340,7 @@ binop span op e1 e2 =
335 do e1' <- expression e1
340 do e1' <- expression e1
336 e2' <- expression e2
341 e2' <- expression e2
337 return $ obj "_L.append" `call` [e1', e2']
342 return $ obj "_L.append" `call` [e1', e2']
338− "::" -> expression (L span (Data "::" [e1,e2]))
343+ "::" -> expression (A region (Data "::" [e1,e2]))
340 do e1' <- expression e1
345 do e1' <- expression e1
341 e2' <- expression e2
346 e2' <- expression e2
@@ -345,7 +350,7 @@ binop span op e1 e2 =
346 collect es e =
351 collect es e =
347 case e of
352 case e of
348− L _ (Binop op e1 e2) | op == "Basics.." -> collect (es ++ [e1]) e2
353+ A _ (Binop op e1 e2) | op == "Basics.." -> collect (es ++ [e1]) e2
349 _ -> es ++ [e]
354 _ -> es ++ [e]
351 func | Help.isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)
356 func | Help.isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)