New OCaml exercise.
This commit is contained in:
parent
b88b92d33c
commit
8c50463ec4
1 changed files with 71 additions and 0 deletions
71
ocaml/EvalCBVExercise.ml
Normal file
71
ocaml/EvalCBVExercise.ml
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
(* -------------------------------------------------------------------------- *)
|
||||||
|
|
||||||
|
(* The type of lambda-terms, in de Bruijn's representation. *)
|
||||||
|
|
||||||
|
type var = int (* a de Bruijn index *)
|
||||||
|
type term =
|
||||||
|
| Var of var
|
||||||
|
| Lam of (* bind: *) term
|
||||||
|
| App of term * term
|
||||||
|
| Let of (* bind: *) term * term
|
||||||
|
|
||||||
|
(* -------------------------------------------------------------------------- *)
|
||||||
|
|
||||||
|
(* An environment-based big-step interpreter. This is the same interpreter
|
||||||
|
that we programmed in Coq, except here, in OCaml, fuel is not needed. *)
|
||||||
|
|
||||||
|
type cvalue =
|
||||||
|
| Clo of (* bind: *) term * cenv
|
||||||
|
|
||||||
|
and cenv =
|
||||||
|
cvalue list
|
||||||
|
|
||||||
|
let empty : cenv =
|
||||||
|
[]
|
||||||
|
|
||||||
|
exception RuntimeError
|
||||||
|
|
||||||
|
let lookup (e : cenv) (x : var) : cvalue =
|
||||||
|
try
|
||||||
|
List.nth e x
|
||||||
|
with Failure _ ->
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
let rec eval (e : cenv) (t : term) : cvalue =
|
||||||
|
match t with
|
||||||
|
| Var x ->
|
||||||
|
lookup e x
|
||||||
|
| Lam t ->
|
||||||
|
Clo (t, e)
|
||||||
|
| App (t1, t2) ->
|
||||||
|
let cv1 = eval e t1 in
|
||||||
|
let cv2 = eval e t2 in
|
||||||
|
let Clo (u1, e') = cv1 in
|
||||||
|
eval (cv2 :: e') u1
|
||||||
|
| Let (t1, t2) ->
|
||||||
|
eval (eval e t1 :: e) t2
|
||||||
|
|
||||||
|
(* -------------------------------------------------------------------------- *)
|
||||||
|
|
||||||
|
(* The CPS-transformed interpreter. *)
|
||||||
|
|
||||||
|
let rec evalk (e : cenv) (t : term) (k : cvalue -> 'a) : 'a =
|
||||||
|
assert false
|
||||||
|
|
||||||
|
let eval (e : cenv) (t : term) : cvalue =
|
||||||
|
evalk e t (fun cv -> cv)
|
||||||
|
|
||||||
|
(* -------------------------------------------------------------------------- *)
|
||||||
|
|
||||||
|
(* The CPS-transformed, defunctionalized interpreter. *)
|
||||||
|
|
||||||
|
type kont
|
||||||
|
|
||||||
|
let rec evalkd (e : cenv) (t : term) (k : kont) : cvalue =
|
||||||
|
assert false
|
||||||
|
|
||||||
|
and apply (k : kont) (cv : cvalue) : cvalue =
|
||||||
|
assert false
|
||||||
|
|
||||||
|
let eval e t =
|
||||||
|
evalkd e t (assert false)
|
Loading…
Reference in a new issue