diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2017, Satoshi Egi
+Copyright (c) 2011-2019, Satoshi Egi
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the "Software"),
diff --git a/benchmark/Benchmark.hs b/benchmark/Benchmark.hs
--- a/benchmark/Benchmark.hs
+++ b/benchmark/Benchmark.hs
@@ -3,25 +3,20 @@
 import           Control.Applicative ((<$>), (<*>))
 import           Control.Applicative
 import           Control.DeepSeq     (NFData (rnf))
-import           Control.Monad.Error
-import           Criterion.Config
+import           Control.Monad.Except
+import           Criterion
 import           Criterion.Main
 import           Language.Egison
 
-runEgisonFile :: String -> IO (Either EgisonError Env)
-runEgisonFile path = loadPrimitives nullEnv >>= loadLibraries >>= flip (loadEgisonFile defaultOption) path
-
-config :: Config
-config = defaultConfig { cfgSamples   = ljust 3
-                       , cfgPerformGC = ljust True }
+runEgisonFile :: String -> IO ()
+runEgisonFile path = initialEnv defaultOption >>= flip (loadEgisonFile defaultOption) path >> return ()
 
 main :: IO ()
-main = defaultMainWith config (return ())
-       [ bgroup "fact" [ bench "30000" $ runEgisonFile "benchmark/fact-30000.egi" ]
-       , bgroup "collection"
-         [ bench "cons-bench" $ runEgisonFile "benchmark/collection-bench-cons.egi"
-         , bench "cons-bench-large" $ runEgisonFile "benchmark/collection-bench-cons-large.egi"
-         , bench "snoc-bench" $ runEgisonFile "benchmark/collection-bench-snoc.egi"
-         ]
-       ]
+main = defaultMainWith defaultConfig
+         [ bgroup "fact" [ bench "30000" $ nfIO $ runEgisonFile "benchmark/fact-30000.egi" ]
+         , bgroup "collection"
+           [ bench "cons-bench" $ nfIO $ runEgisonFile "benchmark/collection-bench-cons.egi"
+           , bench "cons-bench-large" $ nfIO $ runEgisonFile "benchmark/collection-bench-cons-large.egi"
+           , bench "snoc-bench" $ nfIO $ runEgisonFile "benchmark/collection-bench-snoc.egi"
+           ]]
 
diff --git a/egison.cabal b/egison.cabal
--- a/egison.cabal
+++ b/egison.cabal
@@ -1,5 +1,5 @@
 Name:                egison
-Version:             3.9.1
+Version:             3.9.2
 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.
@@ -51,7 +51,7 @@
 Homepage:            http://www.egison.org
 License:             MIT
 License-file:        LICENSE
-Author:              Satoshi Egi, Ryo Tanaka, Takahisa Watanabe, Kentaro Honda, Mayuko Kori
+Author:              Satoshi Egi, Ryo Tanaka, Takahisa Watanabe, Kentaro Honda, Mayuko Kori, Momoko Hattori
 Maintainer:          Satoshi Egi <egi@egison.org>
 Category:            Compilers/Interpreters
 Build-type:          Simple
@@ -68,7 +68,27 @@
   location: https://github.com/egison/egison.git
 
 Library
-  Build-Depends:   base >= 4.7 && < 5, array, random, containers, unordered-containers, haskeline, transformers, mtl >=2.2.1, parsec >= 3.0, directory, ghc, ghc-paths, text, regex-tdfa, process, vector, parallel, split, hashable
+  Build-Depends:
+      base >= 4.7 && < 5
+    , array
+    , random
+    , containers
+    , unordered-containers
+    , haskeline
+    , transformers
+    , mtl >=2.2.1
+    , parsec >= 3.0
+    , megaparsec >= 7.0.0
+    , parser-combinators
+    , directory
+    , ghc
+    , ghc-paths
+    , text
+    , regex-tdfa
+    , process
+    , vector
+    , split
+    , hashable
   if !impl(ghc > 8.0)
     Build-Depends: fail
   Hs-Source-Dirs:  hs-src
@@ -76,8 +96,8 @@
                    Language.Egison
                    Language.Egison.Core
                    Language.Egison.Desugar
-                   Language.Egison.Types
                    Language.Egison.Lexer
+                   Language.Egison.Types
                    Language.Egison.Parser
                    Language.Egison.ParserNonS
                    Language.Egison.ParserNonS2
@@ -85,26 +105,58 @@
                    Language.Egison.Util
                    Language.Egison.MathOutput
   Other-modules:   Paths_egison
-  build-tools:     happy >= 1.17.1, alex
+  Autogen-modules: Language.Egison.Lexer  
   ghc-options:  -O3
 
 Test-Suite test
   Type:           exitcode-stdio-1.0
   Hs-Source-Dirs: test
   Main-Is:        Test.hs
-  Build-Depends: egison, base >= 4.0 && < 5, transformers, mtl, Glob, HUnit, test-framework, test-framework-hunit, filepath
+  Build-Depends:
+      egison
+    , base >= 4.0 && < 5
+    , transformers
+    , mtl
+    , Glob
+    , HUnit
+    , test-framework
+    , test-framework-hunit
+    , filepath
   Other-modules:   Paths_egison
 
 Benchmark benchmark
   Type: exitcode-stdio-1.0
   Hs-Source-Dirs:  benchmark
   Main-Is: Benchmark.hs
-  Build-Depends: egison, base >= 4.0 && < 5, deepseq, criterion >= 0.5, transformers, mtl
+  Build-Depends:
+      egison
+    , base >= 4.0 && < 5
+    , deepseq
+    , criterion >= 0.5
+    , transformers
+    , mtl
   Other-modules:   Paths_egison
 
 Executable egison
   Main-is:             egison.hs
-  Build-depends:       egison, base >= 4.0 && < 5, array, containers, unordered-containers, haskeline, transformers, mtl, parsec >= 3.1, directory, ghc, ghc-paths, filepath, text, regex-tdfa, process, vector, optparse-applicative
+  Build-depends:
+      egison
+    , base >= 4.0 && < 5
+    , array
+    , containers
+    , unordered-containers
+    , haskeline
+    , transformers
+    , mtl
+    , parsec >= 3.1
+    , directory
+    , ghc
+    , ghc-paths
+    , filepath
+    , text
+    , process
+    , vector
+    , optparse-applicative
   if !impl(ghc > 8.0)
     Build-Depends: semigroups
   Hs-Source-Dirs:      hs-src/Interpreter
diff --git a/hs-src/Interpreter/egison.hs b/hs-src/Interpreter/egison.hs
--- a/hs-src/Interpreter/egison.hs
+++ b/hs-src/Interpreter/egison.hs
@@ -10,18 +10,14 @@
 import           Prelude                    hiding (catch)
 
 import           Data.Char
-import           Data.List                  (intercalate)
 import           Data.Semigroup             ((<>))
 import qualified Data.Text                  as T
 
 import           Data.Version
 
-import           System.Console.GetOpt
 import           System.Console.Haskeline   hiding (catch, handle, throwTo)
 import           System.Directory           (getHomeDirectory)
-import           System.Environment
-import           System.Exit                (ExitCode (..), exitFailure,
-                                             exitSuccess)
+import           System.Exit                (exitFailure, exitSuccess)
 import           System.FilePath            ((</>))
 import           System.IO
 
@@ -117,7 +113,7 @@
                   <> long "new-syntax"
                   <> help "Use non-S-expressoin syntax")
             <*> flag False True
-                  (long "happy"
+                  (long "N2"
                   <> help "[experimental] Use new lexer and parser")
 
 readFieldOption :: String -> (String, String)
@@ -145,33 +141,33 @@
       case mEnv of
         Left err -> print err
         Right env ->
-          case optEvalString opts of
-            Just expr ->
-              if optTsvOutput opts
-                then f opts env $ "(execute (each (compose show-tsv print) " ++ expr ++ "))"
-                else do ret <- runEgisonExpr opts env expr
-                        case ret of
-                          Left err  -> hPrint stderr err >> exitFailure
-                          Right val -> print val >> exitSuccess
-            Nothing ->
-              case optExecuteString opts of
-                Just cmd -> f opts env $ "(execute " ++ cmd ++ ")"
-                Nothing ->
-                  case optSubstituteString opts of
-                    Just sub -> f opts env $ "(load \"lib/core/shell.egi\") (execute (each (compose " ++ (if optTsvOutput opts then "show-tsv" else "show") ++ " print) (let {[$SH.input (SH.gen-input {" ++ unwords (map fst $ optFieldInfo opts) ++  "} {" ++ unwords (map snd $ optFieldInfo opts) ++  "})]} (" ++ sub ++ " SH.input))))"
-                    Nothing ->
-                      case optExecFile opts of
-                        Nothing -> when (optShowBanner opts) showBanner >> repl opts env >> when (optShowBanner opts) showByebyeMessage >> exitSuccess
-                        Just (file, args) ->
-                          if optTestOnly opts then do
-                              result <- if optNoIO opts
-                                          then do input <- readFile file
-                                                  runEgisonTopExprs opts env input
-                                          else evalEgisonTopExprs opts env [LoadFile file]
-                              either print (const $ return ()) result
-                          else do
-                              result <- evalEgisonTopExprs opts env [LoadFile file, Execute (ApplyExpr (VarExpr $ stringToVar "main") (CollectionExpr (map ((ElementExpr . StringExpr) . T.pack) args)))]
-                              either print (const $ return ()) result
+          case opts of
+            EgisonOpts { optEvalString = Just expr }
+              | optTsvOutput opts ->
+                f opts env $ "(execute (each (compose show-tsv print) " ++ expr ++ "))"
+              | otherwise -> do
+                ret <- runEgisonExpr opts env expr
+                case ret of
+                  Left err  -> hPrint stderr err >> exitFailure
+                  Right val -> print val >> exitSuccess
+            EgisonOpts { optExecuteString = Just cmd } ->
+              f opts env $ "(execute " ++ cmd ++ ")"
+            EgisonOpts { optSubstituteString = Just sub } ->
+              let expr = "(load \"lib/core/shell.egi\") "
+                      ++ "(execute (each (compose " ++ (if optTsvOutput opts then "show-tsv" else "show") ++ " print) (let {[$SH.input (SH.gen-input {" ++ unwords (map fst $ optFieldInfo opts) ++  "} {" ++ unwords (map snd $ optFieldInfo opts) ++  "})]} (" ++ sub ++ " SH.input))))"
+                in f opts env expr
+            EgisonOpts { optExecFile = Nothing } ->
+              when (optShowBanner opts) showBanner >> repl opts env >> when (optShowBanner opts) showByebyeMessage >> exitSuccess
+            EgisonOpts { optExecFile = Just (file, args) }
+              | optTestOnly opts -> do
+                result <- if optNoIO opts
+                            then do input <- readFile file
+                                    runEgisonTopExprs opts env input
+                            else evalEgisonTopExprs opts env [LoadFile file]
+                either print (const $ return ()) result
+              | otherwise -> do
+                result <- evalEgisonTopExprs opts env [LoadFile file, Execute (ApplyExpr (VarExpr $ stringToVar "main") (CollectionExpr (map ((ElementExpr . StringExpr) . T.pack) args)))]
+                either print (const $ return ()) result
  where
   isInValidMathOption EgisonOpts{ optMathExpr = Just lang } = notElem lang ["asciimath", "latex", "mathematica", "maxima"]
   isInValidMathOption EgisonOpts{ optMathExpr = Nothing } = False
diff --git a/hs-src/Language/Egison.hs b/hs-src/Language/Egison.hs
--- a/hs-src/Language/Egison.hs
+++ b/hs-src/Language/Egison.hs
@@ -80,28 +80,28 @@
 -- |eval an Egison expression. Input is a Haskell string.
 runEgisonExpr :: EgisonOpts -> Env -> String -> IO (Either EgisonError EgisonValue)
 runEgisonExpr opts env input
-  | optUseHappy opts = fromEgisonM $ ParserNonS2.readExpr input >>= evalExprDeep env
+  | optUseNonS2 opts = fromEgisonM $ ParserNonS2.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
-  | optUseHappy opts = fromEgisonM $ ParserNonS2.readTopExpr input >>= evalTopExpr opts env
+  | 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
 
 -- |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
-  | optUseHappy opts = fromEgisonM $ ParserNonS2.readTopExpr input >>= evalTopExpr' opts st
+  | 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
 
 -- |eval Egison top expressions. Input is a Haskell string.
 runEgisonTopExprs :: EgisonOpts -> Env -> String -> IO (Either EgisonError Env)
 runEgisonTopExprs opts env input
-  | optUseHappy opts = fromEgisonM $ ParserNonS2.readTopExprs input >>= evalTopExprs opts env
+  | 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
 
@@ -116,7 +116,10 @@
 -- |Environment that contains core libraries
 initialEnv :: EgisonOpts -> IO Env
 initialEnv opts = do
-  env <- if optNoIO opts then primitiveEnvNoIO else primitiveEnv
+  env <- if optNoIO opts then if optUseNonS2 opts then primitiveEnvNoIO'
+                                                  else primitiveEnvNoIO
+                         else if optUseNonS2 opts then primitiveEnv'
+                                                  else primitiveEnv
   ret <- evalEgisonTopExprs defaultOption env $ map Load coreLibraries
   case ret of
     Left err -> do
diff --git a/hs-src/Language/Egison/Core.hs b/hs-src/Language/Egison/Core.hs
--- a/hs-src/Language/Egison/Core.hs
+++ b/hs-src/Language/Egison/Core.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE LambdaCase      #-}
 {-# LANGUAGE TupleSections   #-}
 {-# LANGUAGE ViewPatterns    #-}
+{-# LANGUAGE MultiWayIf      #-}
 
 {- |
 Module      : Language.Egison.Core
@@ -41,7 +42,6 @@
 
 import           Prelude                     hiding (mapM, mappend, mconcat)
 
-import           Control.Applicative
 import           Control.Arrow
 import           Control.Monad               (when)
 import           Control.Monad.Except        hiding (mapM)
@@ -51,28 +51,19 @@
 
 import           Data.Foldable               (toList)
 import           Data.IORef
-import           Data.List                   (any, drop, last, nub, partition)
-import           Data.List.Split             (oneOf, split)
+import           Data.List                   (partition)
 import           Data.Maybe
-import           Data.Ratio
 import           Data.Sequence               (Seq, ViewL (..), ViewR (..), (><))
 import qualified Data.Sequence               as Sq
 import           Data.Traversable            (mapM)
 
-import           Data.Array                  ((!))
 import qualified Data.Array                  as Array
 import qualified Data.HashMap.Lazy           as HL
-import           Data.HashMap.Strict         (HashMap)
-import qualified Data.HashMap.Strict         as HashMap
-import           Data.Map                    (Map, assocs, empty, singleton,
-                                              unionWith, unionsWith, (!))
-import qualified Data.Map                    as M
 import qualified Data.Vector                 as V
 
 import           Data.Text                   (Text)
 import qualified Data.Text                   as T
 
-import           Language.Egison.MathOutput
 import           Language.Egison.Parser      as Parser
 import           Language.Egison.ParserNonS  as ParserNonS
 import           Language.Egison.ParserNonS2 as ParserNonS2
@@ -92,12 +83,18 @@
     LoadFile file ->
       if optNoIO opts
          then throwError $ Default "No IO support"
-         else do exprs' <- if optUseHappy opts then ParserNonS2.loadFile file else if optSExpr opts then Parser.loadFile file else ParserNonS.loadFile file
+         else do exprs' <- if
+                   | optUseNonS2 opts -> ParserNonS2.loadFile file
+                   | optSExpr opts    -> Parser.loadFile file
+                   | otherwise        -> ParserNonS.loadFile file
                  collectDefs opts (exprs' ++ exprs) bindings rest
     Load file ->
       if optNoIO opts
          then throwError $ Default "No IO support"
-         else do exprs' <- if optUseHappy opts then ParserNonS2.loadLibraryFile file else if optSExpr opts then Parser.loadLibraryFile file else ParserNonS.loadLibraryFile file
+         else do exprs' <- if
+                   | optUseNonS2 opts -> ParserNonS2.loadLibraryFile file
+                   | optSExpr opts    -> Parser.loadLibraryFile file
+                   | otherwise        -> ParserNonS.loadLibraryFile file
                  collectDefs opts (exprs' ++ exprs) bindings rest
 collectDefs _ [] bindings rest = return (bindings, reverse rest)
 
@@ -156,7 +153,7 @@
   refVar' env var = maybe (newEvaluatedObjectRef (Value (symbolScalarData "" $ show var))) return
                           (refVar env var)
 
-evalExpr env (PartialVarExpr n) = evalExpr env (VarExpr $ stringToVar ("::" ++ show n))
+evalExpr env (PartialVarExpr n) = evalExpr env (stringToVarExpr ("::" ++ show n))
 
 evalExpr _ (InductiveDataExpr name []) = return . Value $ InductiveData name []
 evalExpr env (InductiveDataExpr name exprs) =
@@ -429,7 +426,7 @@
         nth n =
           let pattern = TuplePat $ flip map [1..k] $ \i ->
                 if i == n then PatVar (stringToVar "#_") else WildCard
-          in MatchExpr target matcher [(pattern, VarExpr $ stringToVar "#_")]
+          in MatchExpr target matcher [(pattern, stringToVarExpr "#_")]
     return ((var, expr) : map (second nth) (zip names [1..]))
 
   genVar :: State Int Var
@@ -488,12 +485,12 @@
 
 
 evalExpr env (DoExpr bindings expr) = return $ Value $ IOFunc $ do
-  let body = foldr genLet (ApplyExpr expr $ TupleExpr [VarExpr $ stringToVar "#1"]) bindings
+  let body = foldr genLet (ApplyExpr expr $ TupleExpr [stringToVarExpr "#1"]) bindings
   applyFunc env (Value $ Func Nothing env ["#1"] body) $ Value World
  where
   genLet (names, expr) expr' =
-    LetExpr [(map stringToVar ["#1", "#2"], ApplyExpr expr $ TupleExpr [VarExpr $ stringToVar "#1"])] $
-    LetExpr [(names, VarExpr $ stringToVar "#2")] expr'
+    LetExpr [(map stringToVar ["#1", "#2"], ApplyExpr expr $ TupleExpr [stringToVarExpr "#1"])] $
+    LetExpr [(names, stringToVarExpr "#2")] expr'
 
 evalExpr env (IoExpr expr) = do
   io <- evalExpr env expr
@@ -819,7 +816,7 @@
       let argnum = length tds
           subjs = map (Subscript . symbolScalarData symId . show) [1 .. argnum]
           supjs = map (Superscript . symbolScalarData symId . show) [1 .. argnum]
-      dot <- evalExpr env (VarExpr $ stringToVar ".")
+      dot <- evalExpr env (stringToVarExpr ".")
       makeITuple (Value (TensorData (Tensor s1 t1 (i1 ++ supjs))):map (Intermediate .ITensor . addscript) (zip subjs $ map valuetoTensor2 tds)) >>= applyFunc env dot
     else throwError $ Default "applyfunc"
 
@@ -831,7 +828,7 @@
       let argnum = length tds
           subjs = map (Subscript . symbolScalarData symId . show) [1 .. argnum]
           supjs = map (Superscript . symbolScalarData symId . show) [1 .. argnum]
-      dot <- evalExpr env (VarExpr $ stringToVar ".")
+      dot <- evalExpr env (stringToVarExpr ".")
       makeITuple (map Intermediate (ITensor (Tensor s1 t1 (i1 ++ supjs)):map (ITensor . addscript) (zip subjs $ map valuetoTensor2 tds))) >>= applyFunc env dot
     else throwError $ Default "applyfunc"
 
@@ -1209,13 +1206,15 @@
               (carEndsRef, cdrEndsRef) <- fromJust <$> runMaybeT (unconsCollection ends)
               b2 <- evalRef cdrEndsRef >>= isEmptyCollection
               carEndsNum <- evalRef carEndsRef >>= fromWHNF
-              if startNum > carEndsNum
-                then return MNil
-                else if startNum == carEndsNum
-                       then if b2
-                              then return $ fromList [MState env loops' seqs bindings (MAtom endPat startNumWhnf Something:MAtom pat' target matcher:trees)]
-                              else return $ fromList [MState env loops' seqs bindings (MAtom endPat startNumWhnf Something:MAtom pat' target matcher:trees), MState env (LoopPatContext (name, nextNumRef) cdrEndsRef endPat pat pat':loops') seqs bindings (MAtom pat target matcher:trees)]
-                       else return $ fromList [MState env (LoopPatContext (name, nextNumRef) endsRef endPat pat pat':loops') seqs bindings (MAtom pat target matcher:trees)]
+              return $ if
+                | startNum >  carEndsNum -> MNil
+                | startNum == carEndsNum && b2 ->
+                  fromList [MState env loops' seqs bindings (MAtom endPat startNumWhnf Something:MAtom pat' target matcher:trees)]
+                | startNum == carEndsNum ->
+                  fromList [MState env loops' seqs bindings (MAtom endPat startNumWhnf Something:MAtom pat' target matcher:trees),
+                            MState env (LoopPatContext (name, nextNumRef) cdrEndsRef endPat pat pat':loops') seqs bindings (MAtom pat target matcher:trees)]
+                | otherwise ->
+                  fromList [MState env (LoopPatContext (name, nextNumRef) endsRef endPat pat pat':loops') seqs bindings (MAtom pat target matcher:trees)]
     SeqNilPat -> throwError =<< EgisonBug "should not reach here (seq nil pattern)" <$> getFuncNameStack
     SeqConsPat pattern pattern' -> return $ msingleton $ MState env loops (SeqPatContext trees pattern' [] []:seqs) bindings [MAtom pattern target matcher]
     LaterPatVar ->
diff --git a/hs-src/Language/Egison/Desugar.hs b/hs-src/Language/Egison/Desugar.hs
--- a/hs-src/Language/Egison/Desugar.hs
+++ b/hs-src/Language/Egison/Desugar.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE TupleSections              #-}
 
 {- |
 Module      : Language.Egison.Desugar
@@ -19,18 +20,16 @@
     , desugar
     ) where
 
-import           Control.Applicative   (Applicative, pure, (*>), (<$>), (<*),
-                                        (<*>))
+import           Control.Applicative   (Applicative, pure, (<$>), (<*>))
 import           Control.Monad.Except
 import           Control.Monad.Fail
 import           Control.Monad.Reader
 import           Data.Char             (toUpper)
-import           Data.List             (span)
-import           Data.Maybe            (fromMaybe)
-import           Data.Sequence         (ViewL (..), (<|))
-import qualified Data.Sequence         as Sq
+import           Data.List             (find, span)
+import           Data.Maybe            (fromJust, fromMaybe)
 import           Data.Set              (Set)
 import qualified Data.Set              as S
+
 import           Language.Egison.Types
 
 type Subst = [(String, EgisonExpr)]
@@ -81,7 +80,7 @@
       genMainClause patterns matcher = do
         clauses <- genClauses patterns
         return (PPValuePat "val", TupleExpr []
-               ,[(PDPatVar "tgt", MatchExpr (TupleExpr [VarExpr $ stringToVar "val", VarExpr $ stringToVar "tgt"])
+               ,[(PDPatVar "tgt", MatchExpr (TupleExpr [stringToVarExpr "val", stringToVarExpr "tgt"])
                                             (TupleExpr [matcher, matcher])
                                              clauses)])
         where
@@ -123,7 +122,7 @@
 
       genSomethingClause :: DesugarM (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])
       genSomethingClause =
-        return (PPPatVar, TupleExpr [SomethingExpr], [(PDPatVar "tgt", CollectionExpr [ElementExpr (VarExpr $ stringToVar "tgt")])])
+        return (PPPatVar, TupleExpr [SomethingExpr], [(PDPatVar "tgt", CollectionExpr [ElementExpr (stringToVarExpr "tgt")])])
 
       matchingSuccess :: EgisonExpr
       matchingSuccess = CollectionExpr [ElementExpr $ TupleExpr []]
@@ -133,11 +132,11 @@
 
 desugar (MatchAllLambdaExpr matcher clauses) = do
   name <- fresh
-  desugar $ LambdaExpr [TensorArg name] (MatchAllExpr (VarExpr $ stringToVar name) matcher clauses)
+  desugar $ LambdaExpr [TensorArg name] (MatchAllExpr (stringToVarExpr name) matcher clauses)
 
 desugar (MatchLambdaExpr matcher clauses) = do
   name <- fresh
-  desugar $ LambdaExpr [TensorArg name] (MatchExpr (VarExpr $ stringToVar name) matcher clauses)
+  desugar $ LambdaExpr [TensorArg name] (MatchExpr (stringToVarExpr name) matcher clauses)
 
 desugar (ArrayRefExpr expr nums) =
   case nums of
@@ -145,24 +144,30 @@
     _ -> desugar $ IndexedExpr True expr [Subscript nums]
 
 desugar (IndexedExpr b expr indices)
-  | endWithThreeDots expr = case expr of
-                              (VarExpr name) -> let x = show name in desugar $ IndexedExpr False (VarExpr $ stringToVar $ take (length x - 3) x) indices
-  | otherwise = case indices of
-                 [Subscript x, DotSubscript y] -> case (x, y) of
-                                           (IntegerExpr _, IntegerExpr _) -> return $ SubrefsExpr b expr (ApplyExpr (VarExpr $ stringToVar "between") (TupleExpr [x, y]))
-                                           (TupleExpr [IndexedExpr b1 e1 [n1]], TupleExpr [IndexedExpr b2 e2 [n2]]) -> do
-                                             k <- fresh
-                                             return $ SubrefsExpr b expr (ApplyExpr (VarExpr $ stringToVar "map")
-                                                                                    (TupleExpr [LambdaExpr [TensorArg k] (IndexedExpr b1 e1 [Subscript $ VarExpr $ stringToVar k]),
-                                                                                                ApplyExpr (VarExpr $ stringToVar "between") (TupleExpr [fromIndexToExpr n1, fromIndexToExpr n2])]))
-                 [Superscript x, DotSupscript y] -> case (x, y) of
-                                             (IntegerExpr _, IntegerExpr _) -> return $ SubrefsExpr b expr (ApplyExpr (VarExpr $ stringToVar "between") (TupleExpr [x, y]))
-                                             (TupleExpr [IndexedExpr b1 e1 [n1]], TupleExpr [IndexedExpr b2 e2 [n2]]) -> do
-                                               k <- fresh
-                                               return $ SuprefsExpr b expr (ApplyExpr (VarExpr $ stringToVar "map")
-                                                                                      (TupleExpr [LambdaExpr [TensorArg k] (IndexedExpr b1 e1 [Subscript $ VarExpr $ stringToVar k]),
-                                                                                                  ApplyExpr (VarExpr $ stringToVar "between") (TupleExpr [fromIndexToExpr n1, fromIndexToExpr n2])]))
-                 _ -> IndexedExpr b <$> desugar expr <*> mapM desugarIndex indices
+  | endWithThreeDots expr =
+    case expr of
+      VarExpr name ->
+        let x = show name
+         in desugar $ IndexedExpr False (stringToVarExpr $ take (length x - 3) x) indices
+  | otherwise =
+    case indices of
+      [Subscript x, DotSubscript y] ->
+        case (x, y) of
+          (IntegerExpr _, IntegerExpr _) -> return $ SubrefsExpr b expr (makeApply "between" [x, y])
+          (TupleExpr [IndexedExpr b1 e1 [n1]], TupleExpr [IndexedExpr b2 e2 [n2]]) -> do
+            k <- fresh
+            return $ SubrefsExpr b expr (makeApply "map"
+                                                   [LambdaExpr [TensorArg k] (IndexedExpr b1 e1 [Subscript $ stringToVarExpr k]),
+                                                    makeApply "between" [fromIndexToExpr n1, fromIndexToExpr n2]])
+      [Superscript x, DotSupscript y] ->
+        case (x, y) of
+          (IntegerExpr _, IntegerExpr _) -> return $ SubrefsExpr b expr (makeApply "between" [x, y])
+          (TupleExpr [IndexedExpr b1 e1 [n1]], TupleExpr [IndexedExpr b2 e2 [n2]]) -> do
+            k <- fresh
+            return $ SuprefsExpr b expr (makeApply "map"
+                                                   [LambdaExpr [TensorArg k] (IndexedExpr b1 e1 [Subscript $ stringToVarExpr k]),
+                                                    makeApply "between" [fromIndexToExpr n1, fromIndexToExpr n2]])
+      _ -> IndexedExpr b <$> desugar expr <*> mapM desugarIndex indices
  where
   endWithThreeDots :: EgisonExpr -> Bool
   endWithThreeDots (VarExpr name) = take 3 (reverse (show name)) == "..."
@@ -178,38 +183,37 @@
 desugar (SuprefsExpr bool expr1 expr2) =
   SuprefsExpr bool <$> desugar expr1 <*> desugar expr2
 
+desugar (UserrefsExpr bool expr1 expr2) =
+  UserrefsExpr bool <$> desugar expr1 <*> desugar expr2
+
 desugar (PowerExpr expr1 expr2) = do
   expr1' <- desugar expr1
   expr2' <- desugar expr2
-  return $ ApplyExpr (VarExpr $ stringToVar "**") (TupleExpr [expr1', expr2'])
+  return $ ApplyExpr (stringToVarExpr "**") (TupleExpr [expr1', expr2'])
 
-desugar (ArrayBoundsExpr expr) = do
-  expr' <- desugar expr
-  return $ ArrayBoundsExpr expr'
+desugar (ArrayBoundsExpr expr) =
+  ArrayBoundsExpr <$> desugar expr
 
-desugar (InductiveDataExpr name exprs) = do
-  exprs' <- mapM desugar exprs
-  return $ InductiveDataExpr name exprs'
+desugar (InductiveDataExpr name exprs) =
+  InductiveDataExpr name <$> mapM desugar exprs
 
-desugar (TupleExpr exprs) = do
-  exprs' <- mapM desugar exprs
-  return $ TupleExpr exprs'
+desugar (TupleExpr exprs) =
+  TupleExpr <$> mapM desugar exprs
 
 desugar expr@(CollectionExpr []) = return expr
 
 desugar (CollectionExpr (ElementExpr elm:inners)) = do
-      elm' <- desugar elm
-      (CollectionExpr inners') <- desugar (CollectionExpr inners)
-      return $ CollectionExpr (ElementExpr elm':inners')
+  elm' <- desugar elm
+  (CollectionExpr inners') <- desugar (CollectionExpr inners)
+  return $ CollectionExpr (ElementExpr elm':inners')
 
 desugar (CollectionExpr (SubCollectionExpr sub:inners)) = do
-      sub' <- desugar sub
-      (CollectionExpr inners') <- desugar (CollectionExpr inners)
-      return $ CollectionExpr (SubCollectionExpr sub':inners')
+  sub' <- desugar sub
+  (CollectionExpr inners') <- desugar (CollectionExpr inners)
+  return $ CollectionExpr (SubCollectionExpr sub':inners')
 
-desugar (VectorExpr exprs) = do
-  exprs' <- mapM desugar exprs
-  return $ VectorExpr exprs'
+desugar (VectorExpr exprs) =
+  VectorExpr <$> mapM desugar exprs
 
 desugar (TensorExpr nsExpr xsExpr supExpr subExpr) = do
   nsExpr' <- desugar nsExpr
@@ -221,20 +225,22 @@
                                     TensorArg _ -> True
                                     _           -> False) (reverse names)
   case rhnames of
-    [] -> do expr' <- desugar expr
-             return $ LambdaExpr names expr'
-
+    [] -> LambdaExpr names <$> desugar expr
     (InvertedScalarArg rhname:rhnames') -> do
       let (rtnames2, rhnames2) = span (const False) rhnames'
       case rhnames2 of
         [] -> desugar $ LambdaExpr (reverse rhnames' ++ [TensorArg rhname] ++ reverse rtnames)
-                          (TensorMapExpr (LambdaExpr [TensorArg rhname] expr) (FlipIndicesExpr (VarExpr $ stringToVar rhname)))
+                          (TensorMapExpr (LambdaExpr [TensorArg rhname] expr) (FlipIndicesExpr (stringToVarExpr rhname)))
         (ScalarArg rhname2:rhnames2') ->
           desugar $ LambdaExpr (reverse rhnames2' ++ [TensorArg rhname2] ++ rtnames2 ++ [TensorArg rhname] ++ reverse rtnames)
-                      (TensorMap2Expr (LambdaExpr [TensorArg rhname2, TensorArg rhname] expr) (VarExpr $ stringToVar rhname2) (FlipIndicesExpr (VarExpr $ stringToVar rhname)))
+                      (TensorMap2Expr (LambdaExpr [TensorArg rhname2, TensorArg rhname] expr)
+                                      (stringToVarExpr rhname2)
+                                      (FlipIndicesExpr (stringToVarExpr rhname)))
         (InvertedScalarArg rhname2:rhnames2') ->
           desugar $ LambdaExpr (reverse rhnames2' ++ [TensorArg rhname2] ++ rtnames2 ++ [TensorArg rhname] ++ reverse rtnames)
-                      (TensorMap2Expr (LambdaExpr [TensorArg rhname2, TensorArg rhname] expr) (FlipIndicesExpr (VarExpr $ stringToVar rhname2)) (FlipIndicesExpr (VarExpr $ stringToVar rhname)))
+                      (TensorMap2Expr (LambdaExpr [TensorArg rhname2, TensorArg rhname] expr)
+                                      (FlipIndicesExpr (stringToVarExpr rhname2))
+                                      (FlipIndicesExpr (stringToVarExpr rhname)))
 
     (ScalarArg rhname:rhnames') -> do
       let (rtnames2, rhnames2) = span (\case
@@ -242,17 +248,16 @@
                                           _           -> False) rhnames'
       case rhnames2 of
         [] -> desugar $ LambdaExpr (reverse rhnames' ++ [TensorArg rhname] ++ reverse rtnames)
-                          (TensorMapExpr (LambdaExpr [TensorArg rhname] expr) (VarExpr $ stringToVar rhname))
+                          (TensorMapExpr (LambdaExpr [TensorArg rhname] expr) (stringToVarExpr rhname))
         (ScalarArg rhname2:rhnames2') ->
           desugar $ LambdaExpr (reverse rhnames2' ++ [TensorArg rhname2] ++ rtnames2 ++ [TensorArg rhname] ++ reverse rtnames)
-                      (TensorMap2Expr (LambdaExpr [TensorArg rhname2, TensorArg rhname] expr) (VarExpr $ stringToVar rhname2) (VarExpr $ stringToVar rhname))
+                      (TensorMap2Expr (LambdaExpr [TensorArg rhname2, TensorArg rhname] expr) (stringToVarExpr rhname2) (stringToVarExpr rhname))
         (InvertedScalarArg rhname2:rhnames2') ->
           desugar $ LambdaExpr (reverse rhnames2' ++ [TensorArg rhname2] ++ rtnames2 ++ [TensorArg rhname] ++ reverse rtnames)
-                      (TensorMap2Expr (LambdaExpr [TensorArg rhname2, TensorArg rhname] expr) (FlipIndicesExpr (VarExpr $ stringToVar rhname2)) (VarExpr $ stringToVar rhname))
+                      (TensorMap2Expr (LambdaExpr [TensorArg rhname2, TensorArg rhname] expr) (FlipIndicesExpr (stringToVarExpr rhname2)) (stringToVarExpr rhname))
 
-desugar (MemoizedLambdaExpr names expr) = do
-  expr' <- desugar expr
-  return $ MemoizedLambdaExpr names expr'
+desugar (MemoizedLambdaExpr names expr) =
+  MemoizedLambdaExpr names <$> desugar expr
 
 desugar (MemoizeExpr memoizeBindings expr) = do
   memoizeBindings' <- mapM (\(x,y,z) -> do x' <- desugar x
@@ -263,164 +268,129 @@
   expr' <- desugar expr
   return $ MemoizeExpr memoizeBindings' expr'
 
-desugar (CambdaExpr name expr) = do
-  expr' <- desugar expr
-  return $ CambdaExpr name expr'
+desugar (CambdaExpr name expr) =
+  CambdaExpr name <$> desugar expr
 
-desugar (ProcedureExpr names expr) = do
-  expr' <- desugar expr
-  return $ ProcedureExpr names expr'
+desugar (ProcedureExpr names expr) =
+  ProcedureExpr names <$> desugar expr
 
-desugar (PatternFunctionExpr names pattern) = do
-  pattern' <- desugarPattern pattern
-  return $ PatternFunctionExpr names pattern'
+desugar (PatternFunctionExpr names pattern) =
+  PatternFunctionExpr names <$> desugarPattern pattern
 
-desugar (IfExpr expr0 expr1 expr2) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  expr2' <- desugar expr2
-  return $ IfExpr expr0' expr1' expr2'
+desugar (IfExpr expr0 expr1 expr2) =
+  IfExpr <$> desugar expr0 <*> desugar expr1 <*> desugar expr2
 
-desugar (LetRecExpr binds expr) = do
-  binds' <- desugarBindings binds
-  expr' <- desugar expr
-  return $ LetRecExpr binds' expr'
+desugar (LetRecExpr binds expr) =
+  LetRecExpr <$> desugarBindings binds <*> desugar expr
 
-desugar (LetExpr binds expr) = do
-  binds' <- desugarBindings binds
-  expr' <- desugar expr
-  return $ LetExpr binds' expr'
+desugar (LetExpr binds expr) =
+  LetExpr <$> desugarBindings binds <*> desugar expr
 
 desugar (LetStarExpr binds expr) = do
   binds' <- desugarBindings binds
   expr' <- desugar expr
   return $ foldr (\bind ret -> LetExpr [bind] ret) expr' binds'
 
-desugar (WithSymbolsExpr vars expr) = do
-  expr' <- desugar expr
-  return $ WithSymbolsExpr vars expr'
+desugar (WithSymbolsExpr vars expr) =
+  WithSymbolsExpr vars <$> desugar expr
 
-desugar (MatchExpr expr0 expr1 clauses) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  clauses' <- desugarMatchClauses clauses
-  return $ MatchExpr expr0' expr1' clauses'
+desugar (MatchExpr expr0 expr1 clauses) =
+  MatchExpr <$> desugar expr0 <*> desugar expr1 <*> desugarMatchClauses clauses
 
-desugar (MatchDFSExpr expr0 expr1 clauses) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  clauses' <- desugarMatchClauses clauses
-  return $ MatchDFSExpr expr0' expr1' clauses'
+desugar (MatchDFSExpr expr0 expr1 clauses) =
+  MatchDFSExpr <$> desugar expr0 <*> desugar expr1 <*> desugarMatchClauses clauses
 
-desugar (MatchAllExpr expr0 expr1 clauses) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  clauses' <- desugarMatchClauses clauses
-  return $ MatchAllExpr expr0' expr1' clauses'
+desugar (MatchAllExpr expr0 expr1 clauses) =
+  MatchAllExpr <$> desugar expr0 <*> desugar expr1 <*> desugarMatchClauses clauses
 
-desugar (MatchAllDFSExpr expr0 expr1 clauses) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  clauses' <- desugarMatchClauses clauses
-  return $ MatchAllDFSExpr expr0' expr1' clauses'
+desugar (MatchAllDFSExpr expr0 expr1 clauses) =
+  MatchAllDFSExpr <$> desugar expr0 <*> desugar expr1 <*> desugarMatchClauses clauses
 
-desugar (DoExpr binds expr) = do
-  binds' <- desugarBindings binds
-  expr' <- desugar expr
-  return $ DoExpr binds' expr'
+desugar (DoExpr binds expr) =
+  DoExpr <$> desugarBindings binds <*> desugar expr
 
-desugar (IoExpr expr) = do
-  expr' <- desugar expr
-  return $ IoExpr expr'
+desugar (IoExpr expr) =
+  IoExpr <$> desugar expr
 
-desugar (SeqExpr expr0 expr1) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  return $ SeqExpr expr0' expr1'
+desugar (UnaryOpExpr "-" expr) =
+  (\x -> makeApply "neg" [x]) <$> desugar expr
+desugar (UnaryOpExpr "!" (ApplyExpr expr1 expr2)) =
+  WedgeApplyExpr <$> desugar expr1 <*> desugar expr2
+desugar (UnaryOpExpr "'" expr) = QuoteExpr <$> desugar expr
+desugar (UnaryOpExpr "`" expr) = QuoteSymbolExpr <$> desugar expr
 
+desugar (BinaryOpExpr op expr1 expr2) | isWedge op = do
+  (\x y -> WedgeApplyExpr (stringToVarExpr (func op)) (TupleExpr [x, y]))
+    <$> desugar expr1 <*> desugar expr2
+
+desugar (BinaryOpExpr op expr1 expr2) =
+  (\x y -> makeApply (func op) [x, y]) <$> desugar expr1 <*> desugar expr2
+
+desugar (SeqExpr expr0 expr1) =
+  SeqExpr <$> desugar expr0 <*> desugar expr1
+
 desugar (GenerateArrayExpr fnExpr (fstExpr, lstExpr)) = do
   fnExpr' <- desugar fnExpr
   fstExpr' <- desugar fstExpr
   lstExpr' <- desugar lstExpr
   return $ GenerateArrayExpr fnExpr' (fstExpr', lstExpr')
 
-desugar (GenerateTensorExpr fnExpr sizeExpr) = do
-  fnExpr' <- desugar fnExpr
-  sizeExpr' <- desugar sizeExpr
-  return $ GenerateTensorExpr fnExpr' sizeExpr'
+desugar (GenerateTensorExpr fnExpr sizeExpr) =
+  GenerateTensorExpr <$> desugar fnExpr <*> desugar sizeExpr
 
-desugar (TensorContractExpr fnExpr tExpr) = do
-  fnExpr' <- desugar fnExpr
-  tExpr' <- desugar tExpr
-  return $ TensorContractExpr fnExpr' tExpr'
+desugar (TensorContractExpr fnExpr tExpr) =
+  TensorContractExpr <$> desugar fnExpr <*> desugar tExpr
 
-desugar (TensorMapExpr fnExpr tExpr) = do
-  fnExpr' <- desugar fnExpr
-  tExpr' <- desugar tExpr
-  return $ TensorMapExpr fnExpr' tExpr'
+desugar (TensorMapExpr fnExpr tExpr) =
+  TensorMapExpr <$> desugar fnExpr <*> desugar tExpr
 
-desugar (TensorMap2Expr fnExpr t1Expr t2Expr) = do
-  fnExpr' <- desugar fnExpr
-  t1Expr' <- desugar t1Expr
-  t2Expr' <- desugar t2Expr
-  return $ TensorMap2Expr fnExpr' t1Expr' t2Expr'
+desugar (TensorMap2Expr fnExpr t1Expr t2Expr) =
+  TensorMap2Expr <$> desugar fnExpr <*> desugar t1Expr <*> desugar t2Expr
 
-desugar (TransposeExpr vars expr) = do
-  vars' <- desugar vars
-  expr' <- desugar expr
-  return $ TransposeExpr vars' expr'
+desugar (TransposeExpr vars expr) =
+  TransposeExpr <$> desugar vars <*> desugar expr
 
-desugar (FlipIndicesExpr expr) = do
-  expr' <- desugar expr
-  return $ FlipIndicesExpr expr'
+desugar (FlipIndicesExpr expr) =
+  FlipIndicesExpr <$> desugar expr
 
-desugar (ApplyExpr expr0 expr1) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  return $ ApplyExpr expr0' expr1'
+desugar (ApplyExpr expr0 expr1) =
+  ApplyExpr <$> desugar expr0 <*> desugar expr1
 
-desugar (CApplyExpr expr0 expr1) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  return $ CApplyExpr expr0' expr1'
+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 (VarExpr $ stringToVar (":::" ++ id))
+  return $ stringToVarExpr (":::" ++ id)
 
-desugar (MatcherExpr matcherInfo) = do
-  matcherInfo' <- desugarMatcherInfo matcherInfo
-  return $ MatcherExpr matcherInfo'
+desugar (MatcherExpr matcherInfo) =
+  MatcherExpr <$> desugarMatcherInfo matcherInfo
 
 desugar (PartialVarExpr n) = return $ PartialVarExpr n
 
 desugar (PartialExpr n expr) = do
   expr' <- desugar expr
-  return $ LetRecExpr [([stringToVar "::0"], PartialExpr n expr')] (VarExpr $ stringToVar "::0")
+  return $ LetRecExpr [([stringToVar "::0"], PartialExpr n expr')] (stringToVarExpr "::0")
 
-desugar (QuoteExpr expr) = do
-  expr' <- desugar expr
-  return $ QuoteExpr expr'
+desugar (QuoteExpr expr) =
+  QuoteExpr <$> desugar expr
 
-desugar (QuoteSymbolExpr expr) = do
-  expr' <- desugar expr
-  return $ QuoteSymbolExpr expr'
+desugar (QuoteSymbolExpr expr) =
+  QuoteSymbolExpr <$> desugar expr
 
-desugar (WedgeExpr (ApplyExpr expr0 expr1)) = do
-  expr0' <- desugar expr0
-  expr1' <- desugar expr1
-  return $ WedgeApplyExpr expr0' expr1'
+desugar (WedgeExpr (ApplyExpr expr0 expr1)) =
+  WedgeApplyExpr <$> desugar expr0 <*> desugar expr1
 
 desugar expr = return expr
 
 desugarIndex :: Index EgisonExpr -> DesugarM (Index EgisonExpr)
-desugarIndex (Superscript expr)  = Superscript <$> desugar expr
-desugarIndex (Subscript expr)    = Subscript <$> desugar expr
+desugarIndex (Superscript expr)  = Superscript  <$> desugar expr
+desugarIndex (Subscript expr)    = Subscript    <$> desugar expr
 desugarIndex (SupSubscript expr) = SupSubscript <$> desugar expr
-desugarIndex (Userscript expr)   = Userscript <$> desugar expr
+desugarIndex (Userscript expr)   = Userscript   <$> desugar expr
 
 desugarPattern :: EgisonPattern -> DesugarM EgisonPattern
 desugarPattern pattern = LetPat (map makeBinding $ S.elems $ collectName pattern) <$> desugarPattern' pattern
@@ -485,10 +455,10 @@
     lp:hps ->
       return $ InductivePat "mult" [intPat',
                                     foldr (\p r -> case p of
-                                                     (PowerPat p1 p2) -> InductivePat "ncons" [p1, p2, r]
+                                                     PowerPat p1 p2 -> InductivePat "ncons" [p1, p2, r]
                                                      _ -> InductivePat "cons" [p, r])
                                           (case lp of
-                                             (PowerPat p1 p2) -> InductivePat "ncons" [p1, p2, ValuePat (IntegerExpr 1)]
+                                             PowerPat p1 p2 -> InductivePat "ncons" [p1, p2, ValuePat (IntegerExpr 1)]
                                              _ -> lp)
                                           (reverse hps)]
  where
@@ -498,49 +468,26 @@
 desugarPattern' pattern = return pattern
 
 desugarLoopRange :: LoopRange -> DesugarM LoopRange
-desugarLoopRange (LoopRange sExpr eExpr pattern) = do
-  sExpr' <- desugar sExpr
-  eExpr' <- desugar eExpr
-  pattern' <- desugarPattern' pattern
-  return $ LoopRange sExpr' eExpr' pattern'
-
-desugarBinding :: BindingExpr -> DesugarM BindingExpr
-desugarBinding (name, expr) = do
-  expr' <- desugar expr
-  return (name, expr')
+desugarLoopRange (LoopRange sExpr eExpr pattern) =
+  LoopRange <$> desugar sExpr <*> desugar eExpr <*> desugarPattern' pattern
 
 desugarBindings :: [BindingExpr] -> DesugarM [BindingExpr]
-desugarBindings (bind:rest) = do
-  bind' <- desugarBinding bind
-  rest' <- desugarBindings rest
-  return $ bind' : rest'
-
-desugarBindings [] = return []
-
-desugarMatchClause :: MatchClause -> DesugarM MatchClause
-desugarMatchClause (pattern, expr) = do
-  pattern' <- desugarPattern pattern
-  expr'    <- desugar expr
-  return (pattern', expr')
+desugarBindings = mapM f
+  where f (name, expr) = (name,) <$> desugar expr
 
 desugarMatchClauses :: [MatchClause] -> DesugarM [MatchClause]
-desugarMatchClauses (clause:rest) = do
-  clause' <- desugarMatchClause clause
-  rest'   <- desugarMatchClauses rest
-  return $ clause' : rest'
-desugarMatchClauses [] = return []
+desugarMatchClauses = mapM f
+  where f (pattern, expr) = (,) <$> desugarPattern pattern <*> desugar expr
 
 desugarMatcherInfo :: MatcherInfo -> DesugarM MatcherInfo
-desugarMatcherInfo [] = return []
-desugarMatcherInfo ((pp, matcher, pds):matcherInfo) = do
-  matcher' <- desugar matcher
-  pds' <- desugarPrimitiveDataMatchClauses pds
-  matcherInfo' <- desugarMatcherInfo matcherInfo
-  return $ (pp, matcher', pds'):matcherInfo'
+desugarMatcherInfo = mapM f
+  where
+    f (pp, matcher, pds) =
+      (pp,,) <$> desugar matcher <*> desugarPrimitiveDataMatchClauses pds
 
 desugarPrimitiveDataMatchClauses :: [(PrimitiveDataPattern, EgisonExpr)] -> DesugarM [(PrimitiveDataPattern, EgisonExpr)]
-desugarPrimitiveDataMatchClauses [] = return []
-desugarPrimitiveDataMatchClauses ((pd, expr):pds) = do
-  expr' <- desugar expr
-  pds' <- desugarPrimitiveDataMatchClauses pds
-  return $ (pd, expr'):pds'
+desugarPrimitiveDataMatchClauses = mapM f
+  where f (pd, expr) = (pd,) <$> desugar expr
+
+makeApply :: String -> [EgisonExpr] -> EgisonExpr
+makeApply func args = ApplyExpr (stringToVarExpr func) (TupleExpr args)
diff --git a/hs-src/Language/Egison/Lexer.x b/hs-src/Language/Egison/Lexer.x
deleted file mode 100644
--- a/hs-src/Language/Egison/Lexer.x
+++ /dev/null
@@ -1,261 +0,0 @@
-{
-{-# OPTIONS -w #-}
-
-{- |
-Module      : Language.Egison.Lexer
-Copyright   : Satoshi Egi
-Licence     : MIT
-
-This module provides new Egison lexer.
--}
-
-module Language.Egison.Lexer
-       ( Token(..)
-       , AlexPosn(..)
-       , TokenClass(..)
-       , Alex(..)
-       , runAlex'
-       , alexMonadScan'
-       , alexError
-       , alexError'
-       ) where
-
-import           Prelude               hiding (lex)
-import           Control.Monad         (liftM)
-
-import           Language.Egison.Types
-
-}
-
-%wrapper "monadUserState"
-$digit = 0-9
-$alpha = [A-Za-z]
-tokens :-
-  $white+                        ;
-
-  -- Keywords
-  True                           { lex' TokenTrue           }
-  False                          { lex' TokenFalse          }
-  test                           { lex' TokenTest           }
-  match                          { lex' TokenMatch          }
-  matchDFS                       { lex' TokenMatchDFS       }
-  matchAll                       { lex' TokenMatchAll       }
-  matchAllDFS                    { lex' TokenMatchAllDFS    }
-  matchLambda                    { lex' TokenMatchLambda    }
-  matchAllLambda                 { lex' TokenMatchAllLambda }
-  as                             { lex' TokenAs             }
-  with                           { lex' TokenWith           }
-  something                      { lex' TokenSomething      }
-  if                             { lex' TokenIf             }
-  then                           { lex' TokenThen           }
-  else                           { lex' TokenElse           }
-
-  -- Data
-  $digit+                        { lex (TokenInt . read)    }
-  $alpha [$alpha $digit \']*     { lex  TokenVar            }
-
-  -- Operators
-  \=\=                           { lex' TokenEqEq           }
-  \<                             { lex' TokenLT             }
-  \>                             { lex' TokenGT             }
-  \<\=                           { lex' TokenLE             }
-  \>\=                           { lex' TokenGE             }
-  \+                             { lex' TokenPlus           }
-  \-                             { lex' TokenMinus          }
-  \%                             { lex' TokenPercent        }
-  \*                             { lex' TokenAsterisk       }
-  \/                             { lex' TokenDiv            }
-  \^                             { lex' TokenCaret          }
-  \&\&                           { lex' TokenAndAnd         }
-  \|\|                           { lex' TokenBarBar         }
-  \:                             { lex' TokenColon          }
-  \.\.                           { lex' TokenDotDot         }
-  \+\+                           { lex' TokenPlusPlus       }
-
-  \|                             { lex' TokenBar            }
-  \-\>                           { lex' TokenArrow          }
-  \$                             { lex' TokenDollar         }
-  \_                             { lex' TokenUnderscore     }
-  \#                             { lex' TokenSharp          }
-  \,                             { lex' TokenComma          }
-  \\                             { lex' TokenBackSlash      }
-  \*\$                           { lex' TokenAstDollar      }
-  \=                             { lex' TokenEq             }
-
-  \(                             { lex' TokenLParen         }
-  \)                             { lex' TokenRParen         }
-  \[                             { lex' TokenLBracket       }
-  \]                             { lex' TokenRBracket       }
-
-{
--- To improve error messages, We keep the path of the file we are
--- lexing in our own state.
-data AlexUserState = AlexUserState { filePath :: FilePath }
-
-alexInitUserState :: AlexUserState
-alexInitUserState = AlexUserState "<unknown>"
-
-getFilePath :: Alex FilePath
-getFilePath = liftM filePath alexGetUserState
-
-setFilePath :: FilePath -> Alex ()
-setFilePath = alexSetUserState . AlexUserState
-
--- The token type, consisting of the source code position and a token class.
-data Token = Token AlexPosn TokenClass
-  deriving ( Show )
-
-data TokenClass
-  -- Keywords
-  = TokenTrue
-  | TokenFalse
-  | TokenTest
-  | TokenMatch
-  | TokenMatchDFS
-  | TokenMatchAll
-  | TokenMatchAllDFS
-  | TokenMatchLambda
-  | TokenMatchAllLambda
-  | TokenAs
-  | TokenWith
-  | TokenSomething
-  | TokenIf
-  | TokenThen
-  | TokenElse
-
-  -- Data and Variables
-  | TokenInt Integer
-  | TokenVar String
-
-  | TokenEqEq
-  | TokenLT
-  | TokenGT
-  | TokenLE
-  | TokenGE
-  | TokenPlus
-  | TokenMinus
-  | TokenPercent
-  | TokenAsterisk
-  | TokenDiv
-  | TokenCaret
-  | TokenAndAnd
-  | TokenBarBar
-  | TokenColon
-  | TokenDotDot
-  | TokenPlusPlus
-
-  | TokenBar
-  | TokenArrow
-  | TokenDollar
-  | TokenUnderscore
-  | TokenSharp
-  | TokenComma
-  | TokenBackSlash
-  | TokenAstDollar
-  | TokenEq
-
-  | TokenLParen
-  | TokenRParen
-  | TokenLBracket
-  | TokenRBracket
-  | TokenEOF
-
--- For nice parser error messages.
-instance Show TokenClass where
-  show TokenTrue = "True"
-  show TokenFalse = "False"
-  show TokenTest = "test"
-  show TokenMatch = "match"
-  show TokenMatchDFS = "matchDFS"
-  show TokenMatchAll = "matchAll"
-  show TokenMatchAllDFS = "matchAllDFS"
-  show TokenMatchLambda = "matchLambda"
-  show TokenMatchAllLambda = "matchAllLambda"
-  show TokenAs = "as"
-  show TokenWith = "with"
-  show TokenSomething = "something"
-  show TokenIf = "if"
-  show TokenThen = "then"
-  show TokenElse = "else"
-
-  show (TokenInt i) = show i
-  show (TokenVar s) = show s
-
-  show TokenEqEq = "=="
-  show TokenLT = "<"
-  show TokenGT = ">"
-  show TokenLE = "<="
-  show TokenGE = ">="
-  show TokenPlus = "+"
-  show TokenMinus = "-"
-  show TokenPercent = "%"
-  show TokenAsterisk = "*"
-  show TokenDiv = "/"
-  show TokenCaret = "^"
-  show TokenAndAnd = "&&"
-  show TokenBarBar = "||"
-  show TokenColon = ":"
-  show TokenDotDot = ".."
-  show TokenPlusPlus = "++"
-
-  show TokenBar = "|"
-  show TokenArrow = "->"
-  show TokenDollar = "$"
-  show TokenUnderscore = "_"
-  show TokenSharp = "#"
-  show TokenComma = ","
-  show TokenBackSlash = "\\"
-  show TokenAstDollar = "*$"
-  show TokenEq = "="
-
-  show TokenLParen = "("
-  show TokenRParen = ")"
-  show TokenLBracket = "["
-  show TokenRBracket = "]"
-  show TokenEOF = "<EOF>"
-
-alexEOF :: Alex Token
-alexEOF = do
-  (p,_,_,_) <- alexGetInput
-  return $ Token p TokenEOF
-
--- Unfortunately, we have to extract the matching bit of string
--- ourselves...
-lex :: (String -> TokenClass) -> AlexAction Token
-lex f = \(p,_,_,s) i -> return $ Token p (f (take i s))
-
--- For constructing tokens that do not depend on
--- the input
-lex' :: TokenClass -> AlexAction Token
-lex' = lex . const
-
--- We rewrite alexMonadScan' to delegate to alexError' when lexing fails
--- (the default implementation just returns an error message).
-alexMonadScan' :: Alex Token
-alexMonadScan' = do
-  inp <- alexGetInput
-  sc <- alexGetStartCode
-  case alexScan inp sc of
-    AlexEOF -> alexEOF
-    AlexError (p, _, _, s) ->
-        alexError' p ("lexical error at character '" ++ take 1 s ++ "'")
-    AlexSkip  inp' len -> do
-        alexSetInput inp'
-        alexMonadScan'
-    AlexToken inp' len action -> do
-        alexSetInput inp'
-        action (ignorePendingBytes inp) len
-
--- Signal an error, including a commonly accepted source code position.
-alexError' :: AlexPosn -> String -> Alex a
-alexError' (AlexPn _ l c) msg = do
-  fp <- getFilePath
-  alexError (fp ++ ":" ++ show l ++ ":" ++ show c ++ ": " ++ msg)
-
--- A variant of runAlex, keeping track of the path of the file we are lexing.
-runAlex' :: Alex a -> String -> Either EgisonError a
-runAlex' a input =
-  case runAlex input (setFilePath "<stdin>" >> a) of
-    Left msg -> Left $ Parser msg
-    Right r  -> Right r
-}
diff --git a/hs-src/Language/Egison/MathOutput.hs b/hs-src/Language/Egison/MathOutput.hs
--- a/hs-src/Language/Egison/MathOutput.hs
+++ b/hs-src/Language/Egison/MathOutput.hs
@@ -8,10 +8,7 @@
 
 module Language.Egison.MathOutput ( changeOutputInLang ) where
 
-import           Control.Monad
-import           System.Environment
 import           Text.ParserCombinators.Parsec hiding (spaces)
-
 
 changeOutputInLang :: String -> String -> String
 changeOutputInLang "haskell" input     = mathExprToHaskell input
diff --git a/hs-src/Language/Egison/Parser.hs b/hs-src/Language/Egison/Parser.hs
--- a/hs-src/Language/Egison/Parser.hs
+++ b/hs-src/Language/Egison/Parser.hs
@@ -26,9 +26,8 @@
        ) where
 
 import           Control.Applicative     (pure, (*>), (<$>), (<*), (<*>))
-import           Control.Monad.Except    hiding (mapM)
-import           Control.Monad.Identity  hiding (mapM)
-import           Control.Monad.State     hiding (mapM)
+import           Control.Monad.Except    (liftIO, throwError)
+import           Control.Monad.Identity  (Identity, unless)
 import           Prelude                 hiding (mapM)
 
 import           System.Directory        (doesFileExist, getHomeDirectory)
@@ -38,7 +37,6 @@
 import           Data.Functor            (($>))
 import           Data.List.Split         (splitOn)
 import           Data.Ratio
-import qualified Data.Sequence           as Sq
 import qualified Data.Set                as Set
 import           Data.Traversable        (mapM)
 
@@ -47,7 +45,6 @@
 import qualified Text.Parsec.Token       as P
 
 import qualified Data.Text               as T
-import           Text.Regex.TDFA
 
 import           Language.Egison.Desugar
 import           Language.Egison.Types
@@ -169,9 +166,6 @@
 loadExpr :: Parser EgisonTopExpr
 loadExpr = keywordLoad >> Load <$> stringLiteral
 
-exprs :: Parser [EgisonExpr]
-exprs = endBy expr whiteSpace
-
 expr :: Parser EgisonExpr
 expr = P.lexeme lexer (do expr0 <- expr' <|> quoteExpr'
                           expr1 <- option expr0 $ try (string "..." >> IndexedExpr False expr0 <$> parseindex)
@@ -312,10 +306,10 @@
 quoteSymbolExpr = char '`' >> QuoteSymbolExpr <$> expr
 
 matchAllExpr :: Parser EgisonExpr
-matchAllExpr = keywordMatchAll >> MatchAllExpr <$> expr <*> expr <*> ((flip (:) [] <$> matchClause) <|> matchClauses)
+matchAllExpr = keywordMatchAll >> MatchAllExpr <$> expr <*> expr <*> (((:[]) <$> matchClause) <|> matchClauses)
 
 matchAllDFSExpr :: Parser EgisonExpr
-matchAllDFSExpr = keywordMatchAllDFS >> MatchAllDFSExpr <$> expr <*> expr <*> ((flip (:) [] <$> matchClause) <|> matchClauses)
+matchAllDFSExpr = keywordMatchAllDFS >> MatchAllDFSExpr <$> expr <*> expr <*> (((:[]) <$> matchClause) <|> matchClauses)
 
 matchExpr :: Parser EgisonExpr
 matchExpr = keywordMatch >> MatchExpr <$> expr <*> expr <*> matchClauses
@@ -324,7 +318,7 @@
 matchDFSExpr = keywordMatchDFS >> MatchDFSExpr <$> expr <*> expr <*> matchClauses
 
 matchAllLambdaExpr :: Parser EgisonExpr
-matchAllLambdaExpr = keywordMatchAllLambda >> MatchAllLambdaExpr <$> expr <*> ((flip (:) [] <$> matchClause) <|> matchClauses)
+matchAllLambdaExpr = keywordMatchAllLambda >> MatchAllLambdaExpr <$> expr <*> (((:[]) <$> matchClause) <|> matchClauses)
 
 matchLambdaExpr :: Parser EgisonExpr
 matchLambdaExpr = keywordMatchLambda >> MatchLambdaExpr <$> expr <*> matchClauses
@@ -430,7 +424,7 @@
 withSymbolsExpr = keywordWithSymbols >> WithSymbolsExpr <$> braces (sepEndBy ident whiteSpace) <*> expr
 
 doExpr :: Parser EgisonExpr
-doExpr = keywordDo >> DoExpr <$> statements <*> option (ApplyExpr (VarExpr $ stringToVar "return") (TupleExpr [])) expr
+doExpr = keywordDo >> DoExpr <$> statements <*> option (ApplyExpr (stringToVarExpr "return") (TupleExpr [])) expr
 
 statements :: Parser [BindingExpr]
 statements = braces $ sepEndBy statement whiteSpace
@@ -660,7 +654,7 @@
 loopRange = brackets (try (LoopRange <$> expr <*> expr <*> option WildCard pattern)
                       <|> (do s <- expr
                               ep <- option WildCard pattern
-                              return (LoopRange s (ApplyExpr (VarExpr $ stringToVar "from") (ApplyExpr (VarExpr $ stringToVar "-'") (TupleExpr [s, IntegerExpr 1]))) ep)))
+                              return (LoopRange s (ApplyExpr (stringToVarExpr "from") (ApplyExpr (stringToVarExpr "-'") (TupleExpr [s, IntegerExpr 1]))) ep)))
 
 seqNilPat :: Parser EgisonPattern
 seqNilPat = braces $ pure SeqNilPat
@@ -672,7 +666,7 @@
 seqPat = braces $ do
   pats <- sepEndBy pattern whiteSpace
   tailPat <- option SeqNilPat (char '@' >> pattern)
-  return $ foldr (\p rets -> SeqConsPat p rets) tailPat pats
+  return $ foldr SeqConsPat tailPat pats
 
 laterPatVar :: Parser EgisonPattern
 laterPatVar = char '#' >> pure LaterPatVar
@@ -713,9 +707,9 @@
 
 floatExpr :: Parser EgisonExpr
 floatExpr = do
-  (x,y) <- try ((,) <$> floatLiteral' <*> (sign' <*> positiveFloatLiteral) <* char 'i')
-            <|> try ((,) 0 <$> floatLiteral' <* char 'i')
-            <|> try ((, 0) <$> floatLiteral')
+  (x,y) <- try ((,) <$> floatLiteral <*> (sign' <*> positiveFloatLiteral) <* char 'i')
+            <|> try ((0,)  <$> floatLiteral <* char 'i')
+            <|> try ((, 0) <$> floatLiteral)
   return $ FloatExpr x y
 
 integerExpr :: Parser EgisonExpr
@@ -736,8 +730,8 @@
   let l = m % (10 ^ fromIntegral (length mStr))
   return (fromRational (fromIntegral n + l) :: Double)
 
-floatLiteral' :: Parser Double
-floatLiteral' = sign <*> positiveFloatLiteral
+floatLiteral :: Parser Double
+floatLiteral = sign <*> positiveFloatLiteral
 
 --
 -- Tokens
@@ -851,8 +845,6 @@
 keywordLoadFile             = reserved "load-file"
 keywordLoad                 = reserved "load"
 keywordIf                   = reserved "if"
-keywordThen                 = reserved "then"
-keywordElse                 = reserved "else"
 keywordNot                  = reserved "not"
 keywordAnd                  = reserved "and"
 keywordOr                   = reserved "or"
@@ -912,14 +904,8 @@
 sign' = (char '-' >> return negate)
     <|> (char '+' >> return id)
 
-naturalLiteral :: Parser Integer
-naturalLiteral = P.natural lexer
-
 integerLiteral :: Parser Integer
 integerLiteral = sign <*> P.natural lexer
-
-floatLiteral :: Parser Double
-floatLiteral = sign <*> P.float lexer
 
 stringLiteral :: Parser String
 stringLiteral = P.stringLiteral lexer
diff --git a/hs-src/Language/Egison/ParserNonS.hs b/hs-src/Language/Egison/ParserNonS.hs
--- a/hs-src/Language/Egison/ParserNonS.hs
+++ b/hs-src/Language/Egison/ParserNonS.hs
@@ -26,9 +26,8 @@
        ) where
 
 import           Control.Applicative     (pure, (*>), (<$>), (<*), (<*>))
-import           Control.Monad.Except    hiding (mapM)
-import           Control.Monad.Identity  hiding (mapM)
-import           Control.Monad.State     hiding (mapM)
+import           Control.Monad.Except    (liftIO, throwError)
+import           Control.Monad.Identity  (Identity, unless)
 import           Prelude                 hiding (mapM)
 
 import           System.Directory        (doesFileExist, getHomeDirectory)
@@ -39,8 +38,6 @@
 import           Data.List               (intercalate)
 import           Data.List.Split         (split, splitOn, startsWithOneOf)
 import           Data.Ratio
-import qualified Data.Sequence           as Sq
-import qualified Data.Set                as Set
 import           Data.Traversable        (mapM)
 
 import           Text.Parsec
@@ -49,7 +46,6 @@
 import qualified Text.Parsec.Token       as P
 
 import qualified Data.Text               as T
-import           Text.Regex.TDFA
 
 import           Language.Egison.Desugar
 import           Language.Egison.Types
@@ -171,9 +167,6 @@
 loadExpr :: Parser EgisonTopExpr
 loadExpr = keywordLoad >> Load <$> parens stringLiteral
 
-exprs :: Parser [EgisonExpr]
-exprs = endBy expr whiteSpace
-
 expr :: Parser EgisonExpr
 expr = (try applyInfixExpr
         <|> try exprWithSymbol
@@ -195,12 +188,12 @@
           , [binary "&&" "and" AssocLeft, binary "||" "or" AssocLeft]
           , [binary "++" "join" AssocRight]
           ]
-  unary "-" assoc = Prefix (try $ inSpaces (string "-") >> return (\x -> makeApply (VarExpr $ stringToVar "*") [IntegerExpr (-1), x]))
-  unary op assoc = Prefix (try $ inSpaces (string op) >> return (\x -> makeApply (VarExpr $ stringToVar op) [x]))
+  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 (VarExpr $ stringToVar name) [x, y])) assoc
-    | op == "." || op == "%" = Infix (try $ inSpaces1 (string op) >> return (\x y -> makeApply (VarExpr $ stringToVar name) [x, y])) assoc
-    | otherwise = Infix (try $ inSpaces (string op) >> return (\x y -> makeApply (VarExpr $ stringToVar name) [x, y])) 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)
@@ -209,9 +202,9 @@
 inSpaces1 p = skipMany (space <|> newline) >> p >> skipMany1 (space <|> newline)
 
 exprWithSymbol :: Parser EgisonExpr
-exprWithSymbol = (string "d/d" >> applyExpr'' (VarExpr $ stringToVar "d/d"))
-                 <|> (string "V.*" >> applyExpr'' (VarExpr $ stringToVar "V.*"))
-                 <|> (string "M.*" >> applyExpr'' (VarExpr $ stringToVar "M.*"))
+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
@@ -429,7 +422,7 @@
 withSymbolsExpr = keywordWithSymbols >> WithSymbolsExpr <$> braces (sepEndBy ident comma) <*> expr
 
 doExpr :: Parser EgisonExpr
-doExpr = keywordDo >> DoExpr <$> statements <*> option (ApplyExpr (VarExpr $ stringToVar "return") (TupleExpr [])) expr
+doExpr = keywordDo >> DoExpr <$> statements <*> option (ApplyExpr (stringToVarExpr "return") (TupleExpr [])) expr
 
 statements :: Parser [BindingExpr]
 statements = braces $ sepEndBy statement comma
@@ -514,7 +507,7 @@
             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 = Set.size $ Set.fromList 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''
@@ -657,7 +650,7 @@
                  <|> (do s <- expr
                          comma
                          ep <- option WildCard pattern
-                         return (LoopRange s (ApplyExpr (VarExpr $ stringToVar "from") (ApplyExpr (VarExpr $ stringToVar "-'") (TupleExpr [s, IntegerExpr 1]))) ep)))
+                         return (LoopRange s (ApplyExpr (stringToVarExpr "from") (ApplyExpr (stringToVarExpr "-'") (TupleExpr [s, IntegerExpr 1]))) ep)))
 
 -- Constants
 
@@ -682,9 +675,9 @@
 
 floatExpr :: Parser EgisonExpr
 floatExpr = do
-  (x,y) <- try ((,) <$> floatLiteral' <*> (sign' <*> positiveFloatLiteral) <* char 'i')
-            <|> try ((,) 0 <$> floatLiteral' <* char 'i')
-            <|> try ((, 0) <$> floatLiteral')
+  (x,y) <- try ((,) <$> floatLiteral <*> (sign' <*> positiveFloatLiteral) <* char 'i')
+            <|> try ((,) 0 <$> floatLiteral <* char 'i')
+            <|> try ((, 0) <$> floatLiteral)
   return $ FloatExpr x y
 
 integerExpr :: Parser EgisonExpr
@@ -705,8 +698,8 @@
   let l = m % (10 ^ fromIntegral (length mStr))
   return (fromRational (fromIntegral n + l) :: Double)
 
-floatLiteral' :: Parser Double
-floatLiteral' = sign <*> positiveFloatLiteral
+floatLiteral :: Parser Double
+floatLiteral = sign <*> positiveFloatLiteral
 
 --
 -- Tokens
@@ -864,14 +857,8 @@
 sign' = (char '-' >> return negate)
     <|> (char '+' >> return id)
 
-naturalLiteral :: Parser Integer
-naturalLiteral = P.natural lexer
-
 integerLiteral :: Parser Integer
 integerLiteral = sign <*> P.natural lexer
-
-floatLiteral :: Parser Double
-floatLiteral = sign <*> P.float lexer
 
 stringLiteral :: Parser String
 stringLiteral = P.stringLiteral lexer
diff --git a/hs-src/Language/Egison/ParserNonS2.hs b/hs-src/Language/Egison/ParserNonS2.hs
new file mode 100644
--- /dev/null
+++ b/hs-src/Language/Egison/ParserNonS2.hs
@@ -0,0 +1,783 @@
+{-# 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)
diff --git a/hs-src/Language/Egison/ParserNonS2.y b/hs-src/Language/Egison/ParserNonS2.y
deleted file mode 100644
--- a/hs-src/Language/Egison/ParserNonS2.y
+++ /dev/null
@@ -1,304 +0,0 @@
-{
-{-# OPTIONS -w #-}
-
-{- |
-Module      : Language.Egison.ParserNonS2
-Copyright   : Satoshi Egi
-Licence     : MIT
-
-This module provides new 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.Monad.Except    hiding (mapM)
-
-import           Data.Either
-import qualified Data.Set                as Set
-
-import           System.Directory        (doesFileExist, getHomeDirectory)
-
-import           Language.Egison.Desugar
-import           Language.Egison.Lexer
-import           Language.Egison.Types
-import           Paths_egison            (getDataFileName)
-
-}
-
--- %name parseTopExprs_ TopExprs
-%name parseTopExpr_ TopExpr
-%name parseExpr_ Expr
-%tokentype { Token }
-%monad { Alex }
-%lexer { lexwrap } { Token _ TokenEOF }
--- Without this we get a type error
-%error { happyError }
-
-%right '|'
-%right "++"
-%right "||"
-%right "&&"
-%right ':'
-%left '<' '>' "==" "<=" ">="
-%left '+' '-' '%'
-%left '*' '/'
-%left '^'
-%right TENSOR
-
-%token
-      True           { Token _ TokenTrue           }
-      False          { Token _ TokenFalse          }
-      test           { Token _ TokenTest           }
-      match          { Token _ TokenMatch          }
-      matchDFS       { Token _ TokenMatchDFS       }
-      matchAll       { Token _ TokenMatchAll       }
-      matchAllDFS    { Token _ TokenMatchAllDFS    }
-      matchLambda    { Token _ TokenMatchLambda    }
-      matchAllLambda { Token _ TokenMatchAllLambda }
-      as             { Token _ TokenAs             }
-      with           { Token _ TokenWith           }
-      something      { Token _ TokenSomething      }
-      if             { Token _ TokenIf             }
-      then           { Token _ TokenThen           }
-      else           { Token _ TokenElse           }
-
-      int            { Token _ (TokenInt $$)       }
-      var            { Token _ (TokenVar $$)       }
-
-      "=="           { Token _ TokenEqEq           }
-      '<'            { Token _ TokenLT             }
-      '>'            { Token _ TokenGT             }
-      "<="           { Token _ TokenLE             }
-      ">="           { Token _ TokenGE             }
-      '+'            { Token _ TokenPlus           }
-      '-'            { Token _ TokenMinus          }
-      '%'            { Token _ TokenPercent        }
-      '*'            { Token _ TokenAsterisk       }
-      '/'            { Token _ TokenDiv            }
-      '^'            { Token _ TokenCaret          }
-      "&&"           { Token _ TokenAndAnd         }
-      "||"           { Token _ TokenBarBar         }
-      ':'            { Token _ TokenColon          }
-      ".."           { Token _ TokenDotDot         }
-      "++"           { Token _ TokenPlusPlus       }
-
-      '|'            { Token _ TokenBar            }
-      "->"           { Token _ TokenArrow          }
-      '$'            { Token _ TokenDollar         }
-      '_'            { Token _ TokenUnderscore     }
-      '#'            { Token _ TokenSharp          }
-      ','            { Token _ TokenComma          }
-      '\\'           { Token _ TokenBackSlash      }
-      "*$"           { Token _ TokenAstDollar      }
-      '='            { Token _ TokenEq             }
-
-      '('            { Token _ TokenLParen         }
-      ')'            { Token _ TokenRParen         }
-      '['            { Token _ TokenLBracket       }
-      ']'            { Token _ TokenRBracket       }
-
-%%
-
--- TopExprs :
---     TopExpr           { [$1] }
---   | TopExpr TopExprs  { $1 : $2 }
-
-TopExpr :: { EgisonTopExpr }
-  : var '=' Expr            { Define (stringToVar $1) $3 }
-  | var list1(Arg) '=' Expr { Define (stringToVar $1) (LambdaExpr $2 $4) }
-  | Expr                    { Test $1 }
-  | test '(' Expr ')'       { Test $3 }
-
-Expr :: { EgisonExpr }
-  : Expr1                       { $1 }
-  | MatchExpr                   { $1 }
-  | '\\' list1(Arg) "->" Expr   { LambdaExpr $2 $4 }
-  | if Expr then Expr else Expr { IfExpr $2 $4 $6 }
-
-Expr1 :: { EgisonExpr }
-  : Atoms             { $1 }
-  | '-' Atom          { makeApply (VarExpr $ stringToVar "*") [IntegerExpr(-1), $2] }
-  | BinOpExpr         { $1 }
-
-BinOpExpr :: { EgisonExpr }
-  : Expr1 "==" Expr1  { makeApply (VarExpr $ stringToVar "eq?")       [$1, $3] }
-  | Expr1 "<=" Expr1  { makeApply (VarExpr $ stringToVar "lte?")      [$1, $3] }
-  | Expr1 '<'  Expr1  { makeApply (VarExpr $ stringToVar "lt?")       [$1, $3] }
-  | Expr1 ">=" Expr1  { makeApply (VarExpr $ stringToVar "gte?")      [$1, $3] }
-  | Expr1 '>'  Expr1  { makeApply (VarExpr $ stringToVar "gt?")       [$1, $3] }
-  | Expr1 '+'  Expr1  { makeApply (VarExpr $ stringToVar "+")         [$1, $3] }
-  | Expr1 '-'  Expr1  { makeApply (VarExpr $ stringToVar "-")         [$1, $3] }
-  | Expr1 '%'  Expr1  { makeApply (VarExpr $ stringToVar "remainder") [$1, $3] }
-  | Expr1 '*'  Expr1  { makeApply (VarExpr $ stringToVar "*")         [$1, $3] }
-  | Expr1 '/'  Expr1  { makeApply (VarExpr $ stringToVar "/")         [$1, $3] }
-  | Expr1 '^'  Expr1  { makeApply (VarExpr $ stringToVar "**")        [$1, $3] }
-  | Expr1 "&&" Expr1  { makeApply (VarExpr $ stringToVar "and")       [$1, $3] }
-  | Expr1 "||" Expr1  { makeApply (VarExpr $ stringToVar "or")        [$1, $3] }
-  | Expr1 ':'  Expr1  { makeApply (VarExpr $ stringToVar "cons")      [$1, $3] }
-  | Expr1 "++" Expr1  { makeApply (VarExpr $ stringToVar "append")    [$1, $3] }
-
-Atoms :: { EgisonExpr }
-  : Atom              { $1 }
-  | Atom list1(Atom)  { makeApply $1 $2 }
-
-MatchExpr :: { EgisonExpr }
-  : match       Expr as Expr with '|' MatchClauses { MatchExpr $2 $4 $7 }
-  | matchDFS    Expr as Expr with '|' MatchClauses { MatchDFSExpr $2 $4 $7 }
-  | matchAll    Expr as Expr with '|' MatchClauses { MatchAllExpr $2 $4 $7 }
-  | matchAllDFS Expr as Expr with '|' MatchClauses { MatchAllDFSExpr $2 $4 $7 }
-  | matchLambda      as Expr with '|' MatchClauses { MatchLambdaExpr $3 $6 }
-  | matchAllLambda   as Expr with '|' MatchClauses { MatchAllLambdaExpr $3 $6 }
-
-MatchClauses :: { [MatchClause] }
-  : Pattern "->" Expr                               { [($1, $3)] }
-  | MatchClauses '|' Pattern "->" Expr              { $1 ++ [($3, $5)] }
-
--- FIXME :
---   Uncommenting these 2 rules will yield shift/reduce conflict at
---       TopExpr -> var . '=' Expr
---       TopExpr -> var . list1__Arg__ '=' Expr
---       Atom -> var .
-Arg :: { Arg }
-  : '$' var                  { ScalarArg $2 }
-  -- | var                      { ScalarArg $1 }
-  | "*$" var                 { InvertedScalarArg $2 }
-  -- | '%' var %prec TENSOR     { TensorArg $2 }
-
-Atom :: { EgisonExpr }
-  : int                      { IntegerExpr $1 }
-  | var                      { VarExpr $ stringToVar $1 }
-  | True                     { BoolExpr True }
-  | False                    { BoolExpr False }
-  | something                { SomethingExpr }
-  | '(' sep2(Expr, ',') ')'  { TupleExpr $2 }
-  | '[' sep(Expr, ',') ']'   { CollectionExpr (map ElementExpr $2) }
-  | '(' Expr ')'             { $2 }
-  | '[' Expr ".." Expr ']'   { makeApply (VarExpr $ stringToVar "between") [$2, $4] }
-
---
--- Patterns
---
-
-Pattern :: { EgisonPattern }
-  : '_'                        { WildCard }
-  | '$' var                    { PatVar (stringToVar $2) }
-  | '#' Atom                   { ValuePat $2 }
-  | '(' sep2(Pattern, ',') ')' { TuplePat $2 }
-  | Pattern ':' Pattern        { InductivePat "cons" [$1, $3] }
-  | Pattern "++" Pattern       { InductivePat "join" [$1, $3] }
-
---
--- Helpers (Parameterized Products)
---
-
-sep2(p, q)    : p q sep1(p, q)     { $1 : $3 }
-sep1(p, q)    : p list(snd(q, p))  { $1 : $2 }
-sep(p, q)     : sep1(p, q)         { $1 }
-              |                    { [] }
-
-snd(p, q)     : p q                { $2 }
-
-list1(p)      : rev_list1(p)       { reverse $1 }
-list(p)       : list1(p)           { $1 }
-              |                    { [] }
-
-rev_list1(p)  : p                  { [$1] }
-              | rev_list1(p) p     { $2 : $1 }
-
-{
-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 = Set.size $ Set.fromList 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
-
-lexwrap :: (Token -> Alex a) -> Alex a
-lexwrap = (alexMonadScan' >>=)
-
-happyError :: Token -> Alex a
-happyError (Token _ TokenEOF) = alexError "unexpected end of input"
-happyError (Token p t) = alexError' p ("parse error at token '" ++ show t ++ "'")
-
-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 = undefined -- runAlex' parseTopExprs_
-
-parseTopExpr :: String -> Either EgisonError EgisonTopExpr
-parseTopExpr = runAlex' parseTopExpr_
-
-parseExprs :: String -> Either EgisonError [EgisonExpr]
-parseExprs = undefined
-
-parseExpr :: String -> Either EgisonError EgisonExpr
-parseExpr = runAlex' parseExpr_
-
--- |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
-}
diff --git a/hs-src/Language/Egison/Primitives.hs b/hs-src/Language/Egison/Primitives.hs
--- a/hs-src/Language/Egison/Primitives.hs
+++ b/hs-src/Language/Egison/Primitives.hs
@@ -9,27 +9,32 @@
 This module provides primitive functions in Egison.
 -}
 
-module Language.Egison.Primitives (primitiveEnv, primitiveEnvNoIO) where
+module Language.Egison.Primitives
+  (
+  -- S-syntax version
+    primitiveEnv
+  , primitiveEnvNoIO
+  -- Non-S syntax (Camel case) version
+  , primitiveEnv'
+  , primitiveEnvNoIO'
+  ) where
 
-import           Control.Applicative       (pure, (*>), (<$>), (<*), (<*>))
-import           Control.Arrow
 import           Control.Monad.Except
 import           Control.Monad.Trans.Maybe
 
 import           Data.Foldable             (toList)
 import           Data.IORef
 import           Data.Ratio
-import           Text.Regex.TDFA
+import           Text.Regex.TDFA           ((=~))
 
 import           System.IO
-import           System.Process
-import           System.Random
+import           System.Process            (readProcess)
+import           System.Random             (getStdRandom, randomR)
 
 import qualified Data.Sequence             as Sq
 import qualified Data.Vector               as V
 
 import           Data.Char                 (chr, ord)
-import           Data.Text                 (Text)
 import qualified Data.Text                 as T
 import qualified Data.Text.IO              as T
 
@@ -57,6 +62,23 @@
     return (stringToVar name, ref)
   return $ extendEnv nullEnv bindings
 
+-- primitive env for Non-S syntax
+primitiveEnv' :: IO Env
+primitiveEnv' = do
+  let ops = map (\(name, fn) -> (name, PrimitiveFunc name fn)) (primitives' ++ ioPrimitives')
+  bindings <- forM (constants ++ ops) $ \(name, op) -> do
+    ref <- newIORef . WHNF $ Value op
+    return (stringToVar name, ref)
+  return $ extendEnv nullEnv bindings
+
+primitiveEnvNoIO' :: IO Env
+primitiveEnvNoIO' = do
+  let ops = map (\(name, fn) -> (name, PrimitiveFunc name fn)) primitives'
+  bindings <- forM (constants ++ ops) $ \(name, op) -> do
+    ref <- newIORef . WHNF $ Value op
+    return (stringToVar name, ref)
+  return $ extendEnv nullEnv bindings
+
 {-# INLINE noArg #-}
 noArg :: EgisonM EgisonValue -> PrimitiveFunc
 noArg f args = do
@@ -231,6 +253,112 @@
              , ("assert-equal", assertEqual)
              ]
 
+-- for Non-S syntax
+primitives' :: [(String, PrimitiveFunc)]
+primitives' = [ ("b.+", plus)
+             , ("b.-", minus)
+             , ("b.*", multiply)
+             , ("b./", divide)
+             , ("b.+'", plus)
+             , ("b.-'", minus)
+             , ("b.*'", multiply)
+             , ("b./'", divide)
+             , ("f.+", floatPlus)
+             , ("f.-", floatMinus)
+             , ("f.*", floatMult)
+             , ("f./", floatDivide)
+             , ("numerator", numerator')
+             , ("denominator", denominator')
+             , ("fromMathExpr", fromScalarData)
+             , ("toMathExpr", toScalarData)
+             , ("toMathExpr'", toScalarData)
+
+             , ("modulo",    integerBinaryOp mod)
+             , ("quotient",   integerBinaryOp quot)
+             , ("remainder", integerBinaryOp rem)
+             , ("b.abs", rationalUnaryOp abs)
+             , ("b.neg", rationalUnaryOp negate)
+
+             , ("eq?",  eq)
+             , ("lt?",  lt)
+             , ("lte?", lte)
+             , ("gt?",  gt)
+             , ("gte?", gte)
+
+             , ("round",    floatToIntegerOp round)
+             , ("floor",    floatToIntegerOp floor)
+             , ("ceiling",  floatToIntegerOp ceiling)
+             , ("truncate", truncate')
+             , ("realPart", realPart)
+             , ("imaginaryPart", imaginaryPart)
+
+             , ("b.sqrt", floatUnaryOp sqrt)
+             , ("b.sqrt'", floatUnaryOp sqrt)
+             , ("b.exp", floatUnaryOp exp)
+             , ("b.log", floatUnaryOp log)
+             , ("b.sin", floatUnaryOp sin)
+             , ("b.cos", floatUnaryOp cos)
+             , ("b.tan", floatUnaryOp tan)
+             , ("b.asin", floatUnaryOp asin)
+             , ("b.acos", floatUnaryOp acos)
+             , ("b.atan", floatUnaryOp atan)
+             , ("b.sinh", floatUnaryOp sinh)
+             , ("b.cosh", floatUnaryOp cosh)
+             , ("b.tanh", floatUnaryOp tanh)
+             , ("b.asinh", floatUnaryOp asinh)
+             , ("b.acosh", floatUnaryOp acosh)
+             , ("b.atanh", floatUnaryOp atanh)
+
+             , ("tensorSize", tensorSize')
+             , ("tensorToList", tensorToList')
+             , ("dfOrder", dfOrder')
+
+             , ("itof", integerToFloat)
+             , ("rtof", rationalToFloat)
+             , ("ctoi", charToInteger)
+             , ("itoc", integerToChar)
+
+             , ("pack", pack)
+             , ("unpack", unpack)
+             , ("unconsString", unconsString)
+             , ("lengthString", lengthString)
+             , ("appendString", appendString)
+             , ("splitString", splitString)
+             , ("regex", regexString)
+             , ("regexCg", regexStringCaptureGroup)
+
+             , ("addPrime", addPrime)
+             , ("addSubscript", addSubscript)
+             , ("addSuperscript", addSuperscript)
+
+             , ("readProcess", readProcess')
+
+             , ("read", read')
+             , ("readTsv", readTSV)
+             , ("show", show')
+             , ("showTsv", showTSV')
+
+             , ("empty?", isEmpty')
+             , ("uncons", uncons')
+             , ("unsnoc", unsnoc')
+
+             , ("bool?", isBool')
+             , ("integer?", isInteger')
+             , ("rational?", isRational')
+             , ("scalar?", isScalar')
+             , ("float?", isFloat')
+             , ("char?", isChar')
+             , ("string?", isString')
+             , ("collection?", isCollection')
+             , ("array?", isArray')
+             , ("hash?", isHash')
+             , ("tensor?", isTensor')
+             , ("tensorWithIndex?", isTensorWithIndex')
+
+             , ("assert", assert)
+             , ("assertEqual", assertEqual)
+             ]
+
 rationalUnaryOp :: (Rational -> Rational) -> PrimitiveFunc
 rationalUnaryOp op = oneArg $ \val -> do
   r <- fromEgison val
@@ -657,6 +785,35 @@
                , ("eof-port?", isEOFPort)
                , ("flush-port", flushPort)
                , ("read-file", readFile')
+
+               , ("rand", randRange)
+               , ("f.rand", randRangeDouble)
+--               , ("sqlite", sqlite)
+               ]
+
+-- For Non-S syntax
+ioPrimitives' :: [(String, PrimitiveFunc)]
+ioPrimitives' = [
+                 ("return", return')
+               , ("openInputFile", makePort ReadMode)
+               , ("openOutputFile", makePort WriteMode)
+               , ("closeInputPort", closePort)
+               , ("closeOutputPort", closePort)
+               , ("readChar", readChar)
+               , ("readLine", readLine)
+               , ("writeChar", writeChar)
+               , ("write", writeString)
+
+               , ("readCharFromPort", readCharFromPort)
+               , ("readLineFromPort", readLineFromPort)
+               , ("writeCharToPort", writeCharToPort)
+               , ("writeToPort", writeStringToPort)
+
+               , ("eof?", isEOFStdin)
+               , ("flush", flushStdout)
+               , ("eofPort?", isEOFPort)
+               , ("flushPort", flushPort)
+               , ("readFile", readFile')
 
                , ("rand", randRange)
                , ("f.rand", randRangeDouble)
diff --git a/hs-src/Language/Egison/Types.hs b/hs-src/Language/Egison/Types.hs
--- a/hs-src/Language/Egison/Types.hs
+++ b/hs-src/Language/Egison/Types.hs
@@ -34,6 +34,9 @@
     , PrimitiveFunc (..)
     , EgisonData (..)
     , showTSV
+    , EgisonBinOp(..)
+    , BinOpAssoc(..)
+    , reservedBinops
     -- * Egison values
     , EgisonValue (..)
     , ScalarData (..)
@@ -154,6 +157,7 @@
     , isHash'
     , readUTF8File
     , stringToVar
+    , stringToVarExpr
     , varToVarWithIndices
     , EgisonOpts (..)
     , defaultOption
@@ -164,7 +168,6 @@
 import           Control.Exception
 import           Data.Typeable
 
-import           Control.Applicative
 import           Control.Monad.Except
 import           Control.Monad.Fail
 import           Control.Monad.Identity
@@ -176,26 +179,23 @@
 import qualified Data.Array                as Array
 import           Data.Foldable             (foldr, toList)
 import           Data.Hashable             (Hashable)
-import qualified Data.HashMap.Lazy         as HL
 import           Data.HashMap.Strict       (HashMap)
 import qualified Data.HashMap.Strict       as HashMap
 import           Data.IORef
-import           Data.Map                  (Map)
 import           Data.Monoid               (Monoid)
 import           Data.Sequence             (Seq)
 import qualified Data.Sequence             as Sq
 import qualified Data.Vector               as V
 
-import           Data.List                 (any, delete, deleteBy, elem,
-                                            elemIndex, find, findIndex,
-                                            intercalate, partition, sort,
-                                            sortBy, splitAt, (\\))
+import           Data.List                 (any, delete, elem, elemIndex, find,
+                                            findIndex, intercalate, partition,
+                                            splitAt, (\\))
 import           Data.List.Split           (splitOn)
-import           Data.Text                 (Text, pack)
+import           Data.Text                 (Text)
 import qualified Data.Text                 as T
 
 import           Data.Ratio
-import           Numeric
+import           Numeric                   (showFFloat)
 import           System.IO
 
 import           System.IO.Unsafe          (unsafePerformIO)
@@ -228,10 +228,10 @@
   | SubrefsExpr Bool EgisonExpr EgisonExpr
   | SuprefsExpr Bool EgisonExpr EgisonExpr
   | UserrefsExpr Bool EgisonExpr EgisonExpr
-  | PowerExpr EgisonExpr EgisonExpr
+  | PowerExpr EgisonExpr EgisonExpr           -- TODO: delete this in v4.0.0
   | InductiveDataExpr String [EgisonExpr]
   | TupleExpr [EgisonExpr]
-  | CollectionExpr [InnerExpr]
+  | CollectionExpr [InnerExpr]                -- TODO: InnerExpr should be EgisonExpr from v4.0.0
   | ArrayExpr [EgisonExpr]
   | HashExpr [(EgisonExpr, EgisonExpr)]
   | VectorExpr [EgisonExpr]
@@ -264,18 +264,20 @@
   | QuoteExpr EgisonExpr
   | QuoteSymbolExpr EgisonExpr
 
-  | WedgeExpr EgisonExpr
-  | WedgeApplyExpr EgisonExpr EgisonExpr
+  | WedgeExpr EgisonExpr                         -- Desugared to WedgeApplyExpr
+  | WedgeApplyExpr EgisonExpr EgisonExpr         -- Appears after desugar
 
   | DoExpr [BindingExpr] EgisonExpr
   | IoExpr EgisonExpr
 
+  | UnaryOpExpr String EgisonExpr
+  | BinaryOpExpr EgisonBinOp EgisonExpr EgisonExpr
+
   | SeqExpr EgisonExpr EgisonExpr
   | ApplyExpr EgisonExpr EgisonExpr
   | CApplyExpr EgisonExpr EgisonExpr
   | PartialExpr Integer EgisonExpr
   | PartialVarExpr Integer
-  | RecVarExpr
 
   | GenerateArrayExpr EgisonExpr (EgisonExpr, EgisonExpr)
   | ArrayBoundsExpr EgisonExpr
@@ -323,6 +325,7 @@
 type MatchClause = (EgisonPattern, EgisonExpr)
 type MatcherInfo = [(PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])]
 
+-- TODO(momohatt): AndPat and OrPat take only 2 arguments in new syntax
 data EgisonPattern =
     WildCard
   | PatVar Var
@@ -373,6 +376,52 @@
   | PDConstantPat EgisonExpr
  deriving (Show, Eq)
 
+data EgisonBinOp
+  = EgisonBinOp { repr     :: String  -- syntastic representation
+                , func     :: String  -- semantics
+                , priority :: Int
+                , assoc    :: BinOpAssoc
+                , isWedge  :: Bool    -- True if operator is prefixed with '!'
+                }
+  deriving (Eq, Ord)
+
+data BinOpAssoc
+  = LeftAssoc
+  | RightAssoc
+  | NonAssoc
+  deriving (Eq, Ord)
+
+instance Show EgisonBinOp where
+  show op = repr op
+
+instance Show BinOpAssoc where
+  show LeftAssoc  = "infixl"
+  show RightAssoc = "infixr"
+  show NonAssoc   = "infix"
+
+reservedBinops :: [EgisonBinOp]
+reservedBinops =
+  [ makeBinOp "^"  "**"        8 LeftAssoc
+  , makeBinOp "*"  "*"         7 LeftAssoc
+  , makeBinOp "/"  "/"         7 LeftAssoc
+  , makeBinOp "%"  "remainder" 7 LeftAssoc
+  , makeBinOp "+"  "+"         6 LeftAssoc
+  , makeBinOp "-"  "-"         6 LeftAssoc
+  , makeBinOp "++" "append"    5 RightAssoc
+  , makeBinOp ":"  "cons"      5 RightAssoc
+  , makeBinOp "==" "eq?"       4 LeftAssoc
+  , makeBinOp "<=" "lte?"      4 LeftAssoc
+  , makeBinOp ">=" "gte?"      4 LeftAssoc
+  , makeBinOp "<"  "lt?"       4 LeftAssoc
+  , makeBinOp ">"  "gt?"       4 LeftAssoc
+  , makeBinOp "&&" "and"       3 RightAssoc
+  , makeBinOp "||" "or"        2 RightAssoc
+  ]
+  where
+    makeBinOp r f p a =
+      EgisonBinOp { repr = r, func = f, priority = p, assoc = a, isWedge = False }
+
+
 --
 -- Values
 --
@@ -439,11 +488,9 @@
   _ == _ = False
 
 instance Eq TermExpr where
-  (Term a []) == (Term b [])
-    | a /= b =  False
-    | otherwise = True
+  (Term a []) == (Term b []) = a == b
   (Term a ((Quote x, n):xs)) == (Term b ys)
-    | (a /= b) && (a /= negate b) =  False
+    | (a /= b) && (a /= negate b) = False
     | otherwise = case elemIndex (Quote x, n) ys of
                     Just i -> let (hs, _:ts) = splitAt i ys in
                                 Term a xs == Term b (hs ++ ts)
@@ -454,7 +501,7 @@
                                                else Term (negate a) xs == Term b (hs ++ ts)
                                  Nothing -> False
   (Term a (x:xs)) == (Term b ys)
-    | (a /= b) && (a /= negate b) =  False
+    | (a /= b) && (a /= negate b) = False
     | otherwise = case elemIndex x ys of
                     Just i -> let (hs, _:ts) = splitAt i ys in
                                 Term a xs == Term b (hs ++ ts)
@@ -527,9 +574,10 @@
                                       ) js))
 symbolExprToEgison (Apply fn mExprs, n) = Tuple [InductiveData "Apply" [fn, Collection (Sq.fromList (map mathExprToEgison mExprs))], toEgison n]
 symbolExprToEgison (Quote mExpr, n) = Tuple [InductiveData "Quote" [mathExprToEgison mExpr], toEgison n]
-symbolExprToEgison (FunctionData name argnames args js, n) = case name of
-                                                               Nothing -> Tuple [InductiveData "Function" [symbolScalarData "" "", Collection (Sq.fromList argnames), Collection (Sq.fromList args), f js], toEgison n]
-                                                               Just name' -> Tuple [InductiveData "Function" [name', Collection (Sq.fromList argnames), Collection (Sq.fromList args), f js], toEgison n]
+symbolExprToEgison (FunctionData name argnames args js, n) =
+  case name of
+    Nothing -> Tuple [InductiveData "Function" [symbolScalarData "" "", Collection (Sq.fromList argnames), Collection (Sq.fromList args), f js], toEgison n]
+    Just name' -> Tuple [InductiveData "Function" [name', Collection (Sq.fromList argnames), Collection (Sq.fromList args), f js], toEgison n]
  where
   f js = Collection (Sq.fromList (map (\case
                                           Superscript k -> InductiveData "Sup" [ScalarData k]
@@ -1202,6 +1250,12 @@
   show (TupleExpr exprs) = "[" ++ unwords (map show exprs) ++ "]"
   show (CollectionExpr ls) = "{" ++ unwords (map show ls) ++ "}"
 
+  show (UnaryOpExpr op e) = op ++ " " ++ show e
+  show (BinaryOpExpr op e1 e2) = "(" ++ show e1 ++ " " ++ show op ++ " " ++ show e2 ++ ")"
+
+  show (QuoteExpr e) = "'" ++ show e
+  show (QuoteSymbolExpr e) = "`" ++ show e
+
   show (ApplyExpr fn (TupleExpr [])) = "(" ++ show fn ++ ")"
   show (ApplyExpr fn (TupleExpr args)) = "(" ++ show fn ++ " " ++ unwords (map show args) ++ ")"
   show (ApplyExpr fn arg) = "(" ++ show fn ++ " " ++ show arg ++ ")"
@@ -1652,6 +1706,7 @@
   | NotImplemented String CallStack
   | Assertion String CallStack
   | Parser String
+  | ParserUnexpectedEOF
   | EgisonBug String CallStack
   | MatchFailure String CallStack
   | Default String
@@ -1674,8 +1729,9 @@
   show (NotImplemented message stack) = "Not implemented: " ++ message ++ showTrace stack
   show (Assertion message stack) = "Assertion failed: " ++ message ++ showTrace stack
   show (Parser err) = "Parse error at: " ++ err
+  show  ParserUnexpectedEOF = "Parser error: unexpected end of input"
   show (EgisonBug message stack) = "Egison Error: " ++ message ++ showTrace stack
-  show (MatchFailure currentFunc stack) = "Failed pattern match at: " ++ currentFunc ++ showTrace stack
+  show (MatchFailure currentFunc stack) = "Failed pattern match in: " ++ currentFunc ++ showTrace stack
   show (Default message) = "Error: " ++ message
 
 showTrace :: CallStack -> String
@@ -1728,9 +1784,9 @@
   return result
 
 data RuntimeState = RuntimeState
-    -- | index counter for generating fresh variable
+    -- index counter for generating fresh variable
       { indexCounter :: Int
-    -- | names of called functions for improved error message
+    -- names of called functions for improved error message
       , funcNameStack :: [String]
       }
 
@@ -1953,6 +2009,9 @@
 stringToVar :: String -> Var
 stringToVar name = Var (splitOn "." name) []
 
+stringToVarExpr :: String -> EgisonExpr
+stringToVarExpr = VarExpr . stringToVar
+
 varToVarWithIndices :: Var -> VarWithIndices
 varToVarWithIndices (Var xs is) = VarWithIndices xs $ map f is
  where
@@ -1983,7 +2042,7 @@
     optPrompt           :: String,
     optMathExpr         :: Maybe String,
     optSExpr            :: Bool,
-    optUseHappy         :: Bool
+    optUseNonS2         :: Bool
     }
 
 defaultOption :: EgisonOpts
diff --git a/hs-src/Language/Egison/Util.hs b/hs-src/Language/Egison/Util.hs
--- a/hs-src/Language/Egison/Util.hs
+++ b/hs-src/Language/Egison/Util.hs
@@ -6,13 +6,16 @@
 This module provides utility functions.
 -}
 
-module Language.Egison.Util (getEgisonExpr, getEgisonExprOrNewLine, completeEgison) where
+module Language.Egison.Util
+  ( getEgisonExpr
+  , completeEgison
+  ) where
 
 import           Control.Monad.Except             (liftIO)
 import           Data.List
 import           System.Console.Haskeline         hiding (catch, handle, throwTo)
 import           System.Console.Haskeline.History (addHistoryUnlessConsecutiveDupe)
-import           Text.Regex.TDFA
+import           Text.Regex.TDFA                  ((=~))
 
 import           Language.Egison.Parser           as Parser
 import           Language.Egison.ParserNonS       as ParserNonS
@@ -38,7 +41,7 @@
       history <- getHistory
       putHistory $ addHistoryUnlessConsecutiveDupe line history
       let input = prev ++ line
-      let parsedExpr = (if optUseHappy opts then ParserNonS2.parseTopExpr else if optSExpr opts then Parser.parseTopExpr else ParserNonS.parseTopExpr) input
+      let parsedExpr = (if optUseNonS2 opts then ParserNonS2.parseTopExpr else 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"
@@ -46,29 +49,6 @@
           liftIO $ print err
           getEgisonExpr opts
         Right topExpr -> return $ Just (input, topExpr)
-
--- |Get Egison expression from the prompt. We can handle multiline input.
-getEgisonExprOrNewLine :: EgisonOpts -> InputT IO (Either (Maybe String) (String, EgisonTopExpr))
-getEgisonExprOrNewLine opts = getEgisonExprOrNewLine' opts ""
-
-getEgisonExprOrNewLine' :: EgisonOpts -> String -> InputT IO (Either (Maybe String) (String, EgisonTopExpr))
-getEgisonExprOrNewLine' opts prev = do
-  mLine <- case prev of
-             "" -> getInputLine $ optPrompt opts
-             _  -> getInputLine $ replicate (length $ optPrompt opts) ' '
-  case mLine of
-    Nothing -> return $ Left Nothing
-    Just [] -> return $ Left $ Just ""
-    Just line -> do
-      let input = prev ++ line
-      let parsedExpr = (if optUseHappy opts then ParserNonS2.parseTopExpr else if optSExpr opts then Parser.parseTopExpr else ParserNonS.parseTopExpr) input
-      case parsedExpr of
-        Left err | show err =~ "unexpected end of input" ->
-          getEgisonExprOrNewLine' opts $ input ++ "\n"
-        Left err -> do
-          liftIO $ print err
-          getEgisonExprOrNewLine opts
-        Right topExpr -> return $ Right (input, topExpr)
 
 -- |Complete Egison keywords
 completeEgison :: Monad m => CompletionFunc m
diff --git a/lib/core/order.egi b/lib/core/order.egi
--- a/lib/core/order.egi
+++ b/lib/core/order.egi
@@ -91,3 +91,10 @@
        [[<cons $x $txs> <cons ?1#(eq? (f %1 x) <Greater>) _>] {x @(merge txs ys)}]
        [[_ <cons $y $tys>] {y @(merge xs tys)}]})))
 
+(define $minimize
+  (lambda [$f $xs]
+    (foldl 2#(if (eq? (compare (f %1) (f %2)) <Less>) %1 %2) (car xs) (cdr xs))))
+
+(define $maximize
+  (lambda [$f $xs]
+    (foldl 2#(if (eq? (compare (f %1) (f %2)) <Greater>) %1 %2) (car xs) (cdr xs))))
diff --git a/lib/core/string.egi b/lib/core/string.egi
--- a/lib/core/string.egi
+++ b/lib/core/string.egi
@@ -97,19 +97,19 @@
 ;;
 ;; Alphabet
 ;;
-(define $c.between
+(define $C.between
   (lambda [$c1 $c2]
     (map itoc (between (ctoi c1) (ctoi c2)))))
 
-(define $c.between?
+(define $C.between?
   (lambda [$c1 $c2 $c]
     (and (gte? (ctoi c) (ctoi c1))
          (lte? (ctoi c) (ctoi c2)))))
 
 (define $alphabet?
   (lambda [$c]
-    (or (c.between? c#a c#z c)
-        (c.between? c#A c#Z c))))
+    (or (C.between? c#a c#z c)
+        (C.between? c#A c#Z c))))
 
 (define $alphabets?
   (lambda [$s]
@@ -117,12 +117,12 @@
 
 (define $upper-case
   (lambda [$c]
-    (if (c.between? c#a c#z c)
+    (if (C.between? c#a c#z c)
       (itoc (- (ctoi c) 32))
       c)))
 
 (define $lower-case
   (lambda [$c]
-    (if (c.between? c#A c#Z c)
+    (if (C.between? c#A c#Z c)
       (itoc (+ (ctoi c) 32))
       c)))
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -15,31 +15,75 @@
 
 import           Language.Egison
 import           Language.Egison.Core
-import           Language.Egison.Parser
+import qualified Language.Egison.Parser         as Parser
+import qualified Language.Egison.ParserNonS2    as ParserNonS2
 import           Language.Egison.Primitives
 import           Language.Egison.Types
 
+main :: IO ()
 main = do
-  (sampleTestCases, unitTestCases) <- partition (isSubsequenceOf "answer" . show) <$> glob "test/**/*.egi"
-  defaultMain $ hUnitTestToTests $ test $ map runUnitTestCase unitTestCases ++ map runSampleTestCase sampleTestCases
+  let unitTests     = map runUnitTestCase     unitTestCases
+      unitNonSTests = map runUnitTestCaseNonS unitNonSTestCases
+      sampleTests   = map runSampleTestCase   sampleTestCases
+   in defaultMain . hUnitTestToTests . test $ unitNonSTests ++ unitTests ++ sampleTests
 
+unitTestCases :: [FilePath]
+unitTestCases =
+  [ "test/syntax.egi"
+  , "test/primitive.egi"
+  , "test/lib/math/analysis.egi"
+  , "test/lib/math/tensor.egi"
+  , "test/lib/math/arithmetic.egi"
+  , "test/lib/math/algebra.egi"
+  , "test/lib/core/string.egi"
+  , "test/lib/core/base.egi"
+  , "test/lib/core/collection.egi"
+  , "test/lib/core/order.egi"
+  , "test/lib/core/number.egi"
+  ]
+
+unitNonSTestCases :: [FilePath]
+unitNonSTestCases =
+  [
+--    "nons-test/test/syntax.egi"
+--  , "nons-test/test/primitive.egi"
+--  , "nons-test/test/lib/core/base.egi"
+--  , "nons-test/test/lib/core/order.egi"
+  ]
+
+sampleTestCases :: [FilePath]
+sampleTestCases =
+  [ "test/answer/sample/poker-hands-with-joker.egi"
+  , "test/answer/sample/primes.egi"
+  , "test/answer/sample/mahjong.egi"
+  , "test/answer/sample/poker-hands.egi"
+  , "test/answer/sample/math/geometry/riemann-curvature-tensor-of-S2.egi"
+  , "test/answer/sample/math/number/17th-root-of-unity.egi"
+  ]
+
 runUnitTestCase :: FilePath -> Test
 runUnitTestCase file = TestLabel file . TestCase $ do
   env <- initialEnv defaultOption
   assertEgisonM $ do
-    exprs <- loadFile file
+    exprs <- Parser.loadFile file
     let (bindings, tests) = foldr collectDefsAndTests ([], []) exprs
     env' <- recursiveBind env bindings
     forM_ tests $ evalExprDeep env'
-      where
-        assertEgisonM :: EgisonM a -> Assertion
-        assertEgisonM m = fromEgisonM m >>= assertString . either show (const "")
+  where
+    assertEgisonM :: EgisonM a -> Assertion
+    assertEgisonM m = fromEgisonM m >>= assertString . either show (const "")
 
-        collectDefsAndTests (Define name expr) (bindings, tests) =
-          ((name, expr) : bindings, tests)
-        collectDefsAndTests (Test expr) (bindings, tests) =
-          (bindings, expr : tests)
-        collectDefsAndTests _ r = r
+runUnitTestCaseNonS :: FilePath -> Test
+runUnitTestCaseNonS file = TestLabel file . TestCase $ do
+  env <- initialEnv (defaultOption { optUseNonS2 = True })
+  assertEgisonM $ do
+    exprs <- ParserNonS2.loadFile file
+    let (bindings, tests) = foldr collectDefsAndTests ([], []) exprs
+    env' <- recursiveBind env bindings
+    forM_ tests $ evalExprDeep env'
+  where
+    assertEgisonM :: EgisonM a -> Assertion
+    assertEgisonM m = fromEgisonM m >>= assertString . either show (const "")
 
 runSampleTestCase :: FilePath -> Test
 runSampleTestCase file = TestLabel file . TestCase $ do
@@ -47,26 +91,26 @@
   let directory_path = takeDirectory file
   answers <- readFile file
   assertEgisonM (lines answers) $ do
-    exprs <- loadFile (replaceDirectory file $ concat $ drop 2 $ splitPath directory_path)
+    exprs <- Parser.loadFile (replaceDirectory file $ concat $ drop 2 $ splitPath directory_path)
     let (bindings, tests) = foldr collectDefsAndTests ([], []) exprs
     env' <- recursiveBind env bindings
     vals <- forM tests (evalExprDeep env')
     return $ zip tests vals
-      where
-        assertEgisonM :: [String] -> EgisonM [(EgisonExpr, EgisonValue)] -> Assertion
-        assertEgisonM answers m = fromEgisonM m >>= assertString . either show (f answers)
-
-        collectDefsAndTests (Define name expr) (bindings, tests) =
-          ((name, expr) : bindings, tests)
-        collectDefsAndTests (Test expr) (bindings, tests) =
-          (bindings, expr : tests)
-        collectDefsAndTests _ r = r
+  where
+    assertEgisonM :: [String] -> EgisonM [(EgisonExpr, EgisonValue)] -> Assertion
+    assertEgisonM answers m = fromEgisonM m >>= assertString . either show (f answers)
 
-        f :: [String] -> [(EgisonExpr, EgisonValue)] -> String
-        f answers ls = g answers ls 0
-        g x y i = let (e, v) = unzip y in
-                  if (x !! i) == show (v !! i)
-                     then (if i < (length y - 1) then g x y (i + 1)
-                                                 else "")
-                     else "failed " ++ show (e !! i) ++ "\n expected: " ++ (x !! i) ++ "\n but found: " ++ show (v !! i)
+    f :: [String] -> [(EgisonExpr, EgisonValue)] -> String
+    f answers ls = g answers ls 0
+    g x y i = let (e, v) = unzip y in
+              if (x !! i) == show (v !! i)
+                 then (if i < (length y - 1) then g x y (i + 1)
+                                             else "")
+                 else "failed " ++ show (e !! i) ++ "\n expected: " ++ (x !! i) ++ "\n but found: " ++ show (v !! i)
 
+collectDefsAndTests :: EgisonTopExpr -> ([(Var, EgisonExpr)], [EgisonExpr]) -> ([(Var, EgisonExpr)], [EgisonExpr])
+collectDefsAndTests (Define name expr) (bindings, tests) =
+  ((name, expr) : bindings, tests)
+collectDefsAndTests (Test expr) (bindings, tests) =
+  (bindings, expr : tests)
+collectDefsAndTests _ r = r
