csci2041/repo-zhan4854/Hwk_04/arithmetic.ml
Michael Zhang 399845160c
f
2018-01-29 17:35:31 -06:00

68 lines
2.4 KiB
OCaml

type expr
= Const of int
| Add of expr * expr
| Mul of expr * expr
| Sub of expr * expr
| Div of expr * expr
let rec show_expr (e:expr): string =
match e with
| Const i -> string_of_int i
| Add (a, b) -> "(" ^ (show_expr a) ^ "+" ^ (show_expr b) ^ ")"
| Mul (a, b) -> "(" ^ (show_expr a) ^ "*" ^ (show_expr b) ^ ")"
| Sub (a, b) -> "(" ^ (show_expr a) ^ "-" ^ (show_expr b) ^ ")"
| Div (a, b) -> "(" ^ (show_expr a) ^ "/" ^ (show_expr b) ^ ")"
let rec show_pretty_expr (e:expr): string =
let add_sub_left (e:expr): bool =
match e with
| Const i -> false
| Add (a, b) -> false
| Sub (a, b) -> false
| Mul (a, b) -> false
| Div (a, b) -> false in
let mul_div_left (e:expr): bool =
match e with
| Const i -> false
| Add (a, b) -> true
| Sub (a, b) -> true
| Mul (a, b) -> false
| Div (a, b) -> false in
let needs_paren_left (e:expr): bool =
match e with
| Const i -> raise (Failure "This shouldn't be called here.")
| Add (a, b) -> add_sub_left a
| Sub (a, b) -> add_sub_left a
| Mul (a, b) -> mul_div_left a
| Div (a, b) -> mul_div_left a in
let add_sub_right (add:bool) (e:expr): bool =
match e with
| Const i -> false
| Add (a, b) -> add
| Sub (a, b) -> true
| Mul (a, b) -> false
| Div (a, b) -> false in
let mul_div_right (mul:bool) (e:expr): bool =
match e with
| Const i -> false
| Add (a, b) -> true
| Sub (a, b) -> true
| Mul (a, b) -> mul
| Div (a, b) -> true in
let needs_paren_right (e:expr): bool =
match e with
| Const i -> raise (Failure "This shouldn't be called here.")
| Add (a, b) -> add_sub_right true b
| Sub (a, b) -> add_sub_right false b
| Mul (a, b) -> mul_div_right true b
| Div (a, b) -> mul_div_right false b in
let wrap (b:bool) (s:bytes): bytes =
(if b then "(" else "") ^ s ^ (if b then ")" else "") in
match e with
| Const i -> string_of_int i
| Add (a, b) -> wrap (needs_paren_left e) (show_pretty_expr a) ^ "+" ^ wrap (needs_paren_right e) (show_pretty_expr b)
| Sub (a, b) -> wrap (needs_paren_left e) (show_pretty_expr a) ^ "-" ^ wrap (needs_paren_right e) (show_pretty_expr b)
| Mul (a, b) -> wrap (needs_paren_left e) (show_pretty_expr a) ^ "*" ^ wrap (needs_paren_right e) (show_pretty_expr b)
| Div (a, b) -> wrap (needs_paren_left e) (show_pretty_expr a) ^ "/" ^ wrap (needs_paren_right e) (show_pretty_expr b)