packages feed

egison 3.9.3 → 3.9.4

raw patch · 37 files changed

+3388/−2072 lines, 37 filesdep +prettyprinterdep ~basenew-component:exe:egison-translatePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: prettyprinter

Dependency ranges changed: base

API changes (from Hackage documentation)

- Language.Egison.Desugar: data DesugarM a
- Language.Egison.Desugar: desugar :: EgisonExpr -> DesugarM EgisonExpr
- Language.Egison.Desugar: instance Control.Monad.Error.Class.MonadError Language.Egison.Types.EgisonError Language.Egison.Desugar.DesugarM
- Language.Egison.Desugar: instance Control.Monad.Fail.MonadFail Language.Egison.Desugar.DesugarM
- Language.Egison.Desugar: instance Control.Monad.Reader.Class.MonadReader Language.Egison.Desugar.Subst Language.Egison.Desugar.DesugarM
- Language.Egison.Desugar: instance GHC.Base.Applicative Language.Egison.Desugar.DesugarM
- Language.Egison.Desugar: instance GHC.Base.Functor Language.Egison.Desugar.DesugarM
- Language.Egison.Desugar: instance GHC.Base.Monad Language.Egison.Desugar.DesugarM
- Language.Egison.Desugar: instance Language.Egison.Types.MonadFresh Language.Egison.Desugar.DesugarM
- Language.Egison.Desugar: runDesugarM :: DesugarM a -> Fresh (Either EgisonError a)
- Language.Egison.ParserNonS2: instance GHC.Classes.Eq Language.Egison.ParserNonS2.CustomError
- Language.Egison.ParserNonS2: instance GHC.Classes.Ord Language.Egison.ParserNonS2.CustomError
- Language.Egison.ParserNonS2: instance Text.Megaparsec.Error.ShowErrorComponent Language.Egison.ParserNonS2.CustomError
- Language.Egison.ParserNonS2: loadFile :: FilePath -> EgisonM [EgisonTopExpr]
- Language.Egison.ParserNonS2: loadLibraryFile :: FilePath -> EgisonM [EgisonTopExpr]
- Language.Egison.ParserNonS2: parseExpr :: String -> Either EgisonError EgisonExpr
- Language.Egison.ParserNonS2: parseExprs :: String -> Either EgisonError [EgisonExpr]
- Language.Egison.ParserNonS2: parseTopExpr :: String -> Either EgisonError EgisonTopExpr
- Language.Egison.ParserNonS2: parseTopExprs :: String -> Either EgisonError [EgisonTopExpr]
- Language.Egison.ParserNonS2: readExpr :: String -> EgisonM EgisonExpr
- Language.Egison.ParserNonS2: readExprs :: String -> EgisonM [EgisonExpr]
- Language.Egison.ParserNonS2: readTopExpr :: String -> EgisonM EgisonTopExpr
- Language.Egison.ParserNonS2: readTopExprs :: String -> EgisonM [EgisonTopExpr]
- Language.Egison.Types: WedgeExpr :: EgisonExpr -> EgisonExpr
- Language.Egison.Types: [optUseNonS2] :: EgisonOpts -> Bool
- Language.Egison.Types: type MatcherInfo = [(PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])]
+ Language.Egison.ParserNonS: instance GHC.Classes.Eq Language.Egison.ParserNonS.CustomError
+ Language.Egison.ParserNonS: instance GHC.Classes.Ord Language.Egison.ParserNonS.CustomError
+ Language.Egison.ParserNonS: instance Text.Megaparsec.Error.ShowErrorComponent Language.Egison.ParserNonS.CustomError
+ Language.Egison.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty Language.Egison.Types.Arg
+ Language.Egison.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty Language.Egison.Types.EgisonExpr
+ Language.Egison.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty Language.Egison.Types.EgisonPattern
+ Language.Egison.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty Language.Egison.Types.EgisonTopExpr
+ Language.Egison.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty Language.Egison.Types.InnerExpr
+ Language.Egison.Pretty: instance Data.Text.Prettyprint.Doc.Internal.Pretty Language.Egison.Types.Var
+ Language.Egison.Pretty: prettyTopExprs :: [EgisonTopExpr] -> Doc [EgisonTopExpr]
+ Language.Egison.Types: type PatternDef = (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])
- Language.Egison.Types: EgisonOpts :: Maybe (String, [String]) -> Bool -> Maybe String -> Maybe String -> [(String, String)] -> [String] -> [String] -> Maybe String -> Maybe String -> Maybe String -> Bool -> Bool -> Bool -> Bool -> String -> Maybe String -> Bool -> Bool -> EgisonOpts
+ Language.Egison.Types: EgisonOpts :: Maybe (String, [String]) -> Bool -> Maybe String -> Maybe String -> [(String, String)] -> [String] -> [String] -> Maybe String -> Maybe String -> Maybe String -> Bool -> Bool -> Bool -> Bool -> String -> Maybe String -> Bool -> EgisonOpts
- Language.Egison.Types: Float :: Double -> Double -> EgisonValue
+ Language.Egison.Types: Float :: Double -> EgisonValue
- Language.Egison.Types: FloatExpr :: Double -> Double -> EgisonExpr
+ Language.Egison.Types: FloatExpr :: Double -> EgisonExpr
- Language.Egison.Types: MatcherExpr :: MatcherInfo -> EgisonExpr
+ Language.Egison.Types: MatcherExpr :: [PatternDef] -> EgisonExpr
- Language.Egison.Types: UserMatcher :: Env -> MatcherInfo -> EgisonValue
+ Language.Egison.Types: UserMatcher :: Env -> [PatternDef] -> EgisonValue

Files

egison.cabal view
@@ -1,5 +1,5 @@ Name:                egison-Version:             3.9.3+Version:             3.9.4 Synopsis:            Programming language with non-linear pattern-matching against non-free data Description:   An interpreter for Egison, a **pattern-matching-oriented**, purely functional programming language.@@ -61,8 +61,12 @@  Data-files:          lib/core/*.egi lib/math/*.egi lib/math/common/*.egi lib/math/algebra/*.egi lib/math/analysis/*.egi lib/math/geometry/*.egi                      sample/*.egi sample/io/*.egi sample/math/algebra/*.egi sample/math/analysis/*.egi sample/math/geometry/*.egi sample/math/number/*.egi sample/math/others/*.egi+                     test/*.egi test/lib/core/*.egi test/lib/math/*.egi+                     nons-test/test/*.egi nons-test/test/lib/core/*.egi+                     test/answer/sample/*.egi test/answer/sample/math/geometry/*.egi test/answer/sample/math/number/*.egi                      elisp/egison-mode.el + source-repository head   type: git   location: https://github.com/egison/egison.git@@ -89,6 +93,7 @@     , vector     , split     , hashable+    , prettyprinter   if !impl(ghc > 8.0)     Build-Depends: fail   Hs-Source-Dirs:  hs-src@@ -99,7 +104,7 @@                    Language.Egison.Types                    Language.Egison.Parser                    Language.Egison.ParserNonS-                   Language.Egison.ParserNonS2+                   Language.Egison.Pretty                    Language.Egison.Primitives                    Language.Egison.Util                    Language.Egison.MathOutput@@ -160,3 +165,12 @@   Hs-Source-Dirs:      hs-src/Interpreter   Other-modules:       Paths_egison   ghc-options:  -O3 -threaded -eventlog -rtsopts++Executable egison-translate+  Main-is:          translator.hs+  Build-depends:+      egison+    , base >= 4.0 && < 5+    , prettyprinter+    , split+  Hs-Source-Dirs:   hs-src/Tool
hs-src/Interpreter/egison.hs view
@@ -111,10 +111,7 @@             <*> flag True False                   (short 'N'                   <> long "new-syntax"-                  <> help "Use non-S-expressoin syntax")-            <*> flag False True-                  (long "N2"-                  <> help "[experimental] Use new lexer and parser")+                  <> help "[experimental] Use non-S expression syntax")  readFieldOption :: String -> (String, String) readFieldOption str =
hs-src/Language/Egison.hs view
@@ -37,7 +37,6 @@ import           Language.Egison.MathOutput  (changeOutputInLang) import           Language.Egison.Parser      as Parser import           Language.Egison.ParserNonS  as ParserNonS-import           Language.Egison.ParserNonS2 as ParserNonS2 import           Language.Egison.Primitives import           Language.Egison.Types @@ -80,30 +79,26 @@ -- |eval an Egison expression. Input is a Haskell string. runEgisonExpr :: EgisonOpts -> Env -> String -> IO (Either EgisonError EgisonValue) runEgisonExpr opts env input-  | optUseNonS2 opts = fromEgisonM $ ParserNonS2.readExpr input >>= evalExprDeep env-  | optSExpr opts    = fromEgisonM $ Parser.readExpr input >>= evalExprDeep env-  | otherwise        = fromEgisonM $ ParserNonS.readExpr input >>= evalExprDeep env+  | optSExpr opts = fromEgisonM $ Parser.readExpr input >>= evalExprDeep env+  | otherwise     = fromEgisonM $ ParserNonS.readExpr input >>= evalExprDeep env  -- |eval an Egison top expression. Input is a Haskell string. runEgisonTopExpr :: EgisonOpts -> Env -> String -> IO (Either EgisonError Env) runEgisonTopExpr opts env input-  | optUseNonS2 opts = fromEgisonM $ ParserNonS2.readTopExpr input >>= evalTopExpr opts env-  | optSExpr opts    = fromEgisonM $ Parser.readTopExpr input >>= evalTopExpr opts env-  | otherwise        = fromEgisonM $ ParserNonS.readTopExpr input >>= evalTopExpr opts env+  | optSExpr opts = fromEgisonM $ Parser.readTopExpr input >>= evalTopExpr opts env+  | otherwise     = fromEgisonM $ ParserNonS.readTopExpr input >>= evalTopExpr opts env  -- |eval an Egison top expression. Input is a Haskell string. runEgisonTopExpr' :: EgisonOpts -> StateT [(Var, EgisonExpr)] EgisonM Env -> String -> IO (Either EgisonError (Maybe String, StateT [(Var, EgisonExpr)] EgisonM Env)) runEgisonTopExpr' opts st input-  | optUseNonS2 opts = fromEgisonM $ ParserNonS2.readTopExpr input >>= evalTopExpr' opts st-  | optSExpr opts    = fromEgisonM $ Parser.readTopExpr input >>= evalTopExpr' opts st-  | otherwise        = fromEgisonM $ ParserNonS.readTopExpr input >>= evalTopExpr' opts st+  | optSExpr opts = fromEgisonM $ Parser.readTopExpr input >>= evalTopExpr' opts st+  | otherwise     = fromEgisonM $ ParserNonS.readTopExpr input >>= evalTopExpr' opts st  -- |eval Egison top expressions. Input is a Haskell string. runEgisonTopExprs :: EgisonOpts -> Env -> String -> IO (Either EgisonError Env) runEgisonTopExprs opts env input-  | optUseNonS2 opts = fromEgisonM $ ParserNonS2.readTopExprs input >>= evalTopExprs opts env-  | optSExpr opts    = fromEgisonM $ Parser.readTopExprs input >>= evalTopExprs opts env-  | otherwise        = fromEgisonM $ ParserNonS.readTopExprs input >>= evalTopExprs opts env+  | optSExpr opts = fromEgisonM $ Parser.readTopExprs input >>= evalTopExprs opts env+  | otherwise     = fromEgisonM $ ParserNonS.readTopExprs input >>= evalTopExprs opts env  -- |load an Egison file loadEgisonFile :: EgisonOpts -> Env -> FilePath -> IO (Either EgisonError Env)@@ -116,10 +111,10 @@ -- |Environment that contains core libraries initialEnv :: EgisonOpts -> IO Env initialEnv opts = do-  env <- if optNoIO opts then if optUseNonS2 opts then primitiveEnvNoIO'-                                                  else primitiveEnvNoIO-                         else if optUseNonS2 opts then primitiveEnv'-                                                  else primitiveEnv+  env <- if optNoIO opts then if optSExpr opts then primitiveEnvNoIO+                                               else primitiveEnvNoIO'+                         else if optSExpr opts then primitiveEnv+                                               else primitiveEnv'   ret <- evalEgisonTopExprs defaultOption env $ map Load coreLibraries   case ret of     Left err -> do
hs-src/Language/Egison/Core.hs view
@@ -66,7 +66,6 @@  import           Language.Egison.Parser      as Parser import           Language.Egison.ParserNonS  as ParserNonS-import           Language.Egison.ParserNonS2 as ParserNonS2 import           Language.Egison.Types  --@@ -84,7 +83,6 @@       if optNoIO opts          then throwError $ Default "No IO support"          else do exprs' <- if-                   | optUseNonS2 opts -> ParserNonS2.loadFile file                    | optSExpr opts    -> Parser.loadFile file                    | otherwise        -> ParserNonS.loadFile file                  collectDefs opts (exprs' ++ exprs) bindings rest@@ -92,7 +90,6 @@       if optNoIO opts          then throwError $ Default "No IO support"          else do exprs' <- if-                   | optUseNonS2 opts -> ParserNonS2.loadLibraryFile file                    | optSExpr opts    -> Parser.loadLibraryFile file                    | otherwise        -> ParserNonS.loadLibraryFile file                  collectDefs opts (exprs' ++ exprs) bindings rest@@ -126,7 +123,7 @@ evalExpr _ (StringExpr s) = return $ Value $ toEgison s evalExpr _ (BoolExpr b) = return . Value $ Bool b evalExpr _ (IntegerExpr x) = return . Value $ toEgison x-evalExpr _ (FloatExpr x y) = return . Value $ Float x y+evalExpr _ (FloatExpr x) = return . Value $ Float x  evalExpr env (QuoteExpr expr) = do   whnf <- evalExpr env expr@@ -1553,7 +1550,7 @@ extractPrimitiveValue (Value val@(Char _)) = return val extractPrimitiveValue (Value val@(Bool _)) = return val extractPrimitiveValue (Value val@(ScalarData _)) = return val-extractPrimitiveValue (Value val@(Float _ _)) = return val+extractPrimitiveValue (Value val@(Float _)) = return val extractPrimitiveValue whnf =   -- we don't need to extract call stack since detailed error information is not used   throwError $ TypeMismatch "primitive value" whnf@@ -1562,5 +1559,5 @@ isPrimitiveValue (Value (Char _))       = True isPrimitiveValue (Value (Bool _))       = True isPrimitiveValue (Value (ScalarData _)) = True-isPrimitiveValue (Value (Float _ _))    = True+isPrimitiveValue (Value (Float _))      = True isPrimitiveValue _                      = False
hs-src/Language/Egison/Desugar.hs view
@@ -13,62 +13,35 @@  module Language.Egison.Desugar     (-      DesugarM-    , runDesugarM-    , desugarTopExpr+      desugarTopExpr     , desugarExpr-    , desugar     ) where -import           Control.Applicative   (Applicative, pure, (<$>), (<*>))-import           Control.Monad.Except-import           Control.Monad.Fail-import           Control.Monad.Reader import           Data.Char             (toUpper)-import           Data.List             (find, span)-import           Data.Maybe            (fromJust, fromMaybe)+import           Data.List             (span) import           Data.Set              (Set) import qualified Data.Set              as S  import           Language.Egison.Types -type Subst = [(String, EgisonExpr)]--newtype DesugarM a = DesugarM { unDesugarM :: ReaderT Subst (ExceptT EgisonError Fresh) a }-  deriving (Functor, Applicative, Monad, MonadError EgisonError, MonadFresh, MonadReader Subst)--instance MonadFail DesugarM where-    fail msg = throwError =<< EgisonBug msg <$> getFuncNameStack--runDesugarM :: DesugarM a -> Fresh (Either EgisonError a)-runDesugarM = runExceptT . flip runReaderT [] . unDesugarM- desugarTopExpr :: EgisonTopExpr -> EgisonM EgisonTopExpr-desugarTopExpr (Define name expr) = do-  expr' <- liftEgisonM $ runDesugarM $ desugar expr-  return (Define name expr')-desugarTopExpr (Redefine name expr) = do-  expr' <- liftEgisonM $ runDesugarM $ desugar expr-  return (Redefine name expr')-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+desugarTopExpr (Define name expr)   = Define name <$> desugar expr+desugarTopExpr (Redefine name expr) = Redefine name <$> desugar expr+desugarTopExpr (Test expr)          = Test <$> desugar expr+desugarTopExpr (Execute expr)       = Execute <$> desugar expr+desugarTopExpr expr                 = return expr  desugarExpr :: EgisonExpr -> EgisonM EgisonExpr-desugarExpr expr = liftEgisonM $ runDesugarM $ desugar expr+desugarExpr = desugar -desugar :: EgisonExpr -> DesugarM EgisonExpr+desugar :: EgisonExpr -> EgisonM EgisonExpr desugar (AlgebraicDataMatcherExpr patterns) = do   matcherName <- freshV   let matcherRef = VarExpr matcherName   matcher <- genMatcherClauses patterns matcherRef   return $ LetRecExpr [([matcherName], matcher)] matcherRef     where-      genMatcherClauses :: [(String, [EgisonExpr])] ->  EgisonExpr -> DesugarM EgisonExpr+      genMatcherClauses :: [(String, [EgisonExpr])] ->  EgisonExpr -> EgisonM EgisonExpr       genMatcherClauses patterns matcher = do         main <- genMainClause patterns matcher         body <- mapM genMatcherClause patterns@@ -76,7 +49,7 @@         let clauses = [main] ++ body ++ [footer]         return $ MatcherExpr clauses -      genMainClause :: [(String, [EgisonExpr])] -> EgisonExpr -> DesugarM (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])+      genMainClause :: [(String, [EgisonExpr])] -> EgisonExpr -> EgisonM (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])       genMainClause patterns matcher = do         clauses <- genClauses patterns         return (PPValuePat "val", TupleExpr []@@ -84,34 +57,34 @@                                             (TupleExpr [matcher, matcher])                                              clauses)])         where-          genClauses :: [(String, [EgisonExpr])] -> DesugarM [MatchClause]+          genClauses :: [(String, [EgisonExpr])] -> EgisonM [MatchClause]           genClauses patterns = (++) <$> mapM genClause patterns                                      <*> pure [(TuplePat [WildCard, WildCard], matchingFailure)] -          genClause :: (String, [EgisonExpr]) -> DesugarM MatchClause+          genClause :: (String, [EgisonExpr]) -> EgisonM MatchClause           genClause pattern = do             (pat0, pat1) <- genMatchingPattern pattern             return (TuplePat [pat0, pat1], matchingSuccess) -          genMatchingPattern :: (String, [EgisonExpr]) -> DesugarM (EgisonPattern, EgisonPattern)+          genMatchingPattern :: (String, [EgisonExpr]) -> EgisonM (EgisonPattern, EgisonPattern)           genMatchingPattern (name, patterns) = do             names <- mapM (const freshV) patterns             return (InductivePat name (map PatVar names),                     InductivePat name (map (ValuePat . VarExpr) names)) -      genMatcherClause :: (String, [EgisonExpr]) -> DesugarM (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])+      genMatcherClause :: (String, [EgisonExpr]) -> EgisonM (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])       genMatcherClause pattern = do         (ppat, matchers) <- genPrimitivePatPat pattern         (dpat, body)     <- genPrimitiveDataPat pattern         return (ppat, TupleExpr matchers, [(dpat, CollectionExpr [ElementExpr . TupleExpr $ body]), (PDWildCard, matchingFailure)])          where-          genPrimitivePatPat :: (String, [EgisonExpr]) -> DesugarM (PrimitivePatPattern, [EgisonExpr])+          genPrimitivePatPat :: (String, [EgisonExpr]) -> EgisonM (PrimitivePatPattern, [EgisonExpr])           genPrimitivePatPat (name, matchers) = do             patterns' <- mapM (const $ return PPPatVar) matchers             return (PPInductivePat name patterns', matchers) -          genPrimitiveDataPat :: (String, [EgisonExpr]) -> DesugarM (PrimitiveDataPattern, [EgisonExpr])+          genPrimitiveDataPat :: (String, [EgisonExpr]) -> EgisonM (PrimitiveDataPattern, [EgisonExpr])           genPrimitiveDataPat (name, patterns) = do             patterns' <- mapM (const freshV) patterns             return (PDInductivePat (capitalize name) $ map (PDPatVar . show) patterns', map VarExpr patterns')@@ -120,7 +93,7 @@           capitalize (x:xs) = toUpper x : xs  -      genSomethingClause :: DesugarM (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])+      genSomethingClause :: EgisonM (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])       genSomethingClause =         return (PPPatVar, TupleExpr [SomethingExpr], [(PDPatVar "tgt", CollectionExpr [ElementExpr (stringToVarExpr "tgt")])]) @@ -186,10 +159,8 @@ desugar (UserrefsExpr bool expr1 expr2) =   UserrefsExpr bool <$> desugar expr1 <*> desugar expr2 -desugar (PowerExpr expr1 expr2) = do-  expr1' <- desugar expr1-  expr2' <- desugar expr2-  return $ ApplyExpr (stringToVarExpr "**") (TupleExpr [expr1', expr2'])+desugar (PowerExpr expr1 expr2) =+  (\x y -> makeApply "**" [x, y]) <$> desugar expr1 <*> desugar expr2  desugar (ArrayBoundsExpr expr) =   ArrayBoundsExpr <$> desugar expr@@ -359,15 +330,12 @@ desugar (CApplyExpr expr0 expr1) =   CApplyExpr <$> desugar expr0 <*> desugar expr1 -desugar (VarExpr name) =-  asks $ fromMaybe (VarExpr name) . lookup (show name)- desugar FreshVarExpr = do   id <- fresh   return $ stringToVarExpr (":::" ++ id) -desugar (MatcherExpr matcherInfo) =-  MatcherExpr <$> desugarMatcherInfo matcherInfo+desugar (MatcherExpr patternDefs) =+  MatcherExpr <$> mapM desugarPatternDef patternDefs  desugar (PartialVarExpr n) = return $ PartialVarExpr n @@ -381,18 +349,18 @@ desugar (QuoteSymbolExpr expr) =   QuoteSymbolExpr <$> desugar expr -desugar (WedgeExpr (ApplyExpr expr0 expr1)) =+desugar (WedgeApplyExpr expr0 expr1) =   WedgeApplyExpr <$> desugar expr0 <*> desugar expr1  desugar expr = return expr -desugarIndex :: Index EgisonExpr -> DesugarM (Index EgisonExpr)+desugarIndex :: Index EgisonExpr -> EgisonM (Index EgisonExpr) desugarIndex (Superscript expr)  = Superscript  <$> desugar expr desugarIndex (Subscript expr)    = Subscript    <$> desugar expr desugarIndex (SupSubscript expr) = SupSubscript <$> desugar expr desugarIndex (Userscript expr)   = Userscript   <$> desugar expr -desugarPattern :: EgisonPattern -> DesugarM EgisonPattern+desugarPattern :: EgisonPattern -> EgisonM EgisonPattern desugarPattern pattern = LetPat (map makeBinding $ S.elems $ collectName pattern) <$> desugarPattern' pattern  where    collectNames :: [EgisonPattern] -> Set String@@ -419,7 +387,7 @@    makeBinding :: String -> BindingExpr    makeBinding name = ([stringToVar name], HashExpr []) -desugarPattern' :: EgisonPattern -> DesugarM EgisonPattern+desugarPattern' :: EgisonPattern -> EgisonM EgisonPattern desugarPattern' (ValuePat expr) = ValuePat <$> desugar expr desugarPattern' (PredPat expr) = PredPat <$> desugar expr desugarPattern' (NotPat pattern) = NotPat <$> desugarPattern' pattern@@ -467,25 +435,23 @@ desugarPattern' (PowerPat pattern1 pattern2) = PowerPat <$> desugarPattern' pattern1 <*> desugarPattern' pattern2 desugarPattern' pattern = return pattern -desugarLoopRange :: LoopRange -> DesugarM LoopRange+desugarLoopRange :: LoopRange -> EgisonM LoopRange desugarLoopRange (LoopRange sExpr eExpr pattern) =   LoopRange <$> desugar sExpr <*> desugar eExpr <*> desugarPattern' pattern -desugarBindings :: [BindingExpr] -> DesugarM [BindingExpr]+desugarBindings :: [BindingExpr] -> EgisonM [BindingExpr] desugarBindings = mapM f   where f (name, expr) = (name,) <$> desugar expr -desugarMatchClauses :: [MatchClause] -> DesugarM [MatchClause]+desugarMatchClauses :: [MatchClause] -> EgisonM [MatchClause] desugarMatchClauses = mapM f   where f (pattern, expr) = (,) <$> desugarPattern pattern <*> desugar expr -desugarMatcherInfo :: MatcherInfo -> DesugarM MatcherInfo-desugarMatcherInfo = mapM f-  where-    f (pp, matcher, pds) =-      (pp,,) <$> desugar matcher <*> desugarPrimitiveDataMatchClauses pds+desugarPatternDef :: PatternDef -> EgisonM PatternDef+desugarPatternDef (pp, matcher, pds) =+  (pp,,) <$> desugar matcher <*> desugarPrimitiveDataMatchClauses pds -desugarPrimitiveDataMatchClauses :: [(PrimitiveDataPattern, EgisonExpr)] -> DesugarM [(PrimitiveDataPattern, EgisonExpr)]+desugarPrimitiveDataMatchClauses :: [(PrimitiveDataPattern, EgisonExpr)] -> EgisonM [(PrimitiveDataPattern, EgisonExpr)] desugarPrimitiveDataMatchClauses = mapM f   where f (pd, expr) = (pd,) <$> desugar expr 
hs-src/Language/Egison/MathOutput.hs view
@@ -3,71 +3,58 @@ Copyright   : Satoshi Egi Licence     : MIT -This module provides utility functions.+This module provides translation from mathematical Egison expression into+other languages / format of other computer algebra systems. -} -module Language.Egison.MathOutput ( changeOutputInLang ) where+module Language.Egison.MathOutput+  ( changeOutputInLang+  ) where +import           Data.List                     (intercalate)+ import           Text.ParserCombinators.Parsec hiding (spaces)  changeOutputInLang :: String -> String -> String-changeOutputInLang "haskell" input     = mathExprToHaskell input-changeOutputInLang "asciimath" input   = mathExprToAsciiMath input-changeOutputInLang "latex" input       = mathExprToLatex input-changeOutputInLang "mathematica" input = mathExprToMathematica input-changeOutputInLang "maxima" input      = mathExprToMaxima input-changeOutputInLang _ input             = input--mathExprToHaskell :: String -> String-mathExprToHaskell input = case parse parseExpr "math-expr" input of-                            Left err  -> input-                            Right val -> "#haskell|" ++ show val ++ "|#"--mathExprToAsciiMath :: String -> String-mathExprToAsciiMath input = case parse parseExpr "math-expr" input of-                              Left err -> input-                              Right val -> case showMathExprAsciiMath val of-                                             "undefined" -> "undefined"-                                             output -> "#asciimath|" ++ output ++ "|#"--mathExprToLatex :: String -> String-mathExprToLatex input = case parse parseExpr "math-expr" input of-                          Left err -> input-                          Right val -> case showMathExprLatex val of-                                         "undefined" -> "undefined"-                                         output -> "#latex|" ++ output ++ "|#"+changeOutputInLang lang input =+  -- 'lang' is either "asciimath", "latex", "mathematica" or "maxima"+  -- Other invalid options are rejected in Interpreter/egison.hs+  case parse parseExpr "math-expr" input of+    Left err  -> input+    Right val -> case showMathExpr lang val of+                   "undefined" -> "undefined"+                   output      -> "#" ++ lang ++ "|" ++ output ++ "|#" -mathExprToMathematica :: String -> String-mathExprToMathematica input = case parse parseExpr "math-expr" input of-                                Left err -> input-                                Right val -> case showMathExprMathematica val of-                                               "undefined" -> "undefined"-                                               output -> "#mathematica|" ++ output ++ "|#"+showMathExpr :: String -> MathExpr -> String+showMathExpr "asciimath"   = showMathExprAsciiMath+showMathExpr "latex"       = showMathExprLatex+showMathExpr "mathematica" = showMathExprMathematica+showMathExpr "maxima"      = showMathExprMaxima+showMathExpr "haskell"     = show -mathExprToMaxima :: String -> String-mathExprToMaxima input = case parse parseExpr "math-expr" input of-                          Left err -> input-                          Right val -> case showMathExprMaxima val of-                                         "undefined" -> "undefined"-                                         output -> "#maxima|" ++ output ++ "|#"+data MathExpr+  = Atom String [MathIndex]+  | NegativeAtom String+  | Plus [MathExpr]+  | Multiply [MathExpr]+  | Power MathExpr MathExpr+  | Func MathExpr [MathExpr]+  | Tensor [MathExpr] [MathIndex]+  | Tuple [MathExpr]+  | Collection [MathExpr]+  | Exp MathExpr+  | Quote MathExpr+  | Partial MathExpr [MathExpr]+  deriving (Eq, Show) -data MathExpr = Atom String [MathIndex]-              | NegativeAtom String-              | Plus [MathExpr]-              | Multiply [MathExpr]-              | Power MathExpr MathExpr-              | Func MathExpr [MathExpr]-              | Tensor [MathExpr] [MathIndex]-              | Tuple [MathExpr]-              | Collection [MathExpr]-              | Exp MathExpr-              | Quote MathExpr-              | Partial MathExpr [MathExpr]-              deriving (Eq, Show)+data MathIndex+  = Super MathExpr+  | Sub MathExpr+  deriving (Eq, Show) -data MathIndex = Super MathExpr-              | Sub MathExpr-              deriving (Eq, Show)+isSub :: MathIndex -> Bool+isSub (Sub _) = True+isSub _       = False  -- -- Show (AsciiMath)@@ -103,22 +90,16 @@ showMathExprAsciiMath (Collection lvs) = "{" ++ showMathExprAsciiMathArg lvs ++ "}" showMathExprAsciiMath (Exp x) = "e^(" ++ showMathExprAsciiMath x ++ ")" -isSub :: MathIndex -> Bool-isSub (Sub _) = True-isSub _       = False- showMathExprAsciiMath' :: MathExpr -> String showMathExprAsciiMath' (Plus lvs) = "(" ++ showMathExprAsciiMath (Plus lvs) ++ ")" showMathExprAsciiMath' val = showMathExprAsciiMath val  showMathExprAsciiMathArg :: [MathExpr] -> String-showMathExprAsciiMathArg [] = ""-showMathExprAsciiMathArg [a] = showMathExprAsciiMath a-showMathExprAsciiMathArg lvs = showMathExprAsciiMath (head lvs) ++ ", " ++ showMathExprAsciiMathArg (tail lvs)+showMathExprAsciiMathArg exprs = intercalate ", " $ map showMathExprAsciiMath exprs  showMathExprAsciiMathIndices :: [MathIndex] -> String-showMathExprAsciiMathIndices [a] = showMathIndexAsciiMath a-showMathExprAsciiMathIndices lvs = showMathIndexAsciiMath (head lvs) ++ showMathExprAsciiMathIndices (tail lvs)+showMathExprAsciiMathIndices []  = error "unreachable"+showMathExprAsciiMathIndices lvs = concatMap showMathIndexAsciiMath lvs  showMathIndexAsciiMath :: MathIndex -> String showMathIndexAsciiMath (Super a) = showMathExprAsciiMath a@@ -174,9 +155,7 @@ showMathExprLatex' x         = showMathExprLatex x  showMathExprLatexArg :: [MathExpr] -> String -> String-showMathExprLatexArg [] _ = ""-showMathExprLatexArg [a] _ = showMathExprLatex a-showMathExprLatexArg lvs s = showMathExprLatex (head lvs) ++ s ++ showMathExprLatexArg  (tail lvs) s+showMathExprLatexArg exprs sep = intercalate sep $ map showMathExprLatex exprs  showMathExprLatexSuper :: MathIndex -> String showMathExprLatexSuper (Super (Atom "#" [])) = "\\#"@@ -242,16 +221,14 @@ showMathExprMathematica' x = showMathExprMathematica x  showMathExprsMathematica :: String -> [MathExpr] -> String-showMathExprsMathematica _ [] = ""-showMathExprsMathematica _ [a] = showMathExprMathematica a-showMathExprsMathematica s lvs = showMathExprMathematica (head lvs) ++ s ++ showMathExprsMathematica s (tail lvs)+showMathExprsMathematica sep exprs = intercalate sep $ map showMathExprMathematica exprs  showMathExprMathematicaArg :: [MathExpr] -> String-showMathExprMathematicaArg xs = showMathExprsMathematica ", " xs+showMathExprMathematicaArg = showMathExprsMathematica ", "  showMathExprMathematicaIndices :: [MathIndex] -> String-showMathExprMathematicaIndices [a] = showMathIndexMathematica a-showMathExprMathematicaIndices lvs = showMathIndexMathematica (head lvs) ++ showMathExprMathematicaIndices (tail lvs)+showMathExprMathematicaIndices []  = error "unreachable"+showMathExprMathematicaIndices lvs = concatMap showMathIndexMathematica lvs  showMathIndexMathematica :: MathIndex -> String showMathIndexMathematica (Super a) = showMathExprMathematica a
hs-src/Language/Egison/Parser.hs view
@@ -57,10 +57,10 @@ readTopExpr = either throwError desugarTopExpr . parseTopExpr  readExprs :: String -> EgisonM [EgisonExpr]-readExprs = liftEgisonM . runDesugarM . either throwError (mapM desugar) . parseExprs+readExprs = either throwError (mapM desugarExpr) . parseExprs  readExpr :: String -> EgisonM EgisonExpr-readExpr = liftEgisonM . runDesugarM . either throwError desugar . parseExpr+readExpr = either throwError desugarExpr . parseExpr  parseTopExprs :: String -> Either EgisonError [EgisonTopExpr] parseTopExprs = doParse $ do@@ -167,29 +167,21 @@ loadExpr = keywordLoad >> Load <$> stringLiteral  expr :: Parser EgisonExpr-expr = P.lexeme lexer (do expr0 <- expr' <|> quoteExpr'+expr = P.lexeme lexer (do expr0 <- expr' <|> quoteExpr                           expr1 <- option expr0 $ try (string "..." >> IndexedExpr False expr0 <$> parseindex)                                                   <|> IndexedExpr True expr0 <$> parseindex                           option expr1 $ PowerExpr expr1 <$> try (char '^' >> expr'))                             where parseindex :: Parser [Index EgisonExpr]-                                  parseindex = many1 (try (do-                                                           char '_'-                                                           e1 <- expr'-                                                           string "..._"-                                                           MultiSubscript e1 <$> expr')-                                                 <|> try (do-                                                           char '~'-                                                           e1 <- expr'-                                                           string "...~"-                                                           MultiSuperscript e1 <$> expr')-                                                 <|> try (Subscript <$> (char '_' >> expr'))-                                                 <|> try (Superscript <$> (char '~' >> expr'))-                                                 <|> try (SupSubscript <$> (string "~_" >> expr'))-                                                 <|> try (Userscript <$> (char '|' >> expr')))+                                  parseindex = many1 (try (MultiSubscript   <$> (char '_' >> expr') <*> (string "..._" >> expr'))+                                                  <|> try (MultiSuperscript <$> (char '~' >> expr') <*> (string "...~" >> expr'))+                                                  <|> try (Subscript    <$> (char '_' >> expr'))+                                                  <|> try (Superscript  <$> (char '~' >> expr'))+                                                  <|> try (SupSubscript <$> (string "~_" >> expr'))+                                                  <|> try (Userscript   <$> (char '|' >> expr')))  -quoteExpr' :: Parser EgisonExpr-quoteExpr' = char '\'' >> QuoteExpr <$> expr'+quoteExpr :: Parser EgisonExpr+quoteExpr = char '\'' >> QuoteExpr <$> expr'  expr' :: Parser EgisonExpr expr' = try partialExpr@@ -203,7 +195,6 @@             <|> try tupleExpr             <|> try hashExpr             <|> collectionExpr---            <|> quoteExpr             <|> quoteSymbolExpr             <|> wedgeExpr             <|> parens (ifExpr@@ -287,11 +278,11 @@     pairExpr :: Parser (EgisonExpr, EgisonExpr)     pairExpr = brackets $ (,) <$> expr <*> expr -quoteExpr :: Parser EgisonExpr-quoteExpr = char '\'' >> QuoteExpr <$> expr- wedgeExpr :: Parser EgisonExpr-wedgeExpr = char '!' >> WedgeExpr <$> expr+wedgeExpr = do+  e <- char '!' >> expr+  case e of+    ApplyExpr e1 e2 -> return $ WedgeApplyExpr e1 e2  functionWithArgExpr :: Parser EgisonExpr functionWithArgExpr = keywordFunction >> FunctionExpr <$> between lp rp (sepEndBy expr whiteSpace)@@ -332,10 +323,10 @@ matcherExpr :: Parser EgisonExpr matcherExpr = keywordMatcher >> MatcherExpr <$> ppMatchClauses -ppMatchClauses :: Parser MatcherInfo+ppMatchClauses :: Parser [PatternDef] ppMatchClauses = braces $ sepEndBy ppMatchClause whiteSpace -ppMatchClause :: Parser (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])+ppMatchClause :: Parser PatternDef ppMatchClause = brackets $ (,,) <$> ppPattern <*> expr <*> pdMatchClauses  pdMatchClauses :: Parser [(PrimitiveDataPattern, EgisonExpr)]@@ -706,11 +697,7 @@ boolExpr = BoolExpr <$> boolLiteral  floatExpr :: Parser EgisonExpr-floatExpr = do-  (x,y) <- try ((,) <$> floatLiteral <*> (sign' <*> positiveFloatLiteral) <* char 'i')-            <|> try ((0,)  <$> floatLiteral <* char 'i')-            <|> try ((, 0) <$> floatLiteral)-  return $ FloatExpr x y+floatExpr = FloatExpr <$> positiveFloatLiteral  integerExpr :: Parser EgisonExpr integerExpr = IntegerExpr <$> integerLiteral'@@ -729,9 +716,6 @@   let m = read mStr   let l = m % (10 ^ fromIntegral (length mStr))   return (fromRational (fromIntegral n + l) :: Double)--floatLiteral :: Parser Double-floatLiteral = sign <*> positiveFloatLiteral  -- -- Tokens
hs-src/Language/Egison/ParserNonS.hs view
@@ -1,953 +1,805 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TupleSections    #-}--{- |-Module      : Language.Egison.ParserNonS-Copyright   : Satoshi Egi-Licence     : MIT--This module provide Egison parser.--}--module Language.Egison.ParserNonS-       (-       -- * Parse a string-         readTopExprs-       , readTopExpr-       , readExprs-       , readExpr-       , parseTopExprs-       , parseTopExpr-       , parseExprs-       , parseExpr-       -- * Parse a file-       , loadLibraryFile-       , loadFile-       ) where--import           Control.Applicative     (pure, (*>), (<$>), (<*), (<*>))-import           Control.Monad.Except    (liftIO, throwError)-import           Control.Monad.Identity  (Identity, unless)-import           Prelude                 hiding (mapM)--import           System.Directory        (doesFileExist, getHomeDirectory)--import           Data.Char               (isLower, isUpper, toLower)-import           Data.Either-import           Data.Functor            (($>))-import           Data.List               (intercalate)-import           Data.List.Split         (split, splitOn, startsWithOneOf)-import           Data.Ratio-import           Data.Traversable        (mapM)--import           Text.Parsec-import           Text.Parsec.Expr-import           Text.Parsec.String-import qualified Text.Parsec.Token       as P--import qualified Data.Text               as T--import           Language.Egison.Desugar-import           Language.Egison.Types-import           Paths_egison            (getDataFileName)--readTopExprs :: String -> EgisonM [EgisonTopExpr]-readTopExprs = either throwError (mapM desugarTopExpr) . parseTopExprs--readTopExpr :: String -> EgisonM EgisonTopExpr-readTopExpr = either throwError desugarTopExpr . parseTopExpr--readExprs :: String -> EgisonM [EgisonExpr]-readExprs = liftEgisonM . runDesugarM . either throwError (mapM desugar) . parseExprs--readExpr :: String -> EgisonM EgisonExpr-readExpr = liftEgisonM . runDesugarM . either throwError desugar . parseExpr--parseTopExprs :: String -> Either EgisonError [EgisonTopExpr]-parseTopExprs = doParse $ do-  ret <- whiteSpace >> endBy topExpr whiteSpace-  eof-  return ret--parseTopExpr :: String -> Either EgisonError EgisonTopExpr-parseTopExpr = doParse $ do-  ret <- whiteSpace >> topExpr-  whiteSpace >> eof-  return ret--parseExprs :: String -> Either EgisonError [EgisonExpr]-parseExprs = doParse $ do-  ret <- whiteSpace >> endBy expr whiteSpace-  eof-  return ret--parseExpr :: String -> Either EgisonError EgisonExpr-parseExpr = doParse $ do-  ret <- whiteSpace >> expr-  whiteSpace >> eof-  return ret---- |Load a libary file-loadLibraryFile :: FilePath -> EgisonM [EgisonTopExpr]-loadLibraryFile file = do-  homeDir <- liftIO getHomeDirectory-  doesExist <- liftIO $ doesFileExist $ homeDir ++ "/.egison/" ++ file-  if doesExist-    then loadFile $ homeDir ++ "/.egison/" ++ file-    else liftIO (getDataFileName file) >>= loadFile---- |Load a file-loadFile :: FilePath -> EgisonM [EgisonTopExpr]-loadFile file = do-  doesExist <- liftIO $ doesFileExist file-  unless doesExist $ throwError $ Default ("file does not exist: " ++ file)-  input <- liftIO $ readUTF8File file-  exprs <- readTopExprs $ shebang input-  concat <$> mapM  recursiveLoad exprs- where-  recursiveLoad (Load file)     = loadLibraryFile file-  recursiveLoad (LoadFile file) = loadFile file-  recursiveLoad expr            = return [expr]-  shebang :: String -> String-  shebang ('#':'!':cs) = ';':'#':'!':cs-  shebang cs           = cs------- Parser-----doParse :: Parser a -> String -> Either EgisonError a-doParse p input = either (throwError . fromParsecError) return $ parse p "egison" input-  where-    fromParsecError :: ParseError -> EgisonError-    fromParsecError = Parser . show--doParse' :: Parser a -> String -> a-doParse' p input = case doParse p input of-                     Right x -> x------- Expressions-----topExpr :: Parser EgisonTopExpr-topExpr = try defineExpr-          <|> try (Test <$> expr)-          <|> testExpr-          <|> loadFileExpr-          <|> loadExpr-          <?> "top-level expression"--defineExpr :: Parser EgisonTopExpr-defineExpr = try (Define <$ keywordDefine <*> identVar <*> (LambdaExpr <$> parens argNames' <* inSpaces (reservedOp "=") <* notFollowedBy (string "=") <*> expr))-             <|> try (Define <$> identVar <* inSpaces (reservedOp "=") <* notFollowedBy (string "=") <*> expr)-             <|> try (do (VarWithIndices name is) <- identVarWithIndices-                         inSpaces $ reservedOp "=" >> notFollowedBy (string "=")-                         Define (Var name (map f is)) . WithSymbolsExpr (map g is) . TransposeExpr (CollectionExpr (map (ElementExpr . VarExpr . stringToVar . g) is)) <$> expr)- where-  argNames' :: Parser [Arg]-  argNames' = sepEndBy argName' comma-  argName' :: Parser Arg-  argName' = try (ScalarArg <$> ident)-        <|> try (InvertedScalarArg <$> (char '*' >> ident))-        <|> try (TensorArg <$> (char '%' >> ident))-  f (Superscript _)  = Superscript ()-  f (Subscript _)    = Subscript ()-  f (SupSubscript _) = SupSubscript ()-  g (Superscript i)  = i-  g (Subscript i)    = i-  g (SupSubscript i) = i--testExpr :: Parser EgisonTopExpr-testExpr = keywordTest >> Test <$> parens expr--loadFileExpr :: Parser EgisonTopExpr-loadFileExpr = keywordLoadFile >> LoadFile <$> parens stringLiteral--loadExpr :: Parser EgisonTopExpr-loadExpr = keywordLoad >> Load <$> parens stringLiteral--expr :: Parser EgisonExpr-expr = (try applyInfixExpr-        <|> try exprWithSymbol-        <|> try (buildExpressionParser table arg)-        <|> try ifExpr-        <|> try term)-        <?> "expression"- where-  arg = (char '$' *> notFollowedBy varExpr *> (LambdaArgExpr <$> option "" index))-        <|> term-  index = (:) <$> satisfy (\c -> '1' <= c && c <= '9') <*> many digit-  table = [ [unary "not" AssocRight]-          , [binary "^" "**" AssocLeft]-          , [unary "-" AssocLeft]-          , [binary "*" "*" AssocLeft, binary "/" "/" AssocLeft, binary "." "." AssocLeft]-          , [binary "+" "+" AssocLeft, binary "-" "-" AssocLeft, binary "%" "remainder" AssocLeft]-          , [binary "==" "eq?" AssocLeft, binary "<=" "lte?" AssocLeft, binary "<" "lt?" AssocLeft, binary ">=" "gte?" AssocLeft, binary ">" "gt?" AssocLeft]-          , [binary ":" "cons" AssocLeft, binary ".." "between" AssocLeft]-          , [binary "&&" "and" AssocLeft, binary "||" "or" AssocLeft]-          , [binary "++" "join" AssocRight]-          ]-  unary "-" assoc = Prefix (try $ inSpaces (string "-") >> return (\x -> makeApply (stringToVarExpr "*") [IntegerExpr (-1), x]))-  unary op assoc = Prefix (try $ inSpaces (string op) >> return (\x -> makeApply (stringToVarExpr op) [x]))-  binary op name assoc-    | op == "/" = Infix (try $ (try (inSpaces1 $ string op) <|> (inSpaces (string op) >> notFollowedBy (string "m" <|> string "fn"))) >> return (\x y -> makeApply (stringToVarExpr name) [x, y])) assoc-    | op == "." || op == "%" = Infix (try $ inSpaces1 (string op) >> return (\x y -> makeApply (stringToVarExpr name) [x, y])) assoc-    | otherwise = Infix (try $ inSpaces (string op) >> return (\x y -> makeApply (stringToVarExpr name) [x, y])) assoc--inSpaces :: Parser a -> Parser ()-inSpaces p = skipMany (space <|> newline) >> p >> skipMany (space <|> newline)--inSpaces1 :: Parser a -> Parser ()-inSpaces1 p = skipMany (space <|> newline) >> p >> skipMany1 (space <|> newline)--exprWithSymbol :: Parser EgisonExpr-exprWithSymbol = (string "d/d" >> applyExpr'' (stringToVarExpr "d/d"))-                 <|> (string "V.*" >> applyExpr'' (stringToVarExpr "V.*"))-                 <|> (string "M.*" >> applyExpr'' (stringToVarExpr "M.*"))-                 <|> (lookAhead (string "let*") >> letStarExpr)--term :: Parser EgisonExpr-term = P.lexeme lexer-        (do term0 <- term'-            option term0 $ try (IndexedExpr False term0 <$ string "..." <*> parseindex-                           <|> IndexedExpr True term0 <$> parseindex))- where-  parseindex :: Parser [Index EgisonExpr]-  parseindex = many1 $ try (MultiSubscript <$ char '_' <*> term' <* string "..._" <*> term')-                       <|> try (MultiSuperscript <$ char '~' <*> term' <* string "...~" <*> term')-                       <|> try (char '_' >> Subscript <$> term')-                       <|> try (char '~' >> Superscript <$> term')-                       <|> try (string "~_" >> SupSubscript <$> term')-                       <|> try (char '|' >> Userscript <$> term')--term' :: Parser EgisonExpr-term' = matchExpr-        <|> matchAllExpr-        <|> matchAllDFSExpr-        <|> matchLambdaExpr-        <|> matchAllLambdaExpr-        <|> matcherExpr-        <|> functionWithArgExpr-        <|> userrefsExpr-        <|> algebraicDataMatcherExpr-        <|> try applyExpr-        <|> cApplyExpr-        <|> try partialExpr-        <|> try partialVarExpr-        <|> try constantExpr-        <|> try freshVarExpr-        <|> try lambdaExpr-        <|> try cambdaExpr-        <|> try withSymbolsExpr-        <|> try varExpr-        <|> try vectorExpr-        <|> try tupleExpr-        <|> try hashExpr-        <|> try collectionExpr-        <|> inductiveDataExpr-        <|> try doExpr-        <|> generateTensorExpr-        <|> tensorExpr-        <|> letExpr-        <|> letRecExpr-        <|> letStarExpr-        <|> patternFunctionExpr-        <|> quoteExpr-        <|> quoteSymbolExpr-        <|> tensorContractExpr-        <|> subrefsExpr-        <|> suprefsExpr-        <|> macroExpr-        <|> ioExpr-        <|> seqExpr-        <|> memoizedLambdaExpr-        <|> procedureExpr-        <|> wedgeExpr-        <|> parens expr-        <?> "simple expression"--varExpr :: Parser EgisonExpr-varExpr = VarExpr <$> identVarWithoutIndex--freshVarExpr :: Parser EgisonExpr-freshVarExpr = char '#' >> return FreshVarExpr--inductiveDataExpr :: Parser EgisonExpr-inductiveDataExpr = angles $ InductiveDataExpr <$> upperName <*> sepEndBy term whiteSpace--tupleExpr :: Parser EgisonExpr-tupleExpr = parens $ TupleExpr <$> sepEndBy expr comma--collectionExpr :: Parser EgisonExpr-collectionExpr = brackets (CollectionExpr <$> sepEndBy innerExpr comma)-                 <|> braces (CollectionExpr <$> sepEndBy innerExpr comma)- where-  innerExpr :: Parser InnerExpr-  innerExpr = (char '@' >> SubCollectionExpr <$> expr)-               <|> ElementExpr <$> expr--vectorExpr :: Parser EgisonExpr-vectorExpr = between lp rp $ VectorExpr <$> sepEndBy expr comma-  where-    lp = P.lexeme lexer (string "[|")-    rp = string "|]"--hashExpr :: Parser EgisonExpr-hashExpr = between lp rp $ HashExpr <$> sepEndBy pairExpr comma-  where-    lp = P.lexeme lexer (string "{|")-    rp = string "|}"-    pairExpr :: Parser (EgisonExpr, EgisonExpr)-    pairExpr = brackets $ (,) <$> expr <* comma <*> expr--quoteExpr :: Parser EgisonExpr-quoteExpr = char '\'' >> QuoteExpr <$> expr--wedgeExpr :: Parser EgisonExpr-wedgeExpr = char '!' >> WedgeExpr <$> expr--functionWithArgExpr :: Parser EgisonExpr-functionWithArgExpr = keywordFunction >> FunctionExpr <$> parens (sepEndBy expr comma)--quoteSymbolExpr :: Parser EgisonExpr-quoteSymbolExpr = char '`' >> QuoteSymbolExpr <$> expr--matchAllExpr :: Parser EgisonExpr-matchAllExpr = keywordMatchAll >> MatchAllExpr <$> expr <* keywordAs <*> expr <*> matchClauses--matchAllDFSExpr :: Parser EgisonExpr-matchAllDFSExpr = keywordMatchAllDFS >> MatchAllDFSExpr <$> expr <* keywordAs <*> expr <*> matchClauses--matchExpr :: Parser EgisonExpr-matchExpr = keywordMatch >> MatchExpr <$> expr <* keywordAs <*> expr <*> matchClauses--matchLambdaExpr :: Parser EgisonExpr-matchLambdaExpr = keywordMatchLambda >> MatchLambdaExpr <$ keywordAs <*> expr <*> matchClauses--matchAllLambdaExpr :: Parser EgisonExpr-matchAllLambdaExpr = keywordMatchAllLambda >> MatchAllLambdaExpr <$ keywordAs <*> expr <*> matchClauses--matchClauses :: Parser [MatchClause]-matchClauses = many1 matchClause--matchClause :: Parser MatchClause-matchClause = try $ inSpaces (string "|") >> (,) <$> pattern <* reservedOp "->" <*> expr--matcherExpr :: Parser EgisonExpr-matcherExpr = keywordMatcher >> MatcherExpr <$> ppMatchClauses--ppMatchClauses :: Parser MatcherInfo-ppMatchClauses = many1 ppMatchClause--ppMatchClause :: Parser (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])-ppMatchClause = inSpaces (string "|") >> (,,) <$> ppPattern <* keywordAs <*> expr <* reservedOp "->" <*> pdMatchClauses--pdMatchClauses :: Parser [(PrimitiveDataPattern, EgisonExpr)]-pdMatchClauses = many1 pdMatchClause--pdMatchClause :: Parser (PrimitiveDataPattern, EgisonExpr)-pdMatchClause = try $ inSpaces (string "|") >> (,) <$> pdPattern <* reservedOp "->" <*> expr--ppPattern :: Parser PrimitivePatPattern-ppPattern = P.lexeme lexer (ppWildCard-                        <|> try ppValuePat-                        <|> ppPatVar-                        <|> ppInductivePat-                        <?> "primitive-pattren-pattern")--ppWildCard :: Parser PrimitivePatPattern-ppWildCard = reservedOp "_" $> PPWildCard--ppPatVar :: Parser PrimitivePatPattern-ppPatVar = reservedOp "$" $> PPPatVar--ppValuePat :: Parser PrimitivePatPattern-ppValuePat = reservedOp "$" >> PPValuePat <$> ident--ppInductivePat :: Parser PrimitivePatPattern-ppInductivePat = angles (PPInductivePat <$> lowerName <*> sepEndBy ppPattern whiteSpace)--pdPattern :: Parser PrimitiveDataPattern-pdPattern = P.lexeme lexer pdPattern'--pdPattern' :: Parser PrimitiveDataPattern-pdPattern' = reservedOp "_" $> PDWildCard-                    <|> (char '$' >> PDPatVar <$> ident)-                    <|> brackets ((PDConsPat <$> pdPattern <* comma <*> (char '@' *> pdPattern))-                            <|> (PDSnocPat <$> (char '@' *> pdPattern) <* comma <*> pdPattern)-                            <|> pure PDEmptyPat)-                    <|> angles (PDInductivePat <$> upperName <*> sepEndBy pdPattern whiteSpace)-                    <|> parens (PDTuplePat <$> sepEndBy pdPattern comma)-                    <|> PDConstantPat <$> constantExpr-                    <?> "primitive-data-pattern"--ifExpr :: Parser EgisonExpr-ifExpr = keywordIf >> IfExpr <$> expr <* keywordThen <*> expr <* keywordElse <*> expr--lambdaExpr :: Parser EgisonExpr-lambdaExpr = LambdaExpr <$> argNames <* reservedOp "->" <*> expr--memoizedLambdaExpr :: Parser EgisonExpr-memoizedLambdaExpr = keywordMemoizedLambda >> MemoizedLambdaExpr <$> varNames <* reservedOp "->" <*> expr--memoizeFrame :: Parser [(EgisonExpr, EgisonExpr, EgisonExpr)]-memoizeFrame = braces $ sepEndBy memoizeBinding whiteSpace--memoizeBinding :: Parser (EgisonExpr, EgisonExpr, EgisonExpr)-memoizeBinding = brackets $ (,,) <$> expr <*> expr <*> expr--cambdaExpr :: Parser EgisonExpr-cambdaExpr = keywordCambda >> char '$' >> CambdaExpr <$> ident <* reservedOp "->" <*> expr--procedureExpr :: Parser EgisonExpr-procedureExpr = keywordProcedure >> ProcedureExpr <$> varNames <* reservedOp "->" <*> expr--macroExpr :: Parser EgisonExpr-macroExpr = keywordMacro >> MacroExpr <$> varNames <* reservedOp "->" <*> expr--patternFunctionExpr :: Parser EgisonExpr-patternFunctionExpr = keywordPatternFunction >> parens (PatternFunctionExpr <$> brackets (sepEndBy ident comma) <* comma <*> pattern)--letRecExpr :: Parser EgisonExpr-letRecExpr =  keywordLetRec >> LetRecExpr <$> bindings <* keywordLetIn <*> expr--letExpr :: Parser EgisonExpr-letExpr = keywordLet >> LetExpr <$> bindings <* keywordLetIn <*> expr--letStarExpr :: Parser EgisonExpr-letStarExpr = keywordLetStar >> LetStarExpr <$> bindings <* keywordLetIn <*> expr--withSymbolsExpr :: Parser EgisonExpr-withSymbolsExpr = keywordWithSymbols >> WithSymbolsExpr <$> braces (sepEndBy ident comma) <*> expr--doExpr :: Parser EgisonExpr-doExpr = keywordDo >> DoExpr <$> statements <*> option (ApplyExpr (stringToVarExpr "return") (TupleExpr [])) expr--statements :: Parser [BindingExpr]-statements = braces $ sepEndBy statement comma--statement :: Parser BindingExpr-statement = try binding-        <|> (([],) <$> expr)--bindings :: Parser [BindingExpr]-bindings = sepEndBy binding comma--binding :: Parser BindingExpr-binding = (,) <$> varNames' <* inSpaces (string "=") <*> expr--varNames :: Parser [String]-varNames = sepEndBy (char '$' >> ident) whiteSpace--varNames' :: Parser [Var]-varNames' = return <$> identVar-            <|> parens (sepEndBy identVar comma)--argNames :: Parser [Arg]-argNames = sepEndBy argName whiteSpace--argName :: Parser Arg-argName = try (ScalarArg <$> (char '$' >> ident))-      <|> try (InvertedScalarArg <$> (string "*$" >> ident))-      <|> try (TensorArg <$> (char '%' >> ident))--ioExpr :: Parser EgisonExpr-ioExpr = keywordIo >> parens (IoExpr <$> expr)--seqExpr :: Parser EgisonExpr-seqExpr = keywordSeq >> parens (SeqExpr <$> expr <* comma <*> expr)--cApplyExpr :: Parser EgisonExpr-cApplyExpr = keywordCApply >> parens (CApplyExpr <$> expr <* comma <*> expr)--applyExpr :: Parser EgisonExpr-applyExpr = (keywordApply >> parens (ApplyExpr <$> expr <* comma <*> expr))-            <|> try applyExpr'--applyExpr' :: Parser EgisonExpr-applyExpr' = do-  func <- try varExpr <|> try partialExpr <|> try partialVarExpr <|> parens expr-  applyExpr'' func--applyExpr'' :: EgisonExpr -> Parser EgisonExpr-applyExpr'' func = do-  argslist <- many1 $ parens args-  return $ foldl makeApply func argslist- where-  args = sepEndBy arg comma-  arg = try expr-        <|> char '$' *> (LambdaArgExpr <$> option "" index)-  index = (:) <$> satisfy (\c -> '1' <= c && c <= '9') <*> many digit--applyInfixExpr :: Parser EgisonExpr-applyInfixExpr = do-  arg1 <- arg-  spaces-  func <- char '`' *> varExpr <* char '`'-  spaces-  arg2 <- arg-  return $ makeApply func [arg1, arg2]- where-  arg = try term-        <|> char '$' *> (LambdaArgExpr <$> option "" index)-  index = (:) <$> satisfy (\c -> '1' <= c && c <= '9') <*> many digit--makeApply :: EgisonExpr -> [EgisonExpr] -> EgisonExpr-makeApply func xs = do-  let args = map (\x -> case x of-                          LambdaArgExpr s -> Left s-                          _               -> Right x) xs-  let vars = lefts args-  case vars of-    [] -> ApplyExpr func . TupleExpr $ rights args-    _ | all null vars ->-        let args' = rights args-            args'' = zipWith (curry f) args (annonVars 1 (length args))-            args''' = map (VarExpr . stringToVar . either id id) args''-        in ApplyExpr (LambdaExpr (map ScalarArg (rights args'')) (LambdaExpr (map ScalarArg (lefts args'')) $ ApplyExpr func $ TupleExpr args''')) $ TupleExpr args'-      | all (not . null) vars ->-        let n = length vars-            args' = rights args-            args'' = zipWith (curry g) args (annonVars (n + 1) (length args))-            args''' = map (VarExpr . stringToVar . either id id) args''-        in ApplyExpr (LambdaExpr (map ScalarArg (rights args'')) (LambdaExpr (map ScalarArg (annonVars 1 n)) $ ApplyExpr func $ TupleExpr args''')) $ TupleExpr args'- where-  annonVars m n = take n $ map ((':':) . show) [m..]-  f (Left _, var)  = Left var-  f (Right _, var) = Right var-  g (Left arg, _)  = Left (':':arg)-  g (Right _, var) = Right var--partialExpr :: Parser EgisonExpr-partialExpr = (PartialExpr . read <$> index) <*> (char '#' >> (try (parens expr) <|> expr))- where-  index = (:) <$> satisfy (\c -> '1' <= c && c <= '9') <*> many digit--partialVarExpr :: Parser EgisonExpr-partialVarExpr = char '%' >> PartialVarExpr <$> integerLiteral--algebraicDataMatcherExpr :: Parser EgisonExpr-algebraicDataMatcherExpr = keywordAlgebraicDataMatcher-                                >> AlgebraicDataMatcherExpr <$> parens (sepEndBy1 inductivePat' comma)-  where-    inductivePat' :: Parser (String, [EgisonExpr])-    inductivePat' = angles $ (,) <$> lowerName <*> sepEndBy expr whiteSpace--generateTensorExpr :: Parser EgisonExpr-generateTensorExpr = keywordGenerateTensor >> parens (GenerateTensorExpr <$> expr <* comma <*> expr)--tensorExpr :: Parser EgisonExpr-tensorExpr = keywordTensor >> parens (TensorExpr <$> expr <* comma <*> expr <*> option (CollectionExpr []) (comma *> expr) <*> option (CollectionExpr []) (comma *> expr))--tensorContractExpr :: Parser EgisonExpr-tensorContractExpr = keywordTensorContract >> parens (TensorContractExpr <$> expr <* comma <*> expr)--subrefsExpr :: Parser EgisonExpr-subrefsExpr = (keywordSubrefs >> parens (SubrefsExpr False <$> expr <* comma <*> expr))-               <|> (keywordSubrefsNew >> parens (SubrefsExpr True <$> expr <* comma <*> expr))--suprefsExpr :: Parser EgisonExpr-suprefsExpr = (keywordSuprefs >> SuprefsExpr False <$> expr <*> expr)-               <|> (keywordSuprefsNew >> SuprefsExpr True <$> expr <*> expr)--userrefsExpr :: Parser EgisonExpr-userrefsExpr = (do keywordUserrefs-                   xs <- parens $ sepEndBy expr comma-                   case xs of-                     [x, y] -> return $ UserrefsExpr False x y-                     _      -> unexpected "number of arguments (expected 2)")-                <|> (do keywordUserrefsNew-                        xs <- parens $ sepEndBy expr comma-                        case xs of-                          [x, y] -> return $ UserrefsExpr True x y-                          _ -> unexpected "number of arguments (expected 2)")---- Patterns--pattern :: Parser EgisonPattern-pattern = P.lexeme lexer-            (try (buildExpressionParser table pattern')-             <|> try pattern'-             <?> "expression")-- where-  table = [ [unary "!" AssocRight, unary "not" AssocRight]-          , [binary'' "^" PowerPat AssocLeft]-          , [binary' "*" MultPat AssocRight, binary'' "/" DivPat AssocRight]-          , [binary' "+" PlusPat AssocRight]-          , [binary "<:>" "cons" AssocRight]-          , [binary' "and" AndPat AssocLeft, binary' "or" OrPat AssocLeft]-          , [binary "<++>" "join" AssocRight]-          ]-  unary op assoc = Prefix (try $ inSpaces (string op) >> return NotPat)-  binary op name = Infix (try $ inSpaces (string op) >> return (\x y -> InductivePat name [x, y]))-  binary' op epr = Infix (try $ inSpaces (string op) >> return (\x y -> epr [x, y]))-  binary'' op epr = Infix (try $ inSpaces (string op) >> return epr)--pattern' :: Parser EgisonPattern-pattern' = wildCard-           <|> contPat-           <|> try indexedPat-           <|> patVar-           <|> try loopPat-           <|> try pApplyPat-           <|> try dApplyPat-           <|> try varPat-           <|> valuePat-           <|> predPat-           <|> try tuplePat-           <|> inductivePat-           <|> letPat-           <|> parens pattern--pattern'' :: Parser EgisonPattern-pattern'' = wildCard-            <|> patVar-            <|> valuePat--wildCard :: Parser EgisonPattern-wildCard = reservedOp "_" >> pure WildCard--indexedPat :: Parser EgisonPattern-indexedPat = IndexedPat <$> (patVar <|> varPat) <*> many1 (try $ char '_' >> term')--patVar :: Parser EgisonPattern-patVar = char '$' >> PatVar <$> identVarWithoutIndex--varPat :: Parser EgisonPattern-varPat = char '\'' >> VarPat <$> ident--valuePat :: Parser EgisonPattern-valuePat = ValuePat <$> expr--predPat :: Parser EgisonPattern-predPat = char '?' >> PredPat <$> expr--letPat :: Parser EgisonPattern-letPat = keywordLet >> LetPat <$> bindings <* keywordLetIn <*> pattern--tuplePat :: Parser EgisonPattern-tuplePat = TuplePat <$> parens ((:) <$> pattern <* comma <*> sepEndBy1 pattern comma)--inductivePat :: Parser EgisonPattern-inductivePat = angles $ InductivePat <$> lowerName <*> sepEndBy pattern whiteSpace--contPat :: Parser EgisonPattern-contPat = keywordCont >> pure ContPat--pApplyPat :: Parser EgisonPattern-pApplyPat = PApplyPat <$> expr <*> brackets (sepEndBy pattern comma)--dApplyPat :: Parser EgisonPattern-dApplyPat = DApplyPat <$> pattern'' <*> parens (sepEndBy pattern comma)--loopPat :: Parser EgisonPattern-loopPat = keywordLoop >> parens (char '$' >> LoopPat <$> identVarWithoutIndex <*> (comma >> loopRange) <*> (comma >> pattern) <*> (comma >> option (NotPat WildCard) pattern))--loopRange :: Parser LoopRange-loopRange = parens (try (LoopRange <$> expr <* comma <*> expr <*> option WildCard (comma >> pattern))-                 <|> (do s <- expr-                         comma-                         ep <- option WildCard pattern-                         return (LoopRange s (ApplyExpr (stringToVarExpr "from") (ApplyExpr (stringToVarExpr "-'") (TupleExpr [s, IntegerExpr 1]))) ep)))---- Constants--constantExpr :: Parser EgisonExpr-constantExpr = stringExpr-                 <|> boolExpr-                 <|> try charExpr-                 <|> try floatExpr-                 <|> try integerExpr-                 <|> (keywordSomething $> SomethingExpr)-                 <|> (keywordUndefined $> UndefinedExpr)-                 <?> "constant"--charExpr :: Parser EgisonExpr-charExpr = CharExpr <$> oneChar--stringExpr :: Parser EgisonExpr-stringExpr = StringExpr . T.pack <$> stringLiteral--boolExpr :: Parser EgisonExpr-boolExpr = BoolExpr <$> boolLiteral--floatExpr :: Parser EgisonExpr-floatExpr = do-  (x,y) <- try ((,) <$> floatLiteral <*> (sign' <*> positiveFloatLiteral) <* char 'i')-            <|> try ((,) 0 <$> floatLiteral <* char 'i')-            <|> try ((, 0) <$> floatLiteral)-  return $ FloatExpr x y--integerExpr :: Parser EgisonExpr-integerExpr = IntegerExpr <$> integerLiteral'--integerLiteral' :: Parser Integer-integerLiteral' = sign <*> positiveIntegerLiteral--positiveIntegerLiteral :: Parser Integer-positiveIntegerLiteral = read <$> many1 digit--positiveFloatLiteral :: Parser Double-positiveFloatLiteral = do-  n <- positiveIntegerLiteral-  char '.'-  mStr <- many1 digit-  let m = read mStr-  let l = m % (10 ^ fromIntegral (length mStr))-  return (fromRational (fromIntegral n + l) :: Double)--floatLiteral :: Parser Double-floatLiteral = sign <*> positiveFloatLiteral------- Tokens-----egisonDef :: P.GenLanguageDef String () Identity-egisonDef =-  P.LanguageDef { P.commentStart       = "#|"-                , P.commentEnd         = "|#"-                , P.commentLine        = ";"-                , P.identStart         = letter <|> symbol1-                , P.identLetter        = letter <|> digit <|> symbol0 <|> symbol2-                , P.opStart            = symbol1-                , P.opLetter           = symbol0 <|> symbol1-                , P.reservedNames      = reservedKeywords-                , P.reservedOpNames    = reservedOperators-                , P.nestedComments     = True-                , P.caseSensitive      = True }--symbol0 = oneOf "/."-symbol1' = oneOf "∂∇"-symbol1 = symbol1' <|> oneOf "+-"-symbol2 = symbol1' <|> oneOf "'!?"--lexer :: P.GenTokenParser String () Identity-lexer = P.makeTokenParser egisonDef--reservedKeywords :: [String]-reservedKeywords =-  [ "define"-  , "set!"-  , "test"-  , "loadFile"-  , "load"-  , "if"-  , "then"-  , "else"-  , "as"-  , "seq"-  , "apply"-  , "capply"-  , "lambda"-  , "memoizedLambda"-  , "cambda"-  , "procedure"-  , "macro"-  , "patternFunction"-  , "letrec"-  , "let"-  , "let*"-  , "in"-  , "withSymbols"-  , "loop"-  , "matchAll"-  , "matchAllDFS"-  , "matchAllLambda"-  , "match"-  , "matchLambda"-  , "matcher"-  , "do"-  , "io"-  , "something"-  , "undefined"-  , "algebraicDataMatcher"-  , "generateTensor"-  , "tensor"-  , "contract"-  , "subrefs"-  , "subrefs!"-  , "suprefs"-  , "suprefs!"-  , "userRefs"-  , "userRefs!"-  , "function"]--reservedOperators :: [String]-reservedOperators =-  [ "$"-  , "_"-  , "^"-  , "&"-  , "|*"-  , "("-  , ")"-  , "->"-  , "`"-  , "=="-  , "="---  , "'"---  , "~"---  , "!"---  , ","---  , "@"-  , "..."]--reserved :: String -> Parser ()-reserved = P.reserved lexer--reservedOp :: String -> Parser ()-reservedOp = P.reservedOp lexer--keywordDefine               = reserved "def"-keywordSet                  = reserved "set!"-keywordTest                 = reserved "test"-keywordLoadFile             = reserved "loadFile"-keywordLoad                 = reserved "load"-keywordIf                   = reserved "if"-keywordThen                 = reserved "then"-keywordElse                 = reserved "else"-keywordAs                   = reserved "as"-keywordSeq                  = reserved "seq"-keywordApply                = reserved "apply"-keywordCApply               = reserved "capply"-keywordLambda               = reserved "lambda"-keywordMemoizedLambda       = reserved "memoizedLambda"-keywordCambda               = reserved "cambda"-keywordProcedure            = reserved "procedure"-keywordMacro                = reserved "macro"-keywordPatternFunction      = reserved "patternFunction"-keywordLetRec               = reserved "letrec"-keywordLet                  = reserved "let"-keywordLetStar              = reserved "let*"-keywordLetIn                = reserved "in"-keywordWithSymbols          = reserved "withSymbols"-keywordLoop                 = reserved "loop"-keywordCont                 = reserved "..."-keywordMatchAll             = reserved "matchAll"-keywordMatchAllDFS          = reserved "matchAllDFS"-keywordMatchAllLambda       = reserved "matchAllLambda"-keywordMatch                = reserved "match"-keywordMatchLambda          = reserved "matchLambda"-keywordMatcher              = reserved "matcher"-keywordDo                   = reserved "do"-keywordIo                   = reserved "io"-keywordSomething            = reserved "something"-keywordUndefined            = reserved "undefined"-keywordAlgebraicDataMatcher = reserved "algebraicDataMatcher"-keywordGenerateTensor       = reserved "generateTensor"-keywordTensor               = reserved "tensor"-keywordTensorContract       = reserved "contract"-keywordSubrefs              = reserved "subrefs"-keywordSubrefsNew           = reserved "subrefs!"-keywordSuprefs              = reserved "suprefs"-keywordSuprefsNew           = reserved "suprefs!"-keywordUserrefs             = reserved "userRefs"-keywordUserrefsNew          = reserved "userRefs!"-keywordFunction             = reserved "function"--sign :: Num a => Parser (a -> a)-sign = (char '-' >> return negate)-   <|> (char '+' >> return id)-   <|> return id--sign' :: Num a => Parser (a -> a)-sign' = (char '-' >> return negate)-    <|> (char '+' >> return id)--integerLiteral :: Parser Integer-integerLiteral = sign <*> P.natural lexer--stringLiteral :: Parser String-stringLiteral = P.stringLiteral lexer--charLiteral :: Parser Char-charLiteral = P.charLiteral lexer--oneChar :: Parser Char-oneChar = do-  string "c#"-  x <- (char '\\' >> anyChar >>= (\x -> return ['\\', x])) <|> (anyChar >>= (\x -> return [x]))-  return $ doParse' charLiteral $ "'" ++ x ++ "'"--boolLiteral :: Parser Bool-boolLiteral = char '#' >> (char 't' $> True <|> char 'f' $> False)--whiteSpace :: Parser ()-whiteSpace = P.whiteSpace lexer--parens :: Parser a -> Parser a-parens = P.parens lexer--brackets :: Parser a -> Parser a-brackets = P.brackets lexer--braces :: Parser a -> Parser a-braces = P.braces lexer--angles :: Parser a -> Parser a-angles = P.angles lexer--colon :: Parser String-colon = P.colon lexer--comma :: Parser String-comma = P.comma lexer--dot :: Parser String-dot = P.dot lexer--ident :: Parser String-ident = do-  idt <- P.identifier lexer-  let (f, s) = splitLast idt '.'-  case s of-    [] -> return f-    x:xs | isLower x -> return $ f ++ map toLower (intercalate "-" $ split (startsWithOneOf ['A'..'Z']) s)-         | otherwise -> return $ f ++ [x] ++ map toLower (intercalate "-" $ split (startsWithOneOf ['A'..'Z']) xs)- where-  splitLast list elem = let (f, s) = span (/= elem) $ reverse list-                          in (reverse s, reverse f)--identVar :: Parser Var-identVar = P.lexeme lexer (do-  name <- ident-  is <- many indexType-  return $ Var (splitOn "." name) is)--identVarWithoutIndex :: Parser Var-identVarWithoutIndex = stringToVar <$> ident--identVarWithIndices :: Parser VarWithIndices-identVarWithIndices = P.lexeme lexer (do-  name <- ident-  is <- many indexForVar-  return $ VarWithIndices (splitOn "." name) is)--indexForVar :: Parser (Index String)-indexForVar = try (char '~' >> Superscript <$> ident)-        <|> try (char '_' >> Subscript <$> ident)--indexType :: Parser (Index ())-indexType = try (char '~' >> return (Superscript ()))-        <|> try (char '_' >> return (Subscript ()))--upperName :: Parser String-upperName = P.lexeme lexer upperName'--upperName' :: Parser String-upperName' = (:) <$> upper <*> option "" ident- where-  upper :: Parser Char-  upper = satisfy isUpper--lowerName :: Parser String-lowerName = P.lexeme lexer lowerName'--lowerName' :: Parser String-lowerName' = (:) <$> lower <*> option "" ident- where-  lower :: Parser Char-  lower = satisfy isLower+{-# LANGUAGE TupleSections    #-}+{-# LANGUAGE MultiWayIf       #-}++{- |+Module      : Language.Egison.ParserNonS+Copyright   : Satoshi Egi+Licence     : MIT++This module provides the new parser of Egison.+-}++module Language.Egison.ParserNonS+       (+       -- * Parse a string+         readTopExprs+       , readTopExpr+       , readExprs+       , readExpr+       , parseTopExprs+       , parseTopExpr+       , parseExprs+       , parseExpr+       -- * Parse a file+       , loadLibraryFile+       , loadFile+       ) where++import           Control.Applicative            (pure, (*>), (<$>), (<$), (<*), (<*>))+import           Control.Monad.Except           (liftIO, throwError)+import           Control.Monad.State            (unless)+import           Prelude                        hiding (mapM)++import           System.Directory               (doesFileExist, getHomeDirectory)++import           Data.Functor                   (($>))+import           Data.List                      (find)+import           Data.Maybe                     (fromJust, isJust)+import           Data.Traversable               (mapM)++import           Control.Monad.Combinators.Expr+import           Text.Megaparsec+import           Text.Megaparsec.Char+import qualified Text.Megaparsec.Char.Lexer     as L+import           Text.Megaparsec.Debug          (dbg)+import           Text.Megaparsec.Pos            (Pos)++import           Data.Text                      (pack)++import           Language.Egison.Desugar+import           Language.Egison.Types+import           Paths_egison                   (getDataFileName)++readTopExprs :: String -> EgisonM [EgisonTopExpr]+readTopExprs = either throwError (mapM desugarTopExpr) . parseTopExprs++readTopExpr :: String -> EgisonM EgisonTopExpr+readTopExpr = either throwError desugarTopExpr . parseTopExpr++readExprs :: String -> EgisonM [EgisonExpr]+readExprs = either throwError (mapM desugarExpr) . parseExprs++readExpr :: String -> EgisonM EgisonExpr+readExpr = either throwError desugarExpr . parseExpr++parseTopExprs :: String -> Either EgisonError [EgisonTopExpr]+parseTopExprs = doParse $ many (L.nonIndented sc topExpr) <* eof++parseTopExpr :: String -> Either EgisonError EgisonTopExpr+parseTopExpr = doParse $ sc >> topExpr++parseExprs :: String -> Either EgisonError [EgisonExpr]+parseExprs = doParse $ many (L.nonIndented sc expr) <* eof++parseExpr :: String -> Either EgisonError EgisonExpr+parseExpr = doParse $ sc >> expr++-- |Load a libary file+loadLibraryFile :: FilePath -> EgisonM [EgisonTopExpr]+loadLibraryFile file = do+  homeDir <- liftIO getHomeDirectory+  doesExist <- liftIO $ doesFileExist $ homeDir ++ "/.egison/" ++ file+  if doesExist+    then loadFile $ homeDir ++ "/.egison/" ++ file+    else liftIO (getDataFileName file) >>= loadFile++-- |Load a file+loadFile :: FilePath -> EgisonM [EgisonTopExpr]+loadFile file = do+  doesExist <- liftIO $ doesFileExist file+  unless doesExist $ throwError $ Default ("file does not exist: " ++ file)+  input <- liftIO $ readUTF8File file+  exprs <- readTopExprs $ shebang input+  concat <$> mapM  recursiveLoad exprs+ where+  recursiveLoad (Load file)     = loadLibraryFile file+  recursiveLoad (LoadFile file) = loadFile file+  recursiveLoad expr            = return [expr]+  shebang :: String -> String+  shebang ('#':'!':cs) = ';':'#':'!':cs+  shebang cs           = cs++--+-- Parser+--++type Parser = Parsec CustomError String++data CustomError+  = IllFormedPointFreeExpr EgisonBinOp EgisonBinOp+  | IllFormedDefine+  deriving (Eq, Ord)++instance ShowErrorComponent CustomError where+  showErrorComponent (IllFormedPointFreeExpr op op') =+    "The operator " ++ info op ++ " must have lower precedence than " ++ info op'+    where+      info op =+         "'" ++ repr op ++ "' [" ++ show (assoc op) ++ " " ++ show (priority op) ++ "]"+  showErrorComponent IllFormedDefine =+    "Ill-formed definition syntax."+++doParse :: Parser a -> String -> Either EgisonError a+doParse p input = either (throwError . fromParsecError) return $ parse p "egison" input+  where+    fromParsecError :: ParseErrorBundle String CustomError -> EgisonError+    fromParsecError = Parser . errorBundlePretty++--+-- Expressions+--++topExpr :: Parser EgisonTopExpr+topExpr = Load     <$> (keywordLoad >> stringLiteral)+      <|> LoadFile <$> (keywordLoadFile >> stringLiteral)+      <|> defineOrTestExpr+      <?> "toplevel expression"++defineOrTestExpr :: Parser EgisonTopExpr+defineOrTestExpr = do+  e <- expr+  (do symbol "="+      body <- expr+      return $ convertToDefine e body)+      <|> return (Test e)+  where+    -- TODO: Throw IllFormedDefine in pattern match failure.+    -- first 2 cases are the most common ones+    convertToDefine :: EgisonExpr -> EgisonExpr -> EgisonTopExpr+    convertToDefine (VarExpr var) body = Define var body+    convertToDefine (ApplyExpr (VarExpr var) (TupleExpr args)) body =+      Define var (LambdaExpr (map exprToArg args) body)+    convertToDefine e@(BinaryOpExpr op _ _) body+      | repr op == "*" || repr op == "%" =+        case exprToArgs e of+          ScalarArg var : args -> Define (Var [var] []) (LambdaExpr args body)++    exprToArg :: EgisonExpr -> Arg+    exprToArg (VarExpr (Var [x] [])) = ScalarArg x++    exprToArgs :: EgisonExpr -> [Arg]+    exprToArgs (VarExpr (Var [x] [])) = [ScalarArg x]+    exprToArgs (ApplyExpr func (TupleExpr args)) =+      exprToArgs func ++ map exprToArg args+    exprToArgs (BinaryOpExpr op lhs rhs) | repr op == "*" =+      case exprToArgs rhs of+        ScalarArg x : xs -> exprToArgs lhs ++ InvertedScalarArg x : xs+    exprToArgs (BinaryOpExpr op lhs rhs) | repr op == "%" =+      case exprToArgs rhs of+        ScalarArg x : xs -> exprToArgs lhs ++ TensorArg x : xs++expr :: Parser EgisonExpr+expr = ifExpr+   <|> patternMatchExpr+   <|> lambdaExpr+   <|> letExpr+   <|> withSymbolsExpr+   <|> doExpr+   <|> matcherExpr+   <|> algebraicDataMatcherExpr+   <|> memoizedLambdaExpr+   <|> procedureExpr+   <|> macroExpr+   <|> generateTensorExpr+   <|> tensorExpr+   <|> functionExpr+   <|> opExpr+   <?> "expression"++-- Also parses atomExpr+opExpr :: Parser EgisonExpr+opExpr = do+  pos <- L.indentLevel+  makeExprParser atomOrApplyExpr (makeTable pos)+  where+    makeTable :: Pos -> [[Operator Parser EgisonExpr]]+    makeTable pos =+      let unary  sym = UnaryOpExpr  <$> operator sym+          binary sym = do+            op <- try (L.indentGuard sc GT pos >> binOpLiteral sym <* notFollowedBy (symbol ")"))+            return $ BinaryOpExpr op+       in+          [ [ Prefix (unary  "-" )+            , Prefix (unary  "!" ) ]+          -- 8+          , [ InfixL (binary "^" ) ]+          -- 7+          , [ InfixL (binary "*" )+            , InfixL (binary "/" )+            , InfixL (binary "%" ) ]+          -- 6+          , [ InfixL (binary "+" )+            , InfixL (binary "-" ) ]+          -- 5+          , [ InfixR (binary ":" )+            , InfixR (binary "++") ]+          -- 4+          , [ InfixL (binary "==")+            , InfixL (binary "<=")+            , InfixL (binary "<" )+            , InfixL (binary ">=")+            , InfixL (binary ">" ) ]+          -- 3+          , [ InfixR (binary "&&") ]+          -- 2+          , [ InfixR (binary "||") ]+          ]++ifExpr :: Parser EgisonExpr+ifExpr = keywordIf >> IfExpr <$> expr <* keywordThen <*> expr <* keywordElse <*> expr++patternMatchExpr :: Parser EgisonExpr+patternMatchExpr = makeMatchExpr keywordMatch       MatchExpr+               <|> makeMatchExpr keywordMatchDFS    MatchDFSExpr+               <|> makeMatchExpr keywordMatchAll    MatchAllExpr+               <|> makeMatchExpr keywordMatchAllDFS MatchAllDFSExpr+               <?> "pattern match expression"+  where+    makeMatchExpr keyword ctor = ctor <$> (keyword >> expr)+                                      <*> (keywordAs >> expr)+                                      <*> (keywordWith >> matchClauses1)++-- Parse more than 1 match clauses.+matchClauses1 :: Parser [MatchClause]+matchClauses1 = do+  pos <- L.indentLevel+  -- If the first bar '|' is missing, then it is expected to have only one match clause.+  (lookAhead (symbol "|") >> some (matchClause pos)) <|> (:[]) <$> matchClauseWithoutBar+  where+    matchClauseWithoutBar :: Parser MatchClause+    matchClauseWithoutBar = (,) <$> pattern <*> (symbol "->" >> expr)++    matchClause :: Pos -> Parser MatchClause+    matchClause pos = (,) <$> (L.indentGuard sc EQ pos >> symbol "|" >> pattern) <*> (symbol "->" >> expr)++lambdaExpr :: Parser EgisonExpr+lambdaExpr = symbol "\\" >> (+      makeMatchLambdaExpr keywordMatch    MatchLambdaExpr+  <|> makeMatchLambdaExpr keywordMatchAll MatchAllLambdaExpr+  <|> try (LambdaExpr <$> some arg <*> (symbol "->" >> expr))+  <|> PatternFunctionExpr <$> some lowerId <*> (symbol "=>" >> pattern))+  <?> "lambda or pattern function expression"+  where+    makeMatchLambdaExpr keyword ctor = do+      matcher <- keyword >> keywordAs >> expr+      clauses <- keywordWith >> matchClauses1+      return $ ctor matcher clauses++arg :: Parser Arg+arg = InvertedScalarArg <$> (symbol "*" >> lowerId)+  <|> TensorArg         <$> (symbol "%" >> lowerId)+  <|> ScalarArg         <$> lowerId+  <?> "argument"++letExpr :: Parser EgisonExpr+letExpr = do+  pos   <- keywordLet >> L.indentLevel+  binds <- some (L.indentGuard sc EQ pos *> binding)+  body  <- keywordIn >> expr+  return $ LetRecExpr binds body++binding :: Parser BindingExpr+binding = do+  (vars, args) <- (,[]) <$> parens (sepBy varLiteral comma)+              <|> do var <- varLiteral+                     args <- many arg+                     return ([var], args)+  body <- symbol "=" >> expr+  return $ case args of+             [] -> (vars, body)+             _  -> (vars, LambdaExpr args body)++withSymbolsExpr :: Parser EgisonExpr+withSymbolsExpr = WithSymbolsExpr <$> (keywordWithSymbols >> brackets (sepBy lowerId comma)) <*> expr++doExpr :: Parser EgisonExpr+doExpr = do+  pos   <- keywordDo >> L.indentLevel+  stmts <- some $ L.indentGuard sc EQ pos >> statement+  ret   <- option (makeApply' "return" []) $ L.indentGuard sc EQ pos >> expr+  return $ DoExpr stmts ret+  where+    statement :: Parser BindingExpr+    statement = (keywordLet >> binding) <|> ([],) <$> expr++matcherExpr :: Parser EgisonExpr+matcherExpr = do+  keywordMatcher+  pos  <- L.indentLevel+  -- In matcher expression, the first '|' (bar) is indispensable+  info <- some (L.indentGuard sc EQ pos >> symbol "|" >> patternDef)+  return $ MatcherExpr info+  where+    patternDef :: Parser (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])+    patternDef = do+      pp <- ppPattern+      returnMatcher <- keywordAs >> expr <* keywordWith+      pos <- L.indentLevel+      datapat <- some (L.indentGuard sc EQ pos >> symbol "|" >> dataCases)+      return (pp, returnMatcher, datapat)++    dataCases :: Parser (PrimitiveDataPattern, EgisonExpr)+    dataCases = (,) <$> pdPattern <*> (symbol "->" >> expr)++algebraicDataMatcherExpr :: Parser EgisonExpr+algebraicDataMatcherExpr = do+  keywordAlgebraicDataMatcher+  pos  <- L.indentLevel+  defs <- some (L.indentGuard sc EQ pos >> symbol "|" >> patternDef)+  return $ AlgebraicDataMatcherExpr defs+  where+    patternDef :: Parser (String, [EgisonExpr])+    patternDef = do+      pos <- L.indentLevel+      patternCtor <- lowerId+      args <- many (L.indentGuard sc GT pos >> atomExpr)+      return (patternCtor, args)++memoizedLambdaExpr :: Parser EgisonExpr+memoizedLambdaExpr = MemoizedLambdaExpr <$> (keywordMemoizedLambda >> many lowerId) <*> (symbol "->" >> expr)++procedureExpr :: Parser EgisonExpr+procedureExpr = ProcedureExpr <$> (keywordProcedure >> many lowerId) <*> (symbol "->" >> expr)++macroExpr :: Parser EgisonExpr+macroExpr = MacroExpr <$> (keywordMacro >> many lowerId) <*> (symbol "->" >> expr)++generateTensorExpr :: Parser EgisonExpr+generateTensorExpr = GenerateTensorExpr <$> (keywordGenerateTensor >> atomExpr) <*> atomExpr++tensorExpr :: Parser EgisonExpr+tensorExpr = TensorExpr <$> (keywordTensor >> atomExpr) <*> atomExpr+                        <*> option (CollectionExpr []) atomExpr+                        <*> option (CollectionExpr []) atomExpr++functionExpr :: Parser EgisonExpr+functionExpr = FunctionExpr <$> (keywordFunction >> parens (sepBy expr comma))++collectionExpr :: Parser EgisonExpr+collectionExpr = symbol "[" >> (try betweenOrFromExpr <|> elementsExpr)+  where+    betweenOrFromExpr = do+      start <- expr <* symbol ".."+      end   <- optional expr <* symbol "]"+      case end of+        Just end' -> return $ makeApply' "between" [start, end']+        Nothing   -> return $ makeApply' "from" [start]++    elementsExpr = CollectionExpr <$> (sepBy (ElementExpr <$> expr) comma <* symbol "]")++tupleOrParenExpr :: Parser EgisonExpr+tupleOrParenExpr = do+  elems <- symbol "(" >> try (sepBy expr comma <* symbol ")") <|> (pointFreeExpr <* symbol ")")+  case elems of+    [x] -> return x+    _   -> return $ TupleExpr elems+  where+    pointFreeExpr :: Parser [EgisonExpr]+    pointFreeExpr =+          (do op   <- try . choice $ map (binOpLiteral . repr) reservedBinops+              rarg <- optional expr+              -- TODO(momohatt): Take associativity of operands into account+              case rarg of+                Just (BinaryOpExpr op' _ _) | priority op >= priority op' ->+                  customFailure (IllFormedPointFreeExpr op op')+                _ -> return [makeLambda op Nothing rarg])+      <|> (do larg <- opExpr+              op   <- choice $ map (binOpLiteral . repr) reservedBinops+              case larg of+                BinaryOpExpr op' _ _ | priority op >= priority op' ->+                  customFailure (IllFormedPointFreeExpr op op')+                _ -> return [makeLambda op (Just larg) Nothing])++    makeLambda :: EgisonBinOp -> Maybe EgisonExpr -> Maybe EgisonExpr -> EgisonExpr+    makeLambda op Nothing Nothing =+      LambdaExpr [ScalarArg ":x", ScalarArg ":y"]+                 (BinaryOpExpr op (stringToVarExpr ":x") (stringToVarExpr ":y"))+    makeLambda op Nothing (Just rarg) =+      LambdaExpr [ScalarArg ":x"] (BinaryOpExpr op (stringToVarExpr ":x") rarg)+    makeLambda op (Just larg) Nothing =+      LambdaExpr [ScalarArg ":y"] (BinaryOpExpr op larg (stringToVarExpr ":y"))++arrayExpr :: Parser EgisonExpr+arrayExpr = ArrayExpr <$> between (symbol "(|") (symbol "|)") (sepEndBy expr comma)++vectorExpr :: Parser EgisonExpr+vectorExpr = VectorExpr <$> between (symbol "[|") (symbol "|]") (sepEndBy expr comma)++hashExpr :: Parser EgisonExpr+hashExpr = HashExpr <$> hashBraces (sepEndBy hashElem comma)+  where+    hashBraces = between (symbol "{|") (symbol "|}")+    hashElem = brackets $ (,) <$> expr <*> (comma >> expr)++index :: Parser (Index EgisonExpr)+index = SupSubscript <$> (string "~_" >> atomExpr')+    <|> try (char '_' >> subscript)+    <|> try (char '~' >> superscript)+    <|> try (Userscript <$> (char '|' >> atomExpr'))+    <?> "index"+  where+    subscript = do+      e1 <- atomExpr'+      e2 <- optional (string "..._" >> atomExpr')+      case e2 of+        Nothing  -> return $ Subscript e1+        Just e2' -> return $ MultiSubscript e1 e2'+    superscript = do+      e1 <- atomExpr'+      e2 <- optional (string "...~" >> atomExpr')+      case e2 of+        Nothing  -> return $ Superscript e1+        Just e2' -> return $ MultiSuperscript e1 e2'++atomOrApplyExpr :: Parser EgisonExpr+atomOrApplyExpr = do+  pos <- L.indentLevel+  func <- atomExpr+  args <- many (L.indentGuard sc GT pos *> atomExpr)+  return $ case args of+             [] -> func+             _  -> makeApply func args++atomExpr :: Parser EgisonExpr+atomExpr = do+  e <- atomExpr'+  -- TODO(momohatt): "..." (override of index) collides with ContPat+  indices <- many index+  return $ case indices of+             [] -> e+             _  -> IndexedExpr False e indices++-- atom expr without index+atomExpr' :: Parser EgisonExpr+atomExpr' = constantExpr+        <|> VarExpr <$> varLiteral+        <|> (\x -> InductiveDataExpr x []) <$> upperId+        <|> vectorExpr     -- must come before collectionExpr+        <|> arrayExpr      -- must come before tupleOrParenExpr+        <|> collectionExpr+        <|> tupleOrParenExpr+        <|> hashExpr+        <|> QuoteExpr <$> (char '\'' >> atomExpr')+        <|> QuoteSymbolExpr <$> (char '`' >> atomExpr')+        <?> "atomic expression"++constantExpr :: Parser EgisonExpr+constantExpr = numericExpr+           <|> BoolExpr <$> boolLiteral+           <|> CharExpr <$> try charLiteral        -- try for quoteExpr+           <|> StringExpr . pack <$> stringLiteral+           <|> SomethingExpr <$ keywordSomething+           <|> UndefinedExpr <$ keywordUndefined++numericExpr :: Parser EgisonExpr+numericExpr = FloatExpr <$> try positiveFloatLiteral+          <|> IntegerExpr <$> positiveIntegerLiteral+          <?> "numeric expression"+--+-- Pattern+--++pattern :: Parser EgisonPattern+pattern = letPattern+      <|> loopPattern+      <|> opPattern+      <?> "pattern"++letPattern :: Parser EgisonPattern+letPattern = do+  pos   <- keywordLet >> L.indentLevel+  binds <- some (L.indentGuard sc EQ pos *> binding)+  body  <- keywordIn >> pattern+  return $ LetPat binds body++loopPattern :: Parser EgisonPattern+loopPattern = do+  keywordLoop+  iter <- patVarLiteral+  range <- loopRange+  loopBody <- optional (symbol "|") >> pattern+  loopEnd <- symbol "|" >> pattern+  return $ LoopPat iter range loopBody loopEnd+  where+    loopRange :: Parser LoopRange+    loopRange =+      parens $ do start <- expr+                  ends  <- option (defaultEnds start) (try $ comma >> expr)+                  as    <- option WildCard (comma >> pattern)+                  return $ LoopRange start ends as++    defaultEnds s =+      ApplyExpr (stringToVarExpr "from")+                (makeApply (stringToVarExpr "-'") [s, IntegerExpr 1])++seqPattern :: Parser EgisonPattern+seqPattern = do+  pats <- braces $ sepBy pattern comma+  return $ foldr SeqConsPat SeqNilPat pats++opPattern :: Parser EgisonPattern+opPattern = makeExprParser applyOrAtomPattern table+  where+    table :: [[Operator Parser EgisonPattern]]+    table =+      [ [ Prefix (NotPat <$ symbol "!") ]+      -- 5+      , [ InfixR (inductive2 "cons" ":" )+        , InfixR (inductive2 "join" "++") ]+      -- 3+      , [ InfixR (binary AndPat "&&") ]+      -- 2+      , [ InfixR (binary OrPat  "||") ]+      ]+    inductive2 name sym = (\x y -> InductivePat name [x, y]) <$ patOperator sym+    binary name sym     = (\x y -> name [x, y]) <$ patOperator sym++applyOrAtomPattern :: Parser EgisonPattern+applyOrAtomPattern = do+  pos <- L.indentLevel+  func <- atomPattern+  args <- many (L.indentGuard sc GT pos *> atomPattern)+  case (func, args) of+    (_,                 []) -> return func+    (InductivePat x [], _)  -> return $ InductivePat x args++atomPattern :: Parser EgisonPattern+atomPattern = do+  pat     <- atomPattern'+  indices <- many . try $ char '_' >> atomExpr'+  return $ case indices of+             [] -> pat+             _  -> IndexedPat pat indices++-- atomic pattern without index+atomPattern' :: Parser EgisonPattern+atomPattern' = WildCard <$   symbol "_"+           <|> PatVar   <$> patVarLiteral+           <|> ValuePat <$> (char '#' >> atomExpr)+           <|> InductivePat "nil" [] <$ (symbol "[" >> symbol "]")+           <|> InductivePat <$> lowerId <*> pure []+           <|> VarPat   <$> (char '~' >> lowerId)+           <|> PredPat  <$> (symbol "?" >> atomExpr)+           <|> ContPat  <$ symbol "..."+           <|> makeTupleOrParen pattern TuplePat+           <|> seqPattern+           <|> LaterPatVar <$ symbol "@"+           <?> "atomic pattern"++ppPattern :: Parser PrimitivePatPattern+ppPattern = PPInductivePat <$> lowerId <*> many ppAtom+        <|> makeExprParser ppAtom table+        <?> "primitive pattern pattern"+  where+    table :: [[Operator Parser PrimitivePatPattern]]+    table =+      [ [ InfixR (inductive2 "cons" ":" )+        , InfixR (inductive2 "join" "++") ]+      ]+    inductive2 name sym = (\x y -> PPInductivePat name [x, y]) <$ operator sym++    ppAtom :: Parser PrimitivePatPattern+    ppAtom = PPWildCard <$ symbol "_"+         <|> PPPatVar   <$ symbol "$"+         <|> PPValuePat <$> (symbol "#$" >> lowerId)+         <|> PPInductivePat "nil" [] <$ brackets sc+         <|> makeTupleOrParen ppPattern PPTuplePat++pdPattern :: Parser PrimitiveDataPattern+pdPattern = PDInductivePat <$> upperId <*> many pdAtom+        <|> PDSnocPat <$> (symbol "snoc" >> pdAtom) <*> pdAtom+        <|> makeExprParser pdAtom table+        <?> "primitive data pattern"+  where+    table :: [[Operator Parser PrimitiveDataPattern]]+    table =+      [ [ InfixR (PDConsPat <$ symbol ":") ]+      ]+    pdAtom :: Parser PrimitiveDataPattern+    pdAtom = PDWildCard    <$ symbol "_"+         <|> PDPatVar      <$> (symbol "$" >> lowerId)+         <|> PDConstantPat <$> constantExpr+         <|> PDEmptyPat    <$ (symbol "[" >> symbol "]")+         <|> makeTupleOrParen pdPattern PDTuplePat++--+-- Tokens+--++-- space comsumer+sc :: Parser ()+sc = L.space space1 lineCmnt blockCmnt+  where+    lineCmnt  = L.skipLineComment "--"+    blockCmnt = L.skipBlockCommentNested "{-" "-}"++lexeme :: Parser a -> Parser a+lexeme = L.lexeme sc++positiveIntegerLiteral :: Parser Integer+positiveIntegerLiteral = lexeme L.decimal+                     <?> "unsinged integer"++charLiteral :: Parser Char+charLiteral = between (char '\'') (symbol "\'") L.charLiteral+          <?> "character"++stringLiteral :: Parser String+stringLiteral = char '\"' *> manyTill L.charLiteral (symbol "\"")+          <?> "string"++boolLiteral :: Parser Bool+boolLiteral = reserved "True"  $> True+          <|> reserved "False" $> False+          <?> "boolean"++positiveFloatLiteral :: Parser Double+positiveFloatLiteral = lexeme L.float+           <?> "unsigned float"++varLiteral :: Parser Var+varLiteral = stringToVar <$> lowerId++patVarLiteral :: Parser Var+patVarLiteral = stringToVar <$> (char '$' >> lowerId)++binOpLiteral :: String -> Parser EgisonBinOp+binOpLiteral sym = do+  wedge <- optional (char '!')+  opSym <- operator sym+  let opInfo = fromJust $ find ((== opSym) . repr) reservedBinops+  return $ opInfo { isWedge = isJust wedge }++reserved :: String -> Parser ()+reserved w = (lexeme . try) (string w *> notFollowedBy identChar)++symbol :: String -> Parser String+symbol sym = try $ L.symbol sc sym++operator :: String -> Parser String+operator sym = try $ string sym <* notFollowedBy opChar <* sc++patOperator :: String -> Parser String+patOperator sym = try $ string sym <* notFollowedBy patOpChar <* sc++-- Characters that could consist expression operators.+opChar :: Parser Char+opChar = oneOf "%^&*-+\\|:<>.?/'!#@$"++-- Characters that could consist pattern operators.+-- ! # @ $ are omitted because they can appear at the beginning of atomPattern+patOpChar :: Parser Char+patOpChar = oneOf "%^&*-+\\|:<>.?/'"++-- Characters that consist identifiers+identChar :: Parser Char+identChar = alphaNumChar <|> oneOf ['.', '?', '\'']++parens    = between (symbol "(") (symbol ")")+braces    = between (symbol "{") (symbol "}")+brackets  = between (symbol "[") (symbol "]")+comma     = symbol ","++lowerId :: Parser String+lowerId = (lexeme . try) (p >>= check)+  where+    p       = (:) <$> lowerChar <*> many identChar+    check x = if x `elem` lowerReservedWords+                then fail $ "keyword " ++ show x ++ " cannot be an identifier"+                else return x++-- TODO: Deprecate BoolExpr and merge it with InductiveDataExpr+upperId :: Parser String+upperId = (lexeme . try) (p >>= check)+  where+    p       = (:) <$> upperChar <*> many alphaNumChar+    check x = if x `elem` upperReservedWords+                then fail $ "keyword " ++ show x ++ " cannot be an identifier"+                else return x++keywordLoadFile             = reserved "loadFile"+keywordLoad                 = reserved "load"+keywordIf                   = reserved "if"+keywordThen                 = reserved "then"+keywordElse                 = reserved "else"+keywordSeq                  = reserved "seq"+keywordApply                = reserved "apply"+keywordCApply               = reserved "capply"+keywordMemoizedLambda       = reserved "memoizedLambda"+keywordCambda               = reserved "cambda"+keywordProcedure            = reserved "procedure"+keywordMacro                = reserved "macro"+keywordLet                  = reserved "let"+keywordIn                   = reserved "in"+keywordWithSymbols          = reserved "withSymbols"+keywordLoop                 = reserved "loop"+keywordMatch                = reserved "match"+keywordMatchDFS             = reserved "matchDFS"+keywordMatchAll             = reserved "matchAll"+keywordMatchAllDFS          = reserved "matchAllDFS"+keywordAs                   = reserved "as"+keywordWith                 = reserved "with"+keywordMatcher              = reserved "matcher"+keywordDo                   = reserved "do"+keywordIo                   = reserved "io"+keywordSomething            = reserved "something"+keywordUndefined            = reserved "undefined"+keywordAlgebraicDataMatcher = reserved "algebraicDataMatcher"+keywordGenerateTensor       = reserved "generateTensor"+keywordTensor               = reserved "tensor"+keywordTensorContract       = reserved "contract"+keywordSubrefs              = reserved "subrefs"+keywordSubrefsNew           = reserved "subrefs!"+keywordSuprefs              = reserved "suprefs"+keywordSuprefsNew           = reserved "suprefs!"+keywordUserrefs             = reserved "userRefs"+keywordUserrefsNew          = reserved "userRefs!"+keywordFunction             = reserved "function"++upperReservedWords =+  [ "True"+  , "False"+  ]++lowerReservedWords =+  [ "loadFile"+  , "load"+  , "if"+  , "then"+  , "else"+  , "seq"+  , "apply"+  , "capply"+  , "memoizedLambda"+  , "cambda"+  , "procedure"+  , "macro"+  , "let"+  , "in"+  , "withSymbols"+  , "loop"+  , "from"+  , "to"+  , "of"+  , "match"+  , "matchDFS"+  , "matchAll"+  , "matchAllDFS"+  , "as"+  , "with"+  , "matcher"+  , "do"+  , "io"+  , "something"+  , "undefined"+  , "algebraicDataMatcher"+  , "generateTensor"+  , "tensor"+  , "contract"+  , "subrefs"+  , "subrefs!"+  , "suprefs"+  , "suprefs!"+  , "userRefs"+  , "userRefs!"+  , "function"+  ]++--+-- Utils+--++makeTupleOrParen :: Parser a -> ([a] -> a) -> Parser a+makeTupleOrParen parser tupleCtor = do+  elems <- parens $ sepBy parser comma+  case elems of+    [elem] -> return elem+    _      -> return $ tupleCtor elems++makeApply :: EgisonExpr -> [EgisonExpr] -> EgisonExpr+makeApply (InductiveDataExpr x []) xs = InductiveDataExpr x xs+makeApply func xs = ApplyExpr func (TupleExpr xs)++makeApply' :: String -> [EgisonExpr] -> EgisonExpr+makeApply' func xs = ApplyExpr (stringToVarExpr func) (TupleExpr xs)
− hs-src/Language/Egison/ParserNonS2.hs
@@ -1,783 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TupleSections    #-}-{-# LANGUAGE MultiWayIf       #-}--{- |-Module      : Language.Egison.ParserNonS2-Copyright   : Satoshi Egi-Licence     : MIT--This module provide Egison parser.--}--module Language.Egison.ParserNonS2-       (-       -- * Parse a string-         readTopExprs-       , readTopExpr-       , readExprs-       , readExpr-       , parseTopExprs-       , parseTopExpr-       , parseExprs-       , parseExpr-       -- * Parse a file-       , loadLibraryFile-       , loadFile-       ) where--import           Control.Applicative            (pure, (*>), (<$>), (<$), (<*), (<*>))-import           Control.Monad.Except           (liftIO, throwError)-import           Control.Monad.State            (unless)-import           Prelude                        hiding (mapM)--import           System.Directory               (doesFileExist, getHomeDirectory)--import           Data.Functor                   (($>))-import           Data.List                      (find)-import           Data.Maybe                     (fromJust, isJust)-import           Data.Traversable               (mapM)--import           Control.Monad.Combinators.Expr-import           Data.Void-import           Text.Megaparsec-import           Text.Megaparsec.Char-import qualified Text.Megaparsec.Char.Lexer     as L-import           Text.Megaparsec.Debug          (dbg)-import           Text.Megaparsec.Pos            (Pos)--import           Data.Text                      (pack)--import           Language.Egison.Desugar-import           Language.Egison.Types-import           Paths_egison                   (getDataFileName)--readTopExprs :: String -> EgisonM [EgisonTopExpr]-readTopExprs = either throwError (mapM desugarTopExpr) . parseTopExprs--readTopExpr :: String -> EgisonM EgisonTopExpr-readTopExpr = either throwError desugarTopExpr . parseTopExpr--readExprs :: String -> EgisonM [EgisonExpr]-readExprs = liftEgisonM . runDesugarM . either throwError (mapM desugar) . parseExprs--readExpr :: String -> EgisonM EgisonExpr-readExpr = liftEgisonM . runDesugarM . either throwError desugar . parseExpr--parseTopExprs :: String -> Either EgisonError [EgisonTopExpr]-parseTopExprs = doParse $ many (L.nonIndented sc topExpr) <* eof--parseTopExpr :: String -> Either EgisonError EgisonTopExpr-parseTopExpr = doParse $ sc >> topExpr--parseExprs :: String -> Either EgisonError [EgisonExpr]-parseExprs = doParse $ many (L.nonIndented sc expr) <* eof--parseExpr :: String -> Either EgisonError EgisonExpr-parseExpr = doParse $ sc >> expr---- |Load a libary file-loadLibraryFile :: FilePath -> EgisonM [EgisonTopExpr]-loadLibraryFile file = do-  homeDir <- liftIO getHomeDirectory-  doesExist <- liftIO $ doesFileExist $ homeDir ++ "/.egison/" ++ file-  if doesExist-    then loadFile $ homeDir ++ "/.egison/" ++ file-    else liftIO (getDataFileName file) >>= loadFile---- |Load a file-loadFile :: FilePath -> EgisonM [EgisonTopExpr]-loadFile file = do-  doesExist <- liftIO $ doesFileExist file-  unless doesExist $ throwError $ Default ("file does not exist: " ++ file)-  input <- liftIO $ readUTF8File file-  exprs <- readTopExprs $ shebang input-  concat <$> mapM  recursiveLoad exprs- where-  recursiveLoad (Load file)     = loadLibraryFile file-  recursiveLoad (LoadFile file) = loadFile file-  recursiveLoad expr            = return [expr]-  shebang :: String -> String-  shebang ('#':'!':cs) = ';':'#':'!':cs-  shebang cs           = cs------- Parser-----type Parser = Parsec CustomError String--data CustomError-  = IllFormedPointFreeExpr EgisonBinOp EgisonBinOp-  deriving (Eq, Ord)--instance ShowErrorComponent CustomError where-  showErrorComponent (IllFormedPointFreeExpr op op') =-    "The operator " ++ info op ++ " must have lower precedence than " ++ info op'-    where-      info op =-         "'" ++ repr op ++ "' [" ++ show (assoc op) ++ " " ++ show (priority op) ++ "]"---doParse :: Parser a -> String -> Either EgisonError a-doParse p input = either (throwError . fromParsecError) return $ parse p "egison" input-  where-    fromParsecError :: ParseErrorBundle String CustomError -> EgisonError-    fromParsecError = Parser . errorBundlePretty------- Expressions-----topExpr :: Parser EgisonTopExpr-topExpr = Load     <$> (keywordLoad >> stringLiteral)-      <|> LoadFile <$> (keywordLoadFile >> stringLiteral)-      <|> defineOrTestExpr-      <?> "toplevel expression"--defineOrTestExpr :: Parser EgisonTopExpr-defineOrTestExpr = do-  e <- expr-  (do symbol "="-      body <- expr-      return (convertToDefine e body))-      <|> return (Test e)-  where-    convertToDefine :: EgisonExpr -> EgisonExpr -> EgisonTopExpr-    convertToDefine (VarExpr var) body = Define var body-    convertToDefine (ApplyExpr (VarExpr var) (TupleExpr args)) body =-      Define var (LambdaExpr (map exprToArg args) body)--    -- TODO(momohatt): Handle other types of arg-    exprToArg :: EgisonExpr -> Arg-    exprToArg (VarExpr (Var [x] [])) = ScalarArg x--expr :: Parser EgisonExpr-expr = ifExpr-   <|> patternMatchExpr-   <|> lambdaExpr-   <|> letExpr-   <|> withSymbolsExpr-   <|> doExpr-   <|> matcherExpr-   <|> algebraicDataMatcherExpr-   <|> memoizedLambdaExpr-   <|> procedureExpr-   <|> macroExpr-   <|> generateTensorExpr-   <|> tensorExpr-   <|> functionExpr-   <|> opExpr-   <?> "expression"---- Also parses atomExpr-opExpr :: Parser EgisonExpr-opExpr = do-  pos <- L.indentLevel-  makeExprParser atomOrApplyExpr (makeTable pos)-  where-    makeTable :: Pos -> [[Operator Parser EgisonExpr]]-    makeTable pos =-      let unary  sym = UnaryOpExpr  <$> operator sym-          binary sym = do-            op <- try (L.indentGuard sc GT pos >> binOpLiteral sym <* notFollowedBy (symbol ")"))-            return $ BinaryOpExpr op-       in-          [ [ Prefix (unary  "-" )-            , Prefix (unary  "!" ) ]-          -- 8-          , [ InfixL (binary "^" ) ]-          -- 7-          , [ InfixL (binary "*" )-            , InfixL (binary "/" )-            , InfixL (binary "%" ) ]-          -- 6-          , [ InfixL (binary "+" )-            , InfixL (binary "-" ) ]-          -- 5-          , [ InfixR (binary ":" )-            , InfixR (binary "++") ]-          -- 4-          , [ InfixL (binary "==")-            , InfixL (binary "<=")-            , InfixL (binary "<" )-            , InfixL (binary ">=")-            , InfixL (binary ">" ) ]-          -- 3-          , [ InfixR (binary "&&") ]-          -- 2-          , [ InfixR (binary "||") ]-          ]--ifExpr :: Parser EgisonExpr-ifExpr = keywordIf >> IfExpr <$> expr <* keywordThen <*> expr <* keywordElse <*> expr--patternMatchExpr :: Parser EgisonExpr-patternMatchExpr = makeMatchExpr keywordMatch       MatchExpr-               <|> makeMatchExpr keywordMatchDFS    MatchDFSExpr-               <|> makeMatchExpr keywordMatchAll    MatchAllExpr-               <|> makeMatchExpr keywordMatchAllDFS MatchAllDFSExpr-               <?> "pattern match expression"-  where-    makeMatchExpr keyword ctor = do-      tgt     <- keyword >> expr-      matcher <- keywordAs >> expr <* keywordWith-      clauses <- matchClauses1-      return $ ctor tgt matcher clauses---- Parse more than 1 match clauses.--- TODO(momohatt): Require first bar '|' when there are multiple match clauses-matchClauses1 :: Parser [MatchClause]-matchClauses1 = do-  pos <- optional (symbol "|") >> L.indentLevel-  (:) <$> matchClause pos <*> matchClauses pos-  where-    matchClauses :: Pos -> Parser [MatchClause]-    matchClauses pos = try ((:) <$> (symbol "|" >> matchClause pos) <*> matchClauses pos)-                   <|> return []-    matchClause :: Pos -> Parser MatchClause-    matchClause pos = (,) <$> (L.indentGuard sc EQ pos *> pattern) <*> (symbol "->" >> expr)--lambdaExpr :: Parser EgisonExpr-lambdaExpr = symbol "\\" >> (-      makeMatchLambdaExpr keywordMatch    MatchLambdaExpr-  <|> makeMatchLambdaExpr keywordMatchAll MatchAllLambdaExpr-  <|> try (LambdaExpr <$> some arg <*> (symbol "->" >> expr))-  <|> PatternFunctionExpr <$> some lowerId <*> (symbol "=>" >> pattern))-  <?> "lambda or pattern function expression"-  where-    makeMatchLambdaExpr keyword ctor = do-      matcher <- keyword >> keywordAs >> expr-      clauses <- keywordWith >> matchClauses1-      return $ ctor matcher clauses--arg :: Parser Arg-arg = InvertedScalarArg <$> (symbol "*$" >> lowerId)-  <|> TensorArg         <$> (symbol "%"  >> lowerId)-  <|> ScalarArg         <$> lowerId-  <?> "argument"--letExpr :: Parser EgisonExpr-letExpr = do-  pos   <- keywordLet >> L.indentLevel-  binds <- some (L.indentGuard sc EQ pos *> binding)-  body  <- keywordIn >> expr-  return $ LetRecExpr binds body--binding :: Parser BindingExpr-binding = do-  (vars, args) <- (,[]) <$> parens (sepBy varLiteral comma)-              <|> do var <- varLiteral-                     args <- many arg-                     return ([var], args)-  body <- symbol "=" >> expr-  return $ case args of-             [] -> (vars, body)-             _  -> (vars, LambdaExpr args body)--withSymbolsExpr :: Parser EgisonExpr-withSymbolsExpr = WithSymbolsExpr <$> (keywordWithSymbols >> brackets (sepBy lowerId comma)) <*> expr--doExpr :: Parser EgisonExpr-doExpr = do-  pos   <- keywordDo >> L.indentLevel-  stmts <- some $ L.indentGuard sc EQ pos >> statement-  ret   <- option (makeApply' "return" []) $ L.indentGuard sc EQ pos >> expr-  return $ DoExpr stmts ret-  where-    statement :: Parser BindingExpr-    statement = (keywordLet >> binding) <|> ([],) <$> expr--matcherExpr :: Parser EgisonExpr-matcherExpr = do-  keywordMatcher-  pos  <- L.indentLevel-  -- In matcher expression, the first '|' (bar) is indispensable-  info <- some (L.indentGuard sc EQ pos >> symbol "|" >> patternDef)-  return $ MatcherExpr info-  where-    patternDef :: Parser (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])-    patternDef = do-      pp <- ppPattern-      returnMatcher <- keywordAs >> expr <* keywordWith-      pos <- L.indentLevel-      datapat <- some (L.indentGuard sc EQ pos >> symbol "|" >> dataCases)-      return (pp, returnMatcher, datapat)--    dataCases :: Parser (PrimitiveDataPattern, EgisonExpr)-    dataCases = (,) <$> pdPattern <*> (symbol "->" >> expr)--algebraicDataMatcherExpr :: Parser EgisonExpr-algebraicDataMatcherExpr = do-  keywordAlgebraicDataMatcher-  pos  <- L.indentLevel-  defs <- some (L.indentGuard sc EQ pos >> symbol "|" >> patternDef)-  return $ AlgebraicDataMatcherExpr defs-  where-    patternDef :: Parser (String, [EgisonExpr])-    patternDef = do-      pos <- L.indentLevel-      patternCtor <- lowerId-      args <- many (L.indentGuard sc GT pos >> atomExpr)-      return (patternCtor, args)--memoizedLambdaExpr :: Parser EgisonExpr-memoizedLambdaExpr = MemoizedLambdaExpr <$> (keywordMemoizedLambda >> many lowerId) <*> (symbol "->" >> expr)--procedureExpr :: Parser EgisonExpr-procedureExpr = ProcedureExpr <$> (keywordProcedure >> many lowerId) <*> (symbol "->" >> expr)--macroExpr :: Parser EgisonExpr-macroExpr = MacroExpr <$> (keywordMacro >> many lowerId) <*> (symbol "->" >> expr)--generateTensorExpr :: Parser EgisonExpr-generateTensorExpr = GenerateTensorExpr <$> (keywordGenerateTensor >> atomExpr) <*> atomExpr--tensorExpr :: Parser EgisonExpr-tensorExpr = TensorExpr <$> (keywordTensor >> atomExpr) <*> atomExpr-                        <*> option (CollectionExpr []) atomExpr-                        <*> option (CollectionExpr []) atomExpr--functionExpr :: Parser EgisonExpr-functionExpr = FunctionExpr <$> (keywordFunction >> parens (sepBy expr comma))--collectionExpr :: Parser EgisonExpr-collectionExpr = symbol "[" >> (try betweenOrFromExpr <|> elementsExpr)-  where-    betweenOrFromExpr = do-      start <- expr <* symbol ".."-      end   <- optional expr <* symbol "]"-      case end of-        Just end' -> return $ makeApply' "between" [start, end']-        Nothing   -> return $ makeApply' "from" [start]--    elementsExpr = CollectionExpr <$> (sepBy (ElementExpr <$> expr) comma <* symbol "]")--tupleOrParenExpr :: Parser EgisonExpr-tupleOrParenExpr = do-  elems <- symbol "(" >> try (sepBy expr comma <* symbol ")") <|> (pointFreeExpr <* symbol ")")-  case elems of-    [x] -> return x-    _   -> return $ TupleExpr elems-  where-    pointFreeExpr :: Parser [EgisonExpr]-    pointFreeExpr =-          (do op   <- try . choice $ map (binOpLiteral . repr) reservedBinops-              rarg <- optional expr-              case rarg of-                Just (BinaryOpExpr op' _ _) | priority op >= priority op' ->-                  customFailure (IllFormedPointFreeExpr op op')-                _ -> return [makeLambda op Nothing rarg])-      <|> (do larg <- opExpr-              op   <- choice $ map (binOpLiteral . repr) reservedBinops-              case larg of-                BinaryOpExpr op' _ _ | priority op >= priority op' ->-                  customFailure (IllFormedPointFreeExpr op op')-                _ -> return [makeLambda op (Just larg) Nothing])--    makeLambda :: EgisonBinOp -> Maybe EgisonExpr -> Maybe EgisonExpr -> EgisonExpr-    makeLambda op Nothing Nothing =-      LambdaExpr [ScalarArg ":x", ScalarArg ":y"]-                 (BinaryOpExpr op (stringToVarExpr ":x") (stringToVarExpr ":y"))-    makeLambda op Nothing (Just rarg) =-      LambdaExpr [ScalarArg ":x"] (BinaryOpExpr op (stringToVarExpr ":x") rarg)-    makeLambda op (Just larg) Nothing =-      LambdaExpr [ScalarArg ":y"] (BinaryOpExpr op larg (stringToVarExpr ":y"))--arrayExpr :: Parser EgisonExpr-arrayExpr = ArrayExpr <$> between (symbol "(|") (symbol "|)") (sepEndBy expr comma)--vectorExpr :: Parser EgisonExpr-vectorExpr = VectorExpr <$> between (symbol "[|") (symbol "|]") (sepEndBy expr comma)--hashExpr :: Parser EgisonExpr-hashExpr = HashExpr <$> hashBraces (sepEndBy hashElem comma)-  where-    hashBraces = between (symbol "{|") (symbol "|}")-    hashElem = brackets $ (,) <$> expr <*> (comma >> expr)--index :: Parser (Index EgisonExpr)-index = SupSubscript <$> (string "~_" >> atomExpr')-    <|> try (char '_' >> subscript)-    <|> try (char '~' >> superscript)-    <|> try (Userscript <$> (char '|' >> atomExpr'))-    <?> "index"-  where-    subscript = do-      e1 <- atomExpr'-      e2 <- optional (string "..._" >> atomExpr')-      case e2 of-        Nothing  -> return $ Subscript e1-        Just e2' -> return $ MultiSubscript e1 e2'-    superscript = do-      e1 <- atomExpr'-      e2 <- optional (string "...~" >> atomExpr')-      case e2 of-        Nothing  -> return $ Superscript e1-        Just e2' -> return $ MultiSuperscript e1 e2'--atomOrApplyExpr :: Parser EgisonExpr-atomOrApplyExpr = do-  pos <- L.indentLevel-  func <- atomExpr-  args <- many (L.indentGuard sc GT pos *> atomExpr)-  return $ case args of-             [] -> func-             _  -> makeApply func args--atomExpr :: Parser EgisonExpr-atomExpr = do-  e <- atomExpr'-  -- TODO(momohatt): "..." (override of index) collides with ContPat-  indices <- many index-  return $ case indices of-             [] -> e-             _  -> IndexedExpr False e indices---- atom expr without index-atomExpr' :: Parser EgisonExpr-atomExpr' = constantExpr-        <|> VarExpr <$> varLiteral-        <|> (\x -> InductiveDataExpr x []) <$> upperId-        <|> vectorExpr     -- must come before collectionExpr-        <|> arrayExpr      -- must come before tupleOrParenExpr-        <|> collectionExpr-        <|> tupleOrParenExpr-        <|> hashExpr-        <|> QuoteExpr <$> (char '\'' >> atomExpr')-        <|> QuoteSymbolExpr <$> (char '`' >> atomExpr')-        <?> "atomic expression"--constantExpr :: Parser EgisonExpr-constantExpr = numericExpr-           <|> BoolExpr <$> boolLiteral-           <|> CharExpr <$> try charLiteral        -- try for quoteExpr-           <|> StringExpr . pack <$> stringLiteral-           <|> SomethingExpr <$ keywordSomething-           <|> UndefinedExpr <$ keywordUndefined--numericExpr :: Parser EgisonExpr-numericExpr = try (uncurry FloatExpr <$> floatLiteral)-          <|> IntegerExpr <$> positiveIntegerLiteral-          <?> "numeric expression"------ Pattern-----pattern :: Parser EgisonPattern-pattern = letPattern-      <|> loopPattern-      <|> opPattern-      <?> "pattern"--letPattern :: Parser EgisonPattern-letPattern = do-  pos   <- keywordLet >> L.indentLevel-  binds <- some (L.indentGuard sc EQ pos *> binding)-  body  <- keywordIn >> pattern-  return $ LetPat binds body--loopPattern :: Parser EgisonPattern-loopPattern = do-  keywordLoop-  iter <- patVarLiteral-  range <- loopRange-  loopBody <- optional (symbol "|") >> pattern-  loopEnd <- symbol "|" >> pattern-  return $ LoopPat iter range loopBody loopEnd-  where-    loopRange :: Parser LoopRange-    loopRange =-      parens $ do start <- expr-                  ends  <- option (defaultEnds start) (try $ comma >> expr)-                  as    <- option WildCard (comma >> pattern)-                  return $ LoopRange start ends as--    defaultEnds s =-      ApplyExpr (stringToVarExpr "from")-                (makeApply (stringToVarExpr "-'") [s, IntegerExpr 1])--seqPattern :: Parser EgisonPattern-seqPattern = do-  pats <- braces $ sepBy pattern comma-  return $ foldr SeqConsPat SeqNilPat pats--opPattern :: Parser EgisonPattern-opPattern = makeExprParser applyOrAtomPattern table-  where-    table :: [[Operator Parser EgisonPattern]]-    table =-      [ [ Prefix (NotPat <$ symbol "!") ]-      -- 5-      , [ InfixR (inductive2 "cons" ":" )-        , InfixR (inductive2 "join" "++") ]-      -- 3-      , [ InfixR (binary AndPat "&&") ]-      -- 2-      , [ InfixR (binary OrPat  "||") ]-      ]-    inductive2 name sym = (\x y -> InductivePat name [x, y]) <$ patOperator sym-    binary name sym     = (\x y -> name [x, y]) <$ patOperator sym--applyOrAtomPattern :: Parser EgisonPattern-applyOrAtomPattern = do-  pos <- L.indentLevel-  func <- atomPattern-  args <- many (L.indentGuard sc GT pos *> atomPattern)-  case (func, args) of-    (_,                 []) -> return func-    (InductivePat x [], _)  -> return $ InductivePat x args--atomPattern :: Parser EgisonPattern-atomPattern = do-  pat     <- atomPattern'-  indices <- many . try $ char '_' >> atomExpr'-  return $ case indices of-             [] -> pat-             _  -> IndexedPat pat indices---- atomic pattern without index-atomPattern' :: Parser EgisonPattern-atomPattern' = WildCard <$   symbol "_"-           <|> PatVar   <$> patVarLiteral-           <|> ValuePat <$> (char '#' >> atomExpr)-           <|> InductivePat "nil" [] <$ (symbol "[" >> symbol "]")-           <|> InductivePat <$> lowerId <*> pure []-           <|> VarPat   <$> (char '~' >> lowerId)-           <|> PredPat  <$> (symbol "?" >> atomExpr)-           <|> ContPat  <$ symbol "..."-           <|> makeTupleOrParen pattern TuplePat-           <|> seqPattern-           <|> LaterPatVar <$ symbol "@"-           <?> "atomic pattern"--ppPattern :: Parser PrimitivePatPattern-ppPattern = PPInductivePat <$> lowerId <*> many ppAtom-        <|> makeExprParser ppAtom table-        <?> "primitive pattern pattern"-  where-    table :: [[Operator Parser PrimitivePatPattern]]-    table =-      [ [ InfixR (inductive2 "cons" ":" )-        , InfixR (inductive2 "join" "++") ]-      ]-    inductive2 name sym = (\x y -> PPInductivePat name [x, y]) <$ operator sym--    ppAtom :: Parser PrimitivePatPattern-    ppAtom = PPWildCard <$ symbol "_"-         <|> PPPatVar   <$ symbol "$"-         <|> PPValuePat <$> (symbol "#$" >> lowerId)-         <|> PPInductivePat "nil" [] <$ brackets sc-         <|> makeTupleOrParen ppPattern PPTuplePat---- TODO(momohatt): cons pat, snoc pat, empty pat-pdPattern :: Parser PrimitiveDataPattern-pdPattern = PDInductivePat <$> upperId <*> many pdAtom-        <|> pdAtom-        <?> "primitive data pattern"-  where-    pdAtom :: Parser PrimitiveDataPattern-    pdAtom = PDWildCard    <$ symbol "_"-         <|> PDPatVar      <$> (symbol "$" >> lowerId)-         <|> PDConstantPat <$> constantExpr-         <|> makeTupleOrParen pdPattern PDTuplePat------- Tokens------- space comsumer-sc :: Parser ()-sc = L.space space1 lineCmnt blockCmnt-  where-    lineCmnt  = L.skipLineComment "--"-    blockCmnt = L.skipBlockCommentNested "{-" "-}"--lexeme :: Parser a -> Parser a-lexeme = L.lexeme sc--positiveIntegerLiteral :: Parser Integer-positiveIntegerLiteral = lexeme L.decimal-                     <?> "unsinged integer"--charLiteral :: Parser Char-charLiteral = between (char '\'') (symbol "\'") L.charLiteral-          <?> "character"--stringLiteral :: Parser String-stringLiteral = char '\"' *> manyTill L.charLiteral (symbol "\"")-          <?> "string"--boolLiteral :: Parser Bool-boolLiteral = reserved "True"  $> True-          <|> reserved "False" $> False-          <?> "boolean"--floatLiteral :: Parser (Double, Double)-floatLiteral = try ((,0) <$> (lexeme L.float <* notFollowedBy (symbol "i")))-                <|> (0,) <$> (lexeme L.float <* symbol "i")-                <?> "float"--varLiteral :: Parser Var-varLiteral = stringToVar <$> lowerId--patVarLiteral :: Parser Var-patVarLiteral = stringToVar <$> (char '$' >> lowerId)--binOpLiteral :: String -> Parser EgisonBinOp-binOpLiteral sym = do-  wedge <- optional (char '!')-  opSym <- operator sym-  let opInfo = fromJust $ find ((== opSym) . repr) reservedBinops-  return $ opInfo { isWedge = isJust wedge }--reserved :: String -> Parser ()-reserved w = (lexeme . try) (string w *> notFollowedBy alphaNumChar)--symbol :: String -> Parser String-symbol sym = try $ L.symbol sc sym--operator :: String -> Parser String-operator sym = try $ string sym <* notFollowedBy opChar <* sc--patOperator :: String -> Parser String-patOperator sym = try $ string sym <* notFollowedBy patOpChar <* sc---- Characters that could consist expression operators.-opChar :: Parser Char-opChar = oneOf "%^&*-+\\|:<>.?/'!#@$"---- Characters that could consist pattern operators.--- ! # @ $ are omitted because they can appear at the beginning of atomPattern-patOpChar :: Parser Char-patOpChar = oneOf "%^&*-+\\|:<>.?/'"--parens    = between (symbol "(") (symbol ")")-braces    = between (symbol "{") (symbol "}")-brackets  = between (symbol "[") (symbol "]")-comma     = symbol ","--lowerId :: Parser String-lowerId = (lexeme . try) (p >>= check)-  where-    p       = (:) <$> lowerChar <*> many (alphaNumChar <|> oneOf ['.', '?', '\''])-    check x = if x `elem` lowerReservedWords-                then fail $ "keyword " ++ show x ++ " cannot be an identifier"-                else return x---- TODO: Deprecate BoolExpr and merge it with InductiveDataExpr-upperId :: Parser String-upperId = (lexeme . try) (p >>= check)-  where-    p       = (:) <$> upperChar <*> many alphaNumChar-    check x = if x `elem` upperReservedWords-                then fail $ "keyword " ++ show x ++ " cannot be an identifier"-                else return x--keywordLoadFile             = reserved "loadFile"-keywordLoad                 = reserved "load"-keywordIf                   = reserved "if"-keywordThen                 = reserved "then"-keywordElse                 = reserved "else"-keywordSeq                  = reserved "seq"-keywordApply                = reserved "apply"-keywordCApply               = reserved "capply"-keywordMemoizedLambda       = reserved "memoizedLambda"-keywordCambda               = reserved "cambda"-keywordProcedure            = reserved "procedure"-keywordMacro                = reserved "macro"-keywordLetRec               = reserved "letrec"-keywordLet                  = reserved "let"-keywordIn                   = reserved "in"-keywordWithSymbols          = reserved "withSymbols"-keywordLoop                 = reserved "loop"-keywordMatch                = reserved "match"-keywordMatchDFS             = reserved "matchDFS"-keywordMatchAll             = reserved "matchAll"-keywordMatchAllDFS          = reserved "matchAllDFS"-keywordAs                   = reserved "as"-keywordWith                 = reserved "with"-keywordMatcher              = reserved "matcher"-keywordDo                   = reserved "do"-keywordIo                   = reserved "io"-keywordSomething            = reserved "something"-keywordUndefined            = reserved "undefined"-keywordAlgebraicDataMatcher = reserved "algebraicDataMatcher"-keywordGenerateTensor       = reserved "generateTensor"-keywordTensor               = reserved "tensor"-keywordTensorContract       = reserved "contract"-keywordSubrefs              = reserved "subrefs"-keywordSubrefsNew           = reserved "subrefs!"-keywordSuprefs              = reserved "suprefs"-keywordSuprefsNew           = reserved "suprefs!"-keywordUserrefs             = reserved "userRefs"-keywordUserrefsNew          = reserved "userRefs!"-keywordFunction             = reserved "function"--upperReservedWords =-  [ "True"-  , "False"-  ]--lowerReservedWords =-  [ "loadFile"-  , "load"-  , "if"-  , "then"-  , "else"-  , "seq"-  , "apply"-  , "capply"-  , "memoizedLambda"-  , "cambda"-  , "procedure"-  , "macro"-  , "letrec"-  , "let"-  , "in"-  , "withSymbols"-  , "loop"-  , "from"-  , "to"-  , "of"-  , "match"-  , "matchDFS"-  , "matchAll"-  , "matchAllDFS"-  , "as"-  , "with"-  , "matcher"-  , "do"-  , "io"-  , "something"-  , "undefined"-  , "algebraicDataMatcher"-  , "generateTensor"-  , "tensor"-  , "contract"-  , "subrefs"-  , "subrefs!"-  , "suprefs"-  , "suprefs!"-  , "userRefs"-  , "userRefs!"-  , "function"-  ]------- Utils-----makeTupleOrParen :: Parser a -> ([a] -> a) -> Parser a-makeTupleOrParen parser tupleCtor = do-  elems <- parens $ sepBy parser comma-  case elems of-    [elem] -> return elem-    _      -> return $ tupleCtor elems--makeApply :: EgisonExpr -> [EgisonExpr] -> EgisonExpr-makeApply (InductiveDataExpr x []) xs = InductiveDataExpr x xs-makeApply func xs = ApplyExpr func (TupleExpr xs)--makeApply' :: String -> [EgisonExpr] -> EgisonExpr-makeApply' func xs = ApplyExpr (stringToVarExpr func) (TupleExpr xs)
+ hs-src/Language/Egison/Pretty.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE FlexibleInstances #-}++{- |+Module      : Language.Egison.PrettyPrint+Copyright   : Satoshi Egi+Licence     : MIT++This module contains pretty printing for Egison syntax+-}++module Language.Egison.Pretty+    ( prettyTopExprs+    ) where++import           Data.Text.Prettyprint.Doc++import           Language.Egison.Types++--+-- Pretty printing for Non-S syntax+--++prettyTopExprs :: [EgisonTopExpr] -> Doc [EgisonTopExpr]+prettyTopExprs exprs = vsep $ punctuate line (map pretty exprs)++instance Pretty EgisonTopExpr where+  pretty (Define x (LambdaExpr args body)) =+    pretty x <+> hsep (map pretty args) <+> equals <> softline <> pretty body+  pretty (Define x expr) = pretty x <+> equals <> nest 2 (softline <> pretty expr)+  pretty (Test expr) = pretty expr++instance Pretty EgisonExpr where+  pretty (CharExpr x)    = squote <> pretty x <> squote+  pretty (StringExpr x)  = dquote <> pretty x <> dquote+  pretty (BoolExpr x)    = pretty x+  pretty (IntegerExpr x) = pretty x+  pretty (FloatExpr x)   = pretty x+  pretty (VarExpr x)     = pretty x++  pretty (InductiveDataExpr c xs) = nest 2 (pretty c <+> fillSep (map pretty xs))++  pretty (TupleExpr xs) = tupled (map pretty xs)+  pretty (CollectionExpr xs) = list (map pretty xs)+  pretty (ArrayExpr xs)  = listoid "(|" "|)" (map pretty xs)+  pretty (HashExpr xs)   = listoid "{|" "|}" (map (\(x, y) -> list [pretty x, pretty y]) xs)+  pretty (VectorExpr xs) = listoid "[|" "|]" (map pretty xs)++  pretty (LambdaExpr xs y)          = pretty "\\" <> hsep (map pretty xs) <+> pretty "->" <> nest 2 (softline <> pretty y)+  pretty (PatternFunctionExpr xs y) = pretty "\\" <> hsep (map pretty xs) <+> pretty "=>" <> softline <> pretty y++  pretty (UnaryOpExpr op x) = pretty op <> pretty x+  pretty (BinaryOpExpr op x@(BinaryOpExpr op' _ _) y)+    | priority op > priority op' = parens (pretty x) <+> pretty (repr op) <+> pretty' y+    | otherwise                  = pretty x <+> pretty (repr op) <+> pretty' y+  pretty (BinaryOpExpr op x y) = pretty x <+> pretty (repr op) <+> pretty' y++  pretty (ApplyExpr x (TupleExpr ys)) = nest 2 (pretty x <+> fillSep (map pretty ys))++instance Pretty Arg where+  pretty (ScalarArg x)         = pretty x+  pretty (InvertedScalarArg x) = pretty "*$" <> pretty x+  pretty (TensorArg x)         = pretty '%' <> pretty x++instance Pretty Var where+  -- TODO: indices+  pretty (Var xs is) = concatWith (surround dot) (map pretty xs)++instance Pretty InnerExpr where+  pretty (ElementExpr x) = pretty x+  pretty (SubCollectionExpr _) = error "Not supported"++instance Pretty EgisonPattern where+  pretty x = undefined++pretty' :: EgisonExpr -> Doc ann+pretty' x@(UnaryOpExpr _ _) = parens $ pretty x+pretty' x                   = pretty x++listoid :: String -> String -> [Doc ann] -> Doc ann+listoid lp rp elems = encloseSep (pretty lp) (pretty rp) (comma <> space) elems
hs-src/Language/Egison/Primitives.hs view
@@ -25,7 +25,7 @@ import           Data.Foldable             (toList) import           Data.IORef import           Data.Ratio-import           Text.Regex.TDFA           ((=~))+import           Text.Regex.TDFA           ((=~~))  import           System.IO import           System.Process            (readProcess)@@ -140,8 +140,8 @@  constants :: [(String, EgisonValue)] constants = [-              ("f.pi", Float 3.141592653589793 0)-             ,("f.e" , Float 2.718281828459045 0)+              ("f.pi", Float 3.141592653589793)+             ,("f.e" , Float 2.718281828459045)               ]  --@@ -157,10 +157,10 @@              , ("b.-'", minus)              , ("b.*'", multiply)              , ("b./'", divide)-             , ("f.+", floatPlus)-             , ("f.-", floatMinus)-             , ("f.*", floatMult)-             , ("f./", floatDivide)+             , ("f.+", floatBinaryOp (+))+             , ("f.-", floatBinaryOp (-))+             , ("f.*", floatBinaryOp (*))+             , ("f./", floatBinaryOp (/))              , ("numerator", numerator')              , ("denominator", denominator')              , ("from-math-expr", fromScalarData)@@ -168,7 +168,7 @@              , ("to-math-expr'", toScalarData)               , ("modulo",    integerBinaryOp mod)-             , ("quotient",   integerBinaryOp quot)+             , ("quotient",  integerBinaryOp quot)              , ("remainder", integerBinaryOp rem)              , ("b.abs", rationalUnaryOp abs)              , ("b.neg", rationalUnaryOp negate)@@ -183,8 +183,6 @@              , ("floor",    floatToIntegerOp floor)              , ("ceiling",  floatToIntegerOp ceiling)              , ("truncate", truncate')-             , ("real-part", realPart)-             , ("imaginary-part", imaginaryPart)               , ("b.sqrt", floatUnaryOp sqrt)              , ("b.sqrt'", floatUnaryOp sqrt)@@ -263,10 +261,10 @@              , ("b.-'", minus)              , ("b.*'", multiply)              , ("b./'", divide)-             , ("f.+", floatPlus)-             , ("f.-", floatMinus)-             , ("f.*", floatMult)-             , ("f./", floatDivide)+             , ("f.+", floatBinaryOp (+))+             , ("f.-", floatBinaryOp (-))+             , ("f.*", floatBinaryOp (*))+             , ("f./", floatBinaryOp (/))              , ("numerator", numerator')              , ("denominator", denominator')              , ("fromMathExpr", fromScalarData)@@ -289,8 +287,6 @@              , ("floor",    floatToIntegerOp floor)              , ("ceiling",  floatToIntegerOp ceiling)              , ("truncate", truncate')-             , ("realPart", realPart)-             , ("imaginaryPart", imaginaryPart)               , ("b.sqrt", floatUnaryOp sqrt)              , ("b.sqrt'", floatUnaryOp sqrt)@@ -392,12 +388,12 @@  floatUnaryOp :: (Double -> Double) -> PrimitiveFunc floatUnaryOp op = oneArg $ \val -> case val of-                                     (Float f 0) -> return $ Float (op f) 0+                                     (Float f) -> return $ Float (op f)                                      _ -> throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack  floatBinaryOp :: (Double -> Double -> Double) -> PrimitiveFunc floatBinaryOp op = twoArgs $ \val val' -> case (val, val') of-                                            (Float f 0, Float f' 0) -> return $ Float (op f f') 0+                                            (Float f, Float f') -> return $ Float (op f f')                                             _ -> throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack  floatBinaryPred :: (Double -> Double -> Bool) -> PrimitiveFunc@@ -406,27 +402,7 @@   f' <- fromEgison val'   return $ Bool $ pred f f' -floatPlus :: PrimitiveFunc-floatPlus = twoArgs $ \val val' -> case (val, val') of-                                     (Float x y, Float x' y') -> return $ Float (x + x')  (y + y')-                                     _ -> throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack -floatMinus :: PrimitiveFunc-floatMinus = twoArgs $ \val val' -> case (val, val') of-                                      (Float x y, Float x' y') -> return $ Float (x - x')  (y - y')-                                      _ -> throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack--floatMult :: PrimitiveFunc-floatMult = twoArgs $ \val val' -> case (val, val') of-                                     (Float x y, Float x' y') -> return $ Float (x * x' - y * y')  (x * y' + x' * y)-                                     _ -> throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack--floatDivide :: PrimitiveFunc-floatDivide = twoArgs $ \val val' -> case (val, val') of-                                       (Float x y, Float x' y') -> return $ Float ((x * x' + y * y') / (x' * x' + y' * y')) ((y * x' - x * y') / (x' * x' + y' * y'))-                                       _ -> throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack-- -- -- Arith --@@ -487,10 +463,10 @@     r <- fromEgison m :: EgisonM Rational     r' <- fromEgison n :: EgisonM Rational     return $ Bool $ (<) r r'-  scalarBinaryPred' (Float f 0)  (Float f' 0)  = return $ Bool $ (<) f f'-  scalarBinaryPred' (ScalarData _) val         = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack-  scalarBinaryPred' (Float _ _)  val           = throwError =<< TypeMismatch "float"  (Value val) <$> getFuncNameStack-  scalarBinaryPred' val          _             = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack+  scalarBinaryPred' (Float f)      (Float f') = return $ Bool (f < f')+  scalarBinaryPred' (ScalarData _) val        = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack+  scalarBinaryPred' (Float _)      val        = throwError =<< TypeMismatch "float"  (Value val) <$> getFuncNameStack+  scalarBinaryPred' val            _          = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack  lte :: PrimitiveFunc lte = twoArgs' $ \val val' -> scalarBinaryPred' val val'@@ -499,10 +475,10 @@     r <- fromEgison m :: EgisonM Rational     r' <- fromEgison n :: EgisonM Rational     return $ Bool $ (<=) r r'-  scalarBinaryPred' (Float f 0)  (Float f' 0)  = return $ Bool $ (<=) f f'-  scalarBinaryPred' (ScalarData _) val         = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack-  scalarBinaryPred' (Float _ _)  val           = throwError =<< TypeMismatch "float"  (Value val) <$> getFuncNameStack-  scalarBinaryPred' val          _             = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack+  scalarBinaryPred' (Float f)      (Float f') = return $ Bool (f <= f')+  scalarBinaryPred' (ScalarData _) val        = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack+  scalarBinaryPred' (Float _)      val        = throwError =<< TypeMismatch "float"  (Value val) <$> getFuncNameStack+  scalarBinaryPred' val            _          = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack  gt :: PrimitiveFunc gt = twoArgs' $ \val val' -> scalarBinaryPred' val val'@@ -511,10 +487,10 @@     r <- fromEgison m :: EgisonM Rational     r' <- fromEgison n :: EgisonM Rational     return $ Bool $ (>) r r'-  scalarBinaryPred' (Float f 0)  (Float f' 0)  = return $ Bool $ (>) f f'+  scalarBinaryPred' (Float f)      (Float f')  = return $ Bool $ (f > f')   scalarBinaryPred' (ScalarData _) val         = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack-  scalarBinaryPred' (Float _ _)  val           = throwError =<< TypeMismatch "float"  (Value val) <$> getFuncNameStack-  scalarBinaryPred' val          _             = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack+  scalarBinaryPred' (Float _)      val         = throwError =<< TypeMismatch "float"  (Value val) <$> getFuncNameStack+  scalarBinaryPred' val            _           = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack  gte :: PrimitiveFunc gte = twoArgs' $ \val val' -> scalarBinaryPred' val val'@@ -523,31 +499,19 @@     r <- fromEgison m :: EgisonM Rational     r' <- fromEgison n :: EgisonM Rational     return $ Bool $ (>=) r r'-  scalarBinaryPred' (Float f 0)    (Float f' 0)  = return $ Bool $ (>=) f f'-  scalarBinaryPred' (ScalarData _) val           = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack-  scalarBinaryPred' (Float _ _)    val           = throwError =<< TypeMismatch "float"  (Value val) <$> getFuncNameStack-  scalarBinaryPred' val            _             = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack+  scalarBinaryPred' (Float f)      (Float f')  = return $ Bool (f >= f')+  scalarBinaryPred' (ScalarData _) val         = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack+  scalarBinaryPred' (Float _)      val         = throwError =<< TypeMismatch "float"  (Value val) <$> getFuncNameStack+  scalarBinaryPred' val            _           = throwError =<< TypeMismatch "number" (Value val) <$> getFuncNameStack  truncate' :: PrimitiveFunc truncate' = oneArg $ \val -> numberUnaryOp' val  where   numberUnaryOp' (ScalarData (Div (Plus []) _)) = return $ toEgison (0 :: Integer)   numberUnaryOp' (ScalarData (Div (Plus [Term x []]) (Plus [Term y []]))) = return $ toEgison (quot x y)-  numberUnaryOp' (Float x _)           = return $ toEgison (truncate x :: Integer)+  numberUnaryOp' (Float x)             = return $ toEgison (truncate x :: Integer)   numberUnaryOp' val                   = throwError =<< TypeMismatch "rational or float" (Value val) <$> getFuncNameStack -realPart :: PrimitiveFunc-realPart =  oneArg realPart'- where-  realPart' (Float x y) = return $ Float x 0-  realPart' val         = throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack--imaginaryPart :: PrimitiveFunc-imaginaryPart =  oneArg imaginaryPart'- where-  imaginaryPart' (Float _ y) = return $ Float y 0-  imaginaryPart' val         = throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack- -- -- Tensor --@@ -574,8 +538,8 @@ -- Transform -- numberToFloat' :: EgisonValue -> EgisonValue-numberToFloat' (ScalarData (Div (Plus []) _)) = Float 0 0-numberToFloat' (ScalarData (Div (Plus [Term x []]) (Plus [Term y []]))) = Float (fromRational (x % y)) 0+numberToFloat' (ScalarData (Div (Plus []) _)) = Float 0+numberToFloat' (ScalarData (Div (Plus [Term x []]) (Plus [Term y []]))) = Float $ fromRational (x % y)  integerToFloat :: PrimitiveFunc integerToFloat = rationalToFloat@@ -645,22 +609,20 @@  regexString :: PrimitiveFunc regexString = twoArgs $ \pat src -> case (pat, src) of-                                      (String patStr, String srcStr) -> do-                                        let (a, b, c) = (T.unpack srcStr =~ T.unpack patStr) :: (String, String, String)-                                        if b == ""-                                          then return . Collection . Sq.fromList $ []-                                          else return . Collection . Sq.fromList $ [Tuple [String $ T.pack a, String $ T.pack b, String $ T.pack c]]+                                      (String patStr, String srcStr) ->+                                        case (T.unpack srcStr =~~ T.unpack patStr) :: (Maybe (String, String, String)) of+                                          Nothing -> return . Collection . Sq.fromList $ []+                                          Just (a,b,c) -> return . Collection . Sq.fromList $ [Tuple [String $ T.pack a, String $ T.pack b, String $ T.pack c]]                                       (String _, _) -> throwError =<< TypeMismatch "string" (Value src) <$> getFuncNameStack                                       (_, _) -> throwError =<< TypeMismatch "string" (Value pat) <$> getFuncNameStack  regexStringCaptureGroup :: PrimitiveFunc regexStringCaptureGroup = twoArgs $ \pat src -> case (pat, src) of-                                                  (String patStr, String srcStr) -> do-                                                    let ret = (T.unpack srcStr =~ T.unpack patStr) :: [[String]]-                                                    case ret of-                                                      [] -> return . Collection . Sq.fromList $ []-                                                      ((x:xs):_) -> do let (a, c) = T.breakOn (T.pack x) srcStr-                                                                       return . Collection . Sq.fromList $ [Tuple [String a, Collection (Sq.fromList (map (String . T.pack) xs)), String (T.drop (length x) c)]]+                                                  (String patStr, String srcStr) ->+                                                    case (T.unpack srcStr =~~ T.unpack patStr) :: (Maybe [[String]]) of+                                                      Nothing -> return . Collection . Sq.fromList $ []+                                                      Just ((x:xs):_) -> do let (a, c) = T.breakOn (T.pack x) srcStr+                                                                            return . Collection . Sq.fromList $ [Tuple [String a, Collection (Sq.fromList (map (String . T.pack) xs)), String (T.drop (length x) c)]]                                                   (String _, _) -> throwError =<< TypeMismatch "string" (Value src) <$> getFuncNameStack                                                   (_, _) -> throwError =<< TypeMismatch "string" (Value pat) <$> getFuncNameStack 
hs-src/Language/Egison/Types.hs view
@@ -26,7 +26,7 @@     , InnerExpr (..)     , BindingExpr (..)     , MatchClause (..)-    , MatcherInfo (..)+    , PatternDef (..)     , LoopRange (..)     , PrimitivePatPattern (..)     , PrimitiveDataPattern (..)@@ -195,7 +195,6 @@ import qualified Data.Text                 as T  import           Data.Ratio-import           Numeric                   (showFFloat) import           System.IO  import           System.IO.Unsafe          (unsafePerformIO)@@ -221,7 +220,7 @@   | StringExpr Text   | BoolExpr Bool   | IntegerExpr Integer-  | FloatExpr Double Double+  | FloatExpr Double   | VarExpr Var   | FreshVarExpr   | IndexedExpr Bool EgisonExpr [Index EgisonExpr]  -- True -> delete old index and append new one@@ -258,14 +257,12 @@   | MatchLambdaExpr EgisonExpr [MatchClause]   | MatchAllLambdaExpr EgisonExpr [MatchClause] -  | MatcherExpr MatcherInfo+  | MatcherExpr [PatternDef]   | AlgebraicDataMatcherExpr [(String, [EgisonExpr])]    | QuoteExpr EgisonExpr   | QuoteSymbolExpr EgisonExpr--  | WedgeExpr EgisonExpr                         -- Desugared to WedgeApplyExpr-  | WedgeApplyExpr EgisonExpr EgisonExpr         -- Appears after desugar+  | WedgeApplyExpr EgisonExpr EgisonExpr    | DoExpr [BindingExpr] EgisonExpr   | IoExpr EgisonExpr@@ -323,7 +320,7 @@  type BindingExpr = ([Var], EgisonExpr) type MatchClause = (EgisonPattern, EgisonExpr)-type MatcherInfo = [(PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])]+type PatternDef  = (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])  -- TODO(momohatt): AndPat and OrPat take only 2 arguments in new syntax data EgisonPattern =@@ -433,7 +430,7 @@   | Bool Bool   | ScalarData ScalarData   | TensorData (Tensor EgisonValue)-  | Float Double Double+  | Float Double   | InductiveData String [EgisonValue]   | Tuple [EgisonValue]   | Collection (Seq EgisonValue)@@ -441,7 +438,7 @@   | IntHash (HashMap Integer EgisonValue)   | CharHash (HashMap Char EgisonValue)   | StrHash (HashMap Text EgisonValue)-  | UserMatcher Env MatcherInfo+  | UserMatcher Env [PatternDef]   | Func (Maybe Var) Env [String] EgisonExpr   | PartialFunc Env Integer EgisonExpr   | CFunc (Maybe Var) Env String EgisonExpr@@ -1217,16 +1214,16 @@  removePairs :: (Int, Int) -> [a] -> [a] removePairs (m, n) xs =-  let (hs, ms, ts) = removePairs' (m, n) xs in-    hs ++ ms ++ ts+  let (hs, ms, ts) = removePairs' (m, n) xs+   in hs ++ ms ++ ts  removePairs' :: (Int, Int) -> [a] -> ([a],[a],[a])-removePairs' (m, n) xs =           -- (0,1) [i i]-  let (hms, tts) = splitAt n xs in -- [i] [i]-  let ts = tail tts in             -- []-  let (hs, tms) = splitAt m hms in -- [] [i]-  let ms = tail tms in             -- []-    (hs, ms, ts)                   -- [] [] []+removePairs' (m, n) xs =         -- (0,1) [i i]+  let (hms, tts) = splitAt n xs  -- [i] [i]+      ts = tail tts              -- []+      (hs, tms) = splitAt m hms  -- [] [i]+      ms = tail tms              -- []+   in (hs, ms, ts)               -- [] [] [] -- -- --@@ -1241,7 +1238,7 @@   show (BoolExpr True) = "#t"   show (BoolExpr False) = "#f"   show (IntegerExpr n) = show n-  show (FloatExpr x y) = showComplexFloat x y+  show (FloatExpr x) = show x   show (VarExpr name) = show name   show (PartialVarExpr n) = "%" ++ show n   show (FunctionExpr args) = "(function [" ++ unwords (map show args) ++ "])"@@ -1277,7 +1274,7 @@     f j [] = ""     f j xs = "[| " ++ unwords (map show (take j xs)) ++ " |] " ++ f j (drop j xs)   show (TensorData (Tensor ns xs js)) = "(tensor {" ++ unwords (map show ns) ++ "} {" ++ unwords (map show (V.toList xs)) ++ "} )" ++ concatMap show js-  show (Float x y) = showComplexFloat x y+  show (Float x) = show x   show (InductiveData name []) = "<" ++ name ++ ">"   show (InductiveData name vals) = "<" ++ name ++ " " ++ unwords (map show vals) ++ ">"   show (Tuple vals) = "[" ++ unwords (map show vals) ++ "]"@@ -1342,18 +1339,6 @@   show (FunctionData Nothing argnames args js) = "(functionData [" ++ unwords (map show argnames) ++ "])" ++ concatMap show js   show (FunctionData (Just name) argnames args js) = show name ++ concatMap show js -showComplex :: (Num a, Eq a, Ord a, Show a) => a -> a -> String-showComplex x 0 = show x-showComplex 0 y = show y ++ "i"-showComplex x y = show x ++ (if y > 0 then "+" else "") ++ show y ++ "i"--showComplexFloat :: Double -> Double -> String-showComplexFloat x 0.0 = showFFloat Nothing x ""-showComplexFloat 0.0 y = showFFloat Nothing y "i"-showComplexFloat x y = showFFloat Nothing x "" ++ if y > 0-                                                    then "+" ++ showFFloat Nothing y "i"-                                                    else showFFloat Nothing y "i"- showTSV :: EgisonValue -> String showTSV (Tuple (val:vals)) = foldl (\r x -> r ++ "\t" ++ x) (show val) (map show vals) showTSV (Collection vals) = intercalate "\t" (map show (toList vals))@@ -1365,7 +1350,7 @@  (Bool b) == (Bool b') = b == b'  (ScalarData x) == (ScalarData y) = x == y  (TensorData (Tensor js xs _)) == (TensorData (Tensor js' xs' _)) = (js == js') && (xs == xs')- (Float x y) == (Float x' y') = (x == x') && (y == y')+ (Float x) == (Float x') = x == x'  (InductiveData name vals) == (InductiveData name' vals') = (name == name') && (vals == vals')  (Tuple vals) == (Tuple vals') = vals == vals'  (Collection vals) == (Collection vals') = vals == vals'@@ -1457,9 +1442,9 @@   fromEgison val = throwError =<< TypeMismatch "rational" (Value val) <$> getFuncNameStack  instance EgisonData Double where-  toEgison f = Float f 0-  fromEgison (Float f 0) = return f-  fromEgison val         = throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack+  toEgison f = Float f+  fromEgison (Float f) = return f+  fromEgison val       = throwError =<< TypeMismatch "float" (Value val) <$> getFuncNameStack  instance EgisonData Handle where   toEgison = Port@@ -1574,8 +1559,8 @@   fromWHNF whnf = throwError =<< TypeMismatch "integer" whnf <$> getFuncNameStack  instance EgisonWHNF Double where-  fromWHNF (Value (Float f 0)) = return f-  fromWHNF whnf                = throwError =<< TypeMismatch "float" whnf <$> getFuncNameStack+  fromWHNF (Value (Float f)) = return f+  fromWHNF whnf              = throwError =<< TypeMismatch "float" whnf <$> getFuncNameStack  instance EgisonWHNF Handle where   fromWHNF (Value (Port h)) = return h@@ -1948,7 +1933,7 @@ isScalar _              = False  isScalar' :: PrimitiveFunc-isScalar' (Value val) = return $ Value $ Bool $ isScalar val+isScalar' (Value (ScalarData _)) = return $ Value $ Bool $ True isScalar' _           = return $ Value $ Bool False  isTensor :: EgisonValue -> Bool@@ -1956,7 +1941,8 @@ isTensor _              = False  isTensor' :: PrimitiveFunc-isTensor' (Value val) = return $ Value $ Bool $ isTensor val+isTensor' (Value (TensorData _)) = return $ Value $ Bool $ True+isTensor' (Intermediate (ITensor _)) = return $ Value $ Bool $ True isTensor' _           = return $ Value $ Bool False  isTensorWithIndex :: EgisonValue -> Bool@@ -1968,12 +1954,12 @@ isTensorWithIndex' _           = return $ Value $ Bool False  isFloat' :: PrimitiveFunc-isFloat' (Value (Float _ 0)) = return $ Value $ Bool True-isFloat' _                   = return $ Value $ Bool False+isFloat' (Value (Float _)) = return $ Value $ Bool True+isFloat' _                 = return $ Value $ Bool False  isComplex' :: PrimitiveFunc-isComplex' (Value (Float _ _)) = return $ Value $ Bool True-isComplex' _                   = return $ Value $ Bool False+isComplex' (Value (Float _)) = return $ Value $ Bool True+isComplex' _                 = return $ Value $ Bool False  isChar' :: PrimitiveFunc isChar' (Value (Char _)) = return $ Value $ Bool True@@ -2041,9 +2027,8 @@     optTestOnly         :: Bool,     optPrompt           :: String,     optMathExpr         :: Maybe String,-    optSExpr            :: Bool,-    optUseNonS2         :: Bool+    optSExpr            :: Bool     }  defaultOption :: EgisonOpts-defaultOption = EgisonOpts Nothing False Nothing Nothing [] [] [] Nothing Nothing Nothing False False True False "> " Nothing True False+defaultOption = EgisonOpts Nothing False Nothing Nothing [] [] [] Nothing Nothing Nothing False False True False "> " Nothing True
hs-src/Language/Egison/Util.hs view
@@ -19,7 +19,6 @@  import           Language.Egison.Parser           as Parser import           Language.Egison.ParserNonS       as ParserNonS-import           Language.Egison.ParserNonS2      as ParserNonS2 import           Language.Egison.Types  -- |Get Egison expression from the prompt. We can handle multiline input.@@ -41,7 +40,7 @@       history <- getHistory       putHistory $ addHistoryUnlessConsecutiveDupe line history       let input = prev ++ line-      let parsedExpr = (if optUseNonS2 opts then ParserNonS2.parseTopExpr else if optSExpr opts then Parser.parseTopExpr else ParserNonS.parseTopExpr) input+      let parsedExpr = (if optSExpr opts then Parser.parseTopExpr else ParserNonS.parseTopExpr) input       case parsedExpr of         Left err | show err =~ "unexpected end of input" ->           getEgisonExpr' opts $ input ++ "\n"
+ hs-src/Tool/translator.hs view
@@ -0,0 +1,124 @@+{-# LANGUAGE FlexibleInstances #-}++module Main where++import           Control.Arrow                         ((***))+import           Data.Char                             (toUpper)+import           Data.List                             (find)+import           Data.List.Split                       (splitOn)+import           Data.Maybe                            (fromJust)+import           Data.Text.Prettyprint.Doc.Render.Text (putDoc)+import           System.Environment                    (getArgs)++import           Language.Egison.Types+import           Language.Egison.Parser+import           Language.Egison.Pretty++class SyntaxElement a where+  toNonS :: a -> a++instance SyntaxElement EgisonTopExpr where+  toNonS (Define x y)   = Define (toNonS x) (toNonS y)+  toNonS (Redefine x y) = error "Not supported"+  toNonS (Test x)       = Test (toNonS x)+  toNonS (Execute x)    = Execute (toNonS x)+  toNonS x              = x++instance SyntaxElement EgisonExpr where+  toNonS (IntegerExpr x)+    | x < 0     = UnaryOpExpr "-" (IntegerExpr (-x))+    | otherwise = IntegerExpr x+  toNonS (VarExpr x) = VarExpr (toNonS x)++  toNonS (IndexedExpr b x ys)  = IndexedExpr  b (toNonS x) (map toNonS ys)+  toNonS (SubrefsExpr b x y)   = SubrefsExpr  b (toNonS x) (toNonS y)+  toNonS (SuprefsExpr b x y)   = SuprefsExpr  b (toNonS x) (toNonS y)+  toNonS (UserrefsExpr b x y)  = UserrefsExpr b (toNonS x) (toNonS y)+  toNonS (PowerExpr x y) = BinaryOpExpr powerOp (toNonS x) (toNonS y)+    where powerOp = fromJust $ find (\op -> repr op == "^") reservedBinops+  toNonS (InductiveDataExpr x ys) = InductiveDataExpr x (map toNonS ys)+  toNonS (TupleExpr xs)      = TupleExpr (map toNonS xs)+  toNonS (CollectionExpr xs) = CollectionExpr (map toNonS xs)+  toNonS (ArrayExpr xs)      = ArrayExpr (map toNonS xs)+  toNonS (HashExpr xs)       = HashExpr (map (toNonS *** toNonS) xs)+  toNonS (VectorExpr xs)     = VectorExpr (map toNonS xs)++  toNonS (LambdaExpr xs y)          = LambdaExpr xs (toNonS y)+  toNonS (MemoizedLambdaExpr xs y)  = MemoizedLambdaExpr xs (toNonS y)+  toNonS (CambdaExpr _ _)           = error "Not supported"+  toNonS (ProcedureExpr xs y)       = ProcedureExpr xs (toNonS y)+  toNonS (MacroExpr xs y)           = MacroExpr xs (toNonS y)+  -- PatternFunctionExpr++  toNonS (IfExpr x y z)         = IfExpr (toNonS x) (toNonS y) (toNonS z)+  toNonS (LetRecExpr xs y)      = LetRecExpr (map toNonS xs) (toNonS y)+  toNonS (LetExpr xs y)         = LetExpr (map toNonS xs) (toNonS y)+  toNonS (LetStarExpr xs y)     = LetStarExpr (map toNonS xs) (toNonS y)+  toNonS (WithSymbolsExpr xs y) = WithSymbolsExpr xs (toNonS y)++  toNonS (MatchExpr x y zs)        = MatchExpr       (toNonS x) (toNonS y) (map toNonS zs)+  toNonS (MatchDFSExpr x y zs)     = MatchDFSExpr    (toNonS x) (toNonS y) (map toNonS zs)+  toNonS (MatchAllExpr x y zs)     = MatchAllExpr    (toNonS x) (toNonS y) (map toNonS zs)+  toNonS (MatchAllDFSExpr x y zs)  = MatchAllDFSExpr (toNonS x) (toNonS y) (map toNonS zs)+  toNonS (MatchLambdaExpr x ys)    = MatchLambdaExpr    (toNonS x) (map toNonS ys)+  toNonS (MatchAllLambdaExpr x ys) = MatchAllLambdaExpr (toNonS x) (map toNonS ys)++  toNonS (MatcherExpr xs) = MatcherExpr (map toNonS xs)++  toNonS (QuoteExpr x)        = QuoteExpr (toNonS x)+  toNonS (QuoteSymbolExpr x)  = QuoteSymbolExpr (toNonS x)+  toNonS (WedgeApplyExpr x y) = WedgeApplyExpr (toNonS x) (toNonS y)++  toNonS (DoExpr xs y) = DoExpr (map toNonS xs) (toNonS y)+  toNonS (IoExpr x)    = IoExpr (toNonS x)++  toNonS (ApplyExpr x@(VarExpr (Var [f] [])) (TupleExpr [y, z])) =+    case find (\op -> repr op == f) reservedBinops of+      Just op -> BinaryOpExpr op (toNonS y) (toNonS z)+      Nothing -> ApplyExpr x (TupleExpr [toNonS y, toNonS z])++  toNonS x = x++instance SyntaxElement a => SyntaxElement (Index a) where+  toNonS (Subscript x)          = Subscript (toNonS x)+  toNonS (Superscript x)        = Superscript (toNonS x)+  toNonS (SupSubscript x)       = SupSubscript (toNonS x)+  toNonS (MultiSubscript x y)   = MultiSubscript (toNonS x) (toNonS y)+  toNonS (MultiSuperscript x y) = MultiSuperscript (toNonS x) (toNonS y)+  toNonS (Userscript x)         = Userscript (toNonS x)+  toNonS (DotSubscript x)       = DotSubscript (toNonS x)+  toNonS (DotSupscript x)       = DotSupscript (toNonS x)+  toNonS x = x -- DFScript++instance SyntaxElement InnerExpr where+  toNonS (ElementExpr x) = ElementExpr (toNonS x)+  toNonS (SubCollectionExpr _) = error "Not supported"++instance SyntaxElement BindingExpr where+  toNonS (vars, x) = (map toNonS vars, toNonS x)++instance SyntaxElement MatchClause where+  toNonS (x, y) = (x, toNonS y)++instance SyntaxElement PatternDef where+  toNonS (x, y, zs) = (x, toNonS y, map (\(z, w) -> (z, toNonS w)) zs)++instance SyntaxElement Var where+  toNonS (Var xs ys) = Var (map toCamelCase xs) ys+    where+      toCamelCase :: String -> String+      toCamelCase x =+        let heads:tails = splitOn "-" x+         in concat $ heads : map (\ (x:xs) -> toUpper x : xs) tails++main :: IO ()+main = do+  args <- getArgs+  input <- readFile $ head args+  -- 'ast' is not desugared+  let ast = parseTopExprs input+  case ast of+    Left _ -> return ()+    Right ast -> do+      putDoc $ prettyTopExprs $ map toNonS ast+      putStrLn ""
+ nons-test/test/lib/core/base.egi view
@@ -0,0 +1,55 @@+--+-- Matchers+--++assert "bool's value pattern"+  (match (True, False) as (bool, bool) with+   | #(True, False) -> True+   | _ -> False)++assert "char's value pattern"+  (match 'a' as char with+   | #'a' -> True+   | _ -> False)++assert "integer's value pattern"+  (match 10 as integer with+   | #10 -> True+   | _ -> False)++assert "float's value pattern"+  (match 0.1 as float with+   | #0.1 -> True+   | _ -> False)++--+-- Utility+--+assertEqual "id" (id 1) 1++assertEqual "fst" (fst (1, 2)) 1++assertEqual "snd" (snd (1, 2)) 2++assertEqual "compose - case 1" ((compose (fst, snd)) ((1, 2), 3)) 2++assertEqual "compose - case 2" ((compose (fst, snd, fst)) ((1, (2, 3)), 4)) 2++-- assertEqual("eq?/m",+--   eq?/m(integer, 1, 1),+--   True)++--+-- Booleans+--+assertEqual "and"+  [True && True, True && False, False && True, False && False]+  [True, False, False, False]++assertEqual "or"+  [True || True, True || False, False || True, False || False]+  [True, True, True, False]++assertEqual "not"+  [not True, not False]+  [False, True]
+ nons-test/test/lib/core/order.egi view
@@ -0,0 +1,35 @@+assertEqual "compare - case 1"+  (compare 10 10)+  Equal++assertEqual "compare - case 2"+  (compare 11 10)+  Greater++assertEqual "compare - case 3"+  (compare 10 11)+  Less++assertEqual "min"+  (min [20, 5])+  5++-- assertEqual "min/fn"+--   (min/fn compare [10, 20, 5, 20, 30])+--   5++assertEqual "max"+  (max [5, 30])+  30++-- assertEqual "max/fn"+--   (max/fn compare [10, 20, 5, 20, 30])+--   30++assertEqual "sort"+  (sort [10, 20, 5, 20, 30])+  [5, 10, 20, 20, 30]++-- assertEqual "sort/fn"+--   (sort/fn compare [10, 20, 5, 20, 30])+--   [5, 10, 20, 20, 30]
+ nons-test/test/primitive.egi view
@@ -0,0 +1,175 @@+assertEqual "numerator" (numerator (13 / 21)) 13++assertEqual "denominator" (denominator (13 / 21)) 21++assertEqual "modulo" (modulo (-21) 13) 5++assertEqual "quotient" (quotient (-21) 13) (-1)++assertEqual "remainder" (remainder (-21) 13) (-8)++assertEqual "neg" (neg (-89)) 89++assertEqual "abs" (abs 0)     0+assertEqual "abs" (abs 15)    15+assertEqual "abs" (abs (-89)) 89++assertEqual "lt?" (0.1 < 1.0) True+assertEqual "lt?" (1.0 < 0.1) False+assertEqual "lt?" (1.0 < 1.0) False++assertEqual "lte?" (0.1 <= 1.0) True+assertEqual "lte?" (1.0 <= 0.1) False+assertEqual "lte?" (1.0 <= 1.0) True++assertEqual "gt?" (0.1 > 1.0) False+assertEqual "gt?" (1.0 > 0.1) True+assertEqual "gt?" (1.0 > 1.0) False++assertEqual "gte?" (0.1 >= 1.0) False+assertEqual "gte?" (1.0 >= 0.1) True+assertEqual "gte?" (1.0 >= 1.0) True++assertEqual "round" (round 3.1)    3+assertEqual "round" (round 3.7)    4+assertEqual "round" (round (-2.2)) (-2)+assertEqual "round" (round (-2.7)) (-3)++assertEqual "floor" (floor 3.1)    3+assertEqual "floor" (floor 3.7)    3+assertEqual "floor" (floor (-2.2)) (-3)+assertEqual "floor" (floor (-2.7)) (-3)++assertEqual "ceiling" (ceiling 3.1)    4+assertEqual "ceiling" (ceiling 3.7)    4+assertEqual "ceiling" (ceiling (-2.2)) (-2)+assertEqual "ceiling" (ceiling (-2.7)) (-2)++assertEqual "truncate" (truncate 3.1)    3+assertEqual "truncate" (truncate 3.7)    3+assertEqual "truncate" (truncate (-2.2)) (-2)+assertEqual "truncate" (truncate (-2.7)) (-2)++-- assertEqual "sqrt" (sqrt 4) 2+assertEqual "sqrt" (sqrt 4.0) 2.0+-- assertEqual "sqrt" (sqrt (-1)) i++-- assertEqual "exp"+--   [exp 1, exp 1.0, exp (-1.0)]+--   [e, 2.718281828459045, 0.36787944117144233]++-- assertEqual "log"+--   [log e, log 10.0]+--   [1, 2.302585092994046]++-- TODO: trigonometric functions+-- * sin+-- * cos+-- * tan+-- * asin+-- * acos+-- * sinh+-- * cosh+-- * tanh+-- * asinh+-- * acosh+-- * atanh++-- tensorSize+-- tensorToList+-- dfOrder++assertEqual "itof" (itof 4)    4.0+assertEqual "itof" (itof (-1)) (-1.0)++assertEqual "rtof" (rtof (3 / 2)) 1.5+assertEqual "rtof" (rtof 1)       1.0++assertEqual "ctoi" (ctoi '1') 49++assertEqual "itoc" (itoc 49) '1'++assertEqual "pack" (pack []) ""+assertEqual "pack" (pack ['E', 'g', 'i', 's', 'o', 'n']) "Egison"++assertEqual "unpack" (unpack "Egison") ['E', 'g', 'i', 's', 'o', 'n']+assertEqual "unpack" (unpack "") []++assertEqual "unconsString" (unconsString "Egison") ('E', "gison")++assertEqual "lengthString" (lengthString "") 0+assertEqual "lengthString" (lengthString "Egison") 6++assertEqual "appendString" (appendString "" "")       ""+assertEqual "appendString" (appendString "" "Egison") "Egison"+assertEqual "appendString" (appendString "Egison" "") "Egison"+assertEqual "appendString" (appendString "Egi" "son") "Egison"++assertEqual "splitString" (splitString "," "") [""]+assertEqual "splitString" (splitString "," "2,3,5,7,11,13") ["2", "3", "5", "7", "11", "13"]++assertEqual "regex" (regex "cde" "abcdefg") [("ab", "cde", "fg")]+assertEqual "regex" (regex "[0-9]+" "abc123defg") [("abc", "123", "defg")]+assertEqual "regex" (regex "a*" "") [("", "", "")]++assertEqual "regexCg" (regexCg "([0-9]+),([0-9]+)" "abc,123,45,defg") [("abc,", ["123", "45"], ",defg")]++-- addPrime+-- addSubscript+-- addSuperscript+-- readProcess++assertEqual "read" (read "3")                3+assertEqual "read" (read "3.14")             3.14+assertEqual "read" (read "{1 2}")            [1, 2]+assertEqual "read" (read "\"Hello world!\"") "Hello world!"++-- TODO: read-tsv++assertEqual "show" (show 3)              "3"+assertEqual "show" (show 3.14159)        "3.14159"+assertEqual "show" (show [1, 2])         "{1 2}"+assertEqual "show" (show "Hello world!") "\"Hello world!\""++-- TODO: show-tsv++assertEqual "empty?" (empty? [])  True+assertEqual "empty?" (empty? [1]) False++assertEqual "uncons" (uncons [1, 2, 3]) (1, [2, 3])+assertEqual "unsnoc" (unsnoc [1, 2, 3]) ([1, 2], 3)++assertEqual "bool?" (bool? False) True++assertEqual "integer?" (integer? 1) True++assertEqual "rational?" (rational? 1)       True+assertEqual "rational?" (rational? (1 / 2)) True+assertEqual "rational?" (rational? 3.1)     False++assertEqual "scalar?" (scalar? 1) True+assertEqual "scalar?" (scalar? (| 1, 2 |)) False++assertEqual "float?" (float? 1.0) True+assertEqual "float?" (float? 1)   False++assertEqual "char?" (char? 'c') True++assertEqual "string?" (string? "hoge") True++assertEqual "collection?" (collection? []) True+assertEqual "collection?" (collection? [1]) True++assertEqual "array?" (array? (| |)) True+assertEqual "array?" (array? (| 1, 2, 3 |)) True++assertEqual "hash?" (hash? {| |}) True+assertEqual "hash?" (hash? {| [1, 2] |}) True++-- TODO: Add a test case where tensor? returns True+assertEqual "tensor?" (tensor? 1)                           False+assertEqual "tensor?" (tensor? (| 1 |))                     False+assertEqual "tensor?" (tensor? [| 1 |])                     True+assertEqual "tensor?" (tensor? (generateTensor (+) [1, 2])) True++-- TODO: tensorWithIndex?
+ nons-test/test/syntax.egi view
@@ -0,0 +1,467 @@+--+-- Syntax test+--++--+-- Primitive Data+--++assertEqual "char literal"+  ['a', '\n', '\'']+  ['a', '\n', '\'']++assertEqual "string literal" "" ""+assertEqual "string literal" "abc\n" "abc\n"++assertEqual "bool literal"+  [True, False]+  [True, False]++assertEqual "integer literal"+  [1, 0, -100, 1 - 100]+  [1, 0, -100, -99]++assertEqual "rational number"+  [10 / 3, 10 / 20, -1 / 2]+  [10 / 3 , 1 / 2, -1 / 2]++assertEqual "float literal" [1.0, 0.0, -100.012001, 1.0 + 2] [1.0, 0.0, -100.012001, 3.0]++assertEqual "inductive data literal" A A++assertEqual "tuple literal" (1, 2, 3) (1, 2, 3)++assertEqual "singleton tuple literal" (1) 1++assertEqual "collection literal" [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]++assertEqual "collection between" [1..5] [1, 2, 3, 4, 5]+assertEqual "collection from" (take 5 [1..]) [1, 2, 3, 4, 5]++--+-- Basic Sytax+--++assertEqual "if"+  (if True then True else False)+  True++assertEqual "if"+  (if False then True else False)+  False++assertEqual "let binding"+  (let t = (1, 2)+       (x, y) = t+    in x + y)+  3++assertEqual "let binding"+  (let x = 1+       y = x + 1+    in y)+  2++assertEqual "mutual recursion"+  (let even? n = if n == 0 then True else odd? (n - 1)+       odd? n = if n == 0 then False else even? (n - 1)+    in even? 10)+  True++assertEqual "lambda and application"+  ((\x -> x + 1) 10)+  11++assertEqual "application with binops"+  ((\x y -> x + y) 1 2 + 3)+  6++assertEqual "append op" ([1] ++ [2]) [1, 2]+assertEqual "append op" ((++) [1] [2]) [1, 2]++assertEqual "point free expr" ((+) 10 1) 11+assertEqual "point free expr" ((+ 1) 10) 11+assertEqual "point free expr" (foldl (*) 1 [1..5]) 120+assertEqual "point free expr" ((10 -) 1) 9+assertEqual "point free expr" ((10 - ) 1) 9+assertEqual "not point free expr" (- 2) (1 - 3)++-- findFactor = memoizedLambda+--                n -> match takeWhile (<= floor (sqrt (itof n))) primes as list integer with+--                     | _ ++ (?(\m -> divisor? n m) && $x)  :  _ -> x+--                     | _ -> n+-- assertEqual "memoized lambda"+--   (map findFactor [1..10])+--   [1, 2, 3, 2, 5, 2, 7, 2, 3, 2]++twinPrimes =+  matchAll primes as list integer with+  | _ ++ $p : #(p + 2) : _ -> (p, p + 2)++assertEqual "twin primes"+  (take 10 twinPrimes)+  [(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (59, 61), (71, 73), (101, 103), (107, 109)]++someFunction x y z =+  x + y * z++assertEqual "function definition"+  (someFunction 1 2 3)+  7++gcd m n =+  if (m >= n) then+              if (n == 0) then m+                          else gcd n (m % n)+              else gcd n m++assertEqual "recursive function definition"+  (gcd 143 22)+  11++--+-- Pattern-Matching+--++assertEqual "match"+  (match 1 as integer with+   | #0 -> 0+   | $x -> 10 + x)+  11++assertEqual "match-all"+  (matchAll [1, 2, 3] as multiset integer with+   | $x : _ -> x)+  [1, 2, 3]++assertEqual "match-all-multi"+  (matchAll [1, 2, 3] as multiset integer with+   | $x : #(x + 1) : _ -> [x, x + 1]+   | $x : #(x + 2) : _ -> [x, x + 2])+  [[1, 2], [2, 3], [1, 3]]++assertEqual "match-lambda"+  ((\match as list integer with+    | [] -> 0+    | $x : _ -> x) [1, 2, 3])+  1++assertEqual "match-all-lambda"+  ((\matchAll as list something with+    | _ ++ $x : _ -> x) [1, 2, 3])+  [1, 2, 3]++assertEqual "match-all-lambda-multi"+  ((\matchAll as multiset something with+    | $x : #(x + 1) : _ -> [x, x + 1]+    | $x : #(x + 2) : _ -> [x, x + 2]) [1, 2, 3])+  [[1, 2], [2, 3], [1, 3]]++assert "nested pattern match"+  (match [1, 2, 3] as list integer with+   | #2 : $x -> match x as multiset integer with+                | _ -> False+   | #1 : $x -> match x as multiset integer with+                | #1 : _ -> False+                | #2 : _ -> True)++assertEqual "pattern variable"+  (match 1 as something with $x -> x)+  1++assert "value pattern" (match 1 as integer with #1 -> True)++assert "inductive pattern"+  (match [1, 2, 3] as list integer with+   | snoc #3 _ -> True)++assert "and pattern"+  (match [1, 2, 3] as list integer with+   | #1 : _ && snoc #3 _ -> True)++assert "and pattern"+  (match [1, 2, 3] as list integer with+   | #1 : _ && #3 : _ -> False+   | _ -> True)++assert "or pattern"+  (match [1, 2, 3] as list integer with+   | snoc #1 _ || snoc #3 _ -> True)++assert "or pattern"+  (match [1, 2, 3] as list integer with+   | #2 : _ || #1 : _ -> True)++assert "not pattern"+  (match 1 as integer with+   | ! #1 -> False+   | ! #2 -> True)++assertEqual "not pattern"+  (matchAll [1, 2, 2, 3, 3, 3] as multiset integer with+   | $n : !(#n : _) -> n)+  [1]++assert "predicate pattern"+  (match [1, 2, 3] as list integer with+   | ?(== 1) : _ -> True)++assert "predicate pattern"+  (match [1, 2, 3] as list integer with+   | ?(== 2) : _ -> False+   | _ -> True)++assertEqual "indexed pattern variable"+  (match 23 as mod 10 with+   | $a_1 -> a)+  {| [1, 23] |}++assert "loop pattern"+  (match [3, 2, 1] as list integer with+   | loop $i (1, [3], _)+       | snoc #i ...+       | [] -> True)++assertEqual "loop pattern"+  (match [1..10] as list integer with+   | loop $i (1, $n)+       | #i : ...+       | [] -> n)+  10++assert "loop pattern"+  (match [3, 2, 1] as list integer with+   | loop $i (1, [3], _)+       | snoc #i ...+       | [] -> True)++assertEqual "double loop pattern"+  (match [[1, 2, 3], [4, 5, 6], [7, 8, 9]] as (list (list integer)) with+   | loop $i (1, [3], _)+       | ((loop $j (1, [3], _)+             | $n_i_j : ...+             | []) : ...)+       | [] -> n)+  {| [1, {| [1, 1], [2, 2], [3, 3] |}],+     [2, {| [1, 4], [2, 5], [3, 6] |}],+     [3, {| [1, 7], [2, 8], [3, 9] |}] |}++assertEqual "let pattern"+  (match [1, 2, 3] as list integer with+   | let a = 42 in _ -> a)+  42++assertEqual "let pattern"+  (match [1, 2, 3] as list integer with+   | $a : (let x = a in $xs) -> [x, xs])+  [1, [2, 3]]++assertEqual "let pattern"+  (match [1, 2, 3] as list integer with+   | $a && (let n = length a in _) -> [a, n])+  [[1, 2, 3], 3]++assertEqual "tuple pattern"+  (matchAll (1, (2, 3)) as (integer, (integer, integer)) with+   | ($m, ($n, $w)) -> [m, n, w])+  [[1, 2, 3]]++assertEqual "tuple pattern"+  (matchAll [(1, 1), (2, 2)] as multiset (integer, integer) with+   | ($x, #x) : _ -> x)+  [1, 2]++-- assertEqual "pattern function call"+--   (let twin = \pat1 pat2 => (~pat1 && $x) : #x : ~pat2 in+--    match [1, 1, 1, 2, 3] as list integer with+--    | twin $n $ns -> [n, ns])+--   [1, [1, 2, 3]]++-- assertEqual "recursive pattern function call"+--   (let repeat = \pat => [] || (~pat && $x) : (repeat x) in+--    match [1, 1, 1, 1] as list integer with+--    | repeat $n -> n)+--   1++-- assertEqual "loop pattern in pattern function"+--   let comb n = \p =>+--     loop $i (1, n, _) _ ++ ~p_i : ... | _+--    in+--   matchAll [1, 2, 3, 4, 5] as (list integer) with+--   | (comb 2) $n -> n+--   [{|[1, 1], [2, 2]|}, {|[1, 1], [2, 3]|}, {|[1, 2], [2, 3]|}, {|[1, 1], [2, 4]|}, {|[1, 2], [2, 4]|}, {|[1, 3], [2, 4]|}, {|[1, 1], [2, 5]|}, {|[1, 2], [2, 5]|}, {|[1, 3], [2, 5]|}, {|[1, 4], [2, 5]|}]++assertEqual "pairs of 2, natural numbers"+  (take 10 (matchAll nats as set integer with+            | $m : $n : _ -> [m, n]))+  [[1, 1], [1, 2], [2, 1], [1, 3], [2, 2], [3, 1], [1, 4], [2, 3], [3, 2], [4, 1]]++assertEqual "pairs of 2, different natural numbers"+  (take 10 (matchAll nats as list integer with+            | _ ++ $m : _ ++ $n : _ -> [m, n]))+  [[1, 2], [1, 3], [2, 3], [1, 4], [2, 4], [3, 4], [1, 5], [2, 5], [3, 5], [4, 5]]++tree a = algebraicDataMatcher+  | leaf+  | node (tree a) a (tree a)++treeInsert n t =+  match t as tree integer with+  | leaf -> Node Leaf n Leaf+  | node $t1 $m $t2 -> match (compare n m) as ordering with+      | less    -> Node (treeInsert n t1) m t2+      | equal   -> Node t1 n t2+      | greater -> Node t1 m (treeInsert n t2)++treeMember? n t =+  match t as tree integer with+  | leaf -> False+  | node $t1 $m $t2 -> match (compare n m) as ordering with+      | less    -> treeMember? n t1+      | equal   -> True+      | greater -> treeMember? n t2++assertEqual "tree set using algebraic-data-matcher"+  (let t = foldr treeInsert Leaf [4, 1, 2, 4, 3]+    in [treeMember? 1 t, treeMember? 0 t])+  [True, False]++assert "sequential pattern"+  (match [2,3,1,4,5] as list integer with+    { @ : @ : $x : _,+      (#(x + 1), @),+      #(x + 2)} -> True)++--+-- Tensor+--++assertEqual "generate-tensor"+  (generateTensor (*) [3, 5])+  [| [| 1, 2, 3, 4, 5 |], [| 2, 4, 6, 8, 10 |], [| 3, 6, 9, 12, 15 |] |]++assertEqual "tensor"+  (tensor [2, 5] [1, 2, 3, 4, 5, 2, 4, 6, 8, 10])+  [| [| 1, 2, 3, 4, 5 |], [| 2, 4, 6, 8, 10 |] |]++assertEqual "tensor wedge expr"+  (! b.min [| 1, 2, 3 |] [| 1, 2, 3 |])+  [| [| 1, 1, 1 |], [| 1, 2, 2 |], [| 1, 2, 3 |] |]++assertEqual "tensor wedge expr of binary operator"+  ([| 1, 2, 3 |] !+ [| 1, 2, 3 |])+  [| [| 2, 3, 4 |], [| 3, 4, 5 |], [| 4, 5, 6 |] |]++assertEqual "tensor multiplication"+  ([| 1, 2, 3 |]_i * [| 1, 2, 3 |]_i)+  [| 1, 4, 9 |]_i++--+-- Hash+--++assertEqual "hash-literal"+  {| [1, 11], [2, 12], [3, 13], [4, 14], [5, 15], |}+  {| [1, 11], [2, 12], [3, 13], [4, 14], [5, 15], |}++assertEqual "empty hash-literal"+  {| |}+  {| |}++assertEqual "hash access"+  {| [1, 11], [2, 12], [3, 13], [4, 14], [5, 15], |}_3+  13++--+-- Partial Application+--+-- assertEqual "partial application '$'"+--   ($ + $)(1, 2)+--   3+--+-- assertEqual "partial application '$' with index"+--   ($2-$1)(1, 2)+--   1+--+-- assertEqual "partial application '#'"+--   2#(10 * %1 + %2)(1, 2)+--   12+--+-- assertEqual "recursive partial application '#'"+--   take(10, 1#[%1, @(%0(%1 * 2))](2))+--   [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]++f *x *y = x + y++assertEqual "double inverted index"+  (f [|1, 2, 3|]_i [|10, 20, 30|]_j)+  [| [| 11, 21, 31, |], [| 12, 22, 32, |], [| 13, 23, 33, |], |]~i~j++g x *y = x + y++assertEqual "single inverted index"+  (g [|1, 2, 3|]_i  [|10, 20, 30|]_j)+  [| [| 11, 21, 31, |], [| 12, 22, 32, |], [| 13, 23, 33, |], |]_i~j++--+-- matcherExpr, macroExpr+--++list a = matcher+  | [] as () with+    | [] -> [()]+    | _  -> []+  | $ : $    as (a, list a) with+    | $x : $xs -> [(x, xs)]+    | _        -> []+  | snoc $ $ as (a, list a) with+    | snoc $xs $x -> [(x, xs)]+    | _           -> []+  | join _ $ as (list a) with+    | $tgt -> matchAll tgt as list a with+              | loop $i (1, _) | _ : ...  | $rs -> rs+  | join $ $ as (list a, list a) with+    | $tgt -> matchAll tgt as list a with+              | loop $i (1, $n) $xa_i : ... | $rs ->+                (foldr (\%i %r -> xa_i : r) [] [1..n], rs)+  | nioj $ $ as (list a, list a) with+    | $tgt -> matchAll tgt as list a with+              | loop $i (1, $n) snoc $xa_i ... | $rs ->+                (foldr (\%i %r -> r ++ [xa_i]) [] [1..n], rs)+  | #$val as () with+    | $tgt -> if val == tgt then [()] else []+  | $ as something with+    | $tgt -> [tgt]++multiset a = matcher+  | [] as () with+    | $tgt -> match tgt as (mutiset a) with+                | [] -> [()]+                | _ -> []+  | $ : $ as (a, multiset a) with+    | $tgt -> matchAll tgt as list a with+                | $hs ++ $x : $ts -> (x, hs ++ ts)+  | #$val as () with+    | $tgt -> match (val, tgt) as (list a, multiset a) with+                | ([], []) -> [()]+                | ($x : $xs, #x : #xs) -> [()]+                | (_, _) -> []+  | $ as something with+    | $tgt -> [tgt]++assertEqual "matcher definition"+  (matchAll [1, 2, 3] as multiset integer with+   | $x : _ -> x)+  [1, 2, 3]++nishiwakiIf =+  macro b e1 e2 ->+    car (matchAll b as (matcher+                        | $ as something with+                            | True  -> [e1]+                            | False -> [e2]) with+         | $x -> x)++assertEqual "case 1" (nishiwakiIf True     1 2) 1+assertEqual "case 2" (nishiwakiIf False    1 2) 2+assertEqual "case 3" (nishiwakiIf (1 == 1) 1 2) 1
sample/unify.egi view
@@ -52,8 +52,6 @@       (Just {})]      [[<var $x> (& $t !(occur ,x))]       (Just {[x t]})]-     [[<compound $f <nil>> <compound ,f <nil>>]-      (Just {})]      [[<compound $f $xs> <compound ,f $ys>]       (unify-list xs ys)]      [_ Nothing]}))
test/Test.hs view
@@ -16,7 +16,7 @@ import           Language.Egison import           Language.Egison.Core import qualified Language.Egison.Parser         as Parser-import qualified Language.Egison.ParserNonS2    as ParserNonS2+import qualified Language.Egison.ParserNonS     as ParserNonS import           Language.Egison.Primitives import           Language.Egison.Types @@ -74,9 +74,9 @@  runUnitTestCaseNonS :: FilePath -> Test runUnitTestCaseNonS file = TestLabel file . TestCase $ do-  env <- initialEnv (defaultOption { optUseNonS2 = True })+  env <- initialEnv (defaultOption { optSExpr = False })   assertEgisonM $ do-    exprs <- ParserNonS2.loadFile file+    exprs <- ParserNonS.loadFile file     let (bindings, tests) = foldr collectDefsAndTests ([], []) exprs     env' <- recursiveBind env bindings     forM_ tests $ evalExprDeep env'
+ test/answer/sample/mahjong.egi view
@@ -0,0 +1,2 @@+#t+#f
+ test/answer/sample/math/geometry/riemann-curvature-tensor-of-S2.egi view
@@ -0,0 +1,23 @@+[| [| (* r (cos θ) (cos φ)) (* r (cos θ) (sin φ)) (* -1 r (sin θ)) |] [| (* -1 r (sin θ) (sin φ)) (* r (sin θ) (cos φ)) 0 |] |]_i_j+[| [| r^2 0 |] [| 0 (* r^2 (sin θ)^2) |] |]_#_#+[| [| (/ 1 r^2) 0 |] [| 0 (/ 1 (* r^2 (sin θ)^2)) |] |]~#~#+(tensor {2 2 2} {0 0 0 (* -1 r^2 (sin θ) (cos θ)) 0 (* r^2 (sin θ) (cos θ)) (* r^2 (sin θ) (cos θ)) 0} )_#_#_#+[| [| 0 0 |] [| 0 (* -1 r^2 (sin θ) (cos θ)) |] |]_#_#+[| [| 0 (* r^2 (sin θ) (cos θ)) |] [| (* r^2 (sin θ) (cos θ)) 0 |] |]_#_#+(tensor {2 2 2} {0 0 0 (* -1 (sin θ) (cos θ)) 0 (/ (cos θ) (sin θ)) (/ (cos θ) (sin θ)) 0} )~#_#_#+[| [| 0 0 |] [| 0 (* -1 (sin θ) (cos θ)) |] |]_#_#+[| [| 0 (/ (cos θ) (sin θ)) |] [| (/ (cos θ) (sin θ)) 0 |] |]_#_#+(tensor {2 2 2} {0 0 0 0 0 0 0 0} )_#_#_#+(tensor {2 2 2 2} {0 0 0 0 0 (sin θ)^2 (* -1 (sin θ)^2) 0 0 -1 1 0 0 0 0 0} )~#_#_#_#+[| [| 0 0 |] [| 0 0 |] |]~#_#+[| [| 0 (sin θ)^2 |] [| -1 0 |] |]~#_#+[| [| 0 (* -1 (sin θ)^2) |] [| 1 0 |] |]~#_#+[| [| 0 0 |] [| 0 0 |] |]~#_#+(tensor {2 2 2 2} {0 0 0 0 0 (* r^2 (sin θ)^2) (* -1 r^2 (sin θ)^2) 0 0 (* -1 r^2 (sin θ)^2) (* r^2 (sin θ)^2) 0 0 0 0 0} )_#_#_#_#+[| [| 0 0 |] [| 0 0 |] |]_#_#+[| [| 0 (* r^2 (sin θ)^2) |] [| (* -1 r^2 (sin θ)^2) 0 |] |]_#_#+[| [| 0 (* -1 r^2 (sin θ)^2) |] [| (* r^2 (sin θ)^2) 0 |] |]_#_#+[| [| 0 0 |] [| 0 0 |] |]_#_#+[| [| 1 0 |] [| 0 (sin θ)^2 |] |]_#_#+(/ 2 r^2)+(tensor {2 2 2 2 2} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} )_#_#_#_#_#
+ test/answer/sample/math/number/17th-root-of-unity.egi view
@@ -0,0 +1,2 @@+(/ (+ -1 (sqrt 17) (* (sqrt 2) (sqrt (+ 17 (* -1 (sqrt 17))))) (* 2 (sqrt (+ 17 (* 3 (sqrt 17)) (* -1 (sqrt 2) (sqrt (+ 17 (* -1 (sqrt 17))))) (* -2 (sqrt 2) (sqrt (+ 17 (sqrt 17)))))))) 8)+(/ (+ -1 (sqrt 17) (* (sqrt 2) (sqrt (+ 17 (* -1 (sqrt 17))))) (* 2 (sqrt (+ 17 (* 3 (sqrt 17)) (* -1 (sqrt 2) (sqrt (+ 17 (* -1 (sqrt 17))))) (* -2 (sqrt 2) (sqrt (+ 17 (sqrt 17)))))))) 8)
+ test/answer/sample/poker-hands-with-joker.egi view
@@ -0,0 +1,4 @@+<Straight-Flush>+<Full-House>+<Straight>+<One-Pair>
+ test/answer/sample/poker-hands.egi view
@@ -0,0 +1,4 @@+"Straight flush"+"Full house"+"Straight"+"Nothing"
+ test/answer/sample/primes.egi view
@@ -0,0 +1,2 @@+{[3 5] [5 7] [11 13] [17 19] [29 31] [41 43] [59 61] [71 73] [101 103] [107 109]}+{[5 7 11] [7 11 13] [11 13 17] [13 17 19] [17 19 23] [37 41 43] [41 43 47] [67 71 73] [97 101 103] [101 103 107]}
+ test/lib/core/base.egi view
@@ -0,0 +1,68 @@+;;+;; Matchers+;;+(assert "bool's value pattern"+  (match [#t #f] [bool bool]+    {[[,#t ,#f] #t]+     [_ #f]}))++(assert "char's value pattern"+  (match c#a char+    {[,c#a #t]+     [_ #f]}))++(assert "integer's value pattern"+  (match 10 integer+    {[,10 #t]+     [_ #f]}))++(assert "float's value pattern"+  (match 0.1 float+    {[,0.1 #t]+     [_ #f]}))++;;+;; Utility+;;+(assert-equal "id"+  (id 1)+  1)++(assert-equal "fst"+  (fst [1 2])+  1)++(assert-equal "snd"+  (snd [1 2])+  2)++(assert-equal "compose - case 1"+  ((compose fst snd) [[1 2] 3])+  2)++(assert-equal "compose - case 2"+  ((compose fst snd fst) [[1 [2 3]] 4])+  2)++; (assert-equal "ref"+;  (ref (| 1 2 3 |) 2)+;  2)++(assert-equal "eq?/m"+  (eq?/m integer 1 1)+  #t)++;;+;; Booleans+;;+(assert-equal "and"+  [(and #t #t) (and #t #f) (and #f #t) (and #f #f)]+  [#t #f #f #f])++(assert-equal "or"+  [(or #t #t) (or #t #f) (or #f #t) (or #f #f)]+  [#t #t #t #f])++(assert-equal "not"+  [(not #t) (not #f)]+  [#f #t])
+ test/lib/core/collection.egi view
@@ -0,0 +1,417 @@+;;;;;+;;;;; Collection Test+;;;;;++;;;+;;; List Pattern-Matching+;;;+(assert "list's value pattern"+  (match {1 2 3} (list integer)+    {[,{@{@{1}} @{2 @{3}}} #t]+     [_ #f]}))++(assert "list's nil - case 1"+  (match {} (list integer)+    {[<nil> #t]+     [_ #f]}))++(assert "list's nil - case 2"+  (match {1} (list integer)+    {[<nil> #f]+     [_ #t]}))++(assert-equal "list's cons"+  (match {1 2 3} (list integer)+    {[<cons $n $ns> [n ns]]})+  [1 {2 3}])++(assert-equal "list's cons with value pattern"+  (match {1 2 3} (list integer)+    {[<cons ,1 $ns> ns]})+  {2 3})++(assert-equal "list's snoc"+  (match {1 2 3} (list integer)+    {[<snoc $n $ns> [n ns]]})+  [3 {1 2}])++(assert-equal "list's snoc with value pattern"+  (match {1 2 3} (list integer)+    {[<snoc ,3 $ns> ns]})+  {1 2})++(assert-equal "list's join"+  (match-all {1 2 3} (list integer)+    [<join $xs $ys> [xs ys]])+  {[{} {1 2 3}]+   [{1} {2 3}]+   [{1 2} {3}]+   [{1 2 3} {}]})++(assert-equal "list's join with value pattern"+  (match {1 2 3} (list integer)+    {[<join ,{1} $ns> ns]})+  {2 3})++(assert-equal "list's nioj"+  (match-all {1 2 3} (list integer)+    [<nioj $xs $ys> [xs ys]])+  {[{} {1 2 3}]+   [{3} {1 2}]+   [{2 3} {1}]+   [{1 2 3} {}]})++(assert-equal "list's nioj with value pattern"+  (match {1 2 3} (list integer)+    {[<nioj ,{3} $ns> ns]})+  {1 2})++;;;+;;; Multiset Pattern-Matching+;;;+(assert "multiset's nil - case 1"+  (match {} (multiset integer)+    {[<nil> #t]+     [_ #f]}))++(assert "multiset's nil - case 2"+  (match {1} (multiset integer)+    {[<nil> #f]+     [_ #t]}))++(assert "multiset's value pattern"+  (match {1 1 1 2 3} (multiset integer)+    {[,{@{@{1}} @{2 @{1 3}} 1} #t]+     [_ #f]}))++(assert-equal "multiset's cons"+  (match-all {1 2 3} (multiset integer)+    [<cons $n $ns> [n ns]])+  {[1 {2 3}] [2 {1 3}] [3 {1 2}]})++(assert-equal "multiset's cons with value pattern"+  (match {1 2 3} (multiset integer)+    {[<cons ,2 $ns> ns]})+  {1 3})++(assert-equal "multiset's join"+  (match-all {1 2 3} (multiset integer)+    [<join $xs $ys> [xs ys]])+  {[{} {1 2 3}] [{1} {2 3}] [{2} {1 3}] [{3} {1 2}] [{1 2} {3}] [{1 3} {2}] [{2 3} {1}] [{1 2 3} {}]})++(assert-equal "multiset's join with value pattern - case 1"+  (match {1 2 3} (multiset integer)+    {[<join ,{1} $ns> ns]})+  {2 3})++(assert-equal "multiset's join with value pattern - case 2"+  (match-all {1 2 3} (multiset integer)+    [<join ,{1 3} $ys> ys])+  {{2}})++(assert-equal "multiset's join with value pattern - case 3"+  (match-all {1 2 3} (multiset integer)+    [<join ,{1 5 3} $ys> ys])+  {})++;;;+;;; Set Pattern-Matching+;;;;+(assert "set's nil - case 1"+  (match {} (set integer)+    {[<nil> #t]+     [_ #f]}))++(assert "set's nil - case 2"+  (match {1} (set integer)+    {[<nil> #f]+     [_ #t]}))++(assert-equal "set's cons"+  (match-all {1 2 3} (set integer)+    [<cons $n $ns> [n ns]])+  {[1 {1 2 3}] [2 {1 2 3}] [3 {1 2 3}]})++(assert-equal "set's cons with value pattern"+  (match {1 2 3} (set integer)+    {[<cons ,2 $ns> ns]})+  {1 2 3})++(assert-equal "set's join"+  (match-all {1 2 3} (set integer)+    [<join $xs $ys> [xs ys]])+  {[{} {1 2 3}] [{1} {1 2 3}] [{2} {1 2 3}] [{3} {1 2 3}] [{1 2} {1 2 3}] [{1 3} {1 2 3}] [{2 3} {1 2 3}] [{1 2 3} {1 2 3}]})++(assert-equal "set's join with value pattern 1"+  (match-all {1 2 3} (set integer)+    [<join ,{1 3} $ys> ys])+  {{1 2 3}})++(assert-equal "set's join with value pattern 2"+  (match-all {1 2 3} (set integer)+    [<join ,{1 5 3} $ys> ys])+  {})++;;+;; Simple accessors+;;+(assert-equal "nth"+  (nth 1 {1 2 3})+  1)++(assert-equal "take"+  (take 2 {1 2 3})+  {1 2})++(assert-equal "drop"+  (drop 2 {1 2 3})+  {3})++(assert-equal "take-and-drop"+  (take-and-drop 2 {1 2 3})+  [{1 2} {3}])++(assert-equal "take-while"+  (take-while (lt? $ 10) primes)+  {2 3 5 7})++;;+;; cons, car, cdr+;;++(assert-equal "cons"+  (cons 1 {2 3})+  {1 2 3})++(assert-equal "car"+  (car {1 2 3})+  1)++(assert-equal "cdr"+  (cdr {1 2 3})+  {2 3})++(assert-equal "rac"+  (rac {1 2 3})+  3)++(assert-equal "rdc"+  (rdc {1 2 3})+  {1 2})++;;+;; List Functions+;;+(assert-equal "length"+  (length {1 2 3})+  3)++(assert-equal "map"+  (map (* $ 2) {1 2 3})+  {2 4 6})++(assert-equal "map2"+  (map2 (* $ $) {1 2 3} {10 20 30})+  {10 40 90}+  )++(assert-equal "filter"+  (let {[$odd? (lambda [$n] (eq? (modulo n 2) 1))]}+    (filter odd? {1 2 3}))+  {1 3})++(assert-equal "zip"+  (zip {1 2 3} {10 20 30})+  {[1 10] [2 20] [3 30]})++(assert-equal "lookup"+  (lookup 2 {[1 10] [2 20] [3 30]})+  20)++(assert-equal "foldr"+  (foldr (lambda [$n $ns] {n @ns}) {} {1 2 3})+  {1 2 3})++(assert-equal "foldl"+  (foldl (lambda [$ns $n] {n @ns}) {} {1 2 3})+  {3 2 1})++(assert-equal "scanl"+  (scanl (lambda [$r $n] (* r n)) 2 {2 2 2})+  {2 4 8 16})++(assert-equal "append"+  (append {1 2} {3 4 5})+  {1 2 3 4 5})++(assert-equal "concat"+  (concat {{1 2} {3 4 5}})+  {1 2 3 4 5})++(assert-equal "reverse"+  (reverse {1 2 3})+  {3 2 1})++(assert-equal "intersperse"+  (intersperse {0} {{1 2} {3 3} {4} {}})+  {{1 2} {0} {3 3} {0} {4} {0} {}})++(assert-equal "intercalate"+  (intercalate {0} {{1 2} {3 3} {4} {}})+  {1 2 0 3 3 0 4 0})++(assert-equal "split"+  (split {0} {1 2 0 3 3 0 4 0})+  {{1 2} {3 3} {4} {}})++(assert-equal "split/m"+  (split/m integer {0} {1 2 0 3 3 0 4 0})+  {{1 2} {3 3} {4} {}})++(assert-equal "find-cycle"+  (find-cycle {1 3 4 5 2 7 5 2 7 5 2 7})+  [{1 3 4} {5 2 7}])++(assert-equal "repeat"+  (take 5 (repeat {1 2 3}))+  {1 2 3 1 2})++(assert-equal "repeat1"+  (take 5 (repeat1 2))+  {2 2 2 2 2})++;;+;; Others+;;+(assert-equal "all - case 1"+  (all (eq? $ 1) {1 1 1})+  #t)++(assert-equal "all - case 2"+  (all (eq? $ 1) {1 1 2})+  #f)++(assert-equal "any - case 1"+  (any (eq? $ 1) {0 1 0})+  #t)++(assert-equal "any - case 2"+  (any (eq? $ 1) {0 0 0})+  #f)++(assert-equal "from"+  (take 3 (from 2))+  {2 3 4})++(assert-equal "between"+  (between 2 5)+  {2 3 4 5})++;;+;; Multiset Functions+;;+(assert-equal "add - case 1"+  (add 1 {2 3})+  {2 3 1})++(assert-equal "add - case 2"+  (add 1 {1 2 3})+  {1 2 3})++(assert-equal "add/m - case 1"+  (add/m integer 1 {2 3})+  {2 3 1})++(assert-equal "add/m - case 2"+  (add/m integer 1 {1 2 3})+  {1 2 3})++(assert-equal "delete-first"+  (delete-first 2 {1 2 3 2})+  {1 3 2})++(assert-equal "delete-first/m"+  (delete-first/m integer 2 {1 2 3 2})+  {1 3 2})++(assert-equal "delete"+  (delete 2 {1 2 3 1 2 3})+  {1 3 1 3})++(assert-equal "delete/m"+  (delete/m integer 2 {1 2 3 1 2 3})+  {1 3 1 3})++(assert-equal "difference"+  (difference {1 2 3} {1 3})+  {2})++(assert-equal "difference/m"+  (difference/m integer {1 2 3} {1 3})+  {2})++(assert-equal "union"+  (union {1 2 3} {1 3 4})+  {1 2 3 4})++(assert-equal "union/m"+  (union/m integer {1 2 3} {1 3 4})+  {1 2 3 4})++(assert-equal "intersect"+  (intersect {1 2 3} {1 3 4})+  {1 3})++(assert-equal "intersect/m"+  (intersect/m integer {1 2 3} {1 3 4})+  {1 3})++;;+;; Simple predicate+;;++(assert-equal "member? - case 1"+  (member? 1 {1 3 1 4})+  #t)++(assert-equal "member? - case 2"+  (member? 2 {1 3 1 4})+  #f)++(assert-equal "member?/m - case 1"+  (member?/m integer 1 {1 3 1 4})+  #t)++(assert-equal "member?/m - case 2"+  (member?/m integer 2 {1 3 1 4})+  #f)++;;+;; Counting+;;+(assert-equal "count"+  (count 1 {1 3 1 4})+  2)++(assert-equal "count/m"+  (count/m integer 1 {1 3 1 4})+  2)++(assert-equal "frequency"+  (frequency {1 3 1 4})+  {[1 2] [3 1] [4 1]})++(assert-equal "frequency/m"+  (frequency/m integer {1 3 1 4})+  {[1 2] [3 1] [4 1]})++;;+;; Set Functions+;;+(assert-equal "unique"+  (unique {1 2 3 2 1 4})+  {1 2 3 4})++(assert-equal "unique/m"+  (unique/m integer {1 2 3 2 1 4})+  {1 2 3 4})
+ test/lib/core/number.egi view
@@ -0,0 +1,143 @@+;;+;; Matcher+;;+(assert-equal "nat's o - case 1"+  (match 0 nat+    {[<o> #t]+     [_ #f]})+  #t)++(assert-equal "nat's o - case 2"+  (match 1 nat+    {[<o> #t]+     [_ #f]})+  #f)++(assert-equal "nat's s - case 1"+  (match 10 nat+    {[<s $n> n]})+  9)++(assert-equal "nat's s - case 2"+  (match 0 nat+    {[<s <o>> #t]+     [_ #f]})+  #f)++;;+;; Sequences+;;+(assert-equal "nats"+  (take 10 nats)+  {1 2 3 4 5 6 7 8 9 10})++(assert-equal "nats0"+  (take 10 nats0)+  {0 1 2 3 4 5 6 7 8 9})++(assert-equal "odds"+  (take 10 odds)+  {1 3 5 7 9 11 13 15 17 19})++(assert-equal "evens"+  (take 10 evens)+  {2 4 6 8 10 12 14 16 18 20})++(assert-equal "primes"+  (take 10 primes)+  {2 3 5 7 11 13 17 19 23 29})++;;+;; Natural numbers+;;+(assert-equal "divisor?"+  (divisor? 10 5)+  #t)++(assert-equal "find-factor"+  (find-factor 100)+  2)++(assert-equal "p-f"+  (p-f 100)+  {2 2 5 5})++(assert-equal "odd? - case 1"+  (odd? 3)+  #t)++(assert-equal "odd? - case 2"+  (odd? 4)+  #f)++(assert-equal "even? - case 1"+  (even? 4)+  #t)++(assert-equal "even? - case 2"+  (even? 5)+  #f)++(assert-equal "prime? - case 1"+  (prime? 17)+  #t)++(assert-equal "prime? - case 2"+  (prime? 18)+  #f)++(assert-equal "perm"+  (perm 5 2)+  20)++(assert-equal "comb"+  (comb 5 2)+  10)++(assert-equal "n-adic - case 1"+  (n-adic 10 123)+  {1 2 3})++(assert-equal "n-adic - case 2"+  (n-adic 2 10)+  {1 0 1 0})++;;+;; Dicimal fractions+;;+(assert-equal "rtod"+  (2#[%1 (take 10 %2)] (rtod (/ 6 35)))+  [0 {1 7 1 4 2 8 5 7 1 4}])++(assert-equal "rtod'"+  (rtod' (/ 6 35))+  [0 {1} {7 1 4 2 8 5}])++(assert-equal "show-decimal"+  (show-decimal 10 (/ 6 35))+  "0.1714285714")++(assert-equal "show-decimal'"+  (show-decimal' (/ 6 35))+  "0.1 714285 ...")++(assert-equal "regular-continued-fraction sqrt of 2"+  (rtof (regular-continued-fraction 1 {2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2}))+  1.4142135623730951)++(assert-equal "regular-continued-fraction pi"+  (rtof (regular-continued-fraction 3 {7 15 1 292 1 1 1 2 1 3 1 14 2 1 1 2 2 2 2 1 84 2 1 1 15 3 13}))+  3.141592653589793)++(assert-equal "continued-fraction pi"+  (rtof (continued-fraction 3 {7 15 1 292 1 1 1 2 1 3 1 14 2 1 1 2 2 2 2 1 84 2 1 1 15 3 13}+                              {1 1  1 1   1 1 1 1 1 1 1 1  1 1 1 1 1 1 1 1 1  1 1 1 1  1 1}))+  3.141592653589793)++(assert-equal "regular-continued-fraction-of-sqrt case 1"+  (2#[%1 (take 10 %2)] (regular-continued-fraction-of-sqrt 2))+  [1 {2 2 2 2 2 2 2 2 2 2}])+  +(assert-equal "regular-continued-fraction-of-sqrt case 2"+  (rtof (regular-continued-fraction (2#[%1 (take 100 %2)] (regular-continued-fraction-of-sqrt 2))))+  1.4142135623730951)
+ test/lib/core/order.egi view
@@ -0,0 +1,35 @@+(assert-equal "compare - case 1"+  (compare 10 10)+  <Equal>)++(assert-equal "compare - case 2"+  (compare 11 10)+  <Greater>)++(assert-equal "compare - case 3"+  (compare 10 11)+  <Less>)++(assert-equal "min"+  (min {20 5})+  5)++(assert-equal "min/fn"+  (min/fn compare {10 20 5 20 30})+  5)++(assert-equal "max"+  (max {5 30})+  30)++(assert-equal "max/fn"+  (max/fn compare {10 20 5 20 30})+  30)++(assert-equal "sort"+  (sort {10 20 5 20 30})+  {5 10 20 20 30})++(assert-equal "sort/fn"+  (sort/fn compare {10 20 5 20 30})+  {5 10 20 20 30})
+ test/lib/core/string.egi view
@@ -0,0 +1,99 @@+(assert "string's value pattern"+  (match "abc" string+    {[,"abc" #t]+     [_ #f]}))++(assert "string's nil - case 1"+  (match "" string+    {[<nil> #t]+     [_ #f]}))++(assert "string's nil - case 2"+  (match "abc" string+    {[<nil> #f]+     [_ #t]}))++(assert-equal "string's cons"+  (match-all "abc" string+    [<cons $x $xs> [x xs]])+  {[c#a "bc"]})++(assert-equal "string's join"+  (match-all "abc" string+    [<join $xs $ys> [xs ys]])+  {["" "abc"] ["a" "bc"]+   ["ab" "c"] ["abc" ""]})++;;;+;;; String as collection+;;;+(assert-equal "S.empty? - case 1"+  (S.empty? "")+  #t)++(assert-equal "S.empty? - case 2"+  (S.empty? "Egison")+  #f)++(assert-equal "S.car"+  (S.car "Egison")+  c#E)++(assert-equal "S.cdr"+  (S.cdr "Egison")+  "gison")++(assert-equal "S.rac"+  (S.rac "Egison")+  c#n)++(assert-equal "S.map"+  (S.map id "Egison")+  "Egison")++(assert-equal "S.length"+  (S.length "Egison")+  6)++(assert-equal "S.split"+  (S.split "," "Lisp,Haskell,Egison")+  {"Lisp" "Haskell" "Egison"})++(assert-equal "S.append"+  (S.append "Egi" "son")+  "Egison")++(assert-equal "S.concat"+  (S.concat {"Egi" "son"})+  "Egison")++(assert-equal "S.intercalate"+  (S.intercalate "," {"Lisp" "Haskell" "Egison"})+  "Lisp,Haskell,Egison")++;;+;; Characters+;;+(assert-equal "C.between"+  (C.between c#a c#c)+  {c#a c#b c#c})++(assert-equal "C.between?"+  (C.between? c#a c#c c#b)+  #t)++(assert-equal "alphabet?"+  (alphabet? c#a)+  #t)++(assert-equal "alphabets?"+  (alphabets? "Egison")+  #t)++(assert-equal "upper-case"+  (upper-case c#e)+  c#E)++(assert-equal "lower-case"+  (lower-case c#E)+  c#e)
+ test/lib/math/algebra.egi view
@@ -0,0 +1,15 @@+(assert-equal "q-f' - case 1"+  (q-f' 1 2 1)+  [-1 -1])++(assert-equal "q-f' - case 2"+  (q-f' 1 1 -1)+  [(/ (+ -1 (sqrt 5)) 2) (/ (+ -1 (* -1 (sqrt 5))) 2)])++(assert-equal "q-f' - case 3"+  (q-f' 1 (* -1 (/ (+ -1 (sqrt 5)) 2)) 1)+  [(/ (+ -1 (sqrt 5) (sqrt (+ -10 (* -2 (sqrt 5))))) 4) (/ (+ -1 (sqrt 5) (* -1 (sqrt (+ -10 (* -2 (sqrt 5)))))) 4)])++(assert-equal "fifth root of unity"+  (** (/ (+ -1 (sqrt 5) (sqrt (+ -10 (* -2 (sqrt 5))))) 4) 5)+  1)
+ test/lib/math/analysis.egi view
@@ -0,0 +1,41 @@+(assert-equal "d/d - case 1"+  (d/d (** x 2) x)+  (* 2 x))++(assert-equal "d/d - case 2"+  (d/d (** a (** x 2)) x)+  (* 2 (** a x^2) (log a) x))++(assert-equal "d/d - case 3"+  (d/d (* (cos x) (sin x)) x)+  (+ (* -1 (sin x)^2) (cos x)^2))++(assert-equal "d/d - case 4"+  (d/d (sigmoid z) z)+  (/ (exp (* -1 z)) (+ 1 (* 2 (exp (* -1 z))) (exp (* -1 z))^2)))++(assert-equal "d/d - case 5"+  (d/d (d/d (log x) x) x)+  (/ -1 x^2))++(assert-equal "tailor-expansion - case 1"+  (take 4 (taylor-expansion (** e (* i x)) x 0))+  {1 (* i x) (/ (* -1 x^2) 2) (/ (* -1 i x^3) 6)})++(assert-equal "tailor-expansion - case 2"+  (take 4 (taylor-expansion (* i (sin x)) x 0))+  {0 (* i x) 0 (/ (* -1 i x^3) 6)})++;(assert-equal "multivariate-tailor-expansion - case 1"+;  (take 3 (multivariate-taylor-expansion (f x y) [| x y |] [| 0 0 |]))+;  {(f 0 0) (+ (* x (f|1 0 0)) (* y (f|2 0 0))) (/ (+ (* x^2 (f|1|1 0 0)) (* 2 x y (f|1|2 0 0)) (* y^2 (f|2|2 0 0))) 2)})++(assert-equal "multivariate-tailor-expansion - case 2"+  (take 3 (multivariate-taylor-expansion (** e (+ x y)) [| x y |] [| 0 0 |]))+  {1 (+ x y) (/ (+ x^2 (* 2 x y) y^2) 2)})++(assert-equal "function expr"+  (let {[$f (function [x y])]}+    (d/d f y))+  (let {[$f (function [x y])]}+    (user-refs f {y})))
+ test/lib/math/arithmetic.egi view
@@ -0,0 +1,31 @@+(assert-equal "sum"+  (sum (take 5 nats))+  15)++(assert-equal "product"+  (product (take 5 nats))+  120)++(assert-equal "power"+  (power 2 5)+  32)++(assert-equal "** - case 1"+  (power x 3)+  x^3)++(assert-equal "** - case 2"+  (power (sqrt 2) 4)+  4)++(assert-equal "gcd"+  (gcd 15 40)+  5)++(assert-equal "sqrt - case 1"+  (sqrt (/ (* 50 x^2) y))+  (/ (* 5 x (sqrt (* 2 y))) y))++(assert-equal "sqrt - case 2"+  (* (sqrt (* 3 x)) (sqrt (* 2 y)))+  (* (sqrt 6) (sqrt x) (sqrt y)))
+ test/lib/math/tensor.egi view
@@ -0,0 +1,85 @@+(assert-equal "Tensor product - case 1"+  (. [| [| 1 1 |] [| 0 1 |] |]~i~j [| [| 1 1 |] [| 0 1 |] |]_j_k)+  [| [| 1 2 |] [| 0 1 |] |])++(assert-equal "Tensor product - case 2"+  (. [| [| 1 1 |] [| 0 1 |] |]~i~j [| [| 1 1 |] [| 0 1 |] |]_j~k [| [| 1 1 |] [| 0 1 |] |]_k_l)+  [| [| 1 3 |] [| 0 1 |] |]~i_l)++(assert-equal "Vector *"+  (V.* [| 1 1 0 |] [| 10 5 10 |])+  15)++(assert-equal "Matrix * - case 1"+  (M.* [| [| 1 1 |] [| 0 1 |] |] [| [| 1 1 |] [| 0 1 |] |])+  [| [| 1 2 |] [| 0 1 |] |])++(assert-equal "Matrix * - case 2"+  (M.* [| [| 1 1 |] [| 0 1 |] |] [| [| 1 1 |] [| 0 1 |] |] [| [| 1 1 |] [| 0 1 |] |])+  [| [| 1 3 |] [| 0 1 |] |])++(assert-equal "Tensor '+' - case 1"+  (+ 1 [|1 2 3|])+  [|2 3 4|])++(assert-equal "Tensor '+' - case 2"+  (+ [|1 2 3|] 1)+  [|2 3 4|])++(assert-equal "Tensor '+' - case 3"+  (+ [|[|11 12|]+       [|21 22|]+       [|31 32|]|]_i_j+     [|100 200 300|]_i)+  [| [| 111 112 |] [| 221 222 |] [| 331 332 |] |]_i_j)++(assert-equal "Tensor '+' - case 4"+  (+ [|100 200 300|]_i+     [|[|11 12|]+       [|21 22|]+       [|31 32|]|]_i_j)+  [| [| 111 112 |] [| 221 222 |] [| 331 332 |] |]_i_j)++(assert-equal "Tensor '+' - case 5"+  (+ [|[|1 2 3|]+       [|10 20 30|]|]_i_j+     [|100 200 300|]_j)+  [| [| 101 202 303 |] [| 110 220 330 |] |]_i_j)++(assert-equal "Tensor '+' - case 6"+  (+ [|100 200 300|]_j+     [|[|1 2 3|]+       [|10 20 30|]|]_i_j)+  [| [| 101 110 |] [| 202 220 |] [| 303 330 |] |]_j_i)++;(assert-equal "Tensor ∂/∂ - case 1"+;  (∂/∂ [|(f x) (g x)|] x)+;  [|(f|1 x) (g|1 x)|])++;(assert-equal "Tensor ∂/∂ - case 2"+;  (∂/∂ (f x y z) [|x y z|])+;  [|(f|1 x y z) (f|2 x y z) (f|3 x y z)|])++;(assert-equal "Tensor ∂/∂ - case 3"+;  (apply [|(∂/∂ $ x) (∂/∂ $ y)|] (f x y))+;  [|(f|1 x y) (f|2 x y)|])++(assert-equal "append indices with ..."+  (show (let {[$A (generate-tensor 2#1 {2 2})]+              [$f (lambda [%B] B..._j)]}+          (f A_i)))+  (show [| [| 1 1 |] [| 1 1 |] |]_i_j))++(assert-equal "generate_tensor by using function expr"+  (letrec {[$g__ (generate-tensor+                    (match-lambda [integer integer]+                      {[[$n ,n] (function [x y z])]+                       [[_ _] 0]})+                    {3 3})]}+     (show (with-symbols {i j} (d/d g_i_j x))))+  "[| [| g_1_1|x 0 0 |] [| 0 g_2_2|x 0 |] [| 0 0 g_3_3|x |] |]")++(assert-equal "define tensor having value of function expr"+  (letrec {[$g__ [| [| (function [x y z]) 0 0 |] [| 0 (function [x y z]) 0 |] [| 0 0 (function [x y z]) |] |]]}+     (show (with-symbols {i j} (d/d g_i_j x))))+  "[| [| g_1_1|x 0 0 |] [| 0 g_2_2|x 0 |] [| 0 0 g_3_3|x |] |]")
+ test/primitive.egi view
@@ -0,0 +1,15 @@+(assert-equal "less than predicate"+  [(lt? 0.1 1.0) (lt? 1.0 0.1) (lt? 1.0 1.0)]+  [#t #f #f])++(assert-equal "less than or equal predicate"+  [(lte? 0.1 1.0) (lte? 1.0 0.1) (lte? 1.0 1.0)]+  [#t #f #t])++(assert-equal "greater than predicate"+  [(gt? 0.1 1.0) (gt? 1.0 0.1) (gt? 1.0 1.0)]+  [#f #t #f])++(assert-equal "greater than or equal predicate"+  [(gte? 0.1 1.0) (gte? 1.0 0.1) (gte? 1.0 1.0)]+  [#f #t #t])
+ test/syntax.egi view
@@ -0,0 +1,451 @@+;;;;;+;;;;; Syntax Test+;;;;;++;;;+;;; Primitive Data+;;;+(assert-equal "char literal"+  c#a+  c#a)++(assert-equal "string literal"+  "abc\n"+  "abc\n")++(assert-equal "bool literal"+  [#t #f]+  [#t #f])++(assert-equal "integer literal"+  [1 0 -100 (+ 1 -100)]+  [1 0 -100 -99])++(assert-equal "rational number"+  [(/ 10 3) (/ 10 20) (/ -1 2)]+  [(/ 10 3) (/ 1 2) (/ -1 2)])++(assert-equal "float literal"+  [1.0 0.0 -100.012001 (+ 1.0 2)]+  [1.0 0.0 -100.012001 3.0])++(assert-equal "inductive data literal"+  <A>+  <A>)++(assert-equal "tuple literal"+  [1 2 3]+  [1 2 3])++(assert-equal "singleton tuple literal"+  [1]+  1)++(assert-equal "collection literal"+  {1 @{2 3 @{@{4} 5}} 6}+  {1 2 3 4 5 6})++;;;+;;; Basic Sytax+;;;+(assert-equal "if"+  (if #t #t #f)+  #t)++(assert-equal "if"+  (if #f #t #f)+  #f)++(assert-equal "let binding"+  (let {[$t [1 2]]}+    (let {[[$x $y] t]}+      (+ x y)))+  3)++(assert-equal "let* binding"+  (let* {[$x 1] [$y (+ x 1)]} y)+  2)++(assert-equal "letrec binding"+  (letrec {[[$x $y] t]+           [$t [1 2]]}+    (+ x y))+  3)++(assert-equal "mutual recursion"+  (letrec {[$even? (lambda [$n]+                     (if (eq? n 0) #t (odd? (- n 1))))]+           [$odd? (lambda [$n]+                    (if (eq? n 0) #f (even? (- n 1))))]}+    (even? 10))+  #t)++(assert-equal "lambda and application"+  ((lambda [$x] (+ 1 x)) 10)+  11)++(assert-equal "placeholder"+  ((+ $ 1) 10)+  11)++(assert-equal "indexed placeholder"+  ((+ $1 $1) 10)+  20)++(assert-equal "indexed placeholder2"+  ((- $2 $1) 10 20)+  10)++;;;+;;; Pattern-Matching+;;;+(assert-equal "match"+  (match 1 integer+    {[,0 0]+     [$x (+ 10 x)]})+  11)++(assert-equal "match-all"+  (match-all {1 2 3} (list integer)+    [<cons $x $xs> [x xs]])+  {[1 {2 3}]})++(assert-equal "match-all-multi"+  (match-all {1 2 3} (multiset integer)+    {[<cons $x <cons ,(+ x 1) _>> [x (+ x 1)]]+     [<cons $x <cons ,(+ x 2) _>> [x (+ x 2)]]})+  {[1 2] [2 3] [1 3]})++(assert-equal "match-lambda"+  (letrec {[$count (match-lambda (list something)+                     {[<nil> 0]+                      [<cons _ $xs> (+ (count xs) 1)]})]}+    (count {1 2 3}))+  3)++(assert-equal "match-all-lambda"+  ((match-all-lambda (list something) [<join _ <cons $x _>> x]) {1 2 3})+  {1 2 3})++(assert-equal "match-all-lambda-multi"+  ((match-all-lambda (multiset something)+     {[<cons $x <cons ,(+ x 1) _>> [x (+ x 1)]]+      [<cons $x <cons ,(+ x 2) _>> [x (+ x 2)]]}) {1 2 3})+  {[1 2] [2 3] [1 3]})++(assert-equal "pattern variable"+  (match 1 something+    {[$x x]})+  1)++(assert "value pattern"+  (match 1 integer+    {[,1 #t]}))++(assert "and pattern"+  (match {1 2 3} (list integer)+    {[(& <cons ,1 _> <snoc ,3 _>) #t]}))++(assert "and pattern"+  (match {1 2 3} (list integer)+    {[(& <cons ,1 _> <cons ,3 _>) #f]+     [_ #t]}))++(assert "and pattern"+  (match #t something+    {[(&) #t]}))++(assert "or pattern"+  (match {1 2 3} (list integer)+    {[(| <snoc ,1 _> <snoc ,3 _>) #t]}))++(assert "or pattern"+  (match {1 2 3} (list integer)+    {[(| <cons ,2 _> <cons ,3 _>) #f]+     [_ #t]}))++(assert "or pattern"+  (match #t something+    {[(|) #f]+     [_ #t]}))++;(assert-equal "ordered or pattern"+;  (match {1 2 3 4 5} (list integer) {[<join (|* ,{2} ,{1 2 3} ,{1}) $xs> xs]})+;  {4 5})++;(assert-equal "ordered or pattern"+;  (let {[$x [| 1 2 3 |]]}+;    (match-all {2 1 3} (multiset integer)+;      [<cons (& (|* !,x_1 ,x_1) $y_1)+;             <cons (& (|* !,x_2 ,x_2) $y_2)+;                   <cons (& (|* !,x_3 ,x_3) $y_3) <nil>>>> (map 1#y_%1 (between 1 3))]))+;  {{2 3 1} {3 1 2} {2 1 3} {3 2 1} {1 3 2} {1 2 3}})++;(assert "ordered or pattern"+;  (match {1 2 3} (list integer)+;    {[(|* <cons ,2 _> <cons ,3 _>) #f]+;     [_ #t]}))++(assert "not pattern"+  (match 1 integer+    {[!,1 #f]+     [!,2 #t]}))++(assert-equal "not pattern"+  (match-all {1 2 2 3 3 3} (multiset integer)+    [<cons $n !<cons ,n _>> n])+  {1})++(assert-equal "later pattern"+  (match-all {1 1 2} (list integer)+    [<cons (later ,n) <cons $n _>> n])+  {1})++(assert "predicate pattern"+  (match {1 2 3} (list integer)+    {[<cons ?(eq? 1 $) _> #t]}))++(assert "predicate pattern"+  (match {1 2 3} (list integer)+    {[<cons ?(eq? 2 $) _> #f]+     [_ #t]}))++(assert-equal "indexed pattern variable"+  (match 23 (mod 10) {[$a_1 a]})+  {| [1 23] |})++(assert-equal "seq pattern"+  (match-all {1 2 3 2 4 3 5} (list integer)+    [{<join #                     <cons $x _>>+            !<join _ <cons ,x _>>             }+   x])+  {1 2 3 4 5})++;(assert-equal "dfs pattern 1"+;  (take 10 (match-all nats (set integer)+;       [(dfs <cons $m <cons $n <cons $l _>>>) [m n l]]))+;  {[1 1 1] [1 1 2] [1 1 3] [1 1 4] [1 1 5] [1 1 6] [1 1 7] [1 1 8] [1 1 9] [1 1 10]})++;(assert-equal "dfs pattern 2"+;  (take 10 (match-all nats (set integer)+;       [<cons $m (dfs <cons $n <cons $l _>>)> [m n l]]))+;  {[1 1 1] [2 1 1] [3 1 1] [4 1 1] [5 1 1] [6 1 1] [7 1 1] [8 1 1] [9 1 1] [10 1 1]})++;(assert-equal "dfs pattern 3"+;  (match-all (between 1 3) (set integer)+;       [<cons $m <cons $n (dfs <cons $l _>)>> [m n l]])+;  {[1 1 1] [1 2 1] [2 1 1] [1 3 1] [2 2 1] [3 1 1] [2 3 1] [3 2 1] [3 3 1] [1 1 2] [1 2 2] [2 1 2] [1 3 2] [2 2 2] [3 1 2] [2 3 2] [3 2 2] [3 3 2] [1 1 3] [1 2 3] [2 1 3] [1 3 3] [2 2 3] [3 1 3] [2 3 3] [3 2 3] [3 3 3]})++;(assert-equal "dfs and bfs pattern 1"+;  (take 10 (match-all nats (set integer)+;       [(dfs <cons $m (bfs <cons $n <cons $l _>>)>) [m n l]]))+;  {[1 1 1] [1 1 2] [1 2 1] [1 1 3] [1 2 2] [1 3 1] [1 1 4] [1 2 3] [1 3 2] [1 4 1]})++;(assert-equal "dfs and bfs pattern 2"+;  (take 10 (match-all nats (set integer)+;       [(dfs <cons $m <cons $n (bfs <cons $l _>)>>) [m n l]]))+;  {[1 1 1] [1 1 2] [1 1 3] [1 1 4] [1 1 5] [1 1 6] [1 1 7] [1 1 8] [1 1 9] [1 1 10]})++(assert "loop pattern"+  (match {3 2 1} (list integer)+    {[(loop $i [1 {3} _] <snoc ,i ...> <nil>) #t]}))++(assert-equal "double loop pattern"+  (match {{1 2 3} {4 5 6} {7 8 9}} (list (list integer))+    {[(loop $i [1 {3} _]+        <cons (loop $j [1 {3} _]+                <cons $n_i_j ...>+                <nil>) ...>+        <nil>)+      n]})+  {|[1 {|[1 1] [2 2] [3 3]|}] [2 {|[1 4] [2 5] [3 6]|}] [3 {|[1 7] [2 8] [3 9]|}]|})++(assert-equal "let pattern"+  (match {1 2 3} (list integer)+    {[(let {[$a 42]} _) a]})+  42)++(assert-equal "let pattern"+  (match {1 2 3} (list integer)+    {[<cons $a (let {[$x a]} $xs)> [x xs]]})+  [1 { 2 3 }])++(assert-equal "let pattern"+  (match {1 2 3} (list integer)+    {[(& $a (let {[$n (length a)]} _)) [a n]]})+  [{1 2 3} 3])++(assert-equal "tuple patterns"+  (match-all [1 [2 3]] [integer [integer integer]]+    [[$m [$n $w]] [m n w]])+  {[1 2 3]})++(assert-equal "pattern function call"+  (letrec {[$twin (pattern-function [$pat1 $pat2]+                    <cons (& pat1 $x) <cons ,x pat2>>)+            ]}+    (match {1 1 1 2 3} (list integer)+      {[(twin $n $ns) [n ns]]}))+  [1 {1 2 3}])++(assert-equal "recursive pattern function call"+  (letrec {[$repeat (pattern-function [$pat]+                      (| <nil>+                         <cons (& pat $x) (repeat ,x)>))+            ]}+    (match {1 1 1 1} (list integer)+      {[(repeat $n) n]}))+  1)++(assert-equal "loop pattern in pattern function"+  (letrec {[$comb (lambda [$n]+                    (pattern-function [$p]+                      (loop $i [1 {n} _]+                        <join _ <cons p_i ...>>+                        _)))+           ]}+    (match-all {1 2 3 4 5} (list integer)+      [((comb 2) $n) n]))+  {{|[1 1] [2 2]|} {|[1 1] [2 3]|} {|[1 2] [2 3]|} {|[1 1] [2 4]|} {|[1 2] [2 4]|} {|[1 3] [2 4]|} {|[1 1] [2 5]|} {|[1 2] [2 5]|} {|[1 3] [2 5]|} {|[1 4] [2 5]|}})++(assert-equal "pairs of 2 natural numbers"+  (take 10 (match-all nats (set integer)+             [<cons $m <cons $n _>> [m n]]))+  {[1 1] [1 2] [2 1] [1 3] [2 2] [3 1] [1 4] [2 3] [3 2] [4 1]})++(assert-equal "pairs of 2 different natural numbers"+  (take 10 (match-all nats (list integer)+             [<join _ <cons $m <join _ <cons $n _>>>> [m n]]))+  {[1 2] [1 3] [2 3] [1 4] [2 4] [3 4] [1 5] [2 5] [3 5] [4 5]})++(define $tree+  (lambda [$a]+    (algebraic-data-matcher+      {<leaf> <node (tree a) a (tree a)>})))++(define $tree-insert+  (lambda [$n $t]+    (match t (tree integer)+      {[<leaf> <Node <Leaf> n <Leaf>>]+       [<node $t1 $m $t2>+        (match (compare n m) ordering+          {[<less> <Node (tree-insert n t1) m t2>]+           [<equal> <Node t1 n t2>]+           [<greater> <Node t1 m (tree-insert n t2)>]})]})))++(define $tree-member?+  (lambda [$n $t]+    (match t (tree integer)+      {[<leaf> #f]+       [<node $t1 $m $t2>+        (match (compare n m) ordering+          {[<less> (tree-member? n t1)]+           [<equal> #t]+           [<greater> (tree-member? n t2)]})]})))++(assert-equal "tree set using algebraic-data-matcher"+  (let {[$t (foldr tree-insert <Leaf> {4 1 2 4 3})]}+    [(tree-member? 1 t) (tree-member? 0 t)])+  [#t #f])++(assert-equal "tuple pattern"+  (match-all {[1 1] [2 2]} (multiset [integer integer]) [<cons [$x ,x] _> x])+  {1 2})+++;;;+;;; Array+;;;++(assert-equal "array-literal"+  (| 1 2 3 4 5 |)+  (| 1 2 3 4 5 |)+  )++(assert-equal "empty array literal"+  (||)+  (||)+  )++(assert-equal "generate-array"+  (generate-array (+ $ 100) [3 5])_4+  104+  )++(assert-equal "array-bounds - case 1"+  (array-bounds (| 1 2 3 |))+  [1 3]+  )++(assert-equal "array-bounds - case 2"+  (array-bounds (generate-array (+ $ 100) [3 5]))+  [3 5]+  )++(assert-equal "array-ref"+  (array-ref (| 1 2 3 4 5 |) 3)+  3)++;;;+;;; Tensor+;;;+(assert-equal "generate-tensor - case 1"+  (generate-tensor kronecker-delta {3})+  [| 1 1 1 |])++(assert-equal "generate-tensor - case 2"+  (generate-tensor kronecker-delta { 2 2 2 2 })+  (tensor {2 2 2 2} {1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1} ))++;;;+;;; Hash+;;;+(assert-equal "hash-literal"+  {| [1 11] [2 12] [3 13] [4 14] [5 15] |}+  {| [1 11] [2 12] [3 13] [4 14] [5 15] |}+  )++(assert-equal "empty hash-literal"+  {| |}+  {| |}+  )++(assert-equal "hash access"+  {| [1 11] [2 12] [3 13] [4 14] [5 15] |}_3+  13+  )++;(assert-equal "string hash access"+;  {| ["1" 11] ["2" 12] ["3" 13] ["4" 14] ["5" 15] |}_"3"+;  13+;  )++;;;+;;; Partial Application+;;;+(assert-equal "partial application '$'"+  ((+ $ $) 1 2)+  3)++(assert-equal "partial application '$' with index"+  ((- $2 $1) 1 2)+  1)++(assert-equal "partial application '#'"+  (2#(+ (* 10 %1) %2) 1 2)+  12)++(assert-equal "recursive partial application '#'"+  (take 10 (1#{%1 @(%0 (* %1 2))} 2))+  {2 4 8 16 32 64 128 256 512 1024})++(assert-equal "double inverted index"+  (let {[$f (lambda [*$x *$y] (+ x y))]}+    [(f [|1 2 3|]_i [|10 20 30|]_j)])+  [[| [| 11 21 31 |] [| 12 22 32 |] [| 13 23 33 |] |]~i~j])++(assert-equal "single inverted index"+  (let {[$f (lambda [$x *$y] (+ x y))]}+    [(f [|1 2 3|]_i [|10 20 30|]_j)])+  [[| [| 11 21 31 |] [| 12 22 32 |] [| 13 23 33 |] |]_i~j])+