Skip to content

Commit

Permalink
Moved EvalValue to Evaluate
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasPietzschmann committed Jul 17, 2024
1 parent 58e895d commit 762a678
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 14 deletions.
6 changes: 1 addition & 5 deletions src/Math/Haskellator.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-- | Calculator module for evaluating mathematical expressions containing SI units

module Math.Haskellator (EvalValue, calculate) where
module Math.Haskellator (calculate) where

import Control.Monad

Expand All @@ -9,12 +9,8 @@ import Math.Haskellator.Internal.AstProcessingSteps.Normalize
import Math.Haskellator.Internal.Expr
import Math.Haskellator.Internal.Lexer
import Math.Haskellator.Internal.Parser
import Math.Haskellator.Internal.Units
import Math.Haskellator.Internal.Utils.Error

-- | The specific 'Value' type returned by the evaluation
type EvalValue = Value Dimension

getAst :: String -> Either Error Expr
getAst = scan >=> parse >=> normalize

Expand Down
22 changes: 13 additions & 9 deletions src/Math/Haskellator/Internal/AstProcessingSteps/Evaluate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
-- | Evaluate the expression tree to a numeric value and a dimension.

module Math.Haskellator.Internal.AstProcessingSteps.Evaluate (
evaluate
EvalValue
, evaluate
, execute
, mergeUnits
, subtractUnits
Expand All @@ -18,25 +19,28 @@ import Math.Haskellator.Internal.Operators
import Math.Haskellator.Internal.Units
import Math.Haskellator.Internal.Utils.Error

-- | The specific 'Value' type returned by the evaluation
type EvalValue = Value Dimension

-- | Evaluate an expression tree to a numeric value
evaluate :: Expr -- ^ the expression tree to evaluate
-> Either Error Double -- ^ the numeric result or an error
evaluate expr = execute expr <&> value

-- | Determine the result (value and dimension) of an expression tree
execute :: Expr -- ^ the expression tree to evaluate
-> Either Error (Value Dimension) -- ^ the result or an error
-> Either Error EvalValue -- ^ the result or an error
execute expr = do
r <- runAstFold $ execute' expr
return $ r { unit = filterZeroPower $ unit r }

execute' :: Expr -> SimpleAstFold (Value Dimension)
execute' :: Expr -> SimpleAstFold EvalValue
execute' = partiallyFoldExprM execVal execBinOp execUnaryOp execConversion execVarBinds execVar

execVal :: Value Dimension -> SimpleAstFold (Value Dimension)
execVal :: EvalValue -> SimpleAstFold EvalValue
execVal = return

execBinOp :: Value Dimension -> Op -> Value Dimension -> SimpleAstFold (Value Dimension)
execBinOp :: EvalValue -> Op -> EvalValue -> SimpleAstFold EvalValue
execBinOp lhs Plus rhs | unit lhs == unit rhs = return $ combineValues (+) lhs rhs
| otherwise = throwError $ Error RuntimeError $ "Cannot add units " ++ show (unit lhs) ++ " and " ++ show (unit rhs)
execBinOp lhs Minus rhs | unit lhs == unit rhs = return $ combineValues (-) lhs rhs
Expand All @@ -54,20 +58,20 @@ execBinOp lhs Pow rhs = case rhs of
_ -> throwError $ Error RuntimeError "Exponentiation of units is not supported"
execBinOp _ op _ = throwError $ Error ImplementationError $ "Unknown binary operator " ++ show op

execUnaryOp :: Op -> Value Dimension -> SimpleAstFold (Value Dimension)
execUnaryOp :: Op -> EvalValue -> SimpleAstFold EvalValue
execUnaryOp op rhs = case op of
UnaryMinus -> return $ mapValue (0-) rhs
_ -> throwError $ Error ImplementationError $ "Unknown unary operator " ++ show op

execConversion :: Value Dimension -> Dimension -> SimpleAstFold (Value Dimension)
execConversion :: EvalValue -> Dimension -> SimpleAstFold EvalValue
execConversion _ _ = throwError $ Error ImplementationError "Conversion is handled elsewhere"

execVarBinds :: Bindings Expr -> Expr -> SimpleAstFold (Value Dimension)
execVarBinds :: Bindings Expr -> Expr -> SimpleAstFold EvalValue
execVarBinds bs expr = runInNewScope $ do
bindVars $ fmap Expr <$> bs
execute' expr

execVar :: String -> SimpleAstFold (Value Dimension)
execVar :: String -> SimpleAstFold EvalValue
execVar n = getVarBinding n >>= \case
(Result v) -> return v
(Expr e) -> do
Expand Down

0 comments on commit 762a678

Please sign in to comment.