diff --git a/src/BC/Eval.hs b/src/BC/Eval.hs index 4b54076..f30b5c1 100644 --- a/src/BC/Eval.hs +++ b/src/BC/Eval.hs @@ -4,6 +4,29 @@ import BC.Types eval :: [Value] -> Value eval [x@(BInt _)] = x +eval [x@(BErr _)] = x eval [(BOp x)] = BErr ("operation " ++ x ++ " requires arguments") -eval (x:xy) = x eval [] = BOp "" +eval l = treeEval l [] [] + +treeEval :: [Value] -> [Value] -> [Value] -> Value +treeEval [] [] (num:_) = num +treeEval [] ops nums = handleOp [] ops nums +treeEval (x@(BInt _):xy) ops nums = treeEval xy ops (nums ++ [x]) +treeEval expr@(x@(BOp _):xy) ops@(op:_) nums = + if precedence x > precedence op + then treeEval xy (x:ops) nums + else handleOp expr ops nums +treeEval (x@(BOp _):xy) [] nums = treeEval xy [x] nums + +handleOp :: [Value] -> [Value] -> [Value] -> Value +handleOp expr (op:ops) (op1:(op2:nums)) = + treeEval expr ops ((evalOp op op1 op2):nums) + +evalOp :: Value -> Value -> Value -> Value +evalOp (BOp "*") (BInt x) (BInt y) = BInt $ x * y +evalOp (BOp "/") (BInt x) (BInt y) = BInt $ quot x y +evalOp (BOp "+") (BInt x) (BInt y) = BInt $ x + y +evalOp (BOp "-") (BInt x) (BInt y) = BInt $ x - y +evalOp (BOp "^") (BInt x) (BInt y) = BInt $ x ^ y +evalOp _ _ _ = BInt 0 diff --git a/src/BC/Types.hs b/src/BC/Types.hs index 412da85..b9bf2e0 100644 --- a/src/BC/Types.hs +++ b/src/BC/Types.hs @@ -11,3 +11,11 @@ instance Show Value where isErr :: Value -> Bool isErr (BErr _) = True isErr _ = False + +precedence :: Value -> Int +precedence (BOp "^") = 1 +precedence (BOp "*") = 2 +precedence (BOp "/") = 2 +precedence (BOp "-") = 1 +precedence (BOp "+") = 1 +precedence _ = 0