@@ -16,10 +16,14 @@ import Idris.Core.TT
16import IRTS.CodegenCommon
16import IRTS.CodegenCommon
17import IRTS.JavaScript.AST
17import IRTS.JavaScript.AST
18import IRTS.JavaScript.LangTransforms
18import IRTS.JavaScript.LangTransforms
19+import IRTS.JavaScript.Name
20+import IRTS.JavaScript.PrimOp
21+import IRTS.JavaScript.Specialize
19import IRTS.Lang
22import IRTS.Lang
20import IRTS.LangOpts
23import IRTS.LangOpts
21import IRTS.System
24import IRTS.System
23import Control.Monad.Trans.State
27import Control.Monad.Trans.State
24import Data.List (nub)
28import Data.List (nub)
25import Data.Map.Strict (Map)
29import Data.Map.Strict (Map)
@@ -41,8 +45,6 @@ import Data.Generics.Uniplate.Data
41import Data.List
45import Data.List
42import GHC.Generics (Generic)
46import GHC.Generics (Generic)
44−data Partial = Partial Name Int Int deriving (Eq, Ord)
46data CGStats = CGStats { usedWriteStr :: Bool
48data CGStats = CGStats { usedWriteStr :: Bool
47 , usedReadStr :: Bool
49 , usedReadStr :: Bool
48 , usedBigInt :: Bool
50 , usedBigInt :: Bool
@@ -57,6 +59,7 @@ data CGConf = CGConf { header :: Text
57 , initialization :: CGStats -> Text
59 , initialization :: CGStats -> Text
58 , writeStrTemplate :: Text
60 , writeStrTemplate :: Text
59 , readStrTemplate :: Text
61 , readStrTemplate :: Text
60 , extraRunTime :: String
63 , extraRunTime :: String
@@ -96,7 +99,7 @@ codegenJs conf ci =
97 path <- getIdrisJSRTSDir
100 path <- getIdrisJSRTSDir
98 jsbn <- if usedBigInt stats
101 jsbn <- if usedBigInt stats
99− then TIO.readFile $ path </> "jsbn/jsbn.js"
102+ then TIO.readFile $ path </> jsbnPath conf
100 else return ""
103 else return ""
102 runtimeCommon <- TIO.readFile $ path </> "Runtime-common.js"
105 runtimeCommon <- TIO.readFile $ path </> "Runtime-common.js"
@@ -119,17 +122,6 @@ codegenJs conf ci =
119 , footer conf
122 , footer conf
122−jsName :: Name -> Text
123−jsName n = T.pack $ "idris_" ++ concatMap jschar (showCG n)
124− where jschar x | isAlpha x || isDigit x = [x]
125− | otherwise = "_" ++ show (fromEnum x) ++ "_"
127−jsPartialName :: Partial -> Text
128−jsPartialName (Partial n i j) = T.concat ["partial_", T.pack $ show i, "_", T.pack $ show j, "_" , jsName n]
130−jsTailCallOptimName :: Text -> Text
131−jsTailCallOptimName x = T.concat ["tailCallOptim_cgIdris_", x]
133doPartials :: Set Partial -> Text
125doPartials :: Set Partial -> Text
134doPartials x =
126doPartials x =
135 T.intercalate "\n" (map f $ Set.toList x)
127 T.intercalate "\n" (map f $ Set.toList x)
@@ -137,8 +129,9 @@ doPartials x =
137 f p@(Partial n i j) =
129 f p@(Partial n i j) =
138 let vars1 = map (T.pack . ("x"++) . show) [1..i]
130 let vars1 = map (T.pack . ("x"++) . show) [1..i]
139 vars2 = map (T.pack . ("x"++) . show) [(i+1)..j]
131 vars2 = map (T.pack . ("x"++) . show) [(i+1)..j]
140− in jsAst2Text $
132+ in jsStmt2Text $
133+ JsFun (jsNamePartial p) vars1 $ JsReturn $
141− JsFun (jsPartialName p) vars1 $ JsReturn $ JsCurryLambda vars2 (JsApp (jsName n) (map JsVar (vars1 ++ vars2)) )
134+ jsCurryLam vars2 (jsAppN (jsName n) (map JsVar (vars1 ++ vars2)) )
143doCodegen :: CGConf -> Map Name LDecl -> [LDecl] -> (Text, CGStats)
136doCodegen :: CGConf -> Map Name LDecl -> [LDecl] -> (Text, CGStats)
144doCodegen conf defs decls =
137doCodegen conf defs decls =
@@ -153,17 +146,17 @@ doCodegen conf defs decls =
153doCodegenDecl :: CGConf -> Map Name LDecl -> LDecl -> (Text, CGStats)
146doCodegenDecl :: CGConf -> Map Name LDecl -> LDecl -> (Text, CGStats)
154doCodegenDecl conf defs (LFun _ n args def) =
147doCodegenDecl conf defs (LFun _ n args def) =
155 let (ast, stats) = cgFun conf defs n args def
148 let (ast, stats) = cgFun conf defs n args def
156− in (jsAst2Text $ ast, stats)
149+ in (jsStmt2Text $ ast, stats)
157−doCodegenDecl conf defs (LConstructor n i sz) =
150+doCodegenDecl conf defs (LConstructor n i sz) = ("", emptyStats)
160−seqJs :: [JsAST] -> JsAST
152+seqJs :: [JsStmt] -> JsStmt
161seqJs [] = JsEmpty
153seqJs [] = JsEmpty
162seqJs (x:xs) = JsSeq x (seqJs xs)
154seqJs (x:xs) = JsSeq x (seqJs xs)
165data CGBodyState = CGBodyState { defs :: Map Name LDecl
157data CGBodyState = CGBodyState { defs :: Map Name LDecl
166 , lastIntName :: Int
158 , lastIntName :: Int
159+ , reWrittenNames :: Map.Map Name JsExpr
167 , currentFnNameAndArgs :: (Text, [Text])
160 , currentFnNameAndArgs :: (Text, [Text])
168 , usedArgsTailCallOptim :: Set (Text, Text)
161 , usedArgsTailCallOptim :: Set (Text, Text)
169 , isTailRec :: Bool
162 , isTailRec :: Bool
@@ -180,7 +173,7 @@ getNewCGName =
180 st <- get
173 st <- get
181 let v = lastIntName st + 1
174 let v = lastIntName st + 1
182 put $ st {lastIntName = v}
175 put $ st {lastIntName = v}
183− return $ T.pack $ "cgIdris_" ++ show v
176+ return $ jsNameGenerated v
185addPartial :: Partial -> State CGBodyState ()
178addPartial :: Partial -> State CGBodyState ()
186addPartial p =
179addPartial p =
@@ -194,12 +187,12 @@ getNewCGNames :: Int -> State CGBodyState [Text]
194getNewCGNames n =
187getNewCGNames n =
195 mapM (\_ -> getNewCGName) [1..n]
188 mapM (\_ -> getNewCGName) [1..n]
197−getConsId :: Name -> State CGBodyState Int
190+getConsId :: Name -> State CGBodyState (Int, Int)
198getConsId n =
191getConsId n =
200 st <- get
193 st <- get
201 case Map.lookup n (defs st) of
194 case Map.lookup n (defs st) of
202− Just (LConstructor _ conId _) -> pure conId
195+ Just (LConstructor _ conId arity) -> pure (conId, arity)
203 _ -> error $ "Internal JS Backend error " ++ showCG n ++ " is not a constructor."
196 _ -> error $ "Internal JS Backend error " ++ showCG n ++ " is not a constructor."
205getArgList :: Name -> State CGBodyState (Maybe [Name])
198getArgList :: Name -> State CGBodyState (Maybe [Name])
@@ -216,26 +209,15 @@ data BodyResTarget = ReturnBT
216 | DecConstBT Text
209 | DecConstBT Text
217 | GetExpBT
210 | GetExpBT
219−replaceVarsByProj :: JsAST -> Map Text Int -> JsAST -> JsAST
220−replaceVarsByProj n d z =
225− case Map.lookup x d of
226− Nothing -> (JsVar x)
227− Just i -> JsArrayProj (JsInt i) n
230−cgFun :: CGConf -> Map Name LDecl -> Name -> [Name] -> LExp -> (JsAST, CGStats)
212+cgFun :: CGConf -> Map Name LDecl -> Name -> [Name] -> LExp -> (JsStmt, CGStats)
231−cgFun cnf dfs n args def =
213+cgFun cnf dfs n args def = do
233− fnName = jsName n
214+ let fnName = jsName n
234− argNames = map jsName args
215+ let argNames = map jsName args
235− ((decs, res),st) = runState
216+ let ((decs, res),st) = runState
236 (cgBody ReturnBT def)
217 (cgBody ReturnBT def)
237 (CGBodyState { defs=dfs
218 (CGBodyState { defs=dfs
238 , lastIntName = 0
219 , lastIntName = 0
220+ , reWrittenNames = Map.empty
239 , currentFnNameAndArgs = (fnName, argNames)
221 , currentFnNameAndArgs = (fnName, argNames)
240 , usedArgsTailCallOptim = Set.empty
222 , usedArgsTailCallOptim = Set.empty
241 , isTailRec = False
223 , isTailRec = False
@@ -246,19 +228,16 @@ cgFun cnf dfs n args def =
246 , partialApps = Set.empty
228 , partialApps = Set.empty
249− body = if isTailRec st then
251− (declareUsedOptimArgs $ usedArgsTailCallOptim st)
231+ let body = if isTailRec st then JsSeq (declareUsedOptimArgs $ usedArgsTailCallOptim st) (JsForever ((seqJs decs) `JsSeq` res)) else (seqJs decs) `JsSeq` res
252− (JsWhileTrue ((seqJs decs) `JsSeq` res))
232+ let fn = JsFun fnName argNames body
253− else (seqJs decs) `JsSeq` res
254− in (JsFun fnName argNames $ body, CGStats { usedWriteStr = usedWrite st
233+ let state' = CGStats { usedWriteStr = usedWrite st
255− , partialApplications = partialApps st
234+ , partialApplications = partialApps st
256− , usedBigInt = usedITBig st
235+ , usedBigInt = usedITBig st
257− , usedReadStr = usedRead st
236+ , usedReadStr = usedRead st
261−getSwitchJs :: JsAST -> [LAlt] -> JsAST
240+getSwitchJs :: JsExpr -> [LAlt] -> JsExpr
262getSwitchJs x alts =
241getSwitchJs x alts =
263 if any conCase alts then JsArrayProj (JsInt 0) x
242 if any conCase alts then JsArrayProj (JsInt 0) x
264 else if any constBigIntCase alts then JsForeign "%0.toString()" [x]
243 else if any constBigIntCase alts then JsForeign "%0.toString()" [x]
@@ -268,48 +247,75 @@ getSwitchJs x alts =
268 constBigIntCase (LConstCase (BI _) _) = True
247 constBigIntCase (LConstCase (BI _) _) = True
269 constBigIntCase _ = False
248 constBigIntCase _ = False
271−addRT :: BodyResTarget -> JsAST -> JsAST
250+addRT :: BodyResTarget -> JsExpr -> JsStmt
272addRT ReturnBT x = JsReturn x
251addRT ReturnBT x = JsReturn x
273−addRT (DecBT n) x = JsLet n x
252+addRT (DecBT n) x = JsDecLet n x
253+addRT (DecConstBT n) x = JsDecConst n x
274−addRT (SetBT n) x = JsSetVar n x
254+addRT (SetBT n) x = JsSet (JsVar n) x
275−addRT (DecConstBT n) x = JsConst n x
276−addRT GetExpBT x = x
255+addRT GetExpBT x = JsExprStmt x
278−declareUsedOptimArgs :: Set (Text, Text) -> JsAST
257+declareUsedOptimArgs :: Set (Text, Text) -> JsStmt
279−declareUsedOptimArgs x = seqJs $ map (\(x,y) -> JsLet x (JsVar y) ) (Set.toList x)
258+declareUsedOptimArgs x = seqJs $ map (\(x,y) -> JsDecLet x (JsVar y) ) (Set.toList x)
281−tailCallOptimRefreshArgs :: [(Text, JsAST)] -> Set Text -> ((JsAST, JsAST), Set (Text, Text))
260+tailCallOptimRefreshArgs :: [(Text, JsExpr)] -> Set Text -> ((JsStmt, JsStmt), Set (Text, Text))
282tailCallOptimRefreshArgs [] s = ((JsEmpty, JsEmpty), Set.empty)
261tailCallOptimRefreshArgs [] s = ((JsEmpty, JsEmpty), Set.empty)
283tailCallOptimRefreshArgs ((n,x):r) s =
262tailCallOptimRefreshArgs ((n,x):r) s =
284 let ((y1,y2), y3) = tailCallOptimRefreshArgs r (Set.insert n s) --
263 let ((y1,y2), y3) = tailCallOptimRefreshArgs r (Set.insert n s) --
285 in if Set.null $ (Set.fromList [ z | z <- universeBi x ]) `Set.intersection` s then
264 in if Set.null $ (Set.fromList [ z | z <- universeBi x ]) `Set.intersection` s then
286− ((y1, JsSetVar n x `JsSeq` y2), y3)
265+ ((y1, jsSetVar n x `JsSeq` y2), y3)
288 let n' = jsTailCallOptimName n
267 let n' = jsTailCallOptimName n
289− in ((JsSetVar n' x `JsSeq` y1, JsSetVar n (JsVar n') `JsSeq` y2), Set.insert (n',n) y3)
268+ in ((jsSetVar n' x `JsSeq` y1, jsSetVar n (JsVar n') `JsSeq` y2), Set.insert (n',n) y3)
291−
270+cgName :: Name -> State CGBodyState JsExpr
273+ case Map.lookup b (reWrittenNames st) of
275+ _ -> pure $ JsVar $ jsName b
292−cgBody :: BodyResTarget -> LExp -> State CGBodyState ([JsAST], JsAST)
277+cgBody :: BodyResTarget -> LExp -> State CGBodyState ([JsStmt], JsStmt)
280+ (LCase _ (LOp oper [x, y]) [LConstCase (I 0) (LCon _ _ ff []), LDefaultCase (LCon _ _ tt [])])
281+ | (ff == qualifyN "Prelude.Bool" "False" &&
282+ tt == qualifyN "Prelude.Bool" "True") ->
283+ case (Map.lookup oper primDB) of
284+ Just (useBigInt, pti, combinator) | pti == PTBool -> do
285+ z <- mapM (cgBody GetExpBT) [x, y]
286+ when useBigInt setUsedITBig
287+ let res = jsPrimCoerce pti PTBool $ combinator $ map (jsStmt2Expr . snd) z
288+ pure $ (concat $ map fst z, addRT rt res)
289+ _ -> cgBody' rt expr
290+ (LCase f e [LConCase nf ff [] alt, LConCase nt tt [] conseq])
291+ | (ff == qualifyN "Prelude.Bool" "False" &&
292+ tt == qualifyN "Prelude.Bool" "True") ->
293+ cgBody' rt $ LCase f e [LConCase nt tt [] conseq, LConCase nf ff [] alt]
294+ expr -> cgBody' rt expr
296+cgBody' :: BodyResTarget -> LExp -> State CGBodyState ([JsStmt], JsStmt)
293−cgBody rt (LV (Glob n)) =
297+cgBody' rt (LV (Glob n)) =
295 argsFn <- getArgList n
299 argsFn <- getArgList n
296 case argsFn of
300 case argsFn of
297− Just [] ->
301+ Just [] -> do
298− pure $ ([], addRT rt $ JsApp (jsName n) [])
303+ pure $ ([], addRT rt n')
299 Just a ->
304 Just a ->
301− let part = Partial n 0 (length a)
306+ let part = Partial n 0 (length a)
302 addPartial part
307 addPartial part
303− pure ([], addRT rt $ JsApp (jsPartialName part) [])
308+ pure ([], addRT rt $ jsAppN (jsNamePartial part) [])
304− Nothing ->
309+ Nothing -> do
305− pure $ ([], addRT rt $ JsVar $ jsName n)
311+ pure $ ([], addRT rt n')
306−cgBody rt (LApp tailcall (LV (Glob fn)) args) =
312+cgBody' rt (LApp tailcall (LV (Glob fn)) args) =
308 let fname = jsName fn
314 let fname = jsName fn
309 st <- get
315 st <- get
310 let (currFn, argN) = currentFnNameAndArgs st
316 let (currFn, argN) = currentFnNameAndArgs st
311 z <- mapM (cgBody GetExpBT) args
317 z <- mapM (cgBody GetExpBT) args
312− let argVals = map snd z
318+ let argVals = map (jsStmt2Expr . snd) z
313 let preDecs = concat $ map fst z
319 let preDecs = concat $ map fst z
314 case (fname == currFn && (length args) == (length argN), rt) of
320 case (fname == currFn && (length args) == (length argN), rt) of
315 (True, ReturnBT) ->
321 (True, ReturnBT) ->
@@ -323,81 +329,86 @@ cgBody rt (LApp tailcall (LV (Glob fn)) args) =
323 argsFn <- getArgList fn
329 argsFn <- getArgList fn
324 case argsFn of
330 case argsFn of
325 Nothing ->
331 Nothing ->
326− pure (preDecs, addRT rt $ JsCurryApp (JsVar fname) argVals )
332+ pure (preDecs, addRT rt $ jsCurryApp (JsVar fname) argVals )
327 Just agFn ->
333 Just agFn ->
329 let lenAgFn = length agFn
335 let lenAgFn = length agFn
330 let lenArgs = length args
336 let lenArgs = length args
331 case compare lenAgFn lenArgs of
337 case compare lenAgFn lenArgs of
333− pure (preDecs, addRT rt $ JsApp fname argVals)
339+ pure (preDecs, addRT rt $ jsAppN fname argVals)
335− pure (preDecs, addRT rt $ JsCurryApp (JsApp fname (take lenAgFn argVals )) (drop lenAgFn argVals) )
341+ pure (preDecs, addRT rt $ jsCurryApp (jsAppN fname (take lenAgFn argVals)) (drop lenAgFn argVals) )
338 let part = Partial fn lenArgs lenAgFn
344 let part = Partial fn lenArgs lenAgFn
339 addPartial part
345 addPartial part
340− pure (preDecs, addRT rt $ JsApp (jsPartialName part) argVals )
346+ pure (preDecs, addRT rt $ jsAppN (jsNamePartial part) argVals )
342−cgBody rt (LForce (LLazyApp n args)) = cgBody rt (LApp False (LV (Glob n)) args)
348+cgBody' rt (LForce (LLazyApp n args)) = cgBody rt (LApp False (LV (Glob n)) args)
343−cgBody rt (LLazyApp n args) =
349+cgBody' rt (LLazyApp n args) =
345 (d,v) <- cgBody ReturnBT (LApp False (LV (Glob n)) args)
351 (d,v) <- cgBody ReturnBT (LApp False (LV (Glob n)) args)
346− pure ([], addRT rt $ JsLazy $ JsSeq (seqJs d) v)
352+ pure ([], addRT rt $ jsLazy $ jsStmt2Expr $ JsSeq (seqJs d) v)
347−cgBody rt (LForce e) =
353+cgBody' rt (LForce e) =
349 (d,v) <- cgBody GetExpBT e
355 (d,v) <- cgBody GetExpBT e
350− pure (d, addRT rt $ JsForce v)
356+ pure (d, addRT rt $ JsForce $ jsStmt2Expr v)
351−cgBody rt (LLet n v sc) =
357+cgBody' rt (LLet n v sc) =
353 (d1, v1) <- cgBody (DecConstBT $ jsName n) v
359 (d1, v1) <- cgBody (DecConstBT $ jsName n) v
354 (d2, v2) <- cgBody rt sc
360 (d2, v2) <- cgBody rt sc
355− pure $ ((d1 ++ v1 : d2), v2 )
361+ pure $ ((d1 ++ v1 : d2), v2)
356−cgBody rt (LProj e i) =
362+cgBody' rt (LProj e i) =
358 (d, v) <- cgBody GetExpBT e
364 (d, v) <- cgBody GetExpBT e
359− pure $ (d, addRT rt $ JsArrayProj (JsInt $ i+1) $ v)
365+ pure $ (d, addRT rt $ JsArrayProj (JsInt $ i+1) $ jsStmt2Expr v)
360−cgBody rt (LCon _ conId n args) =
366+cgBody' rt (LCon _ conId n args) =
362 z <- mapM (cgBody GetExpBT) args
368 z <- mapM (cgBody GetExpBT) args
369+ con <- formCon n (map (jsStmt2Expr . snd) z)
363− pure $ (concat $ map fst z, addRT rt $ JsArray (JsInt conId : map snd z))
370+ pure $ (concat $ map fst z, addRT rt con)
364−cgBody rt (LCase _ e alts) =
371+cgBody' rt (LCase _ e alts) = do
366− (d,v) <- cgBody GetExpBT e
372+ (d, v) <- cgBody GetExpBT e
367− resName <- getNewCGName
373+ resName <- getNewCGName
368− swName <- getNewCGName
374+ (decSw, entry) <-
369− (altsJs,def) <- cgAlts rt resName (JsVar swName) alts
375+ case (all altHasNoProj alts && length alts <= 2, v) of
370− let decSw = JsConst swName v
376+ (True, _) -> pure (JsEmpty, jsStmt2Expr v)
371− let sw = JsSwitchCase (getSwitchJs (JsVar swName) alts) altsJs def
377+ (False, JsExprStmt (JsVar n)) -> pure (JsEmpty, jsStmt2Expr v)
379+ swName <- getNewCGName
380+ pure (JsDecConst swName $ jsStmt2Expr v, JsVar swName)
381+ sw' <- cgIfTree rt resName entry alts
385+ Nothing -> JsExprStmt JsNull
372− case rt of
386+ case rt of
374− pure (d ++ [decSw], sw)
387+ ReturnBT -> pure (d ++ [decSw], sw)
375− (DecBT nvar) ->
388+ (DecBT nvar) -> pure (d ++ [decSw, JsDecLet nvar JsNull], sw)
376− pure (d ++ [decSw, JsLet nvar JsNull], sw)
389+ (DecConstBT nvar) -> pure (d ++ [decSw, JsDecLet nvar JsNull], sw)
378− pure (d ++ [decSw], sw)
390+ (SetBT nvar) -> pure (d ++ [decSw], sw)
379− GetExpBT ->
391+ GetExpBT ->
380− pure (d ++ [decSw, JsLet resName JsNull, sw], JsVar resName)
393+ (d ++ [decSw, JsDecLet resName JsNull, sw], JsExprStmt $ JsVar resName)
381− (DecConstBT nvar) ->
382− pure (d ++ [decSw, JsLet nvar JsNull], sw)
383−cgBody rt (LConst c) =
394+cgBody' rt (LConst c) =
385 cst <- cgConst c
396 cst <- cgConst c
386 pure ([], (addRT rt) $ cst)
397 pure ([], (addRT rt) $ cst)
387−cgBody rt (LOp op args) =
398+cgBody' rt (LOp op args) =
389 z <- mapM (cgBody GetExpBT) args
400 z <- mapM (cgBody GetExpBT) args
390− res <- cgOp op (map snd z)
401+ res <- cgOp op (map (jsStmt2Expr . snd) z)
391 pure $ (concat $ map fst z, addRT rt $ res)
402 pure $ (concat $ map fst z, addRT rt $ res)
392−cgBody rt LNothing = pure ([], addRT rt JsNull)
403+cgBody' rt LNothing = pure ([], addRT rt JsNull)
393−cgBody rt (LError x) = pure ([], JsError $ JsStr x)
404+cgBody' rt (LError x) = pure ([], JsError $ JsStr x)
394−cgBody rt x@(LForeign dres (FStr code) args ) =
405+cgBody' rt x@(LForeign dres (FStr code) args ) =
396 z <- mapM (cgBody GetExpBT) (map snd args)
407 z <- mapM (cgBody GetExpBT) (map snd args)
397− jsArgs <- sequence $ map cgForeignArg (zip (map fst args) (map snd z))
408+ jsArgs <- sequence $ map cgForeignArg (zip (map fst args) (map (jsStmt2Expr . snd) z))
398 jsDres <- cgForeignRes dres $ JsForeign (T.pack code) jsArgs
409 jsDres <- cgForeignRes dres $ JsForeign (T.pack code) jsArgs
399 pure $ (concat $ map fst z, addRT rt $ jsDres)
410 pure $ (concat $ map fst z, addRT rt $ jsDres)
400−cgBody _ x = error $ "Instruction " ++ show x ++ " not compilable yet"
411+cgBody' _ x = error $ "Instruction " ++ show x ++ " not compilable yet"
402altsRT :: Text -> BodyResTarget -> BodyResTarget
413altsRT :: Text -> BodyResTarget -> BodyResTarget
403altsRT rn ReturnBT = ReturnBT
414altsRT rn ReturnBT = ReturnBT
@@ -406,36 +417,85 @@ altsRT rn (SetBT n) = SetBT n
406altsRT rn (DecConstBT n) = SetBT n
417altsRT rn (DecConstBT n) = SetBT n
407altsRT rn GetExpBT = SetBT rn
418altsRT rn GetExpBT = SetBT rn
409−cgAlts :: BodyResTarget -> Text -> JsAST -> [LAlt] -> State CGBodyState ([(JsAST, JsAST)], Maybe JsAST)
420+altHasNoProj :: LAlt -> Bool
421+altHasNoProj (LConCase _ _ args _) = args == []
422+altHasNoProj _ = True
424+formCon :: Name -> [JsExpr] -> State CGBodyState JsExpr
426+ case specialCased n of
427+ Just (ctor, test, match) -> pure $ ctor args
429+ (conId, arity) <- getConsId n
433+ (T.pack "type", JsInt conId) :
434+ zip (map (\i -> T.pack $ "$" ++ show i) [1 ..]) args
435+ else pure $ JsInt conId
437+formConTest :: Name -> JsExpr -> State CGBodyState JsExpr
439+ case specialCased n of
440+ Just (ctor, test, match) -> pure $ test x
442+ (conId, arity) <- getConsId n
444+ then pure $ JsBinOp "===" (JsProp x (T.pack "type")) (JsInt conId)
445+ else pure $ JsBinOp "===" x (JsInt conId)
447+formProj :: Name -> JsExpr -> Int -> JsExpr
449+ case specialCased n of
450+ Just (ctor, test, proj) -> proj v i
451+ Nothing -> JsProp v (T.pack $ "$" ++ show i)
453+smartif :: JsExpr -> JsStmt -> Maybe JsStmt -> JsStmt
454+smartif cond conseq (Just alt) = JsIf cond conseq (Just alt)
455+smartif cond conseq Nothing = conseq
457+cgIfTree :: BodyResTarget
461+ -> State CGBodyState (Maybe JsStmt)
462+cgIfTree _ _ _ [] = pure Nothing
410−cgAlts rt resName scrvar ((LConstCase t exp):r) =
463+cgIfTree rt resName scrvar ((LConstCase t exp):r) = do
412− (d, v) <- cgBody (altsRT resName rt) exp
464+ (d, v) <- cgBody (altsRT resName rt) exp
413− (ar, def) <- cgAlts rt resName scrvar r
465+ alternatives <- cgIfTree rt resName scrvar r
414− cst <- case t of
466+ test <- case t of
415− BI _ ->
467+ BI _ -> do
418− c' <- cgConst t
468+ t' <- cgConst t
419− pure $ JsForeign "%0.toString()" [c']
469+ cgOp (LPlus (ATInt ITBig)) [scrvar, t']
420− _ -> cgConst t
471+ t' <- cgConst t
472+ pure $ JsBinOp "===" scrvar t'
421− pure ((cst, JsSeq (seqJs d) v) : ar, def)
474+ smartif test (JsSeq (seqJs d) v) alternatives
422−cgAlts rt resName scrvar ((LDefaultCase exp):r) =
475+cgIfTree rt resName scrvar ((LDefaultCase exp):r) = do
424− (d, v) <- cgBody (altsRT resName rt) exp
476+ (d, v) <- cgBody (altsRT resName rt) exp
425− pure ([], Just $ JsSeq (seqJs d) v)
477+ pure $ Just $ JsSeq (seqJs d) v
426−cgAlts rt resName scrvar ((LConCase _ n args exp):r) =
478+cgIfTree rt resName scrvar ((LConCase _ n args exp):r) = do
427− do
479+ alternatives <- cgIfTree rt resName scrvar r
428− (d, v) <- cgBody (altsRT resName rt) exp
480+ test <- formConTest n scrvar
429− (ar, def) <- cgAlts rt resName scrvar r
481+ st <- get
430− conId <- getConsId n
482+ let rwn = reWrittenNames st
431− let replace = replaceVarsByProj scrvar (Map.fromList $ zip (map jsName args) [1..])
483+ put $
432− let branchBody = JsSeq (seqJs $ map replace d) (replace v)
484+ st
433− pure ((JsInt conId, branchBody) : ar, def)
485+ { reWrittenNames =
434−cgAlts _ _ _ [] =
486+ foldl
435− pure ([],Nothing)
487+ (\m (n, j) -> Map.insert n (formProj n scrvar j) m)
437−
489+ (zip args [1 ..])
491+ (d, v) <- cgBody (altsRT resName rt) exp
493+ put $ st1 {reWrittenNames = rwn}
494+ let branchBody = JsSeq (seqJs d) v
495+ pure $ Just $ smartif test branchBody alternatives
438−cgForeignArg :: (FDesc, JsAST) -> State CGBodyState JsAST
498+cgForeignArg :: (FDesc, JsExpr) -> State CGBodyState JsExpr
439cgForeignArg (FApp (UN "JS_IntT") _, v) = pure v
499cgForeignArg (FApp (UN "JS_IntT") _, v) = pure v
440cgForeignArg (FCon (UN "JS_Str"), v) = pure v
500cgForeignArg (FCon (UN "JS_Str"), v) = pure v
441cgForeignArg (FCon (UN "JS_Ptr"), v) = pure v
501cgForeignArg (FCon (UN "JS_Ptr"), v) = pure v
@@ -446,14 +506,14 @@ cgForeignArg (FApp (UN "JS_FnT") [_,FApp (UN "JS_Fn") [_,_, a, FApp (UN "JS_FnBa
446cgForeignArg (FApp (UN "JS_FnT") [_,FApp (UN "JS_Fn") [_,_, a, FApp (UN "JS_FnIO") [_,_, b]]], f) =
506cgForeignArg (FApp (UN "JS_FnT") [_,FApp (UN "JS_Fn") [_,_, a, FApp (UN "JS_FnIO") [_,_, b]]], f) =
448 jsx <- cgForeignArg (a, JsVar "x")
508 jsx <- cgForeignArg (a, JsVar "x")
449− jsres <- cgForeignRes b $ JsCurryApp (JsCurryApp f [jsx]) [JsNull]
509+ jsres <- cgForeignRes b $ jsCurryApp (jsCurryApp f [jsx]) [JsNull]
450 pure $ JsLambda ["x"] $ JsReturn jsres
510 pure $ JsLambda ["x"] $ JsReturn jsres
451cgForeignArg (desc, _) =
511cgForeignArg (desc, _) =
453 st <- get
513 st <- get
454 error $ "Foreign arg type " ++ show desc ++ " not supported. While generating function " ++ (show $ fst $ currentFnNameAndArgs st)
514 error $ "Foreign arg type " ++ show desc ++ " not supported. While generating function " ++ (show $ fst $ currentFnNameAndArgs st)
456−cgForeignRes :: FDesc -> JsAST -> State CGBodyState JsAST
516+cgForeignRes :: FDesc -> JsExpr -> State CGBodyState JsExpr
457cgForeignRes (FApp (UN "JS_IntT") _) x = pure x
517cgForeignRes (FApp (UN "JS_IntT") _) x = pure x
458cgForeignRes (FCon (UN "JS_Unit")) x = pure x
518cgForeignRes (FCon (UN "JS_Unit")) x = pure x
459cgForeignRes (FCon (UN "JS_Str")) x = pure x
519cgForeignRes (FCon (UN "JS_Str")) x = pure x
@@ -468,7 +528,7 @@ setUsedITBig :: State CGBodyState ()
468setUsedITBig = modify (\s -> s {usedITBig = True})
528setUsedITBig = modify (\s -> s {usedITBig = True})
471−cgConst :: Const -> State CGBodyState JsAST
531+cgConst :: Const -> State CGBodyState JsExpr
472cgConst (I i) = pure $ JsInt i
532cgConst (I i) = pure $ JsInt i
473cgConst (BI i) =
533cgConst (BI i) =
@@ -476,7 +536,7 @@ cgConst (BI i) =
476 pure $ JsForeign "new jsbn.BigInteger(%0)" [JsStr $ show i]
536 pure $ JsForeign "new jsbn.BigInteger(%0)" [JsStr $ show i]
477cgConst (Ch c) = pure $ JsStr [c]
537cgConst (Ch c) = pure $ JsStr [c]
478cgConst (Str s) = pure $ JsStr s
538cgConst (Str s) = pure $ JsStr s
479−cgConst (Fl f) = pure $ JsNum f
539+cgConst (Fl f) = pure $ JsDouble f
480cgConst (B8 x) = pure $ JsForeign (T.pack $ show x ++ " & 0xFF") []
540cgConst (B8 x) = pure $ JsForeign (T.pack $ show x ++ " & 0xFF") []
481cgConst (B16 x) = pure $ JsForeign (T.pack $ show x ++ " & 0xFFFF") []
541cgConst (B16 x) = pure $ JsForeign (T.pack $ show x ++ " & 0xFFFF") []
482cgConst (B32 x) = pure $ JsForeign (T.pack $ show x ++ "|0" ) []
542cgConst (B32 x) = pure $ JsForeign (T.pack $ show x ++ "|0" ) []
@@ -487,327 +547,10 @@ cgConst (B64 x) =
487cgConst x | isTypeConst x = pure $ JsInt 0
547cgConst x | isTypeConst x = pure $ JsInt 0
488cgConst x = error $ "Constant " ++ show x ++ " not compilable yet"
548cgConst x = error $ "Constant " ++ show x ++ " not compilable yet"
490−jsB2I :: JsAST -> JsAST
550+jsB2I :: JsExpr -> JsExpr
491jsB2I x = JsForeign "%0 ? 1|0 : 0|0" [x]
551jsB2I x = JsForeign "%0 ? 1|0 : 0|0" [x]
493−cgOp :: PrimFn -> [JsAST] -> State CGBodyState JsAST
553+cgOp :: PrimFn -> [JsExpr] -> State CGBodyState JsExpr
494−cgOp (LPlus ATFloat) [l, r] = pure $ JsBinOp "+" l r
495−cgOp (LPlus (ATInt ITChar)) [l, r] = pure $ JsForeign "String.fromCharCode(%0.charCodeAt(0) + %1.charCodeAt(0))" [l,r]
496−cgOp (LPlus (ATInt ITNative)) [l, r] = pure $ JsForeign "%0+%1|0" [l,r]
497−cgOp (LPlus (ATInt (ITFixed IT8))) [l, r] = pure $ JsForeign "%0 + %1 & 0xFF" [l,r]
498−cgOp (LPlus (ATInt (ITFixed IT16))) [l, r] = pure $ JsForeign "%0 + %1 & 0xFFFF" [l,r]
499−cgOp (LPlus (ATInt (ITFixed IT32))) [l, r] = pure $ JsForeign "%0+%1|0" [l,r]
500−cgOp (LPlus (ATInt ITBig)) [l, r] =
503− pure $ JsMethod l "add" [r]
504−cgOp (LPlus (ATInt (ITFixed IT64))) [l, r] =
507− pure $ JsForeign "%0.add(%1).and(new jsbn.BigInteger(%2))" [l,r, JsStr $ show 0xFFFFFFFFFFFFFFFF]
508−cgOp (LMinus ATFloat) [l, r] = pure $ JsBinOp "-" l r
509−cgOp (LMinus (ATInt ITChar)) [l, r] = pure $ JsForeign "String.fromCharCode(%0.charCodeAt(0) - %1.charCodeAt(0))" [l,r]
510−cgOp (LMinus (ATInt ITNative)) [l, r] = pure $ JsForeign "%0-%1|0" [l,r]
511−cgOp (LMinus (ATInt (ITFixed IT8))) [l, r] = pure $ JsForeign "%0 - %1 & 0xFF" [l,r]
512−cgOp (LMinus (ATInt (ITFixed IT16))) [l, r] = pure $ JsForeign "%0 - %1 & 0xFFFF" [l,r]
513−cgOp (LMinus (ATInt (ITFixed IT32))) [l, r] = pure $ JsForeign "%0-%1|0" [l,r]
514−cgOp (LMinus (ATInt ITBig)) [l, r] =
517− pure $ JsMethod l "subtract" [r]
518−cgOp (LMinus (ATInt (ITFixed IT64))) [l, r] =
521− pure $ JsForeign "%0.subtract(%1).and(new jsbn.BigInteger(%2))" [l,r, JsStr $ show 0xFFFFFFFFFFFFFFFF]
522−cgOp (LTimes ATFloat) [l, r] = pure $ JsBinOp "*" l r
523−cgOp (LTimes (ATInt ITChar)) [l, r] = pure $ JsForeign "String.fromCharCode(%0.charCodeAt(0) * %1.charCodeAt(0))" [l,r]
524−cgOp (LTimes (ATInt ITNative)) [l, r] = pure $ JsForeign "%0*%1|0" [l,r]
525−cgOp (LTimes (ATInt (ITFixed IT8))) [l, r] = pure $ JsForeign "%0 * %1 & 0xFF" [l,r]
526−cgOp (LTimes (ATInt (ITFixed IT16))) [l, r] = pure $ JsForeign "%0 * %1 & 0xFFFF" [l,r]
527−cgOp (LTimes (ATInt (ITFixed IT32))) [l, r] = pure $ JsForeign "%0*%1|0" [l,r]
528−cgOp (LTimes (ATInt ITBig)) [l, r] =
531− pure $ JsMethod l "multiply" [r]
532−cgOp (LTimes (ATInt (ITFixed IT64))) [l, r] =
535− pure $ JsForeign "%0.multiply(%1).and(new jsbn.BigInteger(%2))" [l,r, JsStr $ show 0xFFFFFFFFFFFFFFFF]
536−cgOp (LUDiv (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 / %1" [l,r]
537−cgOp (LUDiv (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 / %1" [l,r]
538−cgOp (LUDiv (ITFixed IT32)) [l, r] = pure $ JsForeign "(%0>>>0) / (%1>>>0) |0" [l,r]
539−cgOp (LUDiv (ITFixed IT64)) [l, r] =
542− pure $ JsForeign "%0.divide(%1)" [l,r]
543−cgOp (LSDiv ATFloat) [l,r] = pure $ JsBinOp "/" l r
544−cgOp (LSDiv (ATInt (ITFixed IT8))) [l, r] = pure $ JsForeign "%0 / %1" [l,r]
545−cgOp (LSDiv (ATInt (ITFixed IT16))) [l, r] = pure $ JsForeign "%0 / %1" [l,r]
546−cgOp (LSDiv (ATInt (ITFixed IT32))) [l, r] = pure $ JsForeign "%0 / %1 |0" [l,r]
547−cgOp (LSDiv (ATInt (ITFixed IT64))) [l, r] =
550− pure $ JsForeign "%0.divide(%1)" [l,r]
551−cgOp (LSDiv (ATInt ITNative)) [l,r] = pure $ JsForeign "%0/%1|0" [l, r]
552−cgOp (LSDiv (ATInt ITBig)) [l,r] =
555− pure $ JsMethod l "divide" [r]
556−cgOp (LURem (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 % %1" [l,r]
557−cgOp (LURem (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 % %1" [l,r]
558−cgOp (LURem (ITFixed IT32)) [l, r] = pure $ JsForeign "(%0>>>0) % (%1>>>0) |0" [l,r]
559−cgOp (LURem (ITFixed IT64)) [l,r] =
562− pure $ JsMethod l "remainder" [r]
563−cgOp (LSRem ATFloat) [l,r] = pure $ JsBinOp "%" l r
564−cgOp (LSRem (ATInt ITNative)) [l,r] = pure $ JsForeign "%0 % %1 |0" [l,r]
565−cgOp (LSRem (ATInt (ITFixed IT8))) [l, r] = pure $ JsForeign "%0 % %1" [l,r]
566−cgOp (LSRem (ATInt (ITFixed IT16))) [l, r] = pure $ JsForeign "%0 % %1" [l,r]
567−cgOp (LSRem (ATInt (ITFixed IT32))) [l, r] = pure $ JsForeign "%0 % %1 |0" [l,r]
568−cgOp (LSRem (ATInt (ITFixed IT64))) [l, r] =
571− pure $ JsMethod l "remainder" [r]
572−cgOp (LSRem (ATInt ITBig)) [l,r] =
575− pure $ JsMethod l "remainder" [r]
576−cgOp (LAnd ITNative) [l, r] = pure $ JsForeign "%0 & %1" [l,r]
577−cgOp (LAnd (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 & %1" [l,r]
578−cgOp (LAnd (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 & %1" [l,r]
579−cgOp (LAnd (ITFixed IT32)) [l, r] = pure $ JsForeign "%0 & %1" [l,r]
580−cgOp (LAnd (ITFixed IT64)) [l,r] =
583− pure $ JsMethod l "and" [r]
584−cgOp (LAnd ITBig) [l,r] =
587− pure $ JsMethod l "and" [r]
588−cgOp (LOr ITNative) [l, r] = pure $ JsForeign "%0 | %1" [l,r]
589−cgOp (LOr (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 | %1" [l,r]
590−cgOp (LOr (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 | %1" [l,r]
591−cgOp (LOr (ITFixed IT32)) [l, r] = pure $ JsForeign "%0 | %1" [l,r]
592−cgOp (LOr (ITFixed IT64)) [l,r] =
595− pure $ JsMethod l "or" [r]
596−cgOp (LOr ITBig) [l,r] =
599− pure $ JsMethod l "or" [r]
600−cgOp (LXOr ITNative) [l, r] = pure $ JsForeign "%0 ^ %1" [l,r]
601−cgOp (LXOr (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 ^ %1" [l,r]
602−cgOp (LXOr (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 ^ %1" [l,r]
603−cgOp (LXOr (ITFixed IT32)) [l, r] = pure $ JsForeign "%0 ^ %1" [l,r]
604−cgOp (LXOr (ITFixed IT64)) [l,r] =
607− pure $ JsMethod l "xor" [r]
608−cgOp (LXOr ITBig) [l,r] =
611− pure $ JsMethod l "xor" [r]
612−cgOp (LSHL ITNative) [l, r] = pure $ JsForeign "%0 << %1 |0" [l,r]
613−cgOp (LSHL (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 << %1 & 0xFF" [l,r]
614−cgOp (LSHL (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 << %1 & 0xFFFF" [l,r]
615−cgOp (LSHL (ITFixed IT32)) [l, r] = pure $ JsForeign "%0 << %1 |0" [l,r]
616−cgOp (LSHL (ITFixed IT64)) [l, r] =
619− pure $ JsForeign "%0.shiftLeft(%1).and(new jsbn.BigInteger(%2))" [l,r, JsStr $ show 0xFFFFFFFFFFFFFFFF]
620−cgOp (LSHL ITBig) [l,r] =
623− pure $ JsMethod l "shiftLeft" [r]
624−cgOp (LLSHR ITNative) [l, r] = pure $ JsForeign "%0 >> %1 |0" [l,r]
625−cgOp (LLSHR (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 >> %1" [l,r]
626−cgOp (LLSHR (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 >> %1" [l,r]
627−cgOp (LLSHR (ITFixed IT32)) [l, r] = pure $ JsForeign "%0 >> %1|0" [l,r]
628−cgOp (LLSHR (ITFixed IT64)) [l, r] =
631− pure $ JsForeign "%0.shiftRight(%1)" [l,r]
632−cgOp (LASHR ITNative) [l, r] = pure $ JsForeign "%0 >> %1 |0" [l,r]
633−cgOp (LASHR (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 >> %1" [l,r]
634−cgOp (LASHR (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 >> %1" [l,r]
635−cgOp (LASHR (ITFixed IT32)) [l, r] = pure $ JsForeign "%0 >> %1|0" [l,r]
636−cgOp (LASHR (ITFixed IT64)) [l, r] =
639− pure $ JsForeign "%0.shiftRight(%1)" [l,r]
640−cgOp (LEq ATFloat) [l, r] = pure $ jsB2I $ JsBinOp "==" l r
641−cgOp (LEq (ATInt ITNative)) [l, r] = pure $ jsB2I $ JsBinOp "==" l r
642−cgOp (LEq (ATInt ITChar)) [l,r] = pure $ jsB2I $ JsBinOp "==" l r
643−cgOp (LEq (ATInt ITBig)) [l, r] =
646− pure $ jsB2I $ JsMethod l "equals" [r]
647−cgOp (LEq (ATInt (ITFixed IT8))) [l, r] = pure $ jsB2I $ JsBinOp "==" l r
648−cgOp (LEq (ATInt (ITFixed IT16))) [l, r] = pure $ jsB2I $ JsBinOp "==" l r
649−cgOp (LEq (ATInt (ITFixed IT32))) [l, r] = pure $ jsB2I $ JsBinOp "==" l r
650−cgOp (LEq (ATInt (ITFixed IT64))) [l, r] =
653− pure $ jsB2I $ JsMethod l "equals" [r]
654−cgOp (LLt (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 < %1" [l,r]
655−cgOp (LLt (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 < %1" [l,r]
656−cgOp (LLt (ITFixed IT32)) [l, r] = pure $ JsForeign "(%0>>>0) < (%1>>>0)" [l,r]
657−cgOp (LLt (ITFixed IT64)) [l, r] =
660− pure $ jsB2I $ JsForeign "%0.compareTo(%1) < 0" [l,r]
661−cgOp (LLe (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 <= %1" [l,r]
662−cgOp (LLe (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 <= %1" [l,r]
663−cgOp (LLe (ITFixed IT32)) [l, r] = pure $ JsForeign "(%0>>>0) <= (%1>>>0)" [l,r]
664−cgOp (LLe (ITFixed IT64)) [l, r] =
667− pure $ jsB2I $ JsForeign "%0.compareTo(%1) <= 0" [l,r]
668−cgOp (LGt (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 > %1" [l,r]
669−cgOp (LGt (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 > %1" [l,r]
670−cgOp (LGt (ITFixed IT32)) [l, r] = pure $ JsForeign "(%0>>>0) > (%1>>>0)" [l,r]
671−cgOp (LGt (ITFixed IT64)) [l, r] =
674− pure $ jsB2I $ JsForeign "%0.compareTo(%1) > 0" [l,r]
675−cgOp (LGe (ITFixed IT8)) [l, r] = pure $ JsForeign "%0 >= %1" [l,r]
676−cgOp (LGe (ITFixed IT16)) [l, r] = pure $ JsForeign "%0 >= %1" [l,r]
677−cgOp (LGe (ITFixed IT32)) [l, r] = pure $ JsForeign "(%0>>>0) >= (%1>>>0)" [l,r]
678−cgOp (LGe (ITFixed IT64)) [l, r] =
681− pure $ jsB2I $ JsForeign "%0.compareTo(%1) >= 0" [l,r]
682−cgOp (LSLt ATFloat) [l, r] = pure $ jsB2I $ JsBinOp "<" l r
683−cgOp (LSLt (ATInt ITChar)) [l, r] = pure $ jsB2I $ JsBinOp "<" l r
684−cgOp (LSLt (ATInt ITNative)) [l, r] = pure $ jsB2I $ JsBinOp "<" l r
685−cgOp (LSLt (ATInt ITBig)) [l, r] =
688− pure $ jsB2I $ JsForeign "%0.compareTo(%1) < 0" [l,r]
689−cgOp (LSLt (ATInt (ITFixed IT8))) [l, r] = pure $ jsB2I $ JsBinOp "<" l r
690−cgOp (LSLt (ATInt (ITFixed IT16))) [l, r] = pure $ jsB2I $ JsBinOp "<" l r
691−cgOp (LSLt (ATInt (ITFixed IT32))) [l, r] = pure $ jsB2I $ JsBinOp "<" l r
692−cgOp (LSLt (ATInt (ITFixed IT64))) [l, r] =
695− pure $ jsB2I $ JsForeign "%0.compareTo(%1) < 0" [l,r]
696−cgOp (LSLe ATFloat) [l, r] = pure $ jsB2I $ JsBinOp "<=" l r
697−cgOp (LSLe (ATInt ITNative)) [l, r] = pure $ jsB2I $ JsBinOp "<=" l r
698−cgOp (LSLe (ATInt ITBig)) [l, r] =
701− pure $ jsB2I $ JsForeign "%0.compareTo(%1) <= 0" [l,r]
702−cgOp (LSLe (ATInt (ITFixed IT8))) [l, r] = pure $ jsB2I $ JsBinOp "<=" l r
703−cgOp (LSLe (ATInt (ITFixed IT16))) [l, r] = pure $ jsB2I $ JsBinOp "<=" l r
704−cgOp (LSLe (ATInt (ITFixed IT32))) [l, r] = pure $ jsB2I $ JsBinOp "<=" l r
705−cgOp (LSLe (ATInt (ITFixed IT64))) [l, r] =
708− pure $ jsB2I $ JsForeign "%0.compareTo(%1) <= 0" [l,r]
709−cgOp (LSGt ATFloat) [l, r] = pure $ jsB2I $ JsBinOp ">" l r
710−cgOp (LSGt (ATInt ITNative)) [l, r] = pure $ jsB2I $ JsBinOp ">" l r
711−cgOp (LSGt (ATInt ITBig)) [l, r] =
714− pure $ jsB2I $ JsForeign "%0.compareTo(%1) > 0" [l,r]
715−cgOp (LSGt (ATInt (ITFixed IT8))) [l, r] = pure $ jsB2I $ JsBinOp ">" l r
716−cgOp (LSGt (ATInt (ITFixed IT16))) [l, r] = pure $ jsB2I $ JsBinOp ">" l r
717−cgOp (LSGt (ATInt (ITFixed IT32))) [l, r] = pure $ jsB2I $ JsBinOp ">" l r
718−cgOp (LSGt (ATInt (ITFixed IT64))) [l, r] =
721− pure $ jsB2I $ JsForeign "%0.compareTo(%1) > 0" [l,r]
722−cgOp (LSGe ATFloat) [l, r] = pure $ jsB2I $ JsBinOp ">=" l r
723−cgOp (LSGe (ATInt ITNative)) [l, r] = pure $ jsB2I $ JsBinOp ">=" l r
724−cgOp (LSGe (ATInt ITBig)) [l, r] =
727− pure $ jsB2I $ JsForeign "%0.compareTo(%1) >= 0" [l,r]
728−cgOp (LSGe (ATInt (ITFixed IT8))) [l, r] = pure $ jsB2I $ JsBinOp ">=" l r
729−cgOp (LSGe (ATInt (ITFixed IT16))) [l, r] = pure $ jsB2I $ JsBinOp ">=" l r
730−cgOp (LSGe (ATInt (ITFixed IT32))) [l, r] = pure $ jsB2I $ JsBinOp ">=" l r
731−cgOp (LSGe (ATInt (ITFixed IT64))) [l, r] =
734− pure $ jsB2I $ JsForeign "%0.compareTo(%1) >= 0" [l,r]
735−cgOp (LSExt ITNative ITBig) [x] =
738− pure $ JsForeign "new jsbn.BigInteger(String(%0))" [x]
739−cgOp (LZExt (ITFixed IT8) ITNative) [x] = pure x
740−cgOp (LZExt (ITFixed IT16) ITNative) [x] = pure x
741−cgOp (LZExt (ITFixed IT32) ITNative) [x] = pure x
742−cgOp (LZExt ITNative ITBig) [x] =
745− pure $ JsForeign "new jsbn.BigInteger(String(%0))" [x]
746−cgOp (LTrunc ITBig ITNative) [x] =
749− pure $ JsForeign "%0.intValue()|0" [x]
750−cgOp (LTrunc (ITFixed IT16) (ITFixed IT8)) [x] = pure $ JsForeign "%0 & 0xFF" [x]
751−cgOp (LTrunc (ITFixed IT32) (ITFixed IT8)) [x] = pure $ JsForeign "%0 & 0xFF" [x]
752−cgOp (LTrunc (ITFixed IT64) (ITFixed IT8)) [x] =
755− pure $ JsForeign "%0.intValue() & 0xFF" [x]
756−cgOp (LTrunc (ITFixed IT32) (ITFixed IT16)) [x] = pure $ JsForeign "%0 & 0xFFFF" [x]
757−cgOp (LTrunc (ITFixed IT64) (ITFixed IT16)) [x] =
760− pure $ JsForeign "%0.intValue() & 0xFFFF" [x]
761−cgOp (LTrunc (ITFixed IT64) (ITFixed IT32)) [x] =
764− pure $ JsForeign "%0.intValue() & 0xFFFFFFFF" [x]
765−cgOp (LTrunc ITBig (ITFixed IT64)) [x] =
768− pure $ JsForeign "%0.and(new jsbn.BigInteger(%1))" [x, JsStr $ show 0xFFFFFFFFFFFFFFFF]
769−cgOp LStrConcat [l,r] = pure $ JsBinOp "+" l r
770−cgOp LStrLt [l, r] = pure $ jsB2I $ JsBinOp "<" l r
771−cgOp LStrEq [l,r] = pure $ jsB2I $ JsBinOp "==" l r
772−cgOp LStrLen [x] = pure $ JsForeign "%0.length" [x]
773−cgOp (LIntFloat ITNative) [x] = pure $ x
774−cgOp (LIntFloat ITBig) [x] =
777− pure $ JsForeign "%0.intValue()" [x]
778−cgOp (LFloatInt ITNative) [x] = pure $ JsForeign "%0|0" [x]
779−cgOp (LIntStr ITNative) [x] = pure $ JsApp "String" [x]
780−cgOp (LIntStr ITBig) [x] =
783− pure $ JsForeign "%0.toString()" [x]
784−cgOp (LStrInt ITNative) [x] = pure $ JsForeign "parseInt(%0)|0" [x]
785−cgOp (LStrInt ITBig) [x] =
788− pure $ JsForeign "new jsbn.BigInteger(%0)" [x]
789−cgOp (LFloatStr) [x] = pure $ JsApp "String" [x]
790−cgOp (LStrFloat) [x] = pure $ JsApp "parseFloat" [x]
791−cgOp (LChInt ITNative) [x] = pure $ JsForeign "%0.charCodeAt(0)|0" [x]
792−cgOp (LIntCh ITNative) [x] = pure $ JsApp "String.fromCharCode" [x]
793−cgOp LFExp [x] = pure $ JsApp "Math.exp" [x]
794−cgOp LFLog [x] = pure $ JsApp "Math.log" [x]
795−cgOp LFSin [x] = pure $ JsApp "Math.sin" [x]
796−cgOp LFCos [x] = pure $ JsApp "Math.cos" [x]
797−cgOp LFTan [x] = pure $ JsApp "Math.tan" [x]
798−cgOp LFASin [x] = pure $ JsApp "Math.asin" [x]
799−cgOp LFACos [x] = pure $ JsApp "Math.acos" [x]
800−cgOp LFATan [x] = pure $ JsApp "Math.atan" [x]
801−cgOp LFSqrt [x] = pure $ JsApp "Math.sqrt" [x]
802−cgOp LFFloor [x] = pure $ JsApp "Math.floor" [x]
803−cgOp LFCeil [x] = pure $ JsApp "Math.ceil" [x]
804−cgOp LFNegate [x] = pure $ JsForeign "-%0" [x]
805−cgOp LStrHead [x] = pure $ JsArrayProj (JsInt 0) x
806−cgOp LStrTail [x] = pure $ JsMethod x "slice" [JsInt 1]
807−cgOp LStrCons [l,r] = pure $ JsForeign "%0+%1" [l,r]
808−cgOp LStrIndex [x, y] = pure $ JsArrayProj y x
809−cgOp LStrRev [x] = pure $ JsForeign "%0.split('').reverse().join('')" [x]
810−cgOp LStrSubstr [offset,len,str] = pure $ JsForeign "%0.substr(Math.max(0,%1), Math.max(0, %2))" [str, offset, len]
811cgOp LReadStr [_] =
554cgOp LReadStr [_] =
@@ -818,9 +561,10 @@ cgOp LWriteStr [_,str] =
819 put $ s {usedWrite = True}
562 put $ s {usedWrite = True}
820 pure $ JsForeign (writeStrTemplate $ conf s) [str]
563 pure $ JsForeign (writeStrTemplate $ conf s) [str]
821−cgOp LSystemInfo [x] = pure $ JsApp "js_idris_systemInfo" [x]
822cgOp (LExternal name) _ | name == sUN "prim__null" = pure JsNull
564cgOp (LExternal name) _ | name == sUN "prim__null" = pure JsNull
823cgOp (LExternal name) [l,r] | name == sUN "prim__eqPtr" = pure $ JsBinOp "==" l r
565cgOp (LExternal name) [l,r] | name == sUN "prim__eqPtr" = pure $ JsBinOp "==" l r
824−cgOp LCrash [l] = pure $ JsErrorExp l
566+cgOp op exps = case Map.lookup op primDB of
825−cgOp LNoOp [x] = pure x
567+ Just (useBigInt, pti, combinator) -> do
568+ when useBigInt setUsedITBig
569+ pure $ jsPrimCoerce pti PTAny $ combinator exps
826−cgOp op exps = error ("Operator " ++ show (op, exps) ++ " not implemented")
570+ Nothing -> error ("Operator " ++ show (op, exps) ++ " not implemented")