@@ -10,59 +10,66 @@ import qualified Data.Set as Set
10import Language.ECMAScript3.PrettyPrint
10import Language.ECMAScript3.PrettyPrint
11import Language.ECMAScript3.Syntax
11import Language.ECMAScript3.Syntax
13−import Generate.JavaScript.Helpers
13+import Generate.JavaScript.Helpers as Help
14import qualified Generate.Cases as Case
14import qualified Generate.Cases as Case
15import qualified Generate.JavaScript.Ports as Port
15import qualified Generate.JavaScript.Ports as Port
16+import qualified Generate.JavaScript.Variable as Var
16import qualified Generate.Markdown as MD
17import qualified Generate.Markdown as MD
17−import SourceSyntax.Annotation
18+
18−import SourceSyntax.Expression
19+import AST.Annotation
19−import qualified SourceSyntax.Helpers as Help
20+import AST.Module
20−import SourceSyntax.Literal
21+import AST.Expression.General
21−import SourceSyntax.Module
22+import qualified AST.Expression.Canonical as Canonical
22−import qualified SourceSyntax.Pattern as P
23+import qualified AST.Module as Module
23−import SourceSyntax.PrettyPrint (renderPretty)
24+import qualified AST.Helpers as Help
24−import qualified SourceSyntax.Variable as V
25+import AST.Literal
25−import qualified Transform.SafeNames as MakeSafe
26+import qualified AST.Pattern as P
27+import qualified AST.Variable as Var
27varDecl :: String -> Expression () -> VarDecl ()
29varDecl :: String -> Expression () -> VarDecl ()
28varDecl x expr =
30varDecl x expr =
29 VarDecl () (var x) (Just expr)
31 VarDecl () (var x) (Just expr)
31−include :: String -> String -> VarDecl ()
33+internalImports :: String -> [VarDecl ()]
32−include alias moduleName =
33− varDecl alias (obj (moduleName ++ ".make") <| ref "_elm")
35−internalImports :: String -> Statement ()
36internalImports name =
34internalImports name =
37− VarDeclStmt ()
35+ [ varDecl "_N" (obj ["Elm","Native"])
38− [ varDecl "_N" (obj "Elm.Native")
36+ , include "_U" "Utils"
39− , include "_U" "_N.Utils"
37+ , include "_L" "List"
40− , include "_L" "_N.List"
38+ , include "_A" "Array"
41− , include "_A" "_N.Array"
39+ , include "_E" "Error"
42− , include "_E" "_N.Error"
40+ , varDecl Help.localModuleName (string name)
43− , varDecl "$moduleName" (string name)
43+ include :: String -> String -> VarDecl ()
44+ include alias modul =
45+ varDecl alias (obj ["_N", modul, "make"] <| ref "_elm")
47+_Utils :: String -> Expression ()
48+_Utils x = obj ["_U", x]
50+_List :: String -> Expression ()
51+_List x = obj ["_L", x]
46literal :: Literal -> Expression ()
53literal :: Literal -> Expression ()
47literal lit =
54literal lit =
48 case lit of
55 case lit of
49− Chr c -> obj "_U.chr" <| string [c]
56+ Chr c -> _Utils "chr" <| string [c]
50 Str s -> string s
57 Str s -> string s
51 IntNum n -> IntLit () n
58 IntNum n -> IntLit () n
52 FloatNum n -> NumLit () n
59 FloatNum n -> NumLit () n
53 Boolean b -> BoolLit () b
60 Boolean b -> BoolLit () b
55−expression :: Expr -> State Int (Expression ())
62+expression :: Canonical.Expr -> State Int (Expression ())
56expression (A region expr) =
63expression (A region expr) =
57 case expr of
64 case expr of
58− Var (V.Raw x) -> return $ obj x
65+ Var var -> return $ Var.canonical var
60 Literal lit -> return $ literal lit
67 Literal lit -> return $ literal lit
62 Range lo hi ->
69 Range lo hi ->
63 do lo' <- expression lo
70 do lo' <- expression lo
64 hi' <- expression hi
71 hi' <- expression hi
65− return $ obj "_L.range" `call` [lo',hi']
72+ return $ _List "range" `call` [lo',hi']
67 Access e x ->
74 Access e x ->
68 do e' <- expression e
75 do e' <- expression e
@@ -70,19 +77,19 @@ expression (A region expr) =
71 Remove e x ->
78 Remove e x ->
72 do e' <- expression e
79 do e' <- expression e
73− return $ obj "_U.remove" `call` [string x, e']
80+ return $ _Utils "remove" `call` [string x, e']
75 Insert e x v ->
82 Insert e x v ->
76 do v' <- expression v
83 do v' <- expression v
77 e' <- expression e
84 e' <- expression e
78− return $ obj "_U.insert" `call` [string x, v', e']
85+ return $ _Utils "insert" `call` [string x, v', e']
80 Modify e fs ->
87 Modify e fs ->
81 do e' <- expression e
88 do e' <- expression e
82 fs' <- forM fs $ \(f,v) -> do
89 fs' <- forM fs $ \(f,v) -> do
83 v' <- expression v
90 v' <- expression v
84 return $ ArrayLit () [string f, v']
91 return $ ArrayLit () [string f, v']
85− return $ obj "_U.replace" `call` [ArrayLit () fs', e']
92+ return $ _Utils "replace" `call` [ArrayLit () fs', e']
87 Record fields ->
94 Record fields ->
88 do fields' <- forM fields $ \(f,e) -> do
95 do fields' <- forM fields $ \(f,e) -> do
@@ -106,10 +113,10 @@ expression (A region expr) =
107 depattern (args, body) pattern =
114 depattern (args, body) pattern =
108 case pattern of
115 case pattern of
109− P.Var x -> return (args ++ [x], body)
116+ P.Var x -> return (args ++ [ Var.varName x ], body)
110 _ -> do arg <- Case.newVar
117 _ -> do arg <- Case.newVar
111 return ( args ++ [arg]
118 return ( args ++ [arg]
112− , A ann (Case (A ann (rawVar arg)) [(pattern, body)]))
119+ , A ann (Case (A ann (localVar arg)) [(pattern, body)]))
114 (patterns, innerBody) = collect [p] e
121 (patterns, innerBody) = collect [p] e
@@ -140,22 +147,23 @@ expression (A region expr) =
140 return $ function [] (stmts ++ [ ret exp ]) `call` []
147 return $ function [] (stmts ++ [ ret exp ]) `call` []
142 MultiIf branches ->
149 MultiIf branches ->
143− do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
150+ do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
144− return $ case last branches of
151+ return $ case last branches of
145− (A _ (Var (V.Raw "Basics.otherwise")), _) -> safeIfs branches'
152+ (A _ (Var (Var.Canonical (Var.Module "Basics") "otherwise")), _) ->
146− (A _ (Literal (Boolean True)), _) -> safeIfs branches'
153+ safeIfs branches'
147− _ -> ifs branches' (obj "_E.If" `call` [ ref "$moduleName", string (renderPretty region) ])
154+ (A _ (Literal (Boolean True)), _) -> safeIfs branches'
148− where
155+ _ -> ifs branches' (throw "If" region)
149− safeIfs branches = ifs (init branches) (snd (last branches))
156+ where
150− ifs branches finally = foldr iff finally branches
157+ safeIfs branches = ifs (init branches) (snd (last branches))
151− iff (if', then') else' = CondExpr () if' then' else'
158+ ifs branches finally = foldr iff finally branches
159+ iff (if', then') else' = CondExpr () if' then' else'
153 Case e cases ->
161 Case e cases ->
154 do (tempVar,initialMatch) <- Case.toMatch cases
162 do (tempVar,initialMatch) <- Case.toMatch cases
155 (revisedMatch, stmt) <-
163 (revisedMatch, stmt) <-
156 case e of
164 case e of
157− A _ (Var (V.Raw x)) ->
165+ A _ (Var (Var.Canonical Var.Local x)) ->
158− return (Case.matchSubst [(tempVar,x)] initialMatch, [])
166+ return (Case.matchSubst [(tempVar, Var.varName x)] initialMatch, [])
160 do e' <- expression e
168 do e' <- expression e
161 return (initialMatch, [VarDeclStmt () [varDecl tempVar e']])
169 return (initialMatch, [VarDeclStmt () [varDecl tempVar e']])
@@ -164,7 +172,7 @@ expression (A region expr) =
165 ExplicitList es ->
173 ExplicitList es ->
166 do es' <- mapM expression es
174 do es' <- mapM expression es
167− return $ obj "_L.fromArray" <| ArrayLit () es'
175+ return $ _List "fromArray" <| ArrayLit () es'
169 Data name es ->
177 Data name es ->
170 do es' <- mapM expression es
178 do es' <- mapM expression es
@@ -175,7 +183,7 @@ expression (A region expr) =
176 Markdown uid doc es ->
184 Markdown uid doc es ->
177 do es' <- mapM expression es
185 do es' <- mapM expression es
178− return $ obj "Text.markdown" `call` (string md : string uid : es')
186+ return $ Var.value "Text" "markdown" `call` (string md : string uid : es')
180 pad = "<div style=\"height:0;width:0;\"> </div>"
188 pad = "<div style=\"height:0;width:0;\"> </div>"
181 md = pad ++ MD.toHtml doc ++ pad
189 md = pad ++ MD.toHtml doc ++ pad
@@ -184,15 +192,16 @@ expression (A region expr) =
184 return $ ObjectLit () [(PropString () "src", literal (Str src))]
192 return $ ObjectLit () [(PropString () "src", literal (Str src))]
186 PortIn name tipe ->
194 PortIn name tipe ->
187− return $ obj "Native.Ports.portIn" `call` [ string name, Port.incoming tipe ]
195+ return $ Var.value "Native.Ports" "portIn" `call`
196+ [ string name, Port.incoming tipe ]
189 PortOut name tipe value ->
198 PortOut name tipe value ->
190 do value' <- expression value
199 do value' <- expression value
191− return $ obj "Native.Ports.portOut" `call`
200+ return $ Var.value "Native.Ports" "portOut" `call`
192 [ string name, Port.outgoing tipe, value' ]
201 [ string name, Port.outgoing tipe, value' ]
194−definition :: Def -> State Int [Statement ()]
203+definition :: Canonical.Def -> State Int [Statement ()]
195−definition (Definition pattern expr@(A region _) _) = do
204+definition (Canonical.Definition pattern expr@(A region _) _) = do
196 expr' <- expression expr
205 expr' <- expression expr
197 let assign x = varDecl x expr'
206 let assign x = varDecl x expr'
198 case pattern of
207 case pattern of
@@ -201,39 +210,39 @@ definition (Definition pattern expr@(A region _) _) = do
201 let op = LBracket () (ref "_op") (string x) in
210 let op = LBracket () (ref "_op") (string x) in
202 return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
211 return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
203 | otherwise ->
212 | otherwise ->
204− return [ VarDeclStmt () [ assign x ] ]
213+ return [ VarDeclStmt () [ assign (Var.varName x) ] ]
206 P.Record fields ->
215 P.Record fields ->
207− let setField f = varDecl f (dotSep ["$",f]) in
216+ let setField f = varDecl f (obj ["$",f]) in
208 return [ VarDeclStmt () (assign "$" : map setField fields) ]
217 return [ VarDeclStmt () (assign "$" : map setField fields) ]
210− P.Data name patterns | vars /= Nothing ->
219+ P.Data (Var.Canonical _ name) patterns | vars /= Nothing ->
211 return [ VarDeclStmt () (setup (zipWith decl (maybe [] id vars) [0..])) ]
220 return [ VarDeclStmt () (setup (zipWith decl (maybe [] id vars) [0..])) ]
213 vars = getVars patterns
222 vars = getVars patterns
214 getVars patterns =
223 getVars patterns =
215 case patterns of
224 case patterns of
216− P.Var x : rest -> (x:) `fmap` getVars rest
225+ P.Var x : rest -> (Var.varName x :) `fmap` getVars rest
217 [] -> Just []
226 [] -> Just []
218 _ -> Nothing
227 _ -> Nothing
220− decl x n = varDecl x (dotSep ["$","_" ++ show n])
229+ decl x n = varDecl x (obj ["$","_" ++ show n])
221 setup vars
230 setup vars
222 | Help.isTuple name = assign "$" : vars
231 | Help.isTuple name = assign "$" : vars
223 | otherwise = assign "_raw" : safeAssign : vars
232 | otherwise = assign "_raw" : safeAssign : vars
225− safeAssign = varDecl "$" (CondExpr () if' (obj "_raw") exception)
234+ safeAssign = varDecl "$" (CondExpr () if' (ref "_raw") exception)
226− if' = InfixExpr () OpStrictEq (obj "_raw.ctor") (string name)
235+ if' = InfixExpr () OpStrictEq (obj ["_raw","ctor"]) (string name)
227− exception = obj "_E.Case" `call` [ref "$moduleName", string (renderPretty region)]
236+ exception = Help.throw "Case" region
230 do defs' <- concat <$> mapM toDef vars
239 do defs' <- concat <$> mapM toDef vars
231 return (VarDeclStmt () [assign "_"] : defs')
240 return (VarDeclStmt () [assign "_"] : defs')
233 vars = P.boundVarList pattern
242 vars = P.boundVarList pattern
234− mkVar = A region . rawVar
243+ mkVar = A region . localVar
235 toDef y = let expr = A region $ Case (mkVar "_") [(pattern, mkVar y)]
244 toDef y = let expr = A region $ Case (mkVar "_") [(pattern, mkVar y)]
236− in definition $ Definition (P.Var y) expr Nothing
245+ in definition $ Canonical.Definition (P.Var y) expr Nothing
238match :: Region -> Case.Match -> State Int [Statement ()]
247match :: Region -> Case.Match -> State Int [Statement ()]
239match region mtch =
248match region mtch =
@@ -248,15 +257,15 @@ match region mtch =
248 _ -> False
257 _ -> False
250 access name
259 access name
251− | any isLiteral clauses = obj name
260+ | any isLiteral clauses = obj [name]
252− | otherwise = dotSep (split name ++ ["ctor"])
261+ | otherwise = obj (Help.splitDots name ++ ["ctor"])
254 format isChars e
263 format isChars e
255 | or isChars = InfixExpr () OpAdd e (string "")
264 | or isChars = InfixExpr () OpAdd e (string "")
256 | otherwise = e
265 | otherwise = e
258 Case.Fail ->
267 Case.Fail ->
259− return [ ExprStmt () (obj "_E.Case" `call` [ref "$moduleName", string (renderPretty region)]) ]
268+ return [ ExprStmt () (Help.throw "Case" region) ]
261 Case.Break -> return [BreakStmt () Nothing]
270 Case.Break -> return [BreakStmt () Nothing]
@@ -283,98 +292,133 @@ clause region variable (Case.Clause value vars mtch) =
283 _ -> (,) False $ case value of
292 _ -> (,) False $ case value of
284 Right (Boolean b) -> BoolLit () b
293 Right (Boolean b) -> BoolLit () b
285 Right lit -> literal lit
294 Right lit -> literal lit
286− Left name -> string $ case List.elemIndices '.' name of
295+ Left (Var.Canonical _ name) ->
287− [] -> name
296+ string name
288− is -> drop (last is + 1) name
290−flattenLets :: [Def] -> Expr -> ([Def], Expr)
298+flattenLets :: [Canonical.Def] -> Canonical.Expr -> ([Canonical.Def], Canonical.Expr)
291flattenLets defs lexpr@(A _ expr) =
299flattenLets defs lexpr@(A _ expr) =
292 case expr of
300 case expr of
293 Let ds body -> flattenLets (defs ++ ds) body
301 Let ds body -> flattenLets (defs ++ ds) body
294 _ -> (defs, lexpr)
302 _ -> (defs, lexpr)
296−generate :: MetadataModule -> String
304+generate :: CanonicalModule -> String
297−generate unsafeModule =
305+generate modul =
298− show . prettyPrint $ setup (Just "Elm") (names modul ++ ["make"]) ++
306+ show . prettyPrint $ setup "Elm" (names ++ ["make"]) ++
299− [ assign ("Elm" : names modul ++ ["make"]) (function ["_elm"] programStmts) ]
307+ [ assign ("Elm" : names ++ ["make"]) (function ["_elm"] programStmts) ]
301− modul = MakeSafe.metadataModule unsafeModule
309+ names :: [String]
302− thisModule = dotSep ("_elm" : names modul ++ ["values"])
310+ names = Module.names modul
312+ thisModule :: Expression ()
313+ thisModule = obj ("_elm" : names ++ ["values"])
315+ programStmts :: [Statement ()]
303 programStmts =
316 programStmts =
305− [ [ ExprStmt () $ string "use strict" ]
318+ [ [ ExprStmt () (string "use strict") ]
306− , setup (Just "_elm") (names modul ++ ["values"])
319+ , setup "_elm" (names ++ ["values"])
307 , [ IfSingleStmt () thisModule (ret thisModule) ]
320 , [ IfSingleStmt () thisModule (ret thisModule) ]
308− , [ internalImports (List.intercalate "." (names modul)) ]
321+ , [ VarDeclStmt () localVars ]
309− , concatMap jsImport . Set.toList . Set.fromList . map fst $ imports modul
322+ , body
310− , [ assign ["_op"] (ObjectLit () []) ]
311− , concat $ evalState (mapM definition . fst . flattenLets [] $ program modul) 0
312 , [ jsExports ]
323 , [ jsExports ]
313 , [ ret thisModule ]
324 , [ ret thisModule ]
316− jsExports = assign ("_elm" : names modul ++ ["values"]) (ObjectLit () exs)
327+ localVars :: [VarDecl ()]
328+ localVars = varDecl "_op" (ObjectLit () []) :
329+ internalImports (Module.getName modul) ++
332+ explicitImports :: [VarDecl ()]
334+ map jsImport . Set.toList . Set.fromList . map fst $ Module.imports modul
336+ jsImport :: String -> VarDecl ()
338+ varDecl (Var.moduleName name) $
339+ obj ("Elm" : Help.splitDots name ++ ["make"]) <| ref "_elm"
341+ body :: [Statement ()]
342+ body = concat $ evalState defs 0
344+ defs = mapM definition . fst . flattenLets [] $ Module.program (Module.body modul)
346+ setup namespace path = map create paths
348+ create name = assign name (InfixExpr () OpLOr (obj name) (ObjectLit () []))
349+ paths = drop 2 . init . List.inits $ namespace : path
351+ jsExports = assign ("_elm" : names ++ ["values"]) (ObjectLit () exs)
318− exs = map entry . filter (not . Help.isOp) $ "_op" : exports modul
353+ exs = map entry $ "_op" : concatMap extract (exports modul)
319 entry x = (prop x, ref x)
354 entry x = (prop x, ref x)
358+ Var.Value x | Help.isOp x -> []
359+ | otherwise -> [Var.varName x]
360+ Var.ADT _ (Var.Listing ctors _) -> map Var.varName ctors
321 assign path expr =
362 assign path expr =
322 case path of
363 case path of
323 [x] -> VarDeclStmt () [ varDecl x expr ]
364 [x] -> VarDeclStmt () [ varDecl x expr ]
324 _ -> ExprStmt () $
365 _ -> ExprStmt () $
325− AssignExpr () OpAssign (LDot () (dotSep (init path)) (last path)) expr
366+ AssignExpr () OpAssign (LDot () (obj (init path)) (last path)) expr
327− jsImport modul = setup Nothing path ++ [ include ]
368+binop :: Region -> Var.Canonical -> Canonical.Expr -> Canonical.Expr
328− where
369+ -> State Int (Expression ())
329− path = Help.splitDots modul
370+binop region func@(Var.Canonical home op) e1 e2 =
330− include = assign path $ dotSep ("Elm" : path ++ ["make"]) <| ref "_elm"
371+ case (home, op) of
331−
372+ (Var.Module "Basics", ">>") ->
332− setup namespace path = map create paths
373+ do es <- mapM expression (collectLeftAssoc [e2] e1)
333− where
374+ return $ ["$"] ==> List.foldl' (\e f -> f <| e) (ref "$") es
334− create name = assign name (InfixExpr () OpLOr (dotSep name) (ObjectLit () []))
375+
335− paths = case namespace of
376+ (Var.Module "Basics", "<<") ->
336− Nothing -> tail . init $ List.inits path
377+ do es <- mapM expression (e1 : collectRightAssoc [] e2)
337− Just nmspc -> drop 2 . init . List.inits $ nmspc : path
339−binop :: Region -> String -> Expr -> Expr -> State Int (Expression ())
340−binop region op e1 e2 =
343− do es <- mapM expression (e1 : collect [] e2)
344 return $ ["$"] ==> foldr (<|) (ref "$") es
378 return $ ["$"] ==> foldr (<|) (ref "$") es
380+ (Var.Module "Basics", "<|") ->
346 do e2' <- expression e2
381 do e2' <- expression e2
347− es <- mapM expression (collect [] e1)
382+ es <- mapM expression (collectRightAssoc [] e1)
348 return $ foldr (<|) e2' es
383 return $ foldr (<|) e2' es
385+ (Var.Module "List", "++") ->
350 do e1' <- expression e1
386 do e1' <- expression e1
351 e2' <- expression e2
387 e2' <- expression e2
352− return $ obj "_L.append" `call` [e1', e2']
388+ return $ _List "append" `call` [e1', e2']
353− "::" -> expression (A region (Data "::" [e1,e2]))
389+
354− _ ->
390+ (Var.BuiltIn, "::") ->
391+ expression (A region (Data "::" [e1,e2]))
393+ (Var.Module "Basics", _) ->
355 do e1' <- expression e1
394 do e1' <- expression e1
356 e2' <- expression e2
395 e2' <- expression e2
357− return $ case Map.lookup op opDict of
396+ return $ case Map.lookup op basicOps of
358 Just f -> f e1' e2'
397 Just f -> f e1' e2'
359− Nothing -> ref "A2" `call` [ func, e1', e2' ]
398+ Nothing -> ref "A2" `call` [ Var.canonical func, e1', e2' ]
401+ do e1' <- expression e1
402+ e2' <- expression e2
403+ return (ref "A2" `call` [ Var.canonical func, e1', e2' ])
361− collect es e =
406+ collectRightAssoc es e =
362 case e of
407 case e of
363− A _ (Binop op e1 e2) | op == "Basics.." -> collect (es ++ [e1]) e2
408+ A _ (Binop (Var.Canonical (Var.Module "Basics") "<<") e1 e2) ->
409+ collectRightAssoc (es ++ [e1]) e2
364 _ -> es ++ [e]
410 _ -> es ++ [e]
366− func | Help.isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)
412+ collectLeftAssoc es e =
367− | otherwise = dotSep parts
413+ case e of
368− where
414+ A _ (Binop (Var.Canonical (Var.Module "Basics") ">>") e1 e2) ->
369− parts = Help.splitDots op
415+ collectLeftAssoc (e2 : es) e1
370− operator = last parts
416+ _ -> e : es
372− opDict = Map.fromList (infixOps ++ specialOps)
374− specialOp str func = [ (str, func), ("Basics." ++ str, func) ]
418+ basicOps = Map.fromList (infixOps ++ specialOps)
375− infixOp str op = specialOp str (InfixExpr () op)
377− infixOps = concat
420+ infixOps =
421+ let infixOp str op = (str, InfixExpr () op) in
378 [ infixOp "+" OpAdd
422 [ infixOp "+" OpAdd
379 , infixOp "-" OpSub
423 , infixOp "-" OpSub
380 , infixOp "*" OpMul
424 , infixOp "*" OpMul
@@ -383,16 +427,16 @@ binop region op e1 e2 =
383 , infixOp "||" OpLOr
427 , infixOp "||" OpLOr
386− specialOps = concat
430+ specialOps =
387− [ specialOp "^" $ \a b -> obj "Math.pow" `call` [a,b]
431+ [ (,) "^" $ \a b -> obj ["Math","pow"] `call` [a,b]
388− , specialOp "|>" $ flip (<|)
432+ , (,) "|>" $ flip (<|)
389− , specialOp "==" $ \a b -> obj "_U.eq" `call` [a,b]
433+ , (,) "==" $ \a b -> _Utils "eq" `call` [a,b]
390− , specialOp "/=" $ \a b -> PrefixExpr () PrefixLNot (obj "_U.eq" `call` [a,b])
434+ , (,) "/=" $ \a b -> PrefixExpr () PrefixLNot (_Utils "eq" `call` [a,b])
391− , specialOp "<" $ cmp OpLT 0
435+ , (,) "<" $ cmp OpLT 0
392− , specialOp ">" $ cmp OpGT 0
436+ , (,) ">" $ cmp OpGT 0
393− , specialOp "<=" $ cmp OpLT 1
437+ , (,) "<=" $ cmp OpLT 1
394− , specialOp ">=" $ cmp OpGT (-1)
438+ , (,) ">=" $ cmp OpGT (-1)
395− , specialOp "div" $ \a b -> InfixExpr () OpBOr (InfixExpr () OpDiv a b) (IntLit () 0)
439+ , (,) "//" $ \a b -> InfixExpr () OpBOr (InfixExpr () OpDiv a b) (IntLit () 0)
398− cmp op n a b = InfixExpr () op (obj "_U.cmp" `call` [a,b]) (IntLit () n)
442+ cmp op n a b = InfixExpr () op (_Utils "cmp" `call` [a,b]) (IntLit () n)