@@ -1,25 +1,27 @@
11{-# OPTIONS_GHC -W #-}
22module Generate.JavaScript (generate) where
33
4−import Control.Arrow (first,(***))
54import Control.Applicative ((<$>),(<*>))
5+import Control.Arrow (first,(***))
66import Control.Monad.State
77import qualified Data.List as List
88import qualified Data.Map as Map
99import qualified Data.Set as Set
10+import Language.ECMAScript3.PrettyPrint
11+import Language.ECMAScript3.Syntax
1012
1113import Generate.JavaScript.Helpers
1214import qualified Generate.Cases as Case
1315import qualified Generate.JavaScript.Ports as Port
1416import qualified Generate.Markdown as MD
17+import SourceSyntax.Annotation
18+import SourceSyntax.Expression
1519import qualified SourceSyntax.Helpers as Help
1620import SourceSyntax.Literal
17−import SourceSyntax.Pattern as Pattern
18−import SourceSyntax.Location
19−import SourceSyntax.Expression
2021import SourceSyntax.Module
21−import Language.ECMAScript3.Syntax
22−import Language.ECMAScript3.PrettyPrint
22+import qualified SourceSyntax.Pattern as P
23+import SourceSyntax.PrettyPrint (renderPretty)
24+import qualified SourceSyntax.Variable as V
2325import qualified Transform.SafeNames as MakeSafe
2426
2527varDecl :: String -> Expression () -> VarDecl ()
@@ -50,10 +52,10 @@ literal lit =
5052 FloatNum n -> NumLit () n
5153 Boolean b -> BoolLit () b
5254
53−expression :: LExpr -> State Int (Expression ())
54−expression (L span expr) =
55+expression :: Expr -> State Int (Expression ())
56+expression (A region expr) =
5557 case expr of
56− Var x -> return $ ref x
58+ Var (V.Raw x) -> return $ ref x
5759 Literal lit -> return $ literal lit
5860
5961 Range lo hi ->
@@ -93,9 +95,9 @@ expression (L span expr) =
9395 Map.toList . Map.filter (not . null) $ Map.map tail fs
9496 visible fs = map (first prop) . Map.toList $ Map.map head fs
9597
96− Binop op e1 e2 -> binop span op e1 e2
98+ Binop op e1 e2 -> binop region op e1 e2
9799
98− Lambda p e@(L s _) ->
100+ Lambda p e@(A ann _) ->
99101 do (args, body) <- foldM depattern ([], innerBody) (reverse patterns)
100102 body' <- expression body
101103 return $ case length args < 2 || length args > 9 of
@@ -104,13 +106,14 @@ expression (L span expr) =
104106 where
105107 depattern (args, body) pattern =
106108 case pattern of
107− PVar x -> return (args ++ [x], body)
109+ P.Var x -> return (args ++ [x], body)
108110 _ -> do arg <- Case.newVar
109− return (args ++ [arg], L s (Case (L s (Var arg)) [(pattern, body)]))
111+ return ( args ++ [arg]
112+ , A ann (Case (A ann (rawVar arg)) [(pattern, body)]))
110113
111114 (patterns, innerBody) = collect [p] e
112115
113− collect patterns lexpr@(L _ expr) =
116+ collect patterns lexpr@(A _ expr) =
114117 case expr of
115118 Lambda p e -> collect (p:patterns) e
116119 _ -> (patterns, lexpr)
@@ -127,7 +130,7 @@ expression (L span expr) =
127130 (func, args) = getArgs e1 [e2]
128131 getArgs func args =
129132 case func of
130− (L _ (App f arg)) -> getArgs f (arg : args)
133+ (A _ (App f arg)) -> getArgs f (arg : args)
131134 _ -> (func, args)
132135
133136 Let defs e ->
@@ -139,9 +142,9 @@ expression (L span expr) =
139142 MultiIf branches ->
140143 do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
141144 return $ case last branches of
142− (L _ (Var "Basics.otherwise"), _) -> safeIfs branches'
143− (L _ (Literal (Boolean True)), _) -> safeIfs branches'
144− _ -> ifs branches' (obj "_E.If" `call` [ ref "$moduleName", string (show span) ])
145+ (A _ (Var (V.Raw "Basics.otherwise")), _) -> safeIfs branches'
146+ (A _ (Literal (Boolean True)), _) -> safeIfs branches'
147+ _ -> ifs branches' (obj "_E.If" `call` [ ref "$moduleName", string (renderPretty region) ])
145148 where
146149 safeIfs branches = ifs (init branches) (snd (last branches))
147150 ifs branches finally = foldr iff finally branches
@@ -151,10 +154,12 @@ expression (L span expr) =
151154 do (tempVar,initialMatch) <- Case.toMatch cases
152155 (revisedMatch, stmt) <-
153156 case e of
154− L _ (Var x) -> return (Case.matchSubst [(tempVar,x)] initialMatch, [])
155− _ -> do e' <- expression e
156− return (initialMatch, [VarDeclStmt () [varDecl tempVar e']])
157− match' <- match span revisedMatch
157+ A _ (Var (V.Raw x)) ->
158+ return (Case.matchSubst [(tempVar,x)] initialMatch, [])
159+ _ ->
160+ do e' <- expression e
161+ return (initialMatch, [VarDeclStmt () [varDecl tempVar e']])
162+ match' <- match region revisedMatch
158163 return (function [] (stmt ++ match') `call` [])
159164
160165 ExplicitList es ->
@@ -184,28 +189,28 @@ expression (L span expr) =
184189 [ string name, Port.outgoing tipe, value' ]
185190
186191definition :: Def -> State Int [Statement ()]
187−definition (Definition pattern expr@(L span _) _) = do
192+definition (Definition pattern expr@(A region _) _) = do
188193 expr' <- expression expr
189194 let assign x = varDecl x expr'
190195 case pattern of
191− PVar x
196+ P.Var x
192197 | Help.isOp x ->
193198 let op = LBracket () (ref "_op") (string x) in
194199 return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
195200 | otherwise ->
196201 return [ VarDeclStmt () [ assign x ] ]
197202
198− PRecord fields ->
203+ P.Record fields ->
199204 let setField f = varDecl f (dotSep ["$",f]) in
200205 return [ VarDeclStmt () (assign "$" : map setField fields) ]
201206
202− PData name patterns | vars /= Nothing ->
207+ P.Data name patterns | vars /= Nothing ->
203208 return [ VarDeclStmt () (setup (zipWith decl (maybe [] id vars) [0..])) ]
204209 where
205210 vars = getVars patterns
206211 getVars patterns =
207212 case patterns of
208− PVar x : rest -> (x:) `fmap` getVars rest
213+ P.Var x : rest -> (x:) `fmap` getVars rest
209214 [] -> Just []
210215 _ -> Nothing
211216
@@ -216,23 +221,23 @@ definition (Definition pattern expr@(L span _) _) = do
216221
217222 safeAssign = varDecl "$" (CondExpr () if' (obj "$raw") exception)
218223 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)]
220225
221226 _ ->
222227 do defs' <- concat <$> mapM toDef vars
223228 return (VarDeclStmt () [assign "$"] : defs')
224229 where
225− vars = Set.toList $ Pattern.boundVars pattern
226− mkVar = L span . Var
227− toDef y = let expr = L span $ Case (mkVar "$") [(pattern, mkVar y)]
228− in definition $ Definition (PVar y) expr Nothing
230+ vars = P.boundVarList pattern
231+ mkVar = A region . rawVar
232+ toDef y = let expr = A region $ Case (mkVar "$") [(pattern, mkVar y)]
233+ in definition $ Definition (P.Var y) expr Nothing
229234
230−match :: SrcSpan -> Case.Match -> State Int [Statement ()]
231−match span mtch =
235+match :: Region -> Case.Match -> State Int [Statement ()]
236+match region mtch =
232237 case mtch of
233238 Case.Match name clauses mtch' ->
234− do (isChars, clauses') <- unzip <$> mapM (clause span name) clauses
235− mtch'' <- match span mtch'
239+ do (isChars, clauses') <- unzip <$> mapM (clause region name) clauses
240+ mtch'' <- match region mtch'
236241 return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
237242 where
238243 isLiteral p = case p of
@@ -244,13 +249,13 @@ match span mtch =
244249 | otherwise = e
245250
246251 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)]) ]
248253
249254 Case.Break -> return [BreakStmt () Nothing]
250255 Case.Other e ->
251256 do e' <- expression e
252257 return [ ret e' ]
253− Case.Seq ms -> concat <$> mapM (match span) (dropEnd [] ms)
258+ Case.Seq ms -> concat <$> mapM (match region) (dropEnd [] ms)
254259 where
255260 dropEnd acc [] = acc
256261 dropEnd acc (m:ms) =
@@ -258,9 +263,9 @@ match span mtch =
258263 Case.Other _ -> acc ++ [m]
259264 _ -> dropEnd (acc ++ [m]) ms
260265
261−clause :: SrcSpan -> String -> Case.Clause -> State Int (Bool, CaseClause ())
262−clause span variable (Case.Clause value vars mtch) =
263− (,) isChar . CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
266+clause :: Region -> String -> Case.Clause -> State Int (Bool, CaseClause ())
267+clause region variable (Case.Clause value vars mtch) =
268+ (,) isChar . CaseClause () pattern <$> match region (Case.matchSubst (zip vars vars') mtch)
264269 where
265270 vars' = map (\n -> variable ++ "._" ++ show n) [0..]
266271 (isChar, pattern) =
@@ -273,8 +278,8 @@ clause span variable (Case.Clause value vars mtch) =
273278 [] -> name
274279 is -> drop (last is + 1) name
275280
276−flattenLets :: [Def] -> LExpr -> ([Def], LExpr)
277−flattenLets defs lexpr@(L _ expr) =
281+flattenLets :: [Def] -> Expr -> ([Def], Expr)
282+flattenLets defs lexpr@(A _ expr) =
278283 case expr of
279284 Let ds body -> flattenLets (defs ++ ds) body
280285 _ -> (defs, lexpr)
@@ -321,8 +326,8 @@ generate unsafeModule =
321326 Nothing -> tail . init $ List.inits path
322327 Just nmspc -> drop 2 . init . List.inits $ nmspc : path
323328
324−binop :: SrcSpan -> String -> LExpr -> LExpr -> State Int (Expression ())
325−binop span op e1 e2 =
329+binop :: Region -> String -> Expr -> Expr -> State Int (Expression ())
330+binop region op e1 e2 =
326331 case op of
327332 "Basics.." ->
328333 do es <- mapM expression (e1 : collect [] e2)
@@ -335,7 +340,7 @@ binop span op e1 e2 =
335340 do e1' <- expression e1
336341 e2' <- expression e2
337342 return $ obj "_L.append" `call` [e1', e2']
338− "::" -> expression (L span (Data "::" [e1,e2]))
343+ "::" -> expression (A region (Data "::" [e1,e2]))
339344 _ ->
340345 do e1' <- expression e1
341346 e2' <- expression e2
@@ -345,7 +350,7 @@ binop span op e1 e2 =
345350 where
346351 collect es e =
347352 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
349354 _ -> es ++ [e]
350355
351356 func | Help.isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)