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 +5/−0
- bench/Bench.hs +12/−10
- doc/guide.pdf binary
- examples/diffctx.jac +1/−6
- examples/nmCtx.jac +0/−3
- examples/slow.jac +0/−1
- examples/tagsex.jac +12/−0
- jacinda.cabal +12/−9
- lib/gitCtx.jac +1/−6
- man/ja.1 +9/−1
- src/A.hs +18/−12
- src/File.hs +34/−16
- src/Jacinda/Backend/T.hs +11/−11
- src/Jacinda/Fuse.hs +0/−59
- src/L.x +12/−15
- src/Parser.y +8/−8
- src/Parser/Rw.hs +1/−0
- src/Ty.hs +1/−0
- test/examples/bookend.jac +0/−1
- x/Main.hs +28/−17
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)