packages feed

jacinda 3.0.2.0 → 3.1.0.0

raw patch · 20 files changed

+165/−175 lines, 20 filesdep +lazy-csv

Dependencies added: lazy-csv

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+# 3.1.0.0++  * Add support for CSV via the `--csv` flag and `:set csv`+  * Add `~?` (maybe match)+   # 3.0.2.0    * Fix list indexing
bench/Bench.hs view
@@ -13,17 +13,19 @@ main =     defaultMain [ bgroup "eval"                       [ bench "exprEval" $ nf exprEval "[x+' '+y]|'' split '01-23-1987' /-/" ]+                , bgroup "csv"+                      [ bench "succdiff" $ nfIO (silence $ runOnFile [] "~.{ix>1}{`8}" CSV "bench/data/food-prices.csv") ]                 , bgroup "stream"-                      [ bench "path" $ nfIO (silence $ runOnFile [] "{|[x+'\\n'+y]|>`$}" (Just ":") Nothing "bench/data/PATH")-                      , bench "RS" $ nfIO (silence $ runOnFile [] "$0" Nothing (Just ":") "bench/data/PATH")-                      , bench "runOnFile" $ nfIO (silence $ runOnFile [] "(+)|0 {%/Bloom/}{1}" Nothing Nothing "bench/data/ulysses.txt")-                      , bench "runOnFile" $ nfIO (silence $ do { contents <- TIO.readFile "examples/wc.jac" ; runOnFile [] contents Nothing Nothing "bench/data/ulysses.txt" })-                      , bench "runOnFile" $ nfIO (silence $ do { contents <- TIO.readFile "examples/span2.jac" ; runOnFile [] contents Nothing Nothing "bench/data/span.txt" })-                      , bench "sedstream.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/sedstream.jac" ; runOnFile [] contents Nothing Nothing "bench/data/lines.txt" })-                      , bench "gnused.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/gnused.jac" ; runOnFile [] contents Nothing Nothing "bench/data/lines.txt" })-                      , bench "fungnused.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/fungnused.jac" ; runOnFile [] contents Nothing Nothing "bench/data/lines.txt" })-                      , bench "hsLibversionMac.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/hsLibversionMac.jac"; runOnFile [] contents Nothing Nothing "bench/data/pandoc-mac" })-                      , bench "sedsmtp.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/sedsmtp.jac" ; runOnFile [] contents Nothing Nothing "test/examples/data/2.txt" })+                      [ bench "path" $ nfIO (silence $ runOnFile [] "{|[x+'\\n'+y]|>`$}" (AWK (Just ":") Nothing) "bench/data/PATH")+                      , bench "RS" $ nfIO (silence $ runOnFile [] "$0" (AWK Nothing (Just ":")) "bench/data/PATH")+                      , bench "runOnFile" $ nfIO (silence $ runOnFile [] "(+)|0 {%/Bloom/}{1}" (AWK Nothing Nothing) "bench/data/ulysses.txt")+                      , bench "runOnFile" $ nfIO (silence $ do { contents <- TIO.readFile "examples/wc.jac" ; runOnFile [] contents (AWK Nothing Nothing) "bench/data/ulysses.txt" })+                      , bench "runOnFile" $ nfIO (silence $ do { contents <- TIO.readFile "examples/span2.jac" ; runOnFile [] contents (AWK Nothing Nothing) "bench/data/span.txt" })+                      , bench "sedstream.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/sedstream.jac" ; runOnFile [] contents (AWK Nothing Nothing) "bench/data/lines.txt" })+                      , bench "gnused.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/gnused.jac" ; runOnFile [] contents (AWK Nothing Nothing) "bench/data/lines.txt" })+                      -- , bench "fungnused.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/fungnused.jac" ; runOnFile [] contents (AWK Nothing Nothing) "bench/data/lines.txt" })+                      , bench "hsLibversionMac.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/hsLibversionMac.jac"; runOnFile [] contents (AWK Nothing Nothing) "bench/data/pandoc-mac" })+                      , bench "sedsmtp.jac" $ nfIO (silence $ do { contents <- TIO.readFile "examples/sedsmtp.jac" ; runOnFile [] contents (AWK Nothing Nothing) "test/examples/data/2.txt" })                       ]                 ] 
doc/guide.pdf view

binary file changed (75903 → 75165 bytes)

examples/diffctx.jac view
@@ -3,15 +3,10 @@ @include'prelude/fn.jac' @include'lib/maybe.jac' -fn mMatch(str, re) :=-  if str ~ re-    then Some str-    else None;- fn step(needle, ctx, line) :=   let      val fpCtx ≔ line ~* 1 /diff --git\s+([^\s]+)/-    val mLine ≔ mMatch line needle+    val mLine ≔ line ~? needle   in (alternative (ctx->1) fpCtx.mLine) end;  fn process(x) :=
examples/nmCtx.jac view
@@ -3,9 +3,6 @@ @include'prelude/fn.jac' @include'lib/maybe.jac' -fn mMatch(str, re) :=-  ?str ~ re; Some str; None;- fn step(ctx, line) :=   let     val fpCtx := line ~* 1 /(.*\.o):$/
− examples/slow.jac
@@ -1,1 +0,0 @@-(+)|> ([x+'\n'+y]|>)¨{|captures `0 1 /-lHS([A-Aa-z][A-Za-z0-9\-]*\d+(\.\d+)*)/}
+ examples/tagsex.jac view
@@ -0,0 +1,12 @@+fn mkEx(s) :=+  '/^' + s + '$/;';++{. TODO: insert \zs at precise identifier! https://stackoverflow.com/a/31089753/11296354++fn processStr(s) :=+  let+    val line := split s /[ \(:]+/+    val outLine := sprintf '%s\t%s\t%s' (line.3 . fp . mkEx s)+  in outLine end;++processStr¨{%/fn +[[:lower:]][[:latin:]]*.*:=/}{`0}
jacinda.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.2 name:               jacinda-version:            3.0.2.0+version:            3.1.0.0 license:            AGPL-3.0-only license-file:       COPYING maintainer:         vamchale@gmail.com@@ -18,8 +18,10 @@     lib/fs/*.jac     prelude/*.jac -extra-source-files:+extra-doc-files:     CHANGELOG.md++extra-source-files:     README.md     man/ja.1     doc/guide.pdf@@ -37,6 +39,7 @@  common warnings     ghc-options:+        -Wall         -Wincomplete-uni-patterns -Wincomplete-record-updates         -Wredundant-constraints -Widentities -Wcpp-undef         -Wmissing-export-lists -Wunused-packages@@ -57,7 +60,6 @@         A.I         A.E         L-        Jacinda.Fuse         Nm         U         R@@ -71,10 +73,10 @@      autogen-modules:  Paths_jacinda     default-language: Haskell2010-    ghc-options:      -Wall -O2 -Wno-missing-signatures -Wno-x-partial+    ghc-options:      -O2 -Wno-missing-signatures -Wno-x-partial     build-depends:         base >=4.11.0.0 && <5,-        bytestring >=0.11.0.0,+        bytestring >=0.11.2.0,         text,         prettyprinter >=1.7.0,         containers >=0.6.0.1,@@ -89,7 +91,8 @@         vector >=0.12.2.0,         recursion >=1.0.0.0,         split,-        deepseq+        deepseq,+        lazy-csv      other-extensions:         OverloadedStrings@@ -110,7 +113,7 @@     other-modules:    Paths_jacinda     autogen-modules:  Paths_jacinda     default-language: Haskell2010-    ghc-options:      -Wall -rtsopts "-with-rtsopts=-A200k -k32k"+    ghc-options:      -rtsopts "-with-rtsopts=-A200k -k32k"     build-depends:         base,         jacinda-lib,@@ -128,7 +131,7 @@     main-is:          Spec.hs     hs-source-dirs:   test     default-language: Haskell2010-    ghc-options:      -Wall -threaded -rtsopts "-with-rtsopts=-N -K1K" -Wall+    ghc-options:      -threaded -rtsopts "-with-rtsopts=-N -K1K"     build-depends:         base,         jacinda-lib,@@ -143,7 +146,7 @@     main-is:          Bench.hs     hs-source-dirs:   bench     default-language: Haskell2010-    ghc-options:      -Wall -rtsopts "-with-rtsopts=-A200k -k32k"+    ghc-options:      -rtsopts "-with-rtsopts=-A200k -k32k"     build-depends:         base,         criterion,
lib/gitCtx.jac view
@@ -1,15 +1,10 @@ @include'prelude/fn.jac' @include'lib/maybe.jac' -fn mMatch(p, str) :=-  if p str-    then Some str-    else None;- fn step(p, ctx, line) :=   let     val fpCtx ≔ line ~* 1 /diff --git\s+([^\s]+)/-    val mLine ≔ mMatch p line+    val mLine ≔ p ~? line   in (alternative (ctx->1) fpCtx.mLine) end;  fn process(x) :=
man/ja.1 view
@@ -35,6 +35,9 @@ .TP \f[B]\-R\f[R] Record separator regex+.TP+\f[B]\-\-csv\f[R]+Process as CSV .SH LANGUAGE .SS REGEX Regular expressions follow Rust\[cq]s regex library:@@ -134,6 +137,9 @@ Str \-> Regex \-> Option (Int . Int) .TP+\f[B]\[ti]?\f[R] Maybe match: return string if it is a match, otherwise None+Str \-> Regex \-> Option Str+.TP \f[B]\[ti]*\f[R] Match, returning nth capture group Str \-> Int \-> Regex \-> Option Str .TP@@ -207,6 +213,8 @@ .PP \f[B]:set rs=/REGEX/;\f[R] Set record separator .PP+\f[B]:set csv;\f[R] Process as CSV+.PP \f[B]:flush;\f[R] Flush stdout for every line .SH INFLUENTIAL ENVIRONMENT VARIABLES \f[CR]JAC_PATH\f[R] \- colon\-separated list of directories to search@@ -227,7 +235,7 @@ :set fs:=/,[ \[rs]t]*|[ \[rs]t]+/; {|sprintf \[aq]%i %i\[aq] (\[ga]2 . \[ga]1)} Same, with input fields separated by comma and/or blanks and tabs. .TP-:set fs:=/,/; {ix=1}{[x+`\[rs]n'+y]|>\[ga]$}+:set csv; {ix=1}{[x+`\[rs]n'+y]|>\[ga]$} Present column names of a .csv file, one per line .TP (+)|0 $1:i
src/A.hs view
@@ -8,6 +8,7 @@          , L (..), N (..), BBin (..), BTer (..)          , BUn (..), DfnVar (..)          , D (..), Program (..)+         , Mode (..)          , mapExpr          , getS, flushD          -- * Base functors@@ -148,7 +149,7 @@           | Eq | Neq | Geq | Gt | Lt | Leq           | Map           | Matches -- ^ @'string' ~ /pat/@-          | NotMatches+          | NotMatches | MMatch           | And | Or           | Min | Max           | Split | Splitc@@ -163,7 +164,7 @@     pretty Plus = "+"; pretty Times = "*"; pretty Div = "%"; pretty Minus = "-"     pretty Eq = "="; pretty Gt = ">"; pretty Lt = "<"; pretty Geq = ">="     pretty Leq = "<="; pretty Neq = "!="; pretty Map = "¨"; pretty Matches = "~"-    pretty NotMatches = "!~"; pretty And = "&"; pretty Or = "||"+    pretty MMatch = "~?"; pretty NotMatches = "!~"; pretty And = "&"; pretty Or = "||"     pretty Max = "max"; pretty Min = "min"; pretty Prior = "\\."; pretty Filter = "#."     pretty Split = "split"; pretty Splitc = "splitc"; pretty Sprintf = "sprintf"     pretty Match = "match"; pretty MapMaybe = ":?"; pretty Fold1 = "|>"@@ -274,8 +275,9 @@ mPrec Gt         = Just 4 mPrec Lt         = Just 4 mPrec Leq        = Just 4-mPrec Matches    = Just 4-mPrec NotMatches = Just 4+mPrec Matches    = Just 5+mPrec NotMatches = Just 5+mPrec MMatch     = Just 5 mPrec Report     = Just 4 mPrec And        = Just 3 mPrec Or         = Just 2@@ -393,7 +395,8 @@ data D a = SetFS T.Text | SetRS T.Text          | FunDecl (Nm a) [Nm a] (E a)          | FlushDecl-         | SetAsv | SetUsv | SetOFS T.Text | SetORS T.Text+         | SetAsv | SetUsv | SetCsv+         | SetOFS T.Text | SetORS T.Text          deriving (Functor)  instance Pretty (D a) where@@ -416,13 +419,16 @@ flushD :: Program a -> Bool flushD (Program ds _) = any p ds where p FlushDecl = True; p _ = False -getS :: Program a -> (Maybe T.Text, Maybe T.Text)-getS (Program ds _) = foldl' go (Nothing, Nothing) ds where-    go (_, rs) (SetFS bs) = (Just bs, rs)-    go _ SetAsv           = (Just "\\x1f", Just "\\x1e")-    go _ SetUsv           = (Just "␞",Just "␟")-    go (fs, _) (SetRS bs) = (fs, Just bs)-    go next _             = next+data Mode = CSV | AWK (Maybe T.Text) (Maybe T.Text) -- field, record++getS :: Program a -> Mode+getS (Program ds _) = foldl' go (AWK Nothing Nothing) ds where+    go (AWK _ rs) (SetFS bs) = AWK (Just bs) rs+    go _ SetAsv              = AWK (Just "\\x1f") (Just "\\x1e")+    go _ SetUsv              = AWK (Just "␞") (Just "␟")+    go _ SetCsv              = CSV+    go (AWK fs _) (SetRS bs) = AWK fs (Just bs)+    go next _                = next  mapExpr :: (E a -> E a) -> Program a -> Program a mapExpr f (Program ds e) = Program ds (f e)
src/File.hs view
@@ -17,12 +17,13 @@ import qualified Data.ByteString            as BS import qualified Data.ByteString.Lazy       as BSL import qualified Data.ByteString.Lazy.Char8 as ASCIIL-import           Data.Foldable              (traverse_)+import           Data.Foldable              (fold, traverse_) import           Data.Functor               (($>)) import qualified Data.Text                  as T import           Data.Text.Encoding         (encodeUtf8) import qualified Data.Text.IO               as TIO import           Data.Tuple                 (swap)+import qualified Data.Vector                as V import           Include import           Jacinda.Backend.Const import           Jacinda.Backend.T@@ -34,8 +35,22 @@ import           R import           Regex.Rure                 (RurePtr) import           System.IO                  (stdin)+import           Text.CSV.Lazy.ByteString   (CSVField (..), parseCSV) import           Ty +csvCtx :: BSL.ByteString -> [LineCtx]+csvCtx = go Nothing . parseCSV where+    go _ []           = []+    go _ (Left err:_) = error (show err)+    -- TODO: re-csv it?+    go (Just n) (Right r:rs) = let fs=mB<$>r in (fold fs, V.fromListN n fs, fromIntegral (line r)):go (Just n) rs+    go Nothing (Right r:rs)  = let fs=mB<$>r; n=length fs in (fold fs, V.fromListN n fs, fromIntegral (line r)):go (Just n) rs+    mB f@CSVField{} = BSL.toStrict (csvFieldContent f)+    mB f            = error (show f)+    line (f@CSVField{}:_) = csvRowNum f+    line (f:_)            = error (show f)+    line []               = error "empty record in csv"+ parseLib :: [FilePath] -> FilePath -> StateT AlexUserState IO [D AlexPosn] parseLib incls fp = do     contents <- liftIO $ TIO.readFile =<< resolveImport incls fp@@ -43,7 +58,7 @@     case parseLibWithCtx contents st of         Left err              -> liftIO (throwIO err)         Right (st', ([], ds)) -> put st' $> (rwD <$> ds)-        Right (st', (is, ds)) -> do { put st' ; dss <- traverse (parseLib incls) is ; pure (concat dss ++ fmap rwD ds) }+        Right (st', (is, ds)) -> do {put st'; dss <- traverse (parseLib incls) is; pure (concat dss ++ fmap rwD ds)}  parseE :: [FilePath] -> T.Text -> StateT AlexUserState IO (Program AlexPosn) parseE incls bs = do@@ -90,37 +105,40 @@ runOnBytes :: [FilePath]            -> FilePath -- ^ Data file name, for @nf@            -> T.Text -- ^ Program-           -> Maybe T.Text -- ^ Field separator-           -> Maybe T.Text -- ^ Record separator+           -> Mode            -> BSL.ByteString            -> IO ()-runOnBytes incls fp src cliFS cliRS contents = do+runOnBytes incls fp src mode contents = do     incls' <- defaultIncludes <*> pure incls     (ast, m) <- parseEWithMax incls' src     (typed, i) <- yIO $ runTyM m (tyP ast)     let (eI, j) = ib i typed     m'Throw $ cF eI-    let ~(afs, ars) = getS ast+    let ~(AWK afs ars) = getS ast         (e', k) = runState (eta eI) j-        cont=run (compileFS (cliFS <|> afs)) (flushD typed) k (compileR (encodeUtf8 $ T.pack fp) e')-    case cliRS <|> ars of-        Nothing -> cont $ fmap BSL.toStrict (ASCIIL.lines contents)-        Just rs -> cont $ lazySplit (tcompile rs) contents+        cont=run (flushD typed) k (compileR (encodeUtf8 $ T.pack fp) e')+    case mode of+        AWK cliFS cliRS ->+            let r=compileFS (cliFS <|> afs)+                bs=case cliRS <|> ars of+                    Nothing -> fmap BSL.toStrict (ASCIIL.lines contents)+                    Just rs -> lazySplit (tcompile rs) contents+                ctxs=zipWith (\ ~(x,y) z -> (x,y,z)) [(b, splitBy r b) | b <- bs] [1..]+            in cont ctxs+        CSV -> let ctxs = csvCtx contents in cont ctxs  runStdin :: [FilePath]          -> T.Text -- ^ Program-         -> Maybe T.Text -- ^ Field separator-         -> Maybe T.Text -- ^ Record separator+         -> Mode          -> IO ()-runStdin is src cliFS cliRS = runOnBytes is "(stdin)" src cliFS cliRS =<< BSL.hGetContents stdin+runStdin is src m = runOnBytes is "(stdin)" src m =<< BSL.hGetContents stdin  runOnFile :: [FilePath]           -> T.Text-          -> Maybe T.Text-          -> Maybe T.Text+          -> Mode           -> FilePath           -> IO ()-runOnFile is e fs rs fp = runOnBytes is fp e fs rs =<< BSL.readFile fp+runOnFile is e m fp = runOnBytes is fp e m =<< BSL.readFile fp  tcIO :: [FilePath] -> T.Text -> IO () tcIO incls src = do
src/Jacinda/Backend/T.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} -module Jacinda.Backend.T ( run, eB ) where+module Jacinda.Backend.T ( LineCtx, run, eB ) where  import           A import           A.I@@ -91,25 +91,22 @@     pSF flush c es pSF _ _ [] = pure () -run :: RurePtr -> Bool -> Int -> E T -> [BS.ByteString] -> IO ()-run r flush j e bs | TyB TyUnit <- eLoc e =  (\(s, f, env) -> pSF flush (s,f) env) $ flip evalState j $ do+run :: Bool -> Int -> E T -> [LineCtx] -> IO ()+run flush j e ctxs | TyB TyUnit <- eLoc e =  (\(s, f, env) -> pSF flush (s,f) env) $ flip evalState j $ do     (res, tt, iEnv, μ) <- unit e     u <- nI-    let ctxs=zipWith (\ ~(x,y) z -> (x,y,z)) [(b, splitBy r b) | b <- bs] [1..]-        outs=μ<$>ctxs; es'=scanl' (&) (Σ u iEnv IM.empty IM.empty IM.empty IS.empty) outs+    let outs=μ<$>ctxs; es'=scanl' (&) (Σ u iEnv IM.empty IM.empty IM.empty IS.empty) outs     pure (res, tt, gE<$>es')-run r flush j e bs | TyB TyStream:$_ <- eLoc e = traverse_ (traverse_ (pS flush)).flip evalState j $ do+run flush j e ctxs | TyB TyStream:$_ <- eLoc e = traverse_ (traverse_ (pS flush)).flip evalState j $ do     t <- nI     (iEnv, μ) <- ctx e t     u <- nI-    let ctxs=zipWith (\ ~(x,y) z -> (x,y,z)) [(b, splitBy r b) | b <- bs] [1..]-        outs=μ<$>ctxs; es=scanl' (&) (Σ u iEnv IM.empty IM.empty IM.empty IS.empty) outs+    let outs=μ<$>ctxs; es=scanl' (&) (Σ u iEnv IM.empty IM.empty IM.empty IS.empty) outs     pure ((! t).gE<$>es)-run r _ j e bs = pDocLn $ flip evalState j $ do+run _ j e ctxs = pDocLn $ flip evalState j $ do     (iEnv, g, e0) <- collect e     u <- nI-    let ctxs=zipWith (\ ~(x,y) z -> (x,y,z)) [(b, splitBy r b) | b <- bs] [1..]-        updates=g<$>ctxs+    let updates=g<$>ctxs         finEnv=foldl' (&) (Σ u iEnv IM.empty IM.empty IM.empty IS.empty) updates     e0@>(fromMaybe (throw EmptyFold)<$>gE finEnv) @@ -363,6 +360,9 @@ (EApp _ (EApp _ (BB _ NotMatches) s) r) @> b = do     se <- s@>b; re <- r@>b     pure (mkB (not$isMatch' (asR re) (asS se)))+(EApp ty (EApp _ (BB _ MMatch) s) r) @> b = do+    se <- s@>b; re <- r@>b+    pure (if isMatch' (asR re) (asS se) then OptionVal ty (Just$!se) else OptionVal ty Nothing) (EApp ty (EApp _ (BB _ Take) n) x) @> b = do     n' <- asI<$>(n@>b); x' <- asV<$>(x@>b)     pure $ Arr ty (V.take (fromIntegral n') x')
− src/Jacinda/Fuse.hs
@@ -1,59 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module Jacinda.Fuse ( fuse ) where--import           A-import           A.E-import           Control.Monad.State.Strict (runState)-import           Ty.Const--fuse :: Int -> E T -> (E T, Int)-fuse i = flip runState i.fM--fM :: E T -> M (E T)-fM (EApp t0 (EApp t1 (EApp t2 ho@(TB _ Fold) op) seed) stream) | TyB TyStream :$ _ <- eLoc stream = do-    stream' <- fM stream-    case stream' of-        (EApp _ (EApp _ (BB _ Filter) p) xs) -> do-            let opTy@(TyArr sTy popTy@(TyArr xTy _)) = eLoc op-            s <- nN "seed" sTy; x <- nN "x" xTy-            let sE=Var sTy s; xE=Var xTy x-            let fop=Lam opTy s (Lam popTy x (Cond sTy (EApp tyB p xE) (EApp sTy (EApp popTy op sE) xE) sE)) in pure (EApp t0 (EApp t1 (EApp t2 ho fop) seed) xs)-        (Guarded t p e) -> do-            let opTy@(TyArr sTy popTy@(TyArr xTy _)) = eLoc op-            s <- nN "seed" sTy; x <- nN "x" xTy-            let sE=Var sTy s; xE=Var xTy x-            let fop=Lam opTy s (Lam popTy x (Cond sTy p (EApp sTy (EApp popTy op sE) xE) sE)) in pure (EApp t0 (EApp t1 (EApp t2 ho fop) seed) (Implicit t e))-            -- FIXME: does this evaluate e? (could be exception)-        (EApp _ (EApp _ (BB _ Map) f) xs) -> do-            let (TyArr xTy yTy) = eLoc f-                (TyArr sTy _) = eLoc op-            s <- nN "seed" sTy; x <- nN "x" xTy-            let sE=Var sTy s; xE=Var xTy x-                popT=xTy ~> sTy; fopT=sTy ~> popT-                fop=Lam fopT s (Lam popT x (EApp undefined (EApp undefined op sE) (EApp yTy f xE)))-            fM (EApp sTy (EApp undefined (EApp undefined (TB (fopT ~> (sTy ~> TyArr (TyB TyStream :$ xTy) sTy)) Fold) fop) seed) xs)-        (EApp _ (EApp _ (BB _ MapMaybe) f) xs) -> do-            -- op | seed (f:?xs) -> [option x (x `op`) (f y)] | seed xs-            let TyArr xT yT=eLoc f-                sT=eLoc seed-            s <- nN "seed" sT; x <- nN "x" xT-            let sE=Var sT s; xE=Var xT x-                popT=xT ~> sT; fopT=sT ~> popT-                fop=Lam fopT s (Lam popT x (EApp sT (EApp undefined (EApp undefined (TB (sT ~> TyArr undefined (yT ~> sT)) Option) sE) (EApp undefined op sE)) (EApp yT f xE)))-            fM (EApp sT (EApp undefined (EApp undefined (TB (TyArr fopT (TyArr sT (TyArr (TyB TyStream :$ xT) sT))) Fold) fop) seed) xs)-        (EApp _ (UB _ CatMaybes) xs) -> do-            -- op | seed (.? xs) -> [option x (x `op`) y] | seed xs-            let TyArr _ (TyArr xTy _)=eLoc op-                xMT=tyOpt xTy-                sTy=eLoc seed-            s <- nN "seed" sTy; x <- nN "x" xMT-            let sE=Var sTy s; xE=Var xMT x-                popT=xMT ~> sTy; fopT=sTy ~> popT-                fop=Lam fopT s (Lam popT x (EApp sTy (EApp undefined (EApp undefined (TB (sTy ~> TyArr undefined (xMT ~> sTy)) Option) sE) (EApp undefined op sE)) xE))-            fM (EApp sTy (EApp undefined (EApp undefined (TB (fopT ~> (sTy ~> TyArr (TyB TyStream :$ xMT) sTy)) Fold) fop) seed) xs)-        _ -> pure (EApp t0 (EApp t1 (EApp t2 ho op) seed) stream')-fM (Tup t es) = Tup t <$> traverse fM es-fM (EApp t e0 e1) = EApp t <$> fM e0 <*> fM e1-fM (Lam t n e) = Lam t n <$> fM e-fM e = pure e
src/L.x view
@@ -105,6 +105,7 @@         "]"                      { mkSym RSqBracket `andBegin` 0 }         "~"                      { mkSym Tilde }         "!~"                     { mkSym NotMatchTok }+        "~?"                     { mkSym MMatch }         ","                      { mkSym Comma }         ",,"                     { mkSym DoubleComma }         "."                      { mkSym Dot }@@ -146,6 +147,7 @@         else                     { mkKw KwElse }         asv                      { mkKw KwAsv }         usv                      { mkKw KwUsv }+        csv                      { mkKw KwCsv }          fs                       { mkRes VarFs }         rs                       { mkRes VarRs }@@ -257,9 +259,7 @@  alexEOF = EOF <$> get_pos -data Sym = PlusTok-         | MinusTok-         | PercentTok+data Sym = PlusTok | MinusTok | PercentTok          | ExpTok          | FoldTok          | IceCreamCone@@ -279,12 +279,10 @@          | GtTok | GeqTok          | LtTok | LeqTok          | AndTok | OrTok-         | Tilde | NotMatchTok-         | Comma+         | Tilde | NotMatchTok | MMatch+         | Comma | Dot          | DoubleComma-         | Dot-         | TallyTok-         | LengthTok+         | TallyTok | LengthTok          | ConstTok          | LBracePercent          | LBraceBar@@ -295,12 +293,9 @@          | BackslashDot          | QuestionMark          | FilterTok-         | FloorSym-         | CeilSym-         | DedupTok-         | DedupOnTok-         | CatMaybesTok-         | MapMaybeTok+         | FloorSym | CeilSym+         | DedupTok | DedupOnTok+         | CatMaybesTok | MapMaybeTok          | CapTok          | NegTok          | LastFieldTok@@ -335,6 +330,7 @@     pretty RSqBracket    = "]"     pretty Tilde         = "~"     pretty NotMatchTok   = "!~"+    pretty MMatch        = "~?"     pretty Comma         = ","     pretty DoubleComma   = ",,"     pretty Dot           = "."@@ -372,7 +368,7 @@              | KwFn              | KwInclude              | KwIf | KwThen | KwElse-             | KwAsv | KwUsv+             | KwAsv | KwUsv | KwCsv  -- | Reserved/special variables data Var = VarX | VarY@@ -407,6 +403,7 @@     pretty KwElse    = "else"     pretty KwUsv     = "usv"     pretty KwAsv     = "asv"+    pretty KwCsv     = "csv"  data Builtin = BuiltinIParse | BuiltinFParse              | BuiltinSubstr
src/Parser.y view
@@ -83,6 +83,7 @@     mapMaybe { TokSym $$ MapMaybeTok }     catMaybes { TokSym $$ CatMaybesTok }     capture { TokSym $$ CapTok }+    mmatch { TokSym $$ L.MMatch }     neg { TokSym $$ NegTok }      eq { TokSym $$ EqTok }@@ -122,6 +123,7 @@     else { TokKeyword $$ KwElse }     usv { TokKeyword $$ KwUsv }     asv { TokKeyword $$ KwAsv }+    csv { TokKeyword $$ KwCsv }      x { TokResVar $$ VarX }     y { TokResVar $$ VarY }@@ -197,16 +199,13 @@      | times { Times }      | minus { Minus }      | percent { Div }-     | gt { Gt }-     | lt { Lt }-     | geq { Geq }-     | leq { Leq }-     | eq { Eq }-     | neq { Neq }+     | gt { Gt } | lt { Lt }+     | geq { Geq } | leq { Leq }+     | eq { Eq } | neq { Neq }      | quot { Map }      | mapMaybe { MapMaybe }-     | tilde { Matches }-     | notMatch { NotMatches }+     | tilde { Matches } | notMatch { NotMatches }+     | mmatch { A.MMatch }      | and { And }      | or { Or }      | backslashdot { Prior }@@ -231,6 +230,7 @@   | set ors defEq strLit semicolon { SetORS (strTok $4) }   | set asv semicolon { SetAsv }   | set usv semicolon { SetUsv }+  | set csv semicolon { SetCsv }   | flush semicolon { FlushDecl }   | fn name Args defEq E semicolon { FunDecl $2 $3 $5 }   | fn name defEq E semicolon { FunDecl $2 [] $4 }
src/Parser/Rw.hs view
@@ -32,6 +32,7 @@ mFi Filter     = Just 5 mFi Fold1      = Just 5 mFi Matches    = Just 5+mFi MMatch     = Just 5 mFi NotMatches = Just 5 mFi Min        = Nothing mFi Max        = Nothing
src/Ty.hs view
@@ -384,6 +384,7 @@ tyES s (BB _ Splitc) = pure (BB (tyStr ~> tyStr ~> tyV tyStr) Splitc, s) tyES s (BB _ Matches) = pure (BB (tyStr ~> tyR ~> tyB) Matches, s) tyES s (BB _ NotMatches) = pure (BB (tyStr ~> tyR ~> tyB) NotMatches, s)+tyES s (BB _ MMatch) = pure (BB (tyStr ~> tyR ~> tyOpt tyStr) MMatch, s) tyES s (UB _ Tally) = pure (UB (tyStr ~> tyI) Tally, s) tyES s (BB _ Take) = do {a <- var<$>freshN "a"; pure (BB (tyI ~> tyV a ~> tyV a) Take, s)} tyES s (BB _ Drop) = do {a <- var<$>freshN "a"; pure (BB (tyI ~> tyV a ~> tyV a) Drop, s)}
− test/examples/bookend.jac
@@ -1,1 +0,0 @@-/Disassembly of section \.text:/,,/Disassembly of section/$0
x/Main.hs view
@@ -2,6 +2,7 @@  module Main (main) where +import           A                   (Mode (..)) import qualified Data.Text           as T import qualified Data.Text.IO        as TIO import qualified Data.Version        as V@@ -11,7 +12,7 @@  data Command = TypeCheck !FilePath ![FilePath]              | Run !FilePath !(Maybe T.Text) !(Maybe T.Text) !(Maybe FilePath) ![FilePath]-             | Expr !T.Text !(Maybe FilePath) !(Maybe T.Text) !Bool !Bool !(Maybe T.Text) ![FilePath]+             | Expr !T.Text !(Maybe FilePath) !(Maybe T.Text) !Bool !Bool !Bool !(Maybe T.Text) ![FilePath]              | Eval !T.Text  jacFile :: Parser FilePath@@ -20,6 +21,11 @@     <> help "Source code"     <> jacCompletions) +csv :: Parser Bool+csv = switch+    (long "csv"+    <> help "Process as CSV")+ asv :: Parser Bool asv = switch     (long "asv"@@ -66,7 +72,7 @@     where         tcP = TypeCheck <$> jacFile <*> includes         runP = Run <$> jacFile <*> jacFs <*> jacRs <*> inpFile <*> includes-        exprP = Expr <$> jacExpr <*> inpFile <*> jacFs <*> asv <*> usv <*> jacRs <*> includes+        exprP = Expr <$> jacExpr <*> inpFile <*> jacFs <*> asv <*> usv <*> csv <*> jacRs <*> includes         eP = Eval <$> jacExpr  includes :: Parser [FilePath]@@ -92,20 +98,25 @@ main :: IO () main = run =<< execParser wrapper -ap :: Bool -> Bool -> Maybe T.Text -> Maybe T.Text -> (Maybe T.Text, Maybe T.Text)-ap True True _ _          = errorWithoutStackTrace "--asv and --usv both specified."-ap _ True Just{} _        = errorWithoutStackTrace "--usv and field separator both speficied."-ap _ True _ Just{}        = errorWithoutStackTrace "--usv and record separator both speficied."-ap True _ Just{} _        = errorWithoutStackTrace "--asv and field separator both speficied."-ap True _ _ Just{}        = errorWithoutStackTrace "--asv and record separator both speficied."-ap True _ Nothing Nothing = (Just "\\x1f", Just "\\x1e")-ap _ True Nothing Nothing = (Just "␟", Just "␞")-ap _ _ fs rs              = (fs,rs)+ap :: Bool -> Bool -> Bool -> Maybe T.Text -> Maybe T.Text -> Mode+ap True True _ _ _          = errorWithoutStackTrace "--asv and --usv both specified."+ap True _ True _ _          = errorWithoutStackTrace "--asv and --csv both specified."+ap _ True True _ _          = errorWithoutStackTrace "--usv and --csv both specified."+ap _ True _ Just{} _        = errorWithoutStackTrace "--usv and field separator both speficied."+ap _ True _ _ Just{}        = errorWithoutStackTrace "--usv and record separator both speficied."+ap True _ _ Just{} _        = errorWithoutStackTrace "--asv and field separator both speficied."+ap True _ _ _ Just{}        = errorWithoutStackTrace "--asv and record separator both speficied."+ap _ _ True Just{} _        = errorWithoutStackTrace "--csv and field separator both speficied."+ap _ _ True _ Just{}        = errorWithoutStackTrace "--csv and record separator both speficied."+ap _ _ True Nothing Nothing = CSV+ap True _ _ Nothing Nothing = AWK (Just "\\x1f") (Just "\\x1e")+ap _ True _ Nothing Nothing = AWK (Just "␟") (Just "␞")+ap _ _ _ fs rs              = AWK fs rs  run :: Command -> IO ()-run (TypeCheck fp is)                = tcIO is =<< TIO.readFile fp-run (Run fp fs rs Nothing is)        = do { contents <- TIO.readFile fp ; runStdin is contents fs rs }-run (Run fp fs rs (Just dat) is)     = do { contents <- TIO.readFile fp ; runOnFile is contents fs rs dat }-run (Expr eb Nothing fs a u rs is)   = let (fs',rs') = ap a u fs rs in runStdin is eb fs' rs'-run (Expr eb (Just fp) fs a u rs is) = let (fs',rs') = ap a u fs rs in runOnFile is eb fs' rs' fp-run (Eval e)                         = print (exprEval e)+run (TypeCheck fp is)                  = tcIO is =<< TIO.readFile fp+run (Run fp fs rs Nothing is)          = do { contents <- TIO.readFile fp ; runStdin is contents (AWK fs rs) }+run (Run fp fs rs (Just dat) is)       = do { contents <- TIO.readFile fp ; runOnFile is contents (AWK fs rs) dat }+run (Expr eb Nothing fs a u c rs is)   = let m = ap a u c fs rs in runStdin is eb m+run (Expr eb (Just fp) fs a u c rs is) = let m = ap a u c fs rs in runOnFile is eb m fp+run (Eval e)                           = print (exprEval e)