packages feed

calculator-0.1.2.2: src/Model/Arithmetic.hs

module Model.Arithmetic (modelEval) where

import           Calculator.Primitives              (Number)

import           Control.Applicative                ((<*))
import           Text.ParserCombinators.Parsec
import           Text.ParserCombinators.Parsec.Expr

modelEval :: String -> Either ParseError Number
modelEval = parse (expr <* eof) "expression"

expr :: Parser Number
expr = buildExpressionParser table factor <?> "Expression"

table :: [[ Operator Char st Number ]]
table = [ [ op "^" (**) AssocRight ]
        , [ op "*" (*) AssocLeft, op "/" (/) AssocLeft ]
        , [ op "+" (+) AssocLeft, op "-" (-) AssocLeft ]
        ]
  where op s f = Infix (string s >> return f)

parseFactor :: Parser Number
parseFactor = do
  _ <- char '('
  x <- expr
  _ <- char ')'
  return x

factor :: Parser Number
factor = parseFactor <|> number <?> "Simple expression"

number :: Parser Number
number = fmap read $ do
  ch <- many1 digit
  de <- option "" $ do
    dot <- char '.'
    flt <- many1 digit
    return $ dot : flt
  return $ if null de
           then ch
           else ch ++ de