type typ = | Int of int | Float of float | Unit let typ_to_string = function | Int n -> Printf.sprintf "%d" n | Float n -> Printf.sprintf "%f" n | Unit -> "()" type binop = | Add | Sub | Mul | Div (* arithmetics *) | Mod (* modular operation *) | Exp (* exponentation *) let binop_to_string = function | Add -> "+" | Sub -> "-" | Mul -> "*" | Div -> "/" | Mod -> "%" | Exp -> "^" type t = | Value of typ | Binop of t * binop * t | Set_binop_pre of binop * t | Get_binop_pre of binop let value v = Value v let binop left op right = Binop (left, op, right) let set_binop_pre op pre = Set_binop_pre (op, pre) (* print ast LISP style. *) let print ast = let pr = Printf.printf in let pv v = pr "%s" @@ typ_to_string v in let rec aux = function | Value n -> pv n | Binop (left, op, right) -> begin pr "(%s " @@ binop_to_string op; aux left; pr " "; aux right; pr ")"; end | Set_binop_pre (op, pre) -> pr "(set_pre %s " (binop_to_string op); aux pre; pr ")" | Get_binop_pre op -> pr "(get_pre %s)" (binop_to_string op) in aux ast; pr "\n"