2022-01-10 01:31:47 +09:00
|
|
|
open Ast
|
|
|
|
|
2022-01-13 01:13:41 +09:00
|
|
|
exception Invalid_type
|
|
|
|
|
2022-01-18 15:33:56 +09:00
|
|
|
let arith intf floatf a b =
|
2022-01-10 23:11:13 +09:00
|
|
|
match a, b with
|
2022-01-18 15:33:56 +09:00
|
|
|
| Int a, Int b -> begin
|
|
|
|
try Int (intf a b)
|
|
|
|
with Exit -> Float (floatf (float a) (float b))
|
|
|
|
end
|
|
|
|
| Float a, Int b -> Float (floatf a (float b))
|
|
|
|
| Int a, Float b -> Float (floatf (float a) b)
|
|
|
|
| Float a, Float b -> Float (floatf a b)
|
2022-01-13 01:13:41 +09:00
|
|
|
| _ -> raise Invalid_type
|
2022-01-10 01:31:47 +09:00
|
|
|
|
2022-01-10 23:11:13 +09:00
|
|
|
let binop_to_func = function
|
2022-01-18 15:33:56 +09:00
|
|
|
| Add -> arith Int.add Float.add
|
|
|
|
| Sub -> arith Int.sub Float.sub
|
|
|
|
| Mul -> arith Int.mul Float.mul
|
|
|
|
| Div -> arith Int.div Float.div
|
|
|
|
| Mod -> arith Int.rem Float.rem
|
|
|
|
| Exp -> arith (fun _ _ -> raise Exit) Float.pow
|
2022-01-10 23:11:13 +09:00
|
|
|
|
|
|
|
let rec eval = function
|
|
|
|
| Value v -> v
|
2022-01-10 01:31:47 +09:00
|
|
|
| Binop (l, op, r) ->
|
|
|
|
let f = binop_to_func op in
|
|
|
|
f (eval l) (eval r)
|
|
|
|
| Set_binop_pre (op, l) ->
|
2022-01-13 01:13:41 +09:00
|
|
|
let l = match eval l with Int n -> n | _ -> raise Invalid_type in
|
2022-01-11 01:05:29 +09:00
|
|
|
Hashtbl.replace Parser.precedence op l;
|
2022-01-10 23:11:13 +09:00
|
|
|
Unit
|
2022-01-11 01:05:29 +09:00
|
|
|
| Get_binop_pre op ->
|
|
|
|
Int (Hashtbl.find Parser.precedence op)
|