1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
(* op : binary operator *)
type op = Plus | Minus | Times | Divide

(* op_to_string : op -> string *)
let op_to_string op = match op with
    Plus -> " + "
  | Minus -> " - "
  | Times -> " * "
  | Divide -> " / "

(* e : syntax *)
type e = Num of int
       | Var of string
       | Op of e * op * e
       | Fun of string * e
       | App of e * e
       | Shift of string * e
       | Control of string * e
       | Shift0 of string * e
       | Control0 of string * e
       | Reset of e

(* to_string : e -> string *)
let rec to_string exp = match exp with
    Num (n) -> string_of_int n
  | Var (x) -> x
  | Op (e0, op, e1) ->
    "(" ^ to_string e0 ^ op_to_string op ^ to_string e1 ^ ")"
  | Fun (x, e) ->
    "(fun " ^ x ^ " -> " ^ to_string e ^ ")"
  | App (e0, e1) ->
    "(" ^ to_string e0 ^ " " ^ to_string e1 ^ ")"
  | Shift (x, e) ->
    "(shift " ^ x ^ " -> " ^ to_string e ^ ")"
  | Control (x, e) ->
    "(control " ^ x ^ " -> " ^ to_string e ^ ")"
  | Shift0 (x, e) ->
    "(shift0 " ^ x ^ " -> " ^ to_string e ^ ")"
  | Control0 (x, e) ->
    "(control0 " ^ x ^ " -> " ^ to_string e ^ ")"
  | Reset (e) ->
    "reset (" ^ to_string e ^ ")"

(* print : e -> unit *)
let print exp =
  let str = to_string exp in
  print_string str