#define nil list0_nil
#define cons list0_cons
#define :: list_cons0
datatype exp =
| EXPint of int | EXPopr of (string, list0 exp)
val exp1 = EXPint 1 and exp2 = EXPint 2
val exp3 = EXPopr ("+", cons (exp1, cons (exp2, nil)))
val exp4 = EXPopr ("*", cons (exp1, nil ()))
extern fun eval (e: exp): int
fun eval_add (es: list0 exp): int = case+ es of
| cons (e1, cons (e2, nil ())) => eval e1 + eval e2
| _ => begin
prerr ("eval_add: arity error"); prerr_newline (); exit {int} (1)
end
fun eval_sub (es: list0 exp): int = case+ es of
| cons (e1, cons (e2, nil ())) => eval e1 - eval e2
| _ => begin
prerr ("eval_sub: arity error"); prerr_newline (); exit {int} (1)
end
fun eval_mul (es: list0 exp): int = case+ es of
| cons (e1, cons (e2, nil ())) => eval e1 * eval e2
| _ => begin
prerr ("eval_mul: arity error"); prerr_newline (); exit {int} (1)
end
fun eval_div (es: list0 exp): int = case+ es of
| cons (e1, cons (e2, nil ())) => eval e1 / eval e2
| _ => begin
prerr ("eval_div: arity error"); prerr_newline (); exit {int} (1)
end
implement eval (e) = case+ e of
| EXPint i => i
| EXPopr (opr, es) => begin case+ opr of
| "+" => eval_add (es)
| "-" => eval_sub (es)
| "*" => eval_mul (es)
| "/" => eval_div (es)
| _ => begin
prerrf ("The operator [%s] is unrecognized.\n", @(opr)); exit {int} (1)
end end
implement main () = let
val ans3 = eval (exp3)
val () = (print "ans3 = "; print ans3; print_newline ())
val ans4 = eval (exp4)
val () = (print "ans4 = "; print ans4; print_newline ())
in
end