Val.t) list let rec find env s = match env with | [] -> failwith "Not found" | (s',v)::env' -> if s = s' then v else find env' s end let rec eval env e = match e with | Exp.Int n -> Val.Int n | Exp.Var s -> Env.find env s | Exp.Call(e1, e2) -> let v1 = eval env e1 in let v2 = eval env e2 in call v1 v2 module Exp = struct type t = | Int of int | Var of string | Call of t * t end module Val = struct type t = | Int of int | Op of string * (Val.t -> Val.t) end
with | Exp.Int n -> cont (Val.Int n) | Exp.Var s -> cont (Env.find env s) | Exp.Call(e1, e2) -> let cont’ v = let cont’’ w = cont (call v w) in eval env cont’’ e2 in eval env cont’ e1
with | Exp.Int n -> apply_cont env cont (Val.Int n) | Exp.Var s -> apply_cont env cont (Env.find env s) | Exp.Call(e1, e2) -> eval env (Cont.Call1(e2)::cont) e1 and apply_cont env cont v = match cont with | [] -> v | Cont.Call1(e)::cont' -> eval env (Cont.Call2(v)::cont') e | Cont.Call2(v')::cont' -> apply_cont env cont' (call v' v) module Cont = struct type t' = | Call1 of Exp.t | Call2 of Val.t type t = t' list end