1 (* calc2.ml: calc1.ml enhanced with Function Values *)
5 | Multiplication of (term * term)
6 | Addition of (term * term)
8 | Let of (char * term * term)
10 | If of (term * term * term)
11 | Makepair of (term * term)
13 | Lambda of (char * term)
14 | Apply of (term * term)
17 type bound_value = expressed_value
18 and assignment = (char * bound_value) list
19 and expressed_value = Int of int | Bool of bool | Pair of expressed_value * expressed_value | Closure of char * term * assignment;;
21 let rec eval (t : term) (g : assignment) = match t with
22 Intconstant x -> Int x
23 | Multiplication (t1, t2) ->
24 (* we don't handle cases where the subterms don't evaluate to Ints *)
25 let Int i1 = eval t1 g
26 in let Int i2 = eval t2 g
27 (* Multiplication (t1, t2) should evaluate to an Int *)
29 | Addition (t1, t2) ->
30 let Int i1 = eval t1 g
31 in let Int i2 = eval t2 g
34 (* we don't handle cases where g doesn't bind var to any value *)
36 | Let (var_to_bind, t2, t3) ->
37 (* evaluate t3 under a new assignment where var_to_bind has been bound to
38 the result of evaluating t1 under the current assignment *)
39 let value2 = eval t2 g
40 in let g' = (var_to_bind, value2) :: g
43 (* we don't handle cases where t1 doesn't evaluate to an Int *)
44 let Int i1 = eval t1 g
45 (* Iszero t1 should evaluate to a Bool *)
48 (* we don't handle cases where t1 doesn't evaluate to a boolean *)
49 let Bool b1 = eval t1 g
50 in if b1 then eval t2 g
52 | Makepair (t1, t2) ->
53 let value1 = eval t1 g
54 in let value2 = eval t2 g
55 in Pair (value1, value2)
57 (* we don't handle cases where t1 doesn't evaluate to a Pair *)
58 let Pair (value1, value2) = eval t1 g
60 | Lambda (arg_var, t2) -> Closure (arg_var, t2, g)
62 (* we don't handle cases where t1 doesn't evaluate to a function value *)
63 let Closure (arg_var, body, savedg) = eval t1 g
64 in let value2 = eval t2 g
65 (* evaluate body under savedg, except with arg_var bound to value2 *)
66 in let savedg' = (arg_var, value2) :: savedg