packages feed

calculator-0.1.4.0: src/Calculator/Evaluator/Base.hs

module Calculator.Evaluator.Base (evaluate) where

--------------------------------------------------------------------------------

import           Calculator.Evaluator.Statement (evalStat)
import           Calculator.Parser.Statement    (parseStat)
import           Calculator.Prim.Expr           (Bindings, Expr (..))

--------------------------------------------------------------------------------

import           Control.Applicative            ((<*))
import           Data.List                      (nub)
import           Text.ParserCombinators.Parsec  (eof, parse)

--------------------------------------------------------------------------------

eval :: Bindings -> String -> Either Expr Bindings
eval b inp = case parse (parseStat <* eof) "Statement" inp of
              Left e  -> Left . InvalidError . tail . lines $ show e
              Right s -> evalStat b s

--------------------------------------------------------------------------------

result :: Either Expr Bindings -> Either String Bindings
result e =
  case e of
   Left (Constant c)     -> Left $ " == " ++ show c
   Left (InvalidError x) -> Left . init . unlines . map (" !! " ++ ) . nub $ x
   Right b               -> Right b
   Left _                -> Left " ~~ Erroneous Result ~~"

--------------------------------------------------------------------------------

evaluate :: Bindings -> String -> Either String Bindings
evaluate b s = result $ eval b s

--------------------------------------------------------------------------------