jacinda-2.0.2.0: src/Jacinda/Backend/P.hs
{-# LANGUAGE OverloadedStrings #-}
module Jacinda.Backend.P ( EvalErr (..), runJac, eB ) where
import A
import A.I
import Control.Exception (Exception, throw)
import Control.Monad (foldM, (<=<))
import Control.Monad.State.Strict (State, evalState, get, modify, runState)
import Data.Bifunctor (bimap)
import qualified Data.ByteString as BS
import Data.Containers.ListUtils (nubOrdOn)
import Data.Foldable (traverse_)
import qualified Data.IntMap as IM
import Data.List (scanl', transpose, uncons, unzip4)
import Data.Maybe (catMaybes, mapMaybe)
import qualified Data.Vector as V
import Data.Word (Word8)
import Foreign.C.String (CString)
import Jacinda.Backend.Const
import Jacinda.Backend.Parse
import Jacinda.Backend.Printf
import Jacinda.Fuse
import Jacinda.Regex
import Nm
import Prettyprinter (hardline, pretty)
import Prettyprinter.Render.Text (putDoc)
import Regex.Rure (RureMatch (RureMatch), RurePtr)
import System.IO (hFlush, stdout)
import System.IO.Unsafe (unsafeDupablePerformIO)
import Ty.Const
import U
φ1 :: E T -> Int
φ1 (BB (TyArr _ (TyArr (TyB TyStream:$_) _)) Fold1) = 1
φ1 (EApp _ e0 e1) = φ1 e0+φ1 e1
φ1 (Tup _ es) = sum (φ1<$>es)
φ1 (OptionVal _ (Just e)) = φ1 e
φ1 (Cond _ p e0 e1) = φ1 p+φ1 e0+φ1 e1
φ1 (Lam _ _ e) = φ1 e
φ1 _ = 0
φ :: E T -> Int
φ (TB (TyArr _ (TyArr _ (TyArr (TyB TyStream:$_) _))) Fold) = 1
φ (EApp _ e0 e1) = φ e0+φ e1
φ (Tup _ es) = sum (φ<$>es)
φ (OptionVal _ (Just e)) = φ e
φ (Cond _ p e0 e1) = φ p+φ e0+φ e1
φ (Lam _ _ e) = φ e
φ _ = 0
noleak :: E T -> Bool
noleak e = φ e > 1 && φ1 e < 1
runJac :: RurePtr -- ^ Record separator
-> Bool -- ^ Flush output?
-> Int
-> E T
-> Either StreamError ([BS.ByteString] -> IO ())
runJac re f i e = ϝ (bsProcess re f) (if noleak e then fuse i e else (e, i)) where ϝ = uncurry.flip
data StreamError = NakedField deriving (Show)
instance Exception StreamError where
data EvalErr = EmptyFold
| IndexOutOfBounds Int
| InternalCoercionError (E T) TB
| ExpectedTup (E T)
| BadHole (Nm T)
deriving (Show)
instance Exception EvalErr where
(!) :: V.Vector a -> Int -> a
v ! ix = case v V.!? ix of {Just x -> x; Nothing -> throw $ IndexOutOfBounds ix}
parseAsEInt :: BS.ByteString -> E T
parseAsEInt = mkI.readDigits
parseAsF :: BS.ByteString -> E T
parseAsF = mkF.readFloat
readFloat :: BS.ByteString -> Double
readFloat = unsafeDupablePerformIO . (`BS.useAsCString` atof)
foreign import ccall unsafe atof :: CString -> IO Double
the :: BS.ByteString -> Word8
the bs = case BS.uncons bs of
Nothing -> error "Empty splitc char!"
Just (c,b) | BS.null b -> c
Just _ -> error "Splitc takes only one char!"
asTup :: Maybe RureMatch -> E T
asTup Nothing = OptionVal undefined Nothing
asTup (Just (RureMatch s e)) = OptionVal undefined (Just (Tup undefined (mkI . fromIntegral <$> [s, e])))
mkFoldVar :: Int -> b -> E b
mkFoldVar i l = Var l (Nm "fold_placeholder" (U i) l)
takeConcatMap :: (a -> [b]) -> [a] -> [b]
takeConcatMap f = concat . transpose . fmap f
-- this relies on all streams being the same length stream which in turn relies
-- on the fuse step (fold-of-filter->fold)
foldAll :: Int -> RurePtr -> [(Int, E T, E T, E T)] -> [BS.ByteString] -> ([(Int, E T)], Int)
foldAll i r xs bs = runState (foldMultiple seeds streams ctxStream ixStream) i
where (ns, ops, seeds, es) = unzip4 xs
mkStream e = eStream i r e bs
streams = mkStream<$>es
ctxStream = [(b, splitBy r b) | b <- bs]
ixStream = [1..]
foldMultiple seedsϵ esϵ (ctx:ctxes) (ix:ixes) = allHeads esϵ `seq` do {es' <- sequence$zipWith3 (c2Mϵ (pure.eCtx ctx ix)) ops seedsϵ (head<$>esϵ); foldMultiple es' (tail<$>esϵ) ctxes ixes}
-- TODO: sanity check same length all streams
foldMultiple seedsϵ _ [] _ = pure$zip ns seedsϵ
allHeads = foldr seq ()
gf :: E T -> State (Int, [(Int, E T, E T, E T)]) (E T)
gf (EApp _ (EApp _ (EApp _ (TB _ Fold) op) seed) stream) | t@(TyB TyStream:$_) <- eLoc stream = do
(i,_) <- get
modify (bimap (+1) ((i, op, seed, stream) :))
pure $ mkFoldVar i t
gf (EApp ty e0 e1) = EApp ty <$> gf e0 <*> gf e1
gf (Tup ty es) = Tup ty <$> traverse gf es
gf (Arr ty es) = Arr ty <$> traverse gf es
gf (OptionVal ty e) = OptionVal ty <$> traverse gf e
gf (Cond ty p e e') = Cond ty <$> gf p <*> gf e <*> gf e'
gf (Lam t n e) = Lam t n <$> gf e
gf e@BB{} = pure e; gf e@TB{} = pure e; gf e@UB{} = pure e; gf e@NB{} = pure e
gf e@Lit{} = pure e
gf e@RC{} = pure e; gf e@Var{} = pure e
ug :: IM.IntMap (E T) -> E T -> E T
ug st (Var _ n@(Nm _ (U i) _)) =
IM.findWithDefault (throw (BadHole n)) i st
ug _ e = e
bsProcess :: RurePtr
-> Bool -- ^ Flush output?
-> Int -- ^ Unique context
-> E T
-> Either StreamError ([BS.ByteString] -> IO ())
bsProcess _ _ _ AllField{} = Left NakedField
bsProcess _ _ _ Field{} = Left NakedField
bsProcess _ _ _ (NB _ Ix) = Left NakedField
bsProcess r f u e | (TyB TyStream:$_) <- eLoc e = Right (pS f.eStream u r e)
bsProcess r f u (Anchor _ es) = Right (\bs -> pS f $ takeConcatMap (\e -> eStream u r e bs) es)
bsProcess r _ u e =
Right $ \bs -> pDocLn (eF u r e bs)
pDocLn = putDoc.(<>hardline).pretty
pS p = traverse_ g where g | p = (*>fflush).pDocLn | otherwise = pDocLn
fflush = hFlush stdout
scanM :: Monad m => (b -> a -> m b) -> b -> [a] -> m [b]
scanM op seed xs = sequence $
scanl' go (pure seed) xs where go seedϵ x = do {seedϵ' <- seedϵ; op seedϵ' x}
eF :: Int -> RurePtr -> E T -> [BS.ByteString] -> E T
eF u r e | noleak e = \bs ->
let (eHoley, (_, folds)) = runState (gf e) (0, [])
(filledHoles, u') = foldAll u r folds bs
in eB u' (pure.ug (IM.fromList filledHoles)) eHoley
| otherwise = \bs ->
eB u (go bs) e
where go bb (EApp _ (EApp _ (EApp _ (TB _ Fold) op) seed) xs) = do
op' <- eBM pure op
seed' <- eBM pure seed
let xsϵ=eStream u r xs bb
foldM (c2M op') seed' xsϵ
go bb (EApp _ (EApp _ (BB _ Fold1) op) xs) = do
op' <- eBM pure op
let (seed',xsϵ)=case uncons $ eStream u r xs bb of {Just s -> s; Nothing -> throw EmptyFold}
foldM (c2M op') seed' xsϵ
go _ eϵ = pure eϵ
a1 :: E T -> E T -> UM (E T)
a1 f x | TyArr _ cod <- eLoc f = lβ (EApp cod f x)
a2 :: E T -> E T -> E T -> UM (E T)
a2 op x0 x1 | TyArr _ t@(TyArr _ t') <- eLoc op = lβ (EApp t' (EApp t op x0) x1)
c1 :: Int -> E T -> E T -> E T
c1 i f x = evalState (eBM pure =<< a1 f x) i
c2M op x0 x1 = eBM pure =<< a2 op x0 x1
c2Mϵ f g e e' = eBM f =<< a2 g e e'
c2 :: Int -> E T -> E T -> E T -> E T
c2 i op x0 x1 = evalState (c2M op x0 x1) i
eStream :: Int -> RurePtr -> E T -> [BS.ByteString] -> [E T]
eStream u r (EApp _ (EApp _ (EApp _ (TB _ Scan) op) seed) xs) bs =
let op'=eB u pure op; seed'=eB u pure seed; xsϵ=eStream u r xs bs
in evalState (scanM (c2M op') seed' xsϵ) u
eStream i r (EApp _ (UB _ CatMaybes) e) bs = mapMaybe asM$eStream i r e bs
eStream u r (Implicit _ e) bs = zipWith (\fs i -> eB u (pure.eCtx fs i) e) [(b, splitBy r b) | b <- bs] [1..]
eStream _ _ AllColumn{} bs = mkStr<$>bs
eStream _ _ IParseAllCol{} bs = parseAsEInt<$>bs
eStream _ _ FParseAllCol{} bs = parseAsF<$>bs
eStream _ _ (ParseAllCol (_:$TyB TyInteger)) bs = parseAsEInt<$>bs
eStream _ _ (ParseAllCol (_:$TyB TyFloat)) bs = parseAsF<$>bs
eStream _ r (Column _ i) bs = mkStr.(! (i-1)).splitBy r<$>bs
eStream _ r (IParseCol _ n) bs = [parseAsEInt (splitBy r b ! (n-1)) | b <- bs]
eStream _ r (ParseCol (_:$TyB TyInteger) n) bs = [parseAsEInt (splitBy r b ! (n-1)) | b <- bs]
eStream _ r (FParseCol _ n) bs = [parseAsF (splitBy r b ! (n-1)) | b <- bs]
eStream _ r (ParseCol (_:$TyB TyFloat) n) bs = [parseAsF (splitBy r b ! (n-1)) | b <- bs]
eStream i r (EApp _ (EApp _ (BB _ MapMaybe) f) e) bs = let xs = eStream i r e bs in mapMaybe (asM.c1 i f) xs
eStream i r (EApp _ (EApp _ (BB _ Map) f) e) bs = let xs=eStream i r e bs in fmap (c1 i f) xs
eStream i r (EApp _ (EApp _ (BB _ Prior) op) e) bs = let xs=eStream i r e bs in zipWith (c2 i op) (tail xs) xs
eStream i r (EApp _ (EApp _ (BB _ Filter) p) e) bs = let xs=eStream i r e bs; ps=fmap (asB.c1 i p) xs in [x | (pϵ,x) <- zip ps xs, pϵ]
eStream i r (EApp _ (EApp _ (EApp _ (TB _ ZipW) f) e0) e1) bs = let xs0=eStream i r e0 bs; xs1=eStream i r e1 bs in zipWith (c2 i f) xs0 xs1
eStream i r (EApp (_:$TyB TyStr) (UB _ Dedup) e) bs = let s = eStream i r e bs in nubOrdOn asS s
eStream i r (EApp (_:$TyB TyInteger) (UB _ Dedup) e) bs = let s = eStream i r e bs in nubOrdOn asI s
eStream i r (EApp (_:$TyB TyFloat) (UB _ Dedup) e) bs = let s = eStream i r e bs in nubOrdOn asF s
eStream i r (EApp _ (EApp _ (BB _ DedupOn) op) e) bs | TyArr _ (TyB TyStr) <- eLoc op = let xs = eStream i r e bs in nubOrdOn (asS.c1 i op) xs
eStream i r (EApp _ (EApp _ (BB _ DedupOn) op) e) bs | TyArr _ (TyB TyInteger) <- eLoc op = let xs = eStream i r e bs in nubOrdOn (asI.c1 i op) xs
eStream i r (EApp _ (EApp _ (BB _ DedupOn) op) e) bs | TyArr _ (TyB TyFloat) <- eLoc op = let xs = eStream i r e bs in nubOrdOn (asF.c1 i op) xs
eStream u r (Guarded _ p e) bs =
let bss=(\b -> (b, splitBy r b))<$>bs
in catMaybes $ zipWith (\fs i -> if asB (eB u (pure.eCtx fs i) p) then Just (eB u (pure.eCtx fs i) e) else Nothing) bss [1..]
asS :: E T -> BS.ByteString
asS (Lit _ (StrLit s)) = s; asS e = throw (InternalCoercionError e TyStr)
asI :: E T -> Integer
asI (Lit _ (ILit i)) = i; asI e = throw (InternalCoercionError e TyInteger)
asF :: E T -> Double
asF (Lit _ (FLit x)) = x; asF e = throw (InternalCoercionError e TyFloat)
asR :: E T -> RurePtr
asR (RC r) = r; asR e = throw (InternalCoercionError e TyR)
asM :: E T -> Maybe (E T)
asM (OptionVal _ e) = e; asM e = throw (InternalCoercionError e TyOption)
asB :: E T -> Bool
asB (Lit _ (BLit b)) = b; asB e = throw (InternalCoercionError e TyBool)
asV :: E T -> V.Vector (E T)
asV (Arr _ v) = v; asV e = throw (InternalCoercionError e TyVec)
asT :: E T -> [E T]
asT (Tup _ es) = es; asT e = throw (ExpectedTup e)
vS :: V.Vector BS.ByteString -> E T
vS = Arr (tyV tyStr).fmap mkStr
eCtx :: (BS.ByteString, V.Vector BS.ByteString) -- ^ Line, split by field separator
-> Integer -- ^ Line number
-> E T -> E T
eCtx ~(f, _) _ AllField{} = mkStr f
eCtx (_, fs) _ (Field _ i) = mkStr (fs ! (i-1))
eCtx (_, fs) _ LastField{} = mkStr (V.last fs)
eCtx (_, fs) _ FieldList{} = vS fs
eCtx _ i (NB _ Ix) = mkI i
eCtx (_, fs) _ (NB _ Nf) = mkI (fromIntegral$V.length fs)
eCtx _ _ e = e
eB :: Int -> (E T -> UM (E T)) -> E T -> E T
eB i f x = evalState (eBM f x) i
{-# SCC eBM #-}
eBM :: (E T -> UM (E T)) -> E T -> UM (E T)
eBM f (EApp t (EApp _ (EApp _ (TB _ Captures) s) i) r) = do
s' <- eBM f s; i' <- eBM f i; r' <- eBM f r
pure $ OptionVal t (mkStr <$> findCapture (asR r') (asS s') (fromIntegral$asI i'))
eBM f (EApp t (EApp _ (EApp _ (TB _ AllCaptures) s) i) r) = do
s' <- eBM f s; i' <- eBM f i; r' <- eBM f r
pure $ Arr t (V.fromList (mkStr <$> captures' (asR r') (asS s') (fromIntegral$asI i')))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Max) x0) x1) = do
x0' <- asI<$>eBM f x0; x1' <- asI<$>eBM f x1
pure (mkI (max x0' x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Min) x0) x1) = do
x0' <- asI<$>eBM f x0; x1' <- asI<$>eBM f x1
pure (mkI (min x0' x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Min) x0) x1) = do
x0' <- asF<$>eBM f x0; x1' <- asF<$>eBM f x1
pure (mkF (min x0' x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Max) x0) x1) = do
x0' <- asF<$>eBM f x0; x1' <- asF<$>eBM f x1
pure (mkF (max x0' x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Min) x0) x1) = do
x0' <- asS<$>eBM f x0; x1' <- asS<$>eBM f x1
pure (mkStr (min x0' x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Max) x0) x1) = do
x0' <- asS<$>eBM f x0; x1' <- asS<$>eBM f x1
pure (mkStr (max x0' x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Plus) x0) x1) = do
x0' <- asI <$> eBM f x0; x1' <- asI<$>eBM f x1
pure (mkI (x0'+x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Minus) x0) x1) = do
x0' <- asI <$> eBM f x0; x1' <- asI<$>eBM f x1
pure (mkI (x0'-x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Times) x0) x1) = do
x0' <- asI <$> eBM f x0; x1' <- asI<$>eBM f x1
pure (mkI (x0'*x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Plus) x0) x1) = do
x0' <- asF <$> eBM f x0; x1' <- asF<$>eBM f x1
pure (mkF (x0'+x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Minus) x0) x1) = do
x0' <- asF <$> eBM f x0; x1' <- asF<$>eBM f x1
pure (mkF (x0'-x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Times) x0) x1) = do
x0' <- asF <$> eBM f x0; x1' <- asF<$>eBM f x1
pure (mkF (x0'*x1'))
eBM f (EApp _ (EApp _ (BB _ Div) x0) x1) = do
x0' <- asF <$> eBM f x0; x1' <- asF<$>eBM f x1
pure (mkF (x0'/x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Eq) x0) x1) = do
x0' <- asI<$>eBM f x0; x1' <- asI<$>eBM f x1
pure (mkB (x0'==x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Neq) x0) x1) = do
x0' <- asI<$>eBM f x0; x1' <- asI<$>eBM f x1
pure (mkB (x0'/=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Gt) x0) x1) = do
x0' <- asI<$>eBM f x0; x1' <- asI<$>eBM f x1
pure (mkB (x0'>x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Lt) x0) x1) = do
x0' <- asI<$>eBM f x0; x1' <- asI<$>eBM f x1
pure (mkB (x0'<x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Leq) x0) x1) = do
x0' <- asI<$>eBM f x0; x1' <- asI<$>eBM f x1
pure (mkB (x0'<=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Geq) x0) x1) = do
x0' <- asI<$>eBM f x0; x1' <- asI<$>eBM f x1
pure (mkB (x0'>=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Gt) x0) x1) = do
x0' <- asF<$>eBM f x0; x1' <- asF<$>eBM f x1
pure (mkB (x0'>x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Lt) x0) x1) = do
x0' <- asF<$>eBM f x0; x1' <- asF<$>eBM f x1
pure (mkB (x0'<x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Eq) x0) x1) = do
x0' <- asF<$>eBM f x0; x1' <- asF<$>eBM f x1
pure (mkB (x0'==x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Neq) x0) x1) = do
x0' <- asF<$>eBM f x0; x1' <- asF<$>eBM f x1
pure (mkB (x0'/=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Geq) x0) x1) = do
x0' <- asF<$>eBM f x0; x1' <- asF<$>eBM f x1
pure (mkB (x0'>=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Leq) x0) x1) = do
x0' <- asF<$>eBM f x0; x1' <- asF<$>eBM f x1
pure (mkB (x0'<=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Eq) x0) x1) = do
x0' <- asS<$>eBM f x0; x1' <- asS<$>eBM f x1
pure (mkB (x0'==x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Neq) x0) x1) = do
x0' <- asS<$>eBM f x0; x1' <- asS<$>eBM f x1
pure (mkB (x0'/=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Gt) x0) x1) = do
x0' <- asS<$>eBM f x0; x1' <- asS<$>eBM f x1
pure (mkB (x0'>x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Geq) x0) x1) = do
x0' <- asS<$>eBM f x0; x1' <- asS<$>eBM f x1
pure (mkB (x0'>=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Lt) x0) x1) = do
x0' <- asS<$>eBM f x0; x1' <- asS<$>eBM f x1
pure (mkB (x0'<x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Leq) x0) x1) = do
x0' <- asS<$>eBM f x0; x1' <- asS<$>eBM f x1
pure (mkB (x0'<=x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyInteger) _) Exp) x0) x1) = do
x0' <- asI <$> eBM f x0; x1' <- asI<$>eBM f x1
pure (mkI (x0'^x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyFloat) _) Exp) x0) x1) = do
x0' <- asF <$> eBM f x0; x1' <- asF<$>eBM f x1
pure (mkF (x0'**x1'))
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyVec:$t) _) Eq) x0) x1) = do
x0' <- asV<$>eBM f x0; x1' <- asV<$>eBM f x1
mkB <$> if V.length x0'==V.length x1'
then all asB <$> V.zipWithM (c2Mϵ f op) x0' x1'
else pure False
where op = BB (TyArr t (TyArr t tyB)) Eq
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyOption:$t) _) Eq) x0) x1) = do
x0' <- asM<$>eBM f x0; x1' <- asM<$>eBM f x1
case (x0',x1') of
(Nothing, Nothing) -> pure (mkB True)
(Nothing, Just{}) -> pure (mkB False)
(Just{}, Nothing) -> pure (mkB False)
(Just e0, Just e1) -> c2Mϵ f op e0 e1
where op = BB (TyArr t (TyArr t tyB)) Eq
eBM f (EApp _ (EApp _ (BB (TyArr (TyB TyStr) _) Plus) x0) x1) = do
x0' <- asS <$> eBM f x0; x1' <- asS<$>eBM f x1
pure (mkStr (x0'<>x1'))
eBM f (EApp _ (EApp _ (BB _ And) x0) x1) = do
x0' <- asB<$>eBM f x0; x1' <- asB<$>eBM f x1
pure (mkB (x0'&&x1'))
eBM f (EApp _ (EApp _ (BB _ Or) x0) x1) = do
x0' <- asB<$>eBM f x0; x1' <- asB<$>eBM f x1
pure (mkB (x0'||x1'))
eBM f (EApp _ (UB _ Not) b) = do {b' <- asB<$>eBM f b; pure $ mkB (not b')}
eBM f (EApp _ (EApp _ (BB _ Matches) s) r) = {-# SCC "eBMMatch" #-} do
s' <- asS<$>eBM f s; r' <- asR<$>eBM f r
pure $ mkB (isMatch' r' s')
eBM f (EApp _ (EApp _ (BB _ NotMatches) s) r) = do
s' <- asS<$>eBM f s; r' <- asR<$>eBM f r
pure $ mkB (not$isMatch' r' s')
eBM f (EApp _ (EApp _ (BB _ Split) s) r) = do
s' <- asS<$>eBM f s; r' <- asR<$>eBM f r
pure (vS (splitBy r' s'))
eBM f (EApp _ (EApp _ (BB _ Splitc) s) c) = do
s' <- asS<$>eBM f s; c' <- the.asS<$>eBM f c
pure (vS (V.fromList (BS.split c' s')))
eBM f (EApp _ (UB _ FParse) x) = do {x' <- eBM f x; pure (parseAsF (asS x'))}
eBM f (EApp _ (UB _ IParse) x) = do {x' <- eBM f x; pure (parseAsEInt (asS x'))}
eBM f (EApp (TyB TyInteger) (UB _ Parse) x) = do {x' <- eBM f x; pure (parseAsEInt (asS x'))}
eBM f (EApp (TyB TyFloat) (UB _ Parse) x) = do {x' <- eBM f x; pure (parseAsF (asS x'))}
eBM f (EApp _ (UB _ (At i)) v) = do {v' <- eBM f v; pure (asV v'!(i-1))}
eBM f (EApp _ (UB _ (Select i)) x) = do {x' <- eBM f x; pure (asT x' !! (i-1))}
eBM f (EApp _ (UB _ Floor) x) = do {xr <- asF<$>eBM f x; pure $ mkI (floor xr)}
eBM f (EApp _ (UB _ Ceiling) x) = do {xr <- asF<$>eBM f x; pure $ mkI (ceiling xr)}
eBM f (EApp (TyB TyInteger) (UB _ Negate) i) = do {i' <- eBM f i; pure $ mkI (negate (asI i'))}
eBM f (EApp (TyB TyFloat) (UB _ Negate) x) = do {x' <- eBM f x; pure $ mkF (negate (asF x'))}
eBM f (EApp t (UB _ Some) e) = do {e' <- eBM f e; pure (OptionVal t (Just e'))}
eBM _ (NB t None) = pure (OptionVal t Nothing)
eBM f (EApp _ (UB _ Tally) e) = do
s' <- eBM f e
let r =fromIntegral (BS.length$asS s')
pure (mkI r)
eBM f (EApp _ (UB _ TallyList) e) = do
e' <- eBM f e
let r=fromIntegral (V.length$asV e')
pure (mkI r)
eBM f (EApp _ (EApp _ (UB _ Const) e) _) = eBM f e
eBM f (EApp _ (EApp _ (BB _ Sprintf) fs) s) = do
fs' <- eBM f fs; s' <- eBM f s
pure $ mkStr (sprintf (asS fs') s')
eBM f (EApp _ (EApp _ (BB _ Match) s) r) = do
s' <- eBM f s; r' <- eBM f r
pure $ asTup (find' (asR r') (asS s'))
eBM f (EApp _ (EApp _ (EApp _ (TB _ Fold) op) seed) xs) | TyB TyVec:$_ <- eLoc xs = do
op' <- eBM f op; seed' <- eBM f seed; xs' <- eBM f xs
V.foldM (c2Mϵ f op') seed' (asV xs')
eBM f (EApp _ (EApp _ (BB _ Fold1) op) xs) | TyB TyVec:$_ <- eLoc xs = do
op' <- eBM f op; xs' <- eBM f xs
let xsV=asV xs'; Just (seed, xs'') = V.uncons xsV
V.foldM (c2Mϵ f op') seed xs''
eBM f (EApp yT@(TyB TyOption:$_) (EApp _ (BB _ Map) g) x) = do
g' <- eBM f g; x' <- eBM f x
OptionVal yT <$> traverse (eBM f <=< a1 g') (asM x')
eBM f (EApp yT@(TyB TyVec:$_) (EApp _ (BB _ Map) g) x) = do
g' <- eBM f g; x' <- eBM f x
Arr yT <$> traverse (eBM f <=< a1 g') (asV x')
eBM f (EApp t (EApp _ (EApp _ (TB _ Option) x) g) y) = do
x' <- eBM f x; g' <- eBM f g; y' <- eBM f y
case asM y' of
Nothing -> pure x'
Just yϵ -> eBM f =<< lβ (EApp t g' yϵ)
eBM f (EApp _ (EApp _ (EApp _ (TB _ Substr) s) i0) i1) = do
i0' <- eBM f i0; i1' <- eBM f i1; s' <- eBM f s
pure $ mkStr (substr (asS s') (fromIntegral$asI i0') (fromIntegral$asI i1'))
eBM f (Cond _ p e e') = do {p' <- eBM f p; if asB p' then eBM f e else eBM f e'}
eBM f (Tup t es) = Tup t <$> traverse (eBM f) es
eBM f e = f e