calculator 0.2.0.0 → 0.2.0.1
raw patch · 5 files changed
+40/−20 lines, 5 files
Files
- calculator.cabal +1/−1
- src/Calculator/Evaluator/Expr.hs +4/−2
- src/Calculator/Parser/Base.hs +1/−3
- src/Calculator/Parser/Expr.hs +27/−13
- src/Calculator/Prim/Definitions.hs +7/−1
calculator.cabal view
@@ -1,5 +1,5 @@ name: calculator-version: 0.2.0.0+version: 0.2.0.1 synopsis: A calculator repl. description: A calculator repl that processes mathematical expressions. Does basic arithmetic, and provides pre-defined basic mathematical functions.
src/Calculator/Evaluator/Expr.hs view
@@ -9,11 +9,13 @@ -------------------------------------------------------------------------------- --- evalExpr b (UnOp (UnaryOp op) e) = Constant . op . fromConst $ evalExpr b e- evalExpr :: Bindings -> Expr -> Expr evalExpr _ e@(Constant _) = e evalExpr _ e@(Message _) = e+evalExpr b (UnOp (UnaryOp op) e) =+ case evalExpr b e of+ Constant z -> Constant (op z)+ _ -> Message ["Negating invalid expression"] evalExpr b (BinOp (e, r)) = process b e r evalExpr b (Variable s) = case getVar s b of
src/Calculator/Parser/Base.hs view
@@ -10,11 +10,9 @@ parseNumber :: Parser Double parseNumber = read <$> do- neg <- optionMaybe (char '-') dec <- many1 digit flt <- option "" (liftM2 (:) (char '.') (many1 digit))- return $ let num = dec ++ flt- in maybe num (:num) neg+ return $ dec ++ flt --------------------------------------------------------------------------------
src/Calculator/Parser/Expr.hs view
@@ -3,7 +3,7 @@ -------------------------------------------------------------------------------- import Calculator.Parser.Base (parseId, parseNumber)-import Calculator.Prim.Definitions (binaryOps)+import Calculator.Prim.Definitions (unaryOps, binaryOps) import Calculator.Prim.Expr (Expr (..), Operator, constEq) --------------------------------------------------------------------------------@@ -18,9 +18,9 @@ parseExpr = do term <- parseTerm rest <- parseRestExpr- if null rest- then return term- else return $ BinOp (term, rest)+ return $ if null rest+ then term+ else BinOp (term, rest) parseRestExpr :: Parser [(Operator, Expr)] parseRestExpr = many $ do@@ -36,9 +36,9 @@ parseTerm = do fact <- parseFact rest <- parseRestTerm- if null rest- then return fact- else return $ BinOp (fact, rest)+ return $ if null rest+ then fact+ else BinOp (fact, rest) parseRestTerm :: Parser [(Operator, Expr)] parseRestTerm = many $ do@@ -55,9 +55,9 @@ parseFact = do val <- parseVal pow <- parsePower- if constEq (Constant 1) (snd pow)- then return val- else return $ BinOp (val, [pow])+ return $ if constEq (Constant 1) (snd pow)+ then val+ else BinOp (val, [pow]) parsePower :: Parser (Operator, Expr) parsePower = let (Just op) = lookup '^' binaryOps@@ -67,11 +67,25 @@ return (op, fact) ----------------------------------------------------------------------------------- val -> ( expr ) | func ( expr ) | var | number+-- Unary operators+-- val -> $? val' parseVal :: Parser Expr-parseVal = parseBrackets <|> parseCall <|> parseVariable <|> parseConstant+parseVal = do+ ch <- optionMaybe $ oneOf (map fst unaryOps)+ v <- parseVal'+ return $ if ch == Nothing+ then v+ else let Just c = ch+ Just op = lookup c unaryOps+ in UnOp op v +--------------------------------------------------------------------------------+-- val' -> ( expr ) | func ( expr ) | var | number+ +parseVal' :: Parser Expr+parseVal' = parseBrackets <|> parseCall <|> parseVariable <|> parseConstant+ parseBrackets :: Parser Expr parseBrackets = do _ <- try (char '(')@@ -88,7 +102,7 @@ parseCall :: Parser Expr parseCall = do ident <- try (parseId <* char '(')- args <- (parseExpr `sepBy` char ',') <* char ')'+ args <- parseExpr `sepBy` char ',' <* char ')' return $ Call ident args --------------------------------------------------------------------------------
src/Calculator/Prim/Definitions.hs view
@@ -1,5 +1,6 @@ module Calculator.Prim.Definitions - ( binaryOps+ ( unaryOps+ , binaryOps , defVars , defFuns , defBinds@@ -14,6 +15,11 @@ -------------------------------------------------------------------------------- import Control.Arrow (second)++--------------------------------------------------------------------------------++unaryOps :: [(Char, Operator)]+unaryOps = [ ('-', UnaryOp negate) ] --------------------------------------------------------------------------------