packages feed

egison 3.4.0 → 3.5.0

raw patch · 15 files changed

+378/−102 lines, 15 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Language.Egison.Types: LoopContext :: Binding -> ObjectRef -> EgisonPattern -> EgisonPattern -> EgisonPattern -> LoopContext
- Language.Egison.Types: data LoopContext
- Language.Egison.Types: instance Show LoopContext
+ Language.Egison.Types: CharHash :: (HashMap Char EgisonValue) -> EgisonValue
+ Language.Egison.Types: ContExpr :: EgisonExpr
+ Language.Egison.Types: ICharHash :: (HashMap Char ObjectRef) -> Intermediate
+ Language.Egison.Types: LoopExpr :: String -> LoopRange -> EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: LoopExprContext :: Binding -> ObjectRef -> EgisonExpr -> EgisonExpr -> LoopExprContext
+ Language.Egison.Types: LoopPatContext :: Binding -> ObjectRef -> EgisonPattern -> EgisonPattern -> EgisonPattern -> LoopPatContext
+ Language.Egison.Types: data LoopExprContext
+ Language.Egison.Types: data LoopPatContext
+ Language.Egison.Types: instance Show LoopExprContext
+ Language.Egison.Types: instance Show LoopPatContext
+ Language.Egison.Types: showTSV :: EgisonValue -> String
- Language.Egison.Types: MState :: Env -> [LoopContext] -> [Binding] -> [MatchingTree] -> MatchingState
+ Language.Egison.Types: MState :: Env -> [LoopPatContext] -> [Binding] -> [MatchingTree] -> MatchingState
- Language.Egison.Types: type Env = [HashMap Var ObjectRef]
+ Language.Egison.Types: type Env = ([LoopExprContext], [HashMap Var ObjectRef])

Files

egison.cabal view
@@ -1,5 +1,5 @@ Name:                egison-Version:             3.4.0+Version:             3.5.0 Synopsis:            Programming language with non-linear pattern-matching against unfree data Description:   An interpreter for Egison, the programming langugage that realized non-linear pattern-matching against unfree data types.
hs-src/Interpreter/egison.hs view
@@ -1,10 +1,12 @@ module Main where -import Prelude hiding ( catch )+import Prelude hiding (catch) import Control.Exception ( AsyncException(..), catch ) import Control.Monad.Error  import qualified Data.Text as T+import Data.Char+import Data.List (intercalate)  import Data.Version @@ -14,6 +16,7 @@ import System.Console.Haskeline hiding (handle, catch, throwTo) import System.Console.GetOpt import System.Exit (ExitCode (..), exitWith, exitFailure)+import System.IO  import Language.Egison import Language.Egison.Util@@ -25,43 +28,61 @@           case opts of             Options {optShowHelp = True} -> printHelp             Options {optShowVersion = True} -> printVersionNumber-            Options {optEvalString = mExpr, optExecuteString = mCmd, optLoadFiles = loadFiles, optPrompt = prompt, optShowBanner = bannerFlag, optNoIO = noIOFlag} -> do-              env <- if noIOFlag then initialEnvNoIO else initialEnv-              result <- evalEgisonTopExprs env (map LoadFile loadFiles)-              case result of+            Options {optEvalString = mExpr, optExecuteString = mCmd, optSubstituteString = mSub, optFieldInfo = fieldInfo, optLoadLibs = loadLibs, optLoadFiles = loadFiles, optPrompt = prompt, optShowBanner = bannerFlag, optTsvOutput = tsvFlag, optNoIO = noIOFlag} -> do+              coreEnv <- if noIOFlag then initialEnvNoIO else initialEnv+              mEnv <- evalEgisonTopExprs coreEnv $ (map Load loadLibs) ++ (map LoadFile loadFiles)+              case mEnv of                 Left err -> putStrLn $ show err                 Right env -> do                   case mExpr of-                    Just expr -> do-                      ret <- runEgisonExpr env expr-                      case ret of-                        Left err -> putStrLn $ show err-                        Right val -> putStrLn $ show val+                    Just expr ->+                      if tsvFlag+                        then do ret <- runEgisonTopExprs env ("(execute (each (compose show-tsv print) " ++ expr ++ "))")+                                case ret of+                                  Left err -> hPutStrLn stderr $ show err+                                  Right _ -> return ()+                        else do ret <- runEgisonExpr env expr+                                case ret of+                                  Left err -> hPutStrLn stderr (show err) >> exitFailure+                                  Right val -> putStrLn (show val) >> exitWith ExitSuccess                     Nothing ->                       case mCmd of-                        Just cmd -> runEgisonTopExpr env ("(execute " ++ cmd ++ ")") >> return ()+                        Just cmd -> do cmdRet <- runEgisonTopExpr env ("(execute " ++ cmd ++ ")")+                                       case cmdRet of+                                         Left err -> putStrLn (show err) >> exitFailure+                                         _ -> exitWith ExitSuccess                         Nothing ->-                          case nonOpts of-                            [] -> do-                              when bannerFlag showBanner >> repl noIOFlag env prompt >> when bannerFlag showByebyeMessage-                            (file:args) -> do-                              case opts of-                                Options {optTestOnly = True} -> do-                                  result <- if noIOFlag-                                              then do input <- readFile file-                                                      runEgisonTopExprsNoIO env input-                                              else evalEgisonTopExprsTestOnly env [LoadFile file]-                                  either print (const $ return ()) result-                                Options {optTestOnly = False} -> do-                                  result <- evalEgisonTopExprs env [LoadFile file, Execute (ApplyExpr (VarExpr "main") (CollectionExpr (map (ElementExpr . StringExpr) (map T.pack args))))]-                                  either print (const $ return ()) result+                          case mSub of+                            Just sub -> do cmdRet <- runEgisonTopExprs env ("(load \"lib/core/shell.egi\") (execute (each (compose " ++ (if tsvFlag then "show-tsv" else "show") ++ " print) (let {[$SH.input (SH.gen-input {" ++ intercalate " " (map fst fieldInfo) ++  "} {" ++ intercalate " " (map snd fieldInfo) ++  "})]} (" ++ sub ++ " SH.input))))")+                                           case cmdRet of+                                             Left err -> putStrLn (show err) >> exitFailure+                                             _ -> exitWith ExitSuccess+                            Nothing ->+                              case nonOpts of+                                [] -> do+                                  when bannerFlag showBanner >> repl noIOFlag env prompt >> when bannerFlag showByebyeMessage >> exitWith ExitSuccess+                                (file:args) -> do+                                  case opts of+                                    Options {optTestOnly = True} -> do+                                      result <- if noIOFlag+                                                  then do input <- readFile file+                                                          runEgisonTopExprsNoIO env input+                                                  else evalEgisonTopExprsTestOnly env [LoadFile file]+                                      either print (const $ return ()) result+                                    Options {optTestOnly = False} -> do+                                      result <- evalEgisonTopExprs env [LoadFile file, Execute (ApplyExpr (VarExpr "main") (CollectionExpr (map (ElementExpr . StringExpr) (map T.pack args))))]+                                      either print (const $ return ()) result  data Options = Options {     optShowVersion :: Bool,     optShowHelp :: Bool,     optEvalString :: Maybe String,     optExecuteString :: Maybe String,+    optSubstituteString :: Maybe String,+    optFieldInfo :: [(String, String)],+    optLoadLibs :: [String],     optLoadFiles :: [String],+    optTsvOutput :: Bool,     optNoIO :: Bool,     optShowBanner :: Bool,     optTestOnly :: Bool,@@ -74,7 +95,11 @@     optShowHelp = False,     optEvalString = Nothing,     optExecuteString = Nothing,+    optSubstituteString = Nothing,+    optFieldInfo = [],+    optLoadLibs = [],     optLoadFiles = [],+    optTsvOutput = False,     optNoIO = False,     optShowBanner = True,     optTestOnly = False,@@ -89,6 +114,9 @@   Option ['h', '?'] ["help"]     (NoArg (\opts -> opts {optShowHelp = True}))     "show usage information",+  Option ['T'] ["tsv"]+    (NoArg (\opts -> opts {optTsvOutput = True}))+    "output in tsv format",   Option ['e'] ["eval"]     (ReqArg (\expr opts -> opts {optEvalString = Just expr})             "String")@@ -97,10 +125,14 @@     (ReqArg (\expr opts -> opts {optExecuteString = Just expr})             "String")     "execute the argument string",+  Option ['L'] ["load-library"]+    (ReqArg (\d opts -> opts {optLoadLibs = optLoadLibs opts ++ [d]})+            "[String]")+    "load library",   Option ['l'] ["load-file"]     (ReqArg (\d opts -> opts {optLoadFiles = optLoadFiles opts ++ [d]})             "[String]")-    "load files",+    "load file",   Option [] ["no-io"]     (NoArg (\opts -> opts {optNoIO = True}))     "prohibit all io primitives",@@ -113,25 +145,68 @@   Option ['p'] ["prompt"]     (ReqArg (\prompt opts -> opts {optPrompt = prompt})             "String")-    "set prompt string"+    "set prompt string",+  Option ['s'] ["substitute"]+    (ReqArg (\expr opts -> opts {optSubstituteString = Just expr})+            "String")+    "substitute strings",+  Option ['m'] ["map"]+    (ReqArg (\expr opts -> opts {optSubstituteString = Just ("(map " ++ expr ++ " $)")})+            "String")+    "filter strings",+  Option ['f'] ["filter"]+    (ReqArg (\expr opts -> opts {optSubstituteString = Just ("(filter " ++ expr ++ " $)")})+            "String")+    "filter strings",+  Option ['F'] ["--field"]+    (ReqArg (\d opts -> opts {optFieldInfo = optFieldInfo opts ++ [(readFieldOption d)]})+            "String")+    "field information"   ] +readFieldOption :: String -> (String, String)+readFieldOption str =+   let (s, rs) = span isDigit str in+   case rs of+     ',':rs' -> let (e, opts) = span isDigit rs' in+                case opts of+                  ['s'] -> ("{" ++ s ++ " " ++ e ++ "}", "")+                  ['c'] -> ("{}", "{" ++ s ++ " " ++ e ++ "}")+                  ['s', 'c'] -> ("{" ++ s ++ " " ++ e ++ "}", "{" ++ s ++ " " ++ e ++ "}")+                  ['c', 's'] -> ("{" ++ s ++ " " ++ e ++ "}", "{" ++ s ++ " " ++ e ++ "}")+     ['s'] -> ("{" ++ s ++ "}", "")+     ['c'] -> ("", "{" ++ s ++ "}")+     ['s', 'c'] -> ("{" ++ s ++ "}", "{" ++ s ++ "}")+     ['c', 's'] -> ("{" ++ s ++ "}", "{" ++ s ++ "}")+ printHelp :: IO () printHelp = do   putStrLn "Usage: egison [options]"   putStrLn "       egison [options] file"+  putStrLn "       egison [options] expr"   putStrLn ""-  putStrLn "Options:"+  putStrLn "Global Options:"   putStrLn "  --help, -h                 Display this information"   putStrLn "  --version, -v              Display egison version information"-  putStrLn "  --eval, -e string          Evaluate the argument string"-  putStrLn "  --command, -c string       Execute the argument string"-  putStrLn "  --load-file, -l string     Load the argument file"-  putStrLn "  --test, -t                 Run only test expressions"+  putStrLn ""+  putStrLn "  --load-library, -L file    Load the argument library"+  putStrLn "  --load-file, -l file       Load the argument file"+  putStrLn "  --no-io                    Prohibit all IO primitives"+  putStrLn ""+  putStrLn "Options as an interactive interpreter:"   putStrLn "  --prompt string            Set prompt of the interpreter"   putStrLn "  --no-banner                Don't show banner"-  putStrLn "  --no-io                    Prohibit all IO primitives"   putStrLn ""+  putStrLn "Options to handle Egison program file:"+  putStrLn "  --test, -t file            Run only test expressions"+  putStrLn ""+  putStrLn "Options as a shell command:"+  putStrLn "  --eval, -e expr            Evaluate the argument expression"+  putStrLn "  --command, -c expr         Execute the argument expression"+  putStrLn ""+  putStrLn "  --substitute, -s expr      Substitute input using the argument expression"+  putStrLn "  --map, -m expr             Substitute each line of input using the argument expression"+  putStrLn "  --filter, -f expr          Filter each line of input using the argument predicate"   exitWith ExitSuccess  printVersionNumber :: IO ()@@ -150,9 +225,7 @@ --  putStrLn $ "*****************"  showByebyeMessage :: IO ()-showByebyeMessage = do-  putStrLn $ "Leaving Egison Interpreter."-  exitWith ExitSuccess+showByebyeMessage = putStrLn $ "Leaving Egison Interpreter."  repl :: Bool -> Env -> String -> IO () repl noIOFlag env prompt = do
hs-src/Language/Egison/Core.hs view
@@ -185,6 +185,9 @@        IntKey _ -> do          let keys' = map (\key -> case key of IntKey i -> i) keys          return . Intermediate . IIntHash $ HL.fromList $ zip keys' refs+       CharKey _ -> do+         let keys' = map (\key -> case key of CharKey c -> c) keys+         return . Intermediate . ICharHash $ HL.fromList $ zip keys' refs        StrKey _ -> do           let keys' = map (\key -> case key of StrKey s -> s) keys           return . Intermediate . IStrHash $ HL.fromList $ zip keys' refs@@ -193,6 +196,7 @@   makeHashKey (Value val) =     case val of       Integer i -> return (IntKey i)+      Char c -> return (CharKey c)       String str -> return (StrKey str)       _ -> throwError $ TypeMismatch "integer or string" $ Value val   makeHashKey whnf = throwError $ TypeMismatch "integer or string" $ whnf@@ -284,6 +288,27 @@   evalExprDeep env expr1   evalExpr env expr2 +evalExpr env@(loopCxts, frames) (LoopExpr name (LoopRange start end WildCard) expr1 expr2) = do+  startNum <- evalExpr env start >>= fromWHNF+  startNumRef <- newEvalutedObjectRef $ Value $ Integer startNum+  end' <- evalExpr env end+  endRef <- newEvalutedObjectRef end'+  endNum <- evalRef endRef >>= fromWHNF+  if startNum > endNum+    then evalExpr (loopCxts, frames) expr2+    else evalExpr (((LoopExprContext (name, startNumRef) endRef expr1 expr2):loopCxts), frames) expr1++evalExpr env@(loopCxts, frames) ContExpr = do+  case loopCxts of+    [] -> throwError $ strMsg "cannot use cont expr except in loop expr"+    ((LoopExprContext (name, startNumRef) endRef expr1 expr2):loopCxts') -> do+      startNum <- evalRef startNumRef >>= fromWHNF+      nextNumRef <- newEvalutedObjectRef $ Value $ Integer (startNum + 1)+      endNum <- evalRef endRef >>= fromWHNF+      if startNum >= endNum+       then evalExpr (loopCxts', frames) expr2+       else evalExpr (((LoopExprContext (name, nextNumRef) endRef expr1 expr2):loopCxts'), frames) expr1+ evalExpr env (ApplyExpr func arg) = do   func <- evalExpr env func   arg <- evalExpr env arg@@ -363,6 +388,9 @@ evalWHNF (Intermediate (IIntHash refs)) = do   refs' <- mapM evalRefDeep refs   return $ IntHash refs'+evalWHNF (Intermediate (ICharHash refs)) = do+  refs' <- mapM evalRefDeep refs+  return $ CharHash refs' evalWHNF (Intermediate (IStrHash refs)) = do   refs' <- mapM evalRefDeep refs   return $ StrHash refs'@@ -424,6 +452,16 @@   case HL.lookup key hash of     Just ref -> evalRef ref >>= flip refArray indices     Nothing -> return $ Value Undefined+refArray (Value (CharHash hash)) (index:indices) = do+  key <- fromEgison index+  case HL.lookup key hash of+    Just val -> refArray (Value val) indices+    Nothing -> return $ Value Undefined+refArray (Intermediate (ICharHash hash)) (index:indices) = do+  key <- fromEgison index+  case HL.lookup key hash of+    Just ref -> evalRef ref >>= flip refArray indices+    Nothing -> return $ Value Undefined refArray (Value (StrHash hash)) (index:indices) = do   key <- fromEgison index   case HL.lookup key hash of@@ -614,14 +652,14 @@           endsRef <- newEvalutedObjectRef ends'           inners <- liftIO $ newIORef $ Sq.fromList [IElement endsRef]           endsRef' <- liftIO $ newIORef (WHNF (Intermediate (ICollection inners)))-          return $ msingleton $ MState env ((LoopContext (name, startNumRef) endsRef' endPat pat pat'):loops) bindings ((MAtom ContPat target matcher):trees)+          return $ msingleton $ MState env ((LoopPatContext (name, startNumRef) endsRef' endPat pat pat'):loops) bindings ((MAtom ContPat target matcher):trees)         else do           endsRef <- newEvalutedObjectRef ends'-          return $ msingleton $ MState env ((LoopContext (name, startNumRef) endsRef endPat pat pat'):loops) bindings ((MAtom ContPat target matcher):trees)+          return $ msingleton $ MState env ((LoopPatContext (name, startNumRef) endsRef endPat pat pat'):loops) bindings ((MAtom ContPat target matcher):trees)     ContPat ->       case loops of         [] -> throwError $ strMsg "cannot use cont pattern except in loop pattern"-        LoopContext (name, startNumRef) endsRef endPat pat pat' : loops' -> do+        LoopPatContext (name, startNumRef) endsRef endPat pat pat' : loops' -> do           startNum <- evalRef startNumRef >>= fromWHNF           nextNumRef <- newEvalutedObjectRef $ Value $ Integer (startNum + 1)           ends <- evalRef endsRef@@ -633,8 +671,8 @@               carEndsNum <- evalRef carEndsRef >>= fromWHNF               if startNum == carEndsNum                 then return $ fromList [MState env loops' bindings ((MAtom endPat startNumRef Something):(MAtom pat' target matcher):trees),-                                        MState env ((LoopContext (name, nextNumRef) cdrEndsRef endPat pat pat'):loops') bindings ((MAtom pat target matcher):trees)]-                else return $ fromList [MState env ((LoopContext (name, nextNumRef) endsRef endPat pat pat'):loops') bindings ((MAtom pat target matcher):trees)]+                                        MState env ((LoopPatContext (name, nextNumRef) cdrEndsRef endPat pat pat'):loops') bindings ((MAtom pat target matcher):trees)]+                else return $ fromList [MState env ((LoopPatContext (name, nextNumRef) endsRef endPat pat pat'):loops') bindings ((MAtom pat target matcher):trees)]     AndPat patterns ->       let trees' = map (\pat -> MAtom pat target matcher) patterns ++ trees       in return $ msingleton $ MState env loops bindings trees'@@ -832,8 +870,8 @@       unsnocCollection coll unsnocCollection _ = matchFail -extendEnvForNonLinearPatterns :: Env -> [Binding] -> [LoopContext] -> Env-extendEnvForNonLinearPatterns env bindings loops =  extendEnv env $ bindings ++ map (\(LoopContext binding _ _ _ _) -> binding) loops+extendEnvForNonLinearPatterns :: Env -> [Binding] -> [LoopPatContext] -> Env+extendEnvForNonLinearPatterns env bindings loops =  extendEnv env $ bindings ++ map (\(LoopPatContext binding _ _ _ _) -> binding) loops  evalMatcherWHNF :: WHNFData -> EgisonM Matcher evalMatcherWHNF (Value matcher@Something) = return matcher@@ -890,6 +928,7 @@ -- data EgisonHashKey =     IntKey Integer+  | CharKey Char   | StrKey Text  extractPrimitiveValue :: WHNFData -> Either EgisonError EgisonValue
hs-src/Language/Egison/Desugar.hs view
@@ -43,6 +43,9 @@ desugarTopExpr (Test expr) = do   expr' <- liftEgisonM $ runDesugarM $ desugar expr   return (Test expr')+desugarTopExpr (Execute expr) = do+  expr' <- liftEgisonM $ runDesugarM $ desugar expr+  return (Execute expr') desugarTopExpr expr = return expr  desugarExpr :: EgisonExpr -> EgisonM EgisonExpr
hs-src/Language/Egison/Parser.hs view
@@ -156,6 +156,7 @@  expr' :: Parser EgisonExpr expr' = (try constantExpr+             <|> contExpr              <|> try varExpr              <|> inductiveDataExpr              <|> try arrayExpr@@ -183,6 +184,7 @@                          <|> matcherBFSExpr                          <|> matcherDFSExpr                          <|> seqExpr+                         <|> loopExpr                          <|> applyExpr                          <|> algebraicDataMatcherExpr                          <|> generateArrayExpr@@ -350,6 +352,12 @@  seqExpr :: Parser EgisonExpr seqExpr = keywordSeq >> SeqExpr <$> expr <*> expr++loopExpr :: Parser EgisonExpr+loopExpr = keywordLoop >> LoopExpr <$> varName <*> loopRange <*> expr <*> expr++contExpr :: Parser EgisonExpr+contExpr = reservedOp "..." >> pure ContExpr  applyExpr :: Parser EgisonExpr applyExpr = (keywordApply >> ApplyExpr <$> expr <*> expr) 
hs-src/Language/Egison/Primitives.hs view
@@ -150,7 +150,9 @@              , ("split-string", splitString)                              , ("read", read')+             , ("read-tsv", readTSV)              , ("show", show')+             , ("show-tsv", showTSV')               , ("empty?", isEmpty')              , ("uncons", uncons')@@ -190,8 +192,10 @@  floatUnaryOp :: (Double -> Double) -> PrimitiveFunc floatUnaryOp op = oneArg $ \val -> do-  f <- fromEgison val-  return $ Float $ op f+  case val of+    (Float f) -> return $ Float $ op f+    (Integer i) -> return $ Float $ op (fromIntegral i)+    (Rational r) -> return $ Float $ op (fromRational r)  floatBinaryOp :: (Double -> Double -> Double) -> PrimitiveFunc floatBinaryOp op = twoArgs $ \val val' -> do@@ -425,8 +429,17 @@ read' :: PrimitiveFunc read'= oneArg $ \val -> fromEgison val >>= readExpr . T.unpack >>= evalExprDeep nullEnv +readTSV :: PrimitiveFunc+readTSV= oneArg $ \val -> do rets <- fromEgison val >>= readExprs . T.unpack >>= mapM (evalExprDeep nullEnv)+                             case rets of+                               [ret] -> return ret+                               _ -> return (Tuple rets)+ show' :: PrimitiveFunc show'= oneArg $ \val -> return $ toEgison $ T.pack $ show val++showTSV' :: PrimitiveFunc+showTSV'= oneArg $ \val -> return $ toEgison $ T.pack $ showTSV val  -- -- Collection
hs-src/Language/Egison/Types.hs view
@@ -1,6 +1,6 @@ {-# Language TypeSynonymInstances, FlexibleInstances, GeneralizedNewtypeDeriving,              MultiParamTypeClasses, UndecidableInstances, DeriveDataTypeable,-             TypeFamilies #-}+             TypeFamilies, TupleSections #-} {- | Module      : Language.Egison.Types Copyright   : Satoshi Egi@@ -27,6 +27,7 @@     , Matcher (..)     , PrimitiveFunc (..)     , EgisonData (..)+    , showTSV     -- * Internal data     , Object (..)     , ObjectRef (..)@@ -41,6 +42,7 @@     , nullEnv     , extendEnv     , refVar+    , LoopExprContext (..)     -- * Pattern matching     , Match     , PMMode (..)@@ -48,7 +50,7 @@     , MatchingState (..)     , MatchingTree (..)     , PatternBinding (..)-    , LoopContext (..)+    , LoopPatContext (..)     -- * Errors     , EgisonError (..)     , liftError@@ -97,6 +99,7 @@ import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap +import Data.List (intercalate) import Data.Text (Text) import qualified Data.Text as T @@ -159,6 +162,8 @@   | IoExpr EgisonExpr        | SeqExpr EgisonExpr EgisonExpr+  | LoopExpr String LoopRange EgisonExpr EgisonExpr+  | ContExpr   | ApplyExpr EgisonExpr EgisonExpr    | AlgebraicDataMatcherExpr [(String, [EgisonExpr])]@@ -234,6 +239,7 @@   | Collection (Seq EgisonValue)   | Array (Array.Array Integer EgisonValue)   | IntHash (HashMap Integer EgisonValue)+  | CharHash (HashMap Char EgisonValue)   | StrHash (HashMap Text EgisonValue)   | UserMatcher Env PMMode MatcherInfo   | Func Env [String] EgisonExpr@@ -266,6 +272,7 @@                              else "{" ++ unwords (map show (toList vals)) ++ "}"   show (Array vals) = "[|" ++ unwords (map show $ Array.elems vals) ++ "|]"   show (IntHash hash) = "{|" ++ unwords (map (\(key, val) -> "[" ++ show key ++ " " ++ show val ++ "]") $ HashMap.toList hash) ++ "|}"+  show (CharHash hash) = "{|" ++ unwords (map (\(key, val) -> "[" ++ show key ++ " " ++ show val ++ "]") $ HashMap.toList hash) ++ "|}"   show (StrHash hash) = "{|" ++ unwords (map (\(key, val) -> "[\"" ++ T.unpack key ++ "\" " ++ show val ++ "]") $ HashMap.toList hash) ++ "|}"   show (UserMatcher _ BFSMode _) = "#<matcher-bfs>"   show (UserMatcher _ DFSMode _) = "#<matcher-dfs>"@@ -280,6 +287,11 @@   show World = "#<world>"   show EOF = "#<eof>" +showTSV :: EgisonValue -> String+showTSV (Tuple (val:vals)) = foldl (\r x -> r ++ "\t" ++ x) (show val) (map showTSV vals)+showTSV (Collection vals) = intercalate "\t" (map showTSV (toList vals))+showTSV val = show val+ instance Eq EgisonValue where  (Char c) == (Char c') = c == c'  (String str) == (String str') = str == str'@@ -291,6 +303,7 @@  (Collection vals) == (Collection vals') = vals == vals'  (Array vals) == (Array vals') = vals == vals'  (IntHash vals) == (IntHash vals') = vals == vals'+ (CharHash vals) == (CharHash vals') = vals == vals'  (StrHash vals) == (StrHash vals') = vals == vals'  _ == _ = False @@ -412,6 +425,7 @@   | ICollection (IORef (Seq Inner))   | IArray (Array.Array Integer ObjectRef)   | IIntHash (HashMap Integer ObjectRef)+  | ICharHash (HashMap Char ObjectRef)   | IStrHash (HashMap Text ObjectRef)  data Inner =@@ -425,6 +439,7 @@   show (Intermediate (ICollection _)) = "{...}"   show (Intermediate (IArray _)) = "[|...|]"    show (Intermediate (IIntHash _)) = "{|...|}" +  show (Intermediate (ICharHash _)) = "{|...|}"    show (Intermediate (IStrHash _)) = "{|...|}"   instance Show Object where@@ -499,20 +514,23 @@ -- Environment -- -type Env = [HashMap Var ObjectRef]+type Env = ([LoopExprContext], [HashMap Var ObjectRef]) type Var = String type Binding = (Var, ObjectRef)  nullEnv :: Env-nullEnv = []+nullEnv = ([], [])  extendEnv :: Env -> [Binding] -> Env-extendEnv env = (: env) . HashMap.fromList+extendEnv env = ([],) . (: (snd env)) . HashMap.fromList  refVar :: Env -> Var -> EgisonM ObjectRef refVar env var = maybe (throwError $ UnboundVariable var) return-                       (msum $ map (HashMap.lookup var) env)+                       (msum $ map (HashMap.lookup var) (snd (extendEnv env (map (\(LoopExprContext binding _ _ _) -> binding) (fst env))))) +data LoopExprContext = LoopExprContext Binding ObjectRef EgisonExpr EgisonExpr+ deriving (Show)+ -- -- Pattern Match --@@ -527,7 +545,7 @@ pmMode (Tuple _) = DFSMode pmMode Something = DFSMode -data MatchingState = MState Env [LoopContext] [Binding] [MatchingTree]+data MatchingState = MState Env [LoopPatContext] [Binding] [MatchingTree]  deriving (Show)  data MatchingTree =@@ -537,7 +555,7 @@  type PatternBinding = (Var, EgisonPattern) -data LoopContext = LoopContext Binding ObjectRef EgisonPattern EgisonPattern EgisonPattern+data LoopPatContext = LoopPatContext Binding ObjectRef EgisonPattern EgisonPattern EgisonPattern  deriving (Show)  --
lib/core/base.egi view
@@ -16,7 +16,9 @@    (define $id (lambda [$x] x)) -(define $bool builtin-data-matcher)+(define $fst (lambda [$x $y] x))++(define $snd (lambda [$x $y] y))(define $bool builtin-data-matcher)  (define $or   (lambda [$b1 $b2]
lib/core/collection.egi view
@@ -26,10 +26,10 @@          [_ {}]}]        [<join $ $> [(list a) (list a)]         {[$tgt (match-all tgt (list a)-                 [(loop $i [1 $n] <cons $xa_i ...> $rs) [(map (lambda [$i] xa_i) (between 1 n)) rs]])]}]+                 [(loop $i [1 $n] <cons $xa_i ...> $rs) [(loop $i [1 n] {xa_i @...} {}) rs]])]}]        [<nioj $ $> [(list a) (list a)]         {[$tgt (match-all tgt (list a)-                 [(loop $i [1 $n] <snoc $xa_i ...> $rs) [(map (lambda [$i] xa_i) (between 1 n)) rs]])]}]+                 [(loop $i [1 $n] <snoc $xa_i ...> $rs) [(loop $i [1 n] {xa_i @...} {}) rs]])]}]        [$ [something]         {[$tgt {tgt}]}]        })))@@ -48,10 +48,10 @@        [<join $ <cons ,$px $>> [(ordered-list a) (ordered-list a)]         {[{} {}]          [$tgt (match-all tgt (list a)-                 [(loop $i [1 $n] <cons (& ?(lt? $ px) $xa_i) ...> <cons ,px $rs>) [(map (lambda [$i] xa_i) (between 1 n)) rs]])]}]+                 [(loop $i [1 $n] <cons (& ?(lt? $ px) $xa_i) ...> <cons ,px $rs>) [(loop $i [1 n] {xa_i @...} {}) rs]])]}]        [<join $ $> [(ordered-list a) (ordered-list a)]         {[$tgt (match-all tgt (list a)-                 [(loop $i [1 $n] <cons $xa_i ...> $rs) [(map (lambda [$i] xa_i) (between 1 n)) rs]])]}]+                 [(loop $i [1 $n] <cons $xa_i ...> $rs) [(loop $i [1 n] {xa_i @...} {}) rs]])]}]        [<cons ,$px $> [(ordered-list a)]         {[{$x @$xs} (if (gt? x px)                       {}@@ -62,7 +62,7 @@          [_ {}]}]        [<nioj $ $> [(ordered-list a) (ordered-list a)]         {[$tgt (match-all tgt (list a)-                 [(loop $i [1 $n] <snoc $xa_i ...> $rs) [(map (lambda [$i] xa_i) (between 1 n)) rs]])]}]+                 [(loop $i [1 $n] <snoc $xa_i ...> $rs) [(loop $i [1 n] {xa_i @...} {}) rs]])]}]        [<snoc ,$px $> [a (ordered-list a)]         {[{@$xs $x} (if (lt? x px)                       {}@@ -86,12 +86,11 @@  (define $between   (lambda [$s $e]-    (if (gt? (+ s 10) e)-      (if (gt? s e)-        {}-        {s @(between (+ s 1) e)})-      {s (+ s 1) (+ s 2) (+ s 3) (+ s 4) (+ s 5) (+ s 6) (+ s 7) (+ s 8) (+ s 9) (+ s 10) @(between (+ s 11) e)})-    ))+    (if (eq? s e)+      {s}+      (if (lt? s e)+        {s @(between (+ s 1) e)}+        {s @(between (- s 1) e)}))))  (define $from   (lambda [$s]@@ -124,12 +123,6 @@         (let {[$z (fn init x)]}           (seq z (foldl' fn z xs)))]}))) -(define $foldl-naive-  (lambda [$fn $init $ls]-    (match ls (list something)-      {[<nil> init]-       [<cons $x $xs> (foldl fn (fn init x) xs)]})))- (define $filter   (lambda [$pred $xs]     (foldr (lambda [$y $ys] (if (pred y) {y @ys} ys))@@ -237,17 +230,23 @@ ;; (define $length   (lambda [$xs]-    (foldl' (lambda [$x $y] (+ x 1)) 0 xs)))+    (foldl (lambda [$r $x] (+ r 1)) 0 xs)))  (define $count   (lambda [$x $xs]-    (length (match-all xs (list something)-              [<join _ <cons ,x _>> x]))))+    (foldl (match-lambda [something something]+             {[[$r ,x] (+ r 1)]+              [[$r $y] r]})+           0+           xs)))  (define $count/m   (lambda [$a $x $xs]-    (length (match-all xs (list a)-              [<join _ <cons ,x _>> x]))))+    (foldl (match-lambda [a a]+             {[[$r ,x] (+ r 1)]+              [[$r $y] r]})+           0+           xs)))  (define $frequency   (lambda [$xs]@@ -387,7 +386,7 @@        })))  ;;-;; multiset operation (Don't use multiset matcher)+;; multiset operation ;; (define $add   (lambda [$x $xs]
lib/core/io.egi view
@@ -11,6 +11,7 @@   (lambda [$x]     (do {[(write x)]          [(write "\n")]+         [(flush)]          })))  (define $print-to-port
lib/core/math.egi view
@@ -6,11 +6,7 @@  (define $fact   (lambda [$n]-    (letrec {[$fact1 (lambda [$n $ret]-                       (match n integer-                         {[,0 ret]-                          [_ (fact1 (- n 1) (* n ret))]}))]}-      (fact1 n 1))))+    (foldl * 1 (between 1 n))))  (define $perm   (lambda [$n $r]
lib/core/number.egi view
@@ -48,6 +48,10 @@  (define $nats0 {0 @nats}) +(define $odds {1 @(map (+ $ 2) odds)})++(define $evens {2 @(map (+ $ 2) odds)})+ (define $primes   (letrec {[$next-primes             (lambda [$primes1 $k]@@ -122,9 +126,49 @@  (define $sum   (lambda [$xs]-    (foldl' + 0 xs)))+    (foldl + 0 xs)))  ;;; ;;; Float Numbers ;;; (define $float builtin-data-matcher)++;;;+;;; Decimal Fractions+;;;+(define $decimal (algebraic-data-matcher {<df integer (list integer)>}))+(define $decimal' (algebraic-data-matcher {<df' integer (list integer) (list integer)>}))++(define $rtod-helper+  (lambda [$m $n]+    (let {[$q (quotient (* m 10) n)]+          [$r (remainder (* m 10) n)]}+      {[q r] @(rtod-helper r n)})))++(define $rtod+  (lambda [$x]+    (let {[$m (numerator x)]+          [$n (denominator x)]}+      (let {[$q (quotient m n)]+            [$r (remainder m n)]}+          <Df q (map (lambda [$x $y] x) (rtod-helper r n))>))))++(define $rtod'+  (lambda [$x]+    (let {[$m (numerator x)]+          [$n (denominator x)]}+      (let {[$q (quotient m n)]+            [$r (remainder m n)]}+        (let {[[$s $c] (match (rtod-helper r n) (list [integer integer])+                         {[<join $s <cons $x <join $c <cons ,x _>>>> [s {x @c}]]})]}+          <Df' q (map (lambda [$x $y] x) s) (map (lambda [$x $y] x) c)>)))))++(define $show-decimal+  (lambda [$n $x]+    (match (rtod x) decimal+      {[<df $q $sc> (foldl S.append (S.append (show q) ".") (map show (take n sc)))]})))++(define $show-decimal'+  (lambda [$x]+    (match (rtod' x) decimal'+      {[<df' $q $s $c> (foldl S.append "" {(S.append (show q) ".") @(map show s) " " @(map show c) " ..."})]})))
+ lib/core/shell.egi view
@@ -0,0 +1,58 @@+(define $SH.gen-input+  (lambda [$sopts $copts]+    (if (io (eof?))+      {}+      (let {[$x (io (TSV.read-line sopts copts))]}+        (seq x {x @(SH.gen-input sopts copts)})))))++(define $TSV.read-line+  (lambda [$sopts $copts]+    (do {[$line (read-line)]}+      (let {[$fs (S.split "\t" line)]}+        (letrec {[$fn-s (match-lambda [(list (list integer)) (list string)]+                          {[[<nil> $fs] fs]+                           [[<cons <cons $m <nil>> $opts'>+                             <join (& $hs ?(lambda [$hs] (eq? (- m 1) (length hs))))+                                   $ts>]+                            (fn-s opts' {@hs @(map (lambda [$t] (S.concat {"\"" t "\""})) ts)})]+                           [[<cons <cons $m <cons ,m <nil>>> $opts'>+                             <join (& $hs ?(lambda [$hs] (eq? (- m 1) (length hs))))+                                   <cons $mf $ts>>]+                            (fn-s opts' {@hs (S.concat {"\"" mf "\""}) @ts})]+                           [[<cons <cons $m <cons $n <nil>>> $opts'>+                             <join (& $hs ?(lambda [$hs] (eq? (- m 1) (length hs))))+                                   <join (& $ms ?(lambda [$ms] (eq? (+ (- n m) 1) (length ms))))+                                         $ts>>]+                            (fn-s opts' {@hs @(map (lambda [$m] (S.concat {"\"" m "\""})) ms) @ts})]+                           [[<cons <cons $m <cons _ <nil>>> $opts'>+                             _]+                            (fn-s {{m} @opts'} fs)]+                           [[_ _] fs]+                           })]+                 [$fn-c (match-lambda [(list (list integer)) (list string)]+                          {[[<nil> $fs] fs]+                           [[<cons <cons $m <nil>> $opts'>+                             <join (& $hs ?(lambda [$hs] (eq? (- m 1) (length hs))))+                                   <cons $mf <nil>>>]+                            (fn-c opts' {@hs (S.concat {"{" mf "}"})})]+                           [[<cons <cons $m <nil>> $opts'>+                             <join (& $hs ?(lambda [$hs] (eq? (- m 1) (length hs))))+                                   <cons $mf <snoc $tf $ms>>>]+                            (fn-c opts' {@hs (S.append "{" mf) @ms (S.append tf "}")})]+                           [[<cons <cons $m <cons ,m <nil>>> $opts'>+                             <join (& $hs ?(lambda [$hs] (eq? (- m 1) (length hs))))+                                   <cons $mf $ts>>]+                            (fn-c opts' {@hs (S.concat {"{" mf "}"}) @ts})]+                           [[<cons <cons $m <cons $n <nil>>> $opts'>+                             <join (& $hs ?(lambda [$hs] (eq? (- m 1) (length hs))))+                                   <cons $mf <join (& $ms ?(lambda [$ms] (eq? (- n m 1) (length ms))))+                                                   <cons $nf $ts>>>>]+                            (fn-c opts' {@hs (S.append "{" mf) @ms (S.append nf "}") @ts})]+                           [[<cons <cons $m <cons _ <nil>>> $opts'>+                             _]+                            (fn-c {{m} @opts'} fs)]+                           [[_ _] fs]+                           })]}+          (return (read-tsv (S.intercalate "\t" (fn-c copts (fn-s sopts fs))))))))))++(define $TSV.show (show-tsv $))
+ sample/pi.egi view
@@ -0,0 +1,23 @@+(define $pi+  (lambda [$n]+    (/ 4+       (+ 1+          (foldr (lambda [$x $r]+                   (/ (power x 2)+                      (+ (+ (* x 2) 1)+                         r)))+                 0+                 (take n nats))))))++(test (pi 5))+(test (rtod' (pi 5)))+(test (show-decimal' (pi 5)))+(test (pi 6))+(test (rtod' (pi 6)))+(test (show-decimal' (pi 6)))+(test (pi 7))+(test (show-decimal 10 (pi 7)))+(test (pi 100))+(test (rtof (pi 100)))+(test (show-decimal 100 (pi 100)))+
sample/salesman.egi view
@@ -2,35 +2,34 @@ ;;; Travelling Salesman Problem ;;; -(define $station string)  ; 駅は文字列として表現-(define $price   integer) ; 運賃は整数値として表現-(define $graph   (multiset [station (multiset [station price])])) ; 運賃グラフのマッチャー+(define $station string)+(define $price   integer)+(define $graph   (multiset [station (multiset [station price])])) -(define $graph-data ; 運賃データ+(define $graph-data   {-   ["東京"   {             ["新宿" 200] ["渋谷" 200] ["三鷹" 390] ["錦糸町" 160] ["北千住" 220]}]-   ["新宿"   {["東京" 200]              ["渋谷" 160] ["三鷹" 220] ["錦糸町" 220] ["北千住" 310]}]-   ["渋谷"   {["東京" 200] ["新宿" 160]              ["三鷹" 310] ["錦糸町" 220] ["北千住" 310]}]-   ["三鷹"   {["東京" 390] ["新宿" 220] ["渋谷" 310]              ["錦糸町" 470] ["北千住" 550]}]-   ["錦糸町" {["東京" 160] ["新宿" 220] ["渋谷" 220] ["三鷹" 470]                ["北千住" 220]}]-   ["北千住" {["東京" 220] ["新宿" 310] ["渋谷" 310] ["三鷹" 550] ["錦糸町" 220]               }]+   ["Tokyo"     {              ["Shinjuku" 200] ["Shibuya" 200] ["Mitaka" 390] ["Kinshicho" 160] ["Kitasenju" 220]}]+   ["Shinjuku"  {["Tokyo" 200]                  ["Shibuya" 160] ["Mitaka" 220] ["Kinshicho" 220] ["Kitasenju" 310]}]+   ["Shibuya"   {["Tokyo" 200] ["Shinjuku" 160]                 ["Mitaka" 310] ["Kinshicho" 220] ["Kitasenju" 310]}]+   ["Mitaka"    {["Tokyo" 390] ["Shinjuku" 220] ["Shibuya" 310]                ["Kinshicho" 470] ["Kitasenju" 550]}]+   ["Kinshicho" {["Tokyo" 160] ["Shinjuku" 220] ["Shibuya" 220] ["Mitaka" 470]                   ["Kitasenju" 220]}]+   ["Kitasenju" {["Tokyo" 220] ["Shinjuku" 310] ["Shibuya" 310] ["Mitaka" 550] ["Kinshicho" 220]                  }]    }) -(define $trips ; 全ての経路をパターンマッチを用いて列挙+(define $trips ; List up all routes that visit each city exactly once and return to Tokyo   (match-all graph-data graph-    [<cons [,"東京" <cons [$s_1 $p_1] _>]+    [<cons [,"Tokyo" <cons [$s_1 $p_1] _>]            (loop $i [2 5]              <cons [,s_(- i 1) <cons [$s_i $p_i] _>]                    ...>-             <cons [,s_5 <cons [(& ,"東京" $s_6) $p_6] _>]+             <cons [,s_5 <cons [(& ,"Tokyo" $s_6) $p_6] _>]                    _>)>      [(sum (map (lambda [$i] p_i) (between 1 6)))       s]]))  (define $main   (lambda [$args]-    (do {[(print "経路一覧:")]-         [(each (compose show print) trips)]                       ; 全ての経路を出力-         [(write "最安値:")]-         [(print (show (min (map (lambda [$x $y] x) trips))))]}))) ; 最安値を出力-+    (do {[(print "Route list:")]+         [(each (compose show print) trips)]+         [(write "Lowest price:")]+         [(print (show (min (map (lambda [$x $y] x) trips))))]})))