@@ -16,10 +16,14 @@ import Idris.Core.TT
1616import IRTS.CodegenCommon
1717import IRTS.JavaScript.AST
1818import IRTS.JavaScript.LangTransforms
19+import IRTS.JavaScript.Name
20+import IRTS.JavaScript.PrimOp
21+import IRTS.JavaScript.Specialize
1922import IRTS.Lang
2023import IRTS.LangOpts
2124import IRTS.System
2225
26+import Control.Monad
2327import Control.Monad.Trans.State
2428import Data.List (nub)
2529import Data.Map.Strict (Map)
@@ -41,8 +45,6 @@ import Data.Generics.Uniplate.Data
4145import Data.List
4246import GHC.Generics (Generic)
4347
44−data Partial = Partial Name Int Int deriving (Eq, Ord)
45−
4648data CGStats = CGStats { usedWriteStr :: Bool
4749 , usedReadStr :: Bool
4850 , usedBigInt :: Bool
@@ -57,6 +59,7 @@ data CGConf = CGConf { header :: Text
5759 , initialization :: CGStats -> Text
5860 , writeStrTemplate :: Text
5961 , readStrTemplate :: Text
62+ , jsbnPath :: String
6063 , extraRunTime :: String
6164 }
6265
@@ -96,7 +99,7 @@ codegenJs conf ci =
9699
97100 path <- getIdrisJSRTSDir
98101 jsbn <- if usedBigInt stats
99− then TIO.readFile $ path </> "jsbn/jsbn.js"
102+ then TIO.readFile $ path </> jsbnPath conf
100103 else return ""
101104
102105 runtimeCommon <- TIO.readFile $ path </> "Runtime-common.js"
@@ -119,17 +122,6 @@ codegenJs conf ci =
119122 , footer conf
120123 ]
121124
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) ++ "_"
126−
127−jsPartialName :: Partial -> Text
128−jsPartialName (Partial n i j) = T.concat ["partial_", T.pack $ show i, "_", T.pack $ show j, "_" , jsName n]
129−
130−jsTailCallOptimName :: Text -> Text
131−jsTailCallOptimName x = T.concat ["tailCallOptim_cgIdris_", x]
132−
133125doPartials :: Set Partial -> Text
134126doPartials x =
135127 T.intercalate "\n" (map f $ Set.toList x)
@@ -137,8 +129,9 @@ doPartials x =
137129 f p@(Partial n i j) =
138130 let vars1 = map (T.pack . ("x"++) . show) [1..i]
139131 vars2 = map (T.pack . ("x"++) . show) [(i+1)..j]
140− in jsAst2Text $
141− JsFun (jsPartialName p) vars1 $ JsReturn $ JsCurryLambda vars2 (JsApp (jsName n) (map JsVar (vars1 ++ vars2)) )
132+ in jsStmt2Text $
133+ JsFun (jsNamePartial p) vars1 $ JsReturn $
134+ jsCurryLam vars2 (jsAppN (jsName n) (map JsVar (vars1 ++ vars2)) )
142135
143136doCodegen :: CGConf -> Map Name LDecl -> [LDecl] -> (Text, CGStats)
144137doCodegen conf defs decls =
@@ -153,17 +146,17 @@ doCodegen conf defs decls =
153146doCodegenDecl :: CGConf -> Map Name LDecl -> LDecl -> (Text, CGStats)
154147doCodegenDecl conf defs (LFun _ n args def) =
155148 let (ast, stats) = cgFun conf defs n args def
156− in (jsAst2Text $ ast, stats)
157−doCodegenDecl conf defs (LConstructor n i sz) =
158− ("", emptyStats)
149+ in (jsStmt2Text $ ast, stats)
150+doCodegenDecl conf defs (LConstructor n i sz) = ("", emptyStats)
159151
160−seqJs :: [JsAST] -> JsAST
152+seqJs :: [JsStmt] -> JsStmt
161153seqJs [] = JsEmpty
162154seqJs (x:xs) = JsSeq x (seqJs xs)
163155
164156
165157data CGBodyState = CGBodyState { defs :: Map Name LDecl
166158 , lastIntName :: Int
159+ , reWrittenNames :: Map.Map Name JsExpr
167160 , currentFnNameAndArgs :: (Text, [Text])
168161 , usedArgsTailCallOptim :: Set (Text, Text)
169162 , isTailRec :: Bool
@@ -180,7 +173,7 @@ getNewCGName =
180173 st <- get
181174 let v = lastIntName st + 1
182175 put $ st {lastIntName = v}
183− return $ T.pack $ "cgIdris_" ++ show v
176+ return $ jsNameGenerated v
184177
185178addPartial :: Partial -> State CGBodyState ()
186179addPartial p =
@@ -194,12 +187,12 @@ getNewCGNames :: Int -> State CGBodyState [Text]
194187getNewCGNames n =
195188 mapM (\_ -> getNewCGName) [1..n]
196189
197−getConsId :: Name -> State CGBodyState Int
190+getConsId :: Name -> State CGBodyState (Int, Int)
198191getConsId n =
199192 do
200193 st <- get
201194 case Map.lookup n (defs st) of
202− Just (LConstructor _ conId _) -> pure conId
195+ Just (LConstructor _ conId arity) -> pure (conId, arity)
203196 _ -> error $ "Internal JS Backend error " ++ showCG n ++ " is not a constructor."
204197
205198getArgList :: Name -> State CGBodyState (Maybe [Name])
@@ -216,26 +209,15 @@ data BodyResTarget = ReturnBT
216209 | DecConstBT Text
217210 | GetExpBT
218211
219−replaceVarsByProj :: JsAST -> Map Text Int -> JsAST -> JsAST
220−replaceVarsByProj n d z =
221− transform f z
222− where
223− f :: JsAST -> JsAST
224− f (JsVar x) =
225− case Map.lookup x d of
226− Nothing -> (JsVar x)
227− Just i -> JsArrayProj (JsInt i) n
228− f x = x
229−
230−cgFun :: CGConf -> Map Name LDecl -> Name -> [Name] -> LExp -> (JsAST, CGStats)
231−cgFun cnf dfs n args def =
232− let
233− fnName = jsName n
234− argNames = map jsName args
235− ((decs, res),st) = runState
212+cgFun :: CGConf -> Map Name LDecl -> Name -> [Name] -> LExp -> (JsStmt, CGStats)
213+cgFun cnf dfs n args def = do
214+ let fnName = jsName n
215+ let argNames = map jsName args
216+ let ((decs, res),st) = runState
236217 (cgBody ReturnBT def)
237218 (CGBodyState { defs=dfs
238219 , lastIntName = 0
220+ , reWrittenNames = Map.empty
239221 , currentFnNameAndArgs = (fnName, argNames)
240222 , usedArgsTailCallOptim = Set.empty
241223 , isTailRec = False
@@ -246,19 +228,16 @@ cgFun cnf dfs n args def =
246228 , partialApps = Set.empty
247229 }
248230 )
249− body = if isTailRec st then
250− JsSeq
251− (declareUsedOptimArgs $ usedArgsTailCallOptim st)
252− (JsWhileTrue ((seqJs decs) `JsSeq` res))
253− else (seqJs decs) `JsSeq` res
254− in (JsFun fnName argNames $ body, CGStats { usedWriteStr = usedWrite st
255− , partialApplications = partialApps st
256− , usedBigInt = usedITBig st
257− , usedReadStr = usedRead st
258− }
259− )
260−
261−getSwitchJs :: JsAST -> [LAlt] -> JsAST
231+ let body = if isTailRec st then JsSeq (declareUsedOptimArgs $ usedArgsTailCallOptim st) (JsForever ((seqJs decs) `JsSeq` res)) else (seqJs decs) `JsSeq` res
232+ let fn = JsFun fnName argNames body
233+ let state' = CGStats { usedWriteStr = usedWrite st
234+ , partialApplications = partialApps st
235+ , usedBigInt = usedITBig st
236+ , usedReadStr = usedRead st
237+ }
238+ (fn, state')
239+
240+getSwitchJs :: JsExpr -> [LAlt] -> JsExpr
262241getSwitchJs x alts =
263242 if any conCase alts then JsArrayProj (JsInt 0) x
264243 else if any constBigIntCase alts then JsForeign "%0.toString()" [x]
@@ -268,48 +247,75 @@ getSwitchJs x alts =
268247 constBigIntCase (LConstCase (BI _) _) = True
269248 constBigIntCase _ = False
270249
271−addRT :: BodyResTarget -> JsAST -> JsAST
250+addRT :: BodyResTarget -> JsExpr -> JsStmt
272251addRT ReturnBT x = JsReturn x
273−addRT (DecBT n) x = JsLet n x
274−addRT (SetBT n) x = JsSetVar n x
275−addRT (DecConstBT n) x = JsConst n x
276−addRT GetExpBT x = x
252+addRT (DecBT n) x = JsDecLet n x
253+addRT (DecConstBT n) x = JsDecConst n x
254+addRT (SetBT n) x = JsSet (JsVar n) x
255+addRT GetExpBT x = JsExprStmt x
277256
278−declareUsedOptimArgs :: Set (Text, Text) -> JsAST
279−declareUsedOptimArgs x = seqJs $ map (\(x,y) -> JsLet x (JsVar y) ) (Set.toList x)
257+declareUsedOptimArgs :: Set (Text, Text) -> JsStmt
258+declareUsedOptimArgs x = seqJs $ map (\(x,y) -> JsDecLet x (JsVar y) ) (Set.toList x)
280259
281−tailCallOptimRefreshArgs :: [(Text, JsAST)] -> Set Text -> ((JsAST, JsAST), Set (Text, Text))
260+tailCallOptimRefreshArgs :: [(Text, JsExpr)] -> Set Text -> ((JsStmt, JsStmt), Set (Text, Text))
282261tailCallOptimRefreshArgs [] s = ((JsEmpty, JsEmpty), Set.empty)
283262tailCallOptimRefreshArgs ((n,x):r) s =
284263 let ((y1,y2), y3) = tailCallOptimRefreshArgs r (Set.insert n s) --
285264 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)
287266 else
288267 let n' = jsTailCallOptimName n
289− in ((JsSetVar n' x `JsSeq` y1, JsSetVar n (JsVar n') `JsSeq` y2), Set.insert (n',n) y3)
290−
291−
292−cgBody :: BodyResTarget -> LExp -> State CGBodyState ([JsAST], JsAST)
293−cgBody rt (LV (Glob n)) =
268+ in ((jsSetVar n' x `JsSeq` y1, jsSetVar n (JsVar n') `JsSeq` y2), Set.insert (n',n) y3)
269+
270+cgName :: Name -> State CGBodyState JsExpr
271+cgName b = do
272+ st <- get
273+ case Map.lookup b (reWrittenNames st) of
274+ Just e -> pure e
275+ _ -> pure $ JsVar $ jsName b
276+
277+cgBody :: BodyResTarget -> LExp -> State CGBodyState ([JsStmt], JsStmt)
278+cgBody rt expr =
279+ case expr of
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
295+
296+cgBody' :: BodyResTarget -> LExp -> State CGBodyState ([JsStmt], JsStmt)
297+cgBody' rt (LV (Glob n)) =
294298 do
295299 argsFn <- getArgList n
296300 case argsFn of
297− Just [] ->
298− pure $ ([], addRT rt $ JsApp (jsName n) [])
301+ Just [] -> do
302+ n' <- cgName n
303+ pure $ ([], addRT rt n')
299304 Just a ->
300305 do
301− let part = Partial n 0 (length a)
306+ let part = Partial n 0 (length a)
302307 addPartial part
303− pure ([], addRT rt $ JsApp (jsPartialName part) [])
304− Nothing ->
305− pure $ ([], addRT rt $ JsVar $ jsName n)
306−cgBody rt (LApp tailcall (LV (Glob fn)) args) =
308+ pure ([], addRT rt $ jsAppN (jsNamePartial part) [])
309+ Nothing -> do
310+ n' <- cgName n
311+ pure $ ([], addRT rt n')
312+cgBody' rt (LApp tailcall (LV (Glob fn)) args) =
307313 do
308314 let fname = jsName fn
309315 st <- get
310316 let (currFn, argN) = currentFnNameAndArgs st
311317 z <- mapM (cgBody GetExpBT) args
312− let argVals = map snd z
318+ let argVals = map (jsStmt2Expr . snd) z
313319 let preDecs = concat $ map fst z
314320 case (fname == currFn && (length args) == (length argN), rt) of
315321 (True, ReturnBT) ->
@@ -323,81 +329,86 @@ cgBody rt (LApp tailcall (LV (Glob fn)) args) =
323329 argsFn <- getArgList fn
324330 case argsFn of
325331 Nothing ->
326− pure (preDecs, addRT rt $ JsCurryApp (JsVar fname) argVals )
332+ pure (preDecs, addRT rt $ jsCurryApp (JsVar fname) argVals )
327333 Just agFn ->
328334 do
329335 let lenAgFn = length agFn
330336 let lenArgs = length args
331337 case compare lenAgFn lenArgs of
332338 EQ ->
333− pure (preDecs, addRT rt $ JsApp fname argVals)
339+ pure (preDecs, addRT rt $ jsAppN fname argVals)
334340 LT ->
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) )
336342 GT ->
337343 do
338344 let part = Partial fn lenArgs lenAgFn
339345 addPartial part
340− pure (preDecs, addRT rt $ JsApp (jsPartialName part) argVals )
346+ pure (preDecs, addRT rt $ jsAppN (jsNamePartial part) argVals )
341347
342−cgBody rt (LForce (LLazyApp n args)) = cgBody rt (LApp False (LV (Glob n)) args)
343−cgBody rt (LLazyApp n args) =
348+cgBody' rt (LForce (LLazyApp n args)) = cgBody rt (LApp False (LV (Glob n)) args)
349+cgBody' rt (LLazyApp n args) =
344350 do
345351 (d,v) <- cgBody ReturnBT (LApp False (LV (Glob n)) args)
346− pure ([], addRT rt $ JsLazy $ JsSeq (seqJs d) v)
347−cgBody rt (LForce e) =
352+ pure ([], addRT rt $ jsLazy $ jsStmt2Expr $ JsSeq (seqJs d) v)
353+cgBody' rt (LForce e) =
348354 do
349355 (d,v) <- cgBody GetExpBT e
350− pure (d, addRT rt $ JsForce v)
351−cgBody rt (LLet n v sc) =
356+ pure (d, addRT rt $ JsForce $ jsStmt2Expr v)
357+cgBody' rt (LLet n v sc) =
352358 do
353359 (d1, v1) <- cgBody (DecConstBT $ jsName n) v
354360 (d2, v2) <- cgBody rt sc
355− pure $ ((d1 ++ v1 : d2), v2 )
356−cgBody rt (LProj e i) =
361+ pure $ ((d1 ++ v1 : d2), v2)
362+cgBody' rt (LProj e i) =
357363 do
358364 (d, v) <- cgBody GetExpBT e
359− pure $ (d, addRT rt $ JsArrayProj (JsInt $ i+1) $ v)
360−cgBody rt (LCon _ conId n args) =
365+ pure $ (d, addRT rt $ JsArrayProj (JsInt $ i+1) $ jsStmt2Expr v)
366+cgBody' rt (LCon _ conId n args) =
361367 do
362368 z <- mapM (cgBody GetExpBT) args
363− pure $ (concat $ map fst z, addRT rt $ JsArray (JsInt conId : map snd z))
364−cgBody rt (LCase _ e alts) =
365− do
366− (d,v) <- cgBody GetExpBT e
367− resName <- getNewCGName
368− swName <- getNewCGName
369− (altsJs,def) <- cgAlts rt resName (JsVar swName) alts
370− let decSw = JsConst swName v
371− let sw = JsSwitchCase (getSwitchJs (JsVar swName) alts) altsJs def
372− case rt of
373− ReturnBT ->
374− pure (d ++ [decSw], sw)
375− (DecBT nvar) ->
376− pure (d ++ [decSw, JsLet nvar JsNull], sw)
377− (SetBT nvar) ->
378− pure (d ++ [decSw], sw)
379− GetExpBT ->
380− pure (d ++ [decSw, JsLet resName JsNull, sw], JsVar resName)
381− (DecConstBT nvar) ->
382− pure (d ++ [decSw, JsLet nvar JsNull], sw)
383−cgBody rt (LConst c) =
369+ con <- formCon n (map (jsStmt2Expr . snd) z)
370+ pure $ (concat $ map fst z, addRT rt con)
371+cgBody' rt (LCase _ e alts) = do
372+ (d, v) <- cgBody GetExpBT e
373+ resName <- getNewCGName
374+ (decSw, entry) <-
375+ case (all altHasNoProj alts && length alts <= 2, v) of
376+ (True, _) -> pure (JsEmpty, jsStmt2Expr v)
377+ (False, JsExprStmt (JsVar n)) -> pure (JsEmpty, jsStmt2Expr v)
378+ _ -> do
379+ swName <- getNewCGName
380+ pure (JsDecConst swName $ jsStmt2Expr v, JsVar swName)
381+ sw' <- cgIfTree rt resName entry alts
382+ let sw =
383+ case sw' of
384+ (Just x) -> x
385+ Nothing -> JsExprStmt JsNull
386+ case rt of
387+ ReturnBT -> pure (d ++ [decSw], sw)
388+ (DecBT nvar) -> pure (d ++ [decSw, JsDecLet nvar JsNull], sw)
389+ (DecConstBT nvar) -> pure (d ++ [decSw, JsDecLet nvar JsNull], sw)
390+ (SetBT nvar) -> pure (d ++ [decSw], sw)
391+ GetExpBT ->
392+ pure
393+ (d ++ [decSw, JsDecLet resName JsNull, sw], JsExprStmt $ JsVar resName)
394+cgBody' rt (LConst c) =
384395 do
385396 cst <- cgConst c
386397 pure ([], (addRT rt) $ cst)
387−cgBody rt (LOp op args) =
398+cgBody' rt (LOp op args) =
388399 do
389400 z <- mapM (cgBody GetExpBT) args
390− res <- cgOp op (map snd z)
401+ res <- cgOp op (map (jsStmt2Expr . snd) z)
391402 pure $ (concat $ map fst z, addRT rt $ res)
392−cgBody rt LNothing = pure ([], addRT rt JsNull)
393−cgBody rt (LError x) = pure ([], JsError $ JsStr x)
394−cgBody rt x@(LForeign dres (FStr code) args ) =
403+cgBody' rt LNothing = pure ([], addRT rt JsNull)
404+cgBody' rt (LError x) = pure ([], JsError $ JsStr x)
405+cgBody' rt x@(LForeign dres (FStr code) args ) =
395406 do
396407 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))
398409 jsDres <- cgForeignRes dres $ JsForeign (T.pack code) jsArgs
399410 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"
401412
402413altsRT :: Text -> BodyResTarget -> BodyResTarget
403414altsRT rn ReturnBT = ReturnBT
@@ -406,36 +417,85 @@ altsRT rn (SetBT n) = SetBT n
406417altsRT rn (DecConstBT n) = SetBT n
407418altsRT rn GetExpBT = SetBT rn
408419
409−cgAlts :: BodyResTarget -> Text -> JsAST -> [LAlt] -> State CGBodyState ([(JsAST, JsAST)], Maybe JsAST)
410−cgAlts rt resName scrvar ((LConstCase t exp):r) =
411− do
412− (d, v) <- cgBody (altsRT resName rt) exp
413− (ar, def) <- cgAlts rt resName scrvar r
414− cst <- case t of
415− BI _ ->
416− do
417− setUsedITBig
418− c' <- cgConst t
419− pure $ JsForeign "%0.toString()" [c']
420− _ -> cgConst t
421− pure ((cst, JsSeq (seqJs d) v) : ar, def)
422−cgAlts rt resName scrvar ((LDefaultCase exp):r) =
423− do
424− (d, v) <- cgBody (altsRT resName rt) exp
425− pure ([], Just $ JsSeq (seqJs d) v)
426−cgAlts rt resName scrvar ((LConCase _ n args exp):r) =
427− do
428− (d, v) <- cgBody (altsRT resName rt) exp
429− (ar, def) <- cgAlts rt resName scrvar r
430− conId <- getConsId n
431− let replace = replaceVarsByProj scrvar (Map.fromList $ zip (map jsName args) [1..])
432− let branchBody = JsSeq (seqJs $ map replace d) (replace v)
433− pure ((JsInt conId, branchBody) : ar, def)
434−cgAlts _ _ _ [] =
435− pure ([],Nothing)
436−
437−
438−cgForeignArg :: (FDesc, JsAST) -> State CGBodyState JsAST
420+altHasNoProj :: LAlt -> Bool
421+altHasNoProj (LConCase _ _ args _) = args == []
422+altHasNoProj _ = True
423+
424+formCon :: Name -> [JsExpr] -> State CGBodyState JsExpr
425+formCon n args = do
426+ case specialCased n of
427+ Just (ctor, test, match) -> pure $ ctor args
428+ Nothing -> do
429+ (conId, arity) <- getConsId n
430+ if (arity > 0)
431+ then pure $
432+ JsObj $
433+ (T.pack "type", JsInt conId) :
434+ zip (map (\i -> T.pack $ "$" ++ show i) [1 ..]) args
435+ else pure $ JsInt conId
436+
437+formConTest :: Name -> JsExpr -> State CGBodyState JsExpr
438+formConTest n x = do
439+ case specialCased n of
440+ Just (ctor, test, match) -> pure $ test x
441+ Nothing -> do
442+ (conId, arity) <- getConsId n
443+ if (arity > 0)
444+ then pure $ JsBinOp "===" (JsProp x (T.pack "type")) (JsInt conId)
445+ else pure $ JsBinOp "===" x (JsInt conId)
446+
447+formProj :: Name -> JsExpr -> Int -> JsExpr
448+formProj n v i =
449+ case specialCased n of
450+ Just (ctor, test, proj) -> proj v i
451+ Nothing -> JsProp v (T.pack $ "$" ++ show i)
452+
453+smartif :: JsExpr -> JsStmt -> Maybe JsStmt -> JsStmt
454+smartif cond conseq (Just alt) = JsIf cond conseq (Just alt)
455+smartif cond conseq Nothing = conseq
456+
457+cgIfTree :: BodyResTarget
458+ -> Text
459+ -> JsExpr
460+ -> [LAlt]
461+ -> State CGBodyState (Maybe JsStmt)
462+cgIfTree _ _ _ [] = pure Nothing
463+cgIfTree rt resName scrvar ((LConstCase t exp):r) = do
464+ (d, v) <- cgBody (altsRT resName rt) exp
465+ alternatives <- cgIfTree rt resName scrvar r
466+ test <- case t of
467+ BI _ -> do
468+ t' <- cgConst t
469+ cgOp (LPlus (ATInt ITBig)) [scrvar, t']
470+ _ -> do
471+ t' <- cgConst t
472+ pure $ JsBinOp "===" scrvar t'
473+ pure $ Just $
474+ smartif test (JsSeq (seqJs d) v) alternatives
475+cgIfTree rt resName scrvar ((LDefaultCase exp):r) = do
476+ (d, v) <- cgBody (altsRT resName rt) exp
477+ pure $ Just $ JsSeq (seqJs d) v
478+cgIfTree rt resName scrvar ((LConCase _ n args exp):r) = do
479+ alternatives <- cgIfTree rt resName scrvar r
480+ test <- formConTest n scrvar
481+ st <- get
482+ let rwn = reWrittenNames st
483+ put $
484+ st
485+ { reWrittenNames =
486+ foldl
487+ (\m (n, j) -> Map.insert n (formProj n scrvar j) m)
488+ rwn
489+ (zip args [1 ..])
490+ }
491+ (d, v) <- cgBody (altsRT resName rt) exp
492+ st1 <- get
493+ put $ st1 {reWrittenNames = rwn}
494+ let branchBody = JsSeq (seqJs d) v
495+ pure $ Just $ smartif test branchBody alternatives
496+
497+
498+cgForeignArg :: (FDesc, JsExpr) -> State CGBodyState JsExpr
439499cgForeignArg (FApp (UN "JS_IntT") _, v) = pure v
440500cgForeignArg (FCon (UN "JS_Str"), v) = pure v
441501cgForeignArg (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
446506cgForeignArg (FApp (UN "JS_FnT") [_,FApp (UN "JS_Fn") [_,_, a, FApp (UN "JS_FnIO") [_,_, b]]], f) =
447507 do
448508 jsx <- cgForeignArg (a, JsVar "x")
449− jsres <- cgForeignRes b $ JsCurryApp (JsCurryApp f [jsx]) [JsNull]
509+ jsres <- cgForeignRes b $ jsCurryApp (jsCurryApp f [jsx]) [JsNull]
450510 pure $ JsLambda ["x"] $ JsReturn jsres
451511cgForeignArg (desc, _) =
452512 do
453513 st <- get
454514 error $ "Foreign arg type " ++ show desc ++ " not supported. While generating function " ++ (show $ fst $ currentFnNameAndArgs st)
455515
456−cgForeignRes :: FDesc -> JsAST -> State CGBodyState JsAST
516+cgForeignRes :: FDesc -> JsExpr -> State CGBodyState JsExpr
457517cgForeignRes (FApp (UN "JS_IntT") _) x = pure x
458518cgForeignRes (FCon (UN "JS_Unit")) x = pure x
459519cgForeignRes (FCon (UN "JS_Str")) x = pure x
@@ -468,7 +528,7 @@ setUsedITBig :: State CGBodyState ()
468528setUsedITBig = modify (\s -> s {usedITBig = True})
469529
470530
471−cgConst :: Const -> State CGBodyState JsAST
531+cgConst :: Const -> State CGBodyState JsExpr
472532cgConst (I i) = pure $ JsInt i
473533cgConst (BI i) =
474534 do
@@ -476,7 +536,7 @@ cgConst (BI i) =
476536 pure $ JsForeign "new jsbn.BigInteger(%0)" [JsStr $ show i]
477537cgConst (Ch c) = pure $ JsStr [c]
478538cgConst (Str s) = pure $ JsStr s
479−cgConst (Fl f) = pure $ JsNum f
539+cgConst (Fl f) = pure $ JsDouble f
480540cgConst (B8 x) = pure $ JsForeign (T.pack $ show x ++ " & 0xFF") []
481541cgConst (B16 x) = pure $ JsForeign (T.pack $ show x ++ " & 0xFFFF") []
482542cgConst (B32 x) = pure $ JsForeign (T.pack $ show x ++ "|0" ) []
@@ -487,327 +547,10 @@ cgConst (B64 x) =
487547cgConst x | isTypeConst x = pure $ JsInt 0
488548cgConst x = error $ "Constant " ++ show x ++ " not compilable yet"
489549
490−jsB2I :: JsAST -> JsAST
550+jsB2I :: JsExpr -> JsExpr
491551jsB2I x = JsForeign "%0 ? 1|0 : 0|0" [x]
492552
493−cgOp :: PrimFn -> [JsAST] -> State CGBodyState JsAST
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] =
501− do
502− setUsedITBig
503− pure $ JsMethod l "add" [r]
504−cgOp (LPlus (ATInt (ITFixed IT64))) [l, r] =
505− do
506− setUsedITBig
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] =
515− do
516− setUsedITBig
517− pure $ JsMethod l "subtract" [r]
518−cgOp (LMinus (ATInt (ITFixed IT64))) [l, r] =
519− do
520− setUsedITBig
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] =
529− do
530− setUsedITBig
531− pure $ JsMethod l "multiply" [r]
532−cgOp (LTimes (ATInt (ITFixed IT64))) [l, r] =
533− do
534− setUsedITBig
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] =
540− do
541− setUsedITBig
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] =
548− do
549− setUsedITBig
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] =
553− do
554− setUsedITBig
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] =
560− do
561− setUsedITBig
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] =
569− do
570− setUsedITBig
571− pure $ JsMethod l "remainder" [r]
572−cgOp (LSRem (ATInt ITBig)) [l,r] =
573− do
574− setUsedITBig
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] =
581− do
582− setUsedITBig
583− pure $ JsMethod l "and" [r]
584−cgOp (LAnd ITBig) [l,r] =
585− do
586− setUsedITBig
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] =
593− do
594− setUsedITBig
595− pure $ JsMethod l "or" [r]
596−cgOp (LOr ITBig) [l,r] =
597− do
598− setUsedITBig
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] =
605− do
606− setUsedITBig
607− pure $ JsMethod l "xor" [r]
608−cgOp (LXOr ITBig) [l,r] =
609− do
610− setUsedITBig
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] =
617− do
618− setUsedITBig
619− pure $ JsForeign "%0.shiftLeft(%1).and(new jsbn.BigInteger(%2))" [l,r, JsStr $ show 0xFFFFFFFFFFFFFFFF]
620−cgOp (LSHL ITBig) [l,r] =
621− do
622− setUsedITBig
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] =
629− do
630− setUsedITBig
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] =
637− do
638− setUsedITBig
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] =
644− do
645− setUsedITBig
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] =
651− do
652− setUsedITBig
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] =
658− do
659− setUsedITBig
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] =
665− do
666− setUsedITBig
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] =
672− do
673− setUsedITBig
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] =
679− do
680− setUsedITBig
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] =
686− do
687− setUsedITBig
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] =
693− do
694− setUsedITBig
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] =
699− do
700− setUsedITBig
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] =
706− do
707− setUsedITBig
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] =
712− do
713− setUsedITBig
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] =
719− do
720− setUsedITBig
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] =
725− do
726− setUsedITBig
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] =
732− do
733− setUsedITBig
734− pure $ jsB2I $ JsForeign "%0.compareTo(%1) >= 0" [l,r]
735−cgOp (LSExt ITNative ITBig) [x] =
736− do
737− setUsedITBig
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] =
743− do
744− setUsedITBig
745− pure $ JsForeign "new jsbn.BigInteger(String(%0))" [x]
746−cgOp (LTrunc ITBig ITNative) [x] =
747− do
748− setUsedITBig
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] =
753− do
754− setUsedITBig
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] =
758− do
759− setUsedITBig
760− pure $ JsForeign "%0.intValue() & 0xFFFF" [x]
761−cgOp (LTrunc (ITFixed IT64) (ITFixed IT32)) [x] =
762− do
763− setUsedITBig
764− pure $ JsForeign "%0.intValue() & 0xFFFFFFFF" [x]
765−cgOp (LTrunc ITBig (ITFixed IT64)) [x] =
766− do
767− setUsedITBig
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] =
775− do
776− setUsedITBig
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] =
781− do
782− setUsedITBig
783− pure $ JsForeign "%0.toString()" [x]
784−cgOp (LStrInt ITNative) [x] = pure $ JsForeign "parseInt(%0)|0" [x]
785−cgOp (LStrInt ITBig) [x] =
786− do
787− setUsedITBig
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]
553+cgOp :: PrimFn -> [JsExpr] -> State CGBodyState JsExpr
811554cgOp LReadStr [_] =
812555 do
813556 s <- get
@@ -818,9 +561,10 @@ cgOp LWriteStr [_,str] =
818561 s <- get
819562 put $ s {usedWrite = True}
820563 pure $ JsForeign (writeStrTemplate $ conf s) [str]
821−cgOp LSystemInfo [x] = pure $ JsApp "js_idris_systemInfo" [x]
822564cgOp (LExternal name) _ | name == sUN "prim__null" = pure JsNull
823565cgOp (LExternal name) [l,r] | name == sUN "prim__eqPtr" = pure $ JsBinOp "==" l r
824−cgOp LCrash [l] = pure $ JsErrorExp l
825−cgOp LNoOp [x] = pure x
826−cgOp op exps = error ("Operator " ++ show (op, exps) ++ " not implemented")
566+cgOp op exps = case Map.lookup op primDB of
567+ Just (useBigInt, pti, combinator) -> do
568+ when useBigInt setUsedITBig
569+ pure $ jsPrimCoerce pti PTAny $ combinator exps
570+ Nothing -> error ("Operator " ++ show (op, exps) ++ " not implemented")