let rec eval_expr_int e =
match e.expr_val with
| Int i -> i
| Var(v, []) when is_some v.var_def ->
(
match (get_some v.var_def).def_value with
| Constant c -> eval_expr_int c
| _ -> raise (Parse_error("internal error in eval_expr_int function (trying to compute a non-integer expression)", e.expr_pos))
)
| Uminus e -> -(eval_expr_int e)
| Plus(e1, e2) -> (eval_expr_int e1) + (eval_expr_int e2)
| Minus(e1, e2) -> (eval_expr_int e1) - (eval_expr_int e2)
| Mult(e1, e2) -> (eval_expr_int e1) * (eval_expr_int e2)
| Div(e1, e2) -> (eval_expr_int e1) / (eval_expr_int e2)
| Mod(e1, e2) -> (eval_expr_int e1) mod (eval_expr_int e2)
| Not _ | And _ | Or _ | Neq _ | Eq _ | Le _ | Lt _ | Bool _
-> raise (Parse_error("internal error in eval_expr_int function (trying to compute a non-integer expression)", e.expr_pos))
| Bang _ | Address_of _ | Rec _ | Arr _ | Var _ | New _
-> raise (Parse_error("internal error in eval_expr_int function (trying to compute a non-constant expression)", e.expr_pos))
and eval_expr_bool e =
match e.expr_val with
| Bool b -> b
| Var(v, []) when is_some v.var_def ->
(
match (get_some v.var_def).def_value with
| Constant c -> eval_expr_bool c
| _ -> raise (Parse_error("internal error in eval_expr_bool function (trying to compute a non-boolean expression)", e.expr_pos))
)
| Le(e1, e2) -> (eval_expr_int e1) <= (eval_expr_int e2)
| Lt(e1, e2) -> (eval_expr_int e1) < (eval_expr_int e2)
| Eq(e1, e2) ->
(
match e1.expr_type with
| Integer -> (eval_expr_int e1) = (eval_expr_int e2)
| Boolean -> (eval_expr_bool e1) = (eval_expr_bool e2)
| _ -> raise (Parse_error("internal error in eval_expr_bool function (equality can only be computed between integers or booleans)", e.expr_pos))
)
| Neq(e1, e2) ->
(
match e1.expr_type with
| Integer -> (eval_expr_int e1) <> (eval_expr_int e2)
| Boolean -> (eval_expr_bool e1) <> (eval_expr_bool e2)
| _ -> raise (Parse_error("internal error in eval_expr_bool function (inequality can only be computed between integers or booleans)", e.expr_pos))
)
| Not e -> not (eval_expr_bool e)
| Or(e1, e2) -> (eval_expr_bool e1) || (eval_expr_bool e2)
| And(e1, e2) -> (eval_expr_bool e1) && (eval_expr_bool e2)
| _ -> raise (Parse_error("internal error in eval_expr_bool function (trying to compute a non-boolean expression)", e.expr_pos))