packages feed

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

module Calculator.Evaluator.Base (evaluate, evalTest) where

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

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

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

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

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

eval :: Bindings -> String -> Either Expr Bindings
eval b i = case parse (spaces >> parseStat <* spaces <* eof) "Statement" i of
             Left e  -> Left . Message . 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 (Message 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

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

evalTest :: String -> String
evalTest s = case eval (mkBind [] []) s of
               Left (Constant n) -> show n
               _                 -> ""

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