Advertisement
Guest User

Untitled

a guest
Apr 27th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.18 KB | None | 0 0
  1. (* Requires: OCaml 4.03.0+ *)
  2. (* Usage: `ocaml eff.ml` *)
  3.  
  4. (** Identifiers *)
  5. module Ident = struct
  6. type t = string
  7.  
  8. let id = ref 0
  9.  
  10. let create base =
  11. incr id;
  12. base ^ "_" ^ (string_of_int !id)
  13.  
  14. module Map = Map.Make (struct
  15. type nonrec t = t
  16. let compare = String.compare
  17. end)
  18.  
  19. end
  20.  
  21. (* Our lambda calculus, which is standard lambda-calculus, plus:
  22.  
  23. - atoms;
  24. - primitives: basically ocaml functions, applied to λ-terms.
  25. The arguments are guaranteed to be reduced before being given
  26. to the function;
  27. - effects primitives: handle & perform.
  28. *)
  29.  
  30. type term = ..
  31.  
  32. type atom =
  33. | Unit
  34. | Int of int
  35. | String of string
  36.  
  37. and handlers = {
  38. hv: Ident.t * term; (* Value *)
  39. hx: Ident.t * term; (* Exception *)
  40. hf: Ident.t * Ident.t * term (* Effect *)
  41. }
  42.  
  43. (* A runtime value: a closure of a term with its environment.
  44.  
  45. It is defined now as primitives can access and modify the runtime
  46. environment; and thus take it as an argument and return it.
  47. *)
  48. and value = Closure of environment * term
  49. and environment = value Ident.Map.t
  50.  
  51. type term +=
  52. | Var of Ident.t
  53. | Lambda of Ident.t * term
  54. | App of term * term
  55. | Atom of atom
  56. | Prim of string * (term list -> term) * term list
  57. | Handle of term * handlers
  58. | Perform of term
  59. | Raise of term
  60.  
  61.  
  62.  
  63. (* Helpers ********************************************************************)
  64.  
  65. (* Lambda and App constructors are the simplest possible. To define
  66. lambdas with multiple identifiers at the same time, or application
  67. with multiple arguments, use the [lam] and [app] helpers.
  68. *)
  69.  
  70. let lam (idents: Ident.t list) (body: term): term =
  71. List.fold_right (fun id acc -> Lambda (id, acc)) idents body
  72.  
  73. let app (f: term) (args: term list): term =
  74. let hd, args = (List.hd args), (List.tl args) in
  75. List.fold_left (fun acc arg -> App (acc, arg)) (App (f, hd)) args
  76.  
  77. let rec seq : term list -> term = function
  78. | [] -> Atom Unit
  79. | [e] -> e
  80. | e :: es ->
  81. let dummy = Ident.create "_" in
  82. App (Lambda (dummy, seq es), e)
  83.  
  84. let letin (x: Ident.t) (e1: term) (e2: term): term =
  85. App (Lambda (x, e2), e1)
  86.  
  87. (* Helpers for building atomic terms. *)
  88.  
  89. let int (x: int): term = Atom (Int x)
  90. let string (s: string): term = Atom (String s)
  91. let unit : term = Atom Unit
  92.  
  93. (* Effects wrappers. *)
  94. let handle body handlers = Handle (body, handlers)
  95.  
  96. let delegate =
  97. let ve = Ident.create "ve" in
  98. let vk = Ident.create "vk" in
  99. ve, vk, App (Var vk, Perform (Var ve))
  100.  
  101. let continue k v = App (k, v)
  102.  
  103. (* Printers. *)
  104.  
  105. let print_atom ppf = function
  106. | Unit -> Format.fprintf ppf "()"
  107. | Int i -> Format.fprintf ppf "%d" i
  108. | String s -> Format.fprintf ppf "%s" s
  109.  
  110. let print_t ppf =
  111. let open Format in
  112. let rec aux paren ppf = function
  113. | Var x -> fprintf ppf "%s" x
  114. | Lambda (x, e) ->
  115. fprintf ppf "@[<2>%s%a%s@]"
  116. (if paren then "(" else "")
  117. (aux_lambda [x]) e
  118. (if paren then ")" else "")
  119.  
  120. | App (u, v) ->
  121. fprintf ppf "@[<2>%s%a%s@]"
  122. (if paren then "(" else "")
  123. (aux_app [v]) u
  124. (if paren then ")" else "")
  125.  
  126. | Atom a -> print_atom ppf a
  127. | Prim (name, f, args) ->
  128. fprintf ppf "@[<2>%s%s%a%s@]"
  129. (if paren then "(" else "")
  130. name
  131. (fun ppf _ ->
  132. List.iter (fun arg -> fprintf ppf "@ %a" (aux false) arg) args)
  133. ()
  134. (if paren then ")" else "")
  135.  
  136. | Perform e ->
  137. fprintf ppf "@[<2>%sperform@ %a%s@]"
  138. (if paren then "(" else "")
  139. (aux false) e
  140. (if paren then ")" else "")
  141.  
  142. | Handle (body, {hv = (v, hv); hx = (x, hx); hf = (e, k, hf)}) ->
  143. fprintf ppf "@[<2>%s%a@ with@ %s@ ->@ %a@ |@ exn@ %s@ ->@ %a@ |@ effect@ %s@ %s@ ->@ %a%s@]"
  144. (if paren then "(" else "")
  145. (aux true) body
  146. v (aux false) hv x (aux false) hx e k (aux false) hf
  147. (if paren then ")" else "")
  148.  
  149. | Raise e ->
  150. fprintf ppf "@[<2>%sraise@ %a%s@]"
  151. (if paren then "(" else "")
  152. (aux false) e
  153. (if paren then ")" else "")
  154.  
  155. | _ -> failwith "aux : unknown term"
  156.  
  157. and aux_lambda idents ppf = function
  158. | Lambda (i, e) -> aux_lambda (i :: idents) ppf e
  159. | e ->
  160. fprintf ppf "λ";
  161. List.iter (fun id -> fprintf ppf "@ %s" id) (List.rev idents);
  162. fprintf ppf ".@ %a" (aux false) e
  163.  
  164. and aux_app args ppf = function
  165. | App (u, v) -> aux_app (v :: args) ppf u
  166. | e ->
  167. fprintf ppf "%a"
  168. (aux true) e;
  169. List.iter (fun arg -> fprintf ppf "@ %a" (aux true) arg) args
  170. in
  171. aux false ppf
  172.  
  173. (* Printing primitives. *)
  174.  
  175. let debug = ref true
  176.  
  177. let printl t =
  178. let f = function
  179. | [t] when !debug ->
  180. Format.(fprintf str_formatter "%a\n%!" print_t t);
  181. unit
  182. | [t] -> Format.printf "%a\n%!" print_t t; unit
  183. | _ as l ->
  184. Printf.printf "printl.args_length = %d\n%!" (List.length l);
  185. List.iter (fun t -> Format.printf "%a\n%!" print_t t) l;
  186. raise (Invalid_argument "printl")
  187. in
  188. Prim ("printl", f, [t])
  189.  
  190. (* CPS transform **************************************************************)
  191.  
  192. (* Variable substitution. Only used to perform administrative
  193. reductions. *)
  194. let rec subst map e =
  195. match e with
  196. | Var x -> (try Ident.Map.find x map with Not_found -> e)
  197. | Lambda (x, e) -> Lambda (x, subst map e)
  198. | App (u, v) -> App (subst map u, subst map v)
  199. | Prim (name, f, args) -> Prim (name, f, List.map (subst map) args)
  200. | _ -> e
  201.  
  202. let rec cps e =
  203. let k = Ident.create "k" in
  204.  
  205. (* [cont e c] "continues" term [e] with continuation [c].
  206.  
  207. It is semantically equivalent to [app e [c]], but can
  208. perform some administrative reductions.
  209. *)
  210. let cont e c =
  211. let is_value = function
  212. | Var _ | Atom _ | Prim _ -> true
  213. | _ -> false
  214. in
  215.  
  216. match e with
  217. | Lambda (k, App (Var k', e')) when k = k' && is_value e' ->
  218. begin match c with
  219. | Var k -> App (Var k, e')
  220. | Lambda (x, body) ->
  221. subst Ident.Map.(add x e' empty) body
  222. | _ -> raise (Invalid_argument "cont")
  223. end
  224.  
  225. | _ -> app e [c]
  226. in
  227.  
  228. match e with
  229. | Var _ | Atom _ -> lam [k] (App (Var k, e))
  230.  
  231. | Prim (name, f, args) ->
  232. let args_idents = List.map (fun _ -> Ident.create "v") args in
  233. lam [k] @@
  234. List.fold_right (fun (arg, id) e -> cont (cps arg) (Lambda (id, e)))
  235. (List.combine args args_idents)
  236. (App (Var k, Prim (name, f, List.map (fun v -> Var v) args_idents)))
  237.  
  238.  
  239. | Lambda (x, e) -> lam [k] (App (Var k, Lambda (x, cps e)))
  240.  
  241. | App (u, v) ->
  242. let val_u = Ident.create "v" in
  243. let val_v = Ident.create "v" in
  244. lam [k] @@
  245. (cont (cps u) (lam [val_u]
  246. (cont (cps v) (lam [val_v]
  247. (cont (App (Var val_u, Var val_v)) (Var k))))))
  248.  
  249. | Handle (body, { hv = (v, hv); hx = (vx, hx); hf = (ve, vk, hf) }) ->
  250. let _1 = Ident.create "_" in
  251. let _2 = Ident.create "_" in
  252. lam [k] @@
  253. app (cps body) [lam [v; _1; _2] (cps hv);
  254. lam [vx] (cps hx);
  255. lam [ve; vk] (cps hf);
  256. Var k]
  257.  
  258. | Perform e ->
  259. let val_e = Ident.create "e" in
  260. let x = Ident.create "x" in
  261. let hx = Ident.create "hx" in
  262. let hf = Ident.create "hf" in
  263. let k' = Ident.create "k'" in
  264.  
  265. let return_k =
  266. lam [x; k'] @@ app (Var k) [Var x; Var hx; Var hf; Var k']
  267. in
  268.  
  269. lam [k] @@
  270. cont (cps e) (lam [val_e; hx; hf]
  271. (app (Var hf) [ Var val_e; return_k ]))
  272.  
  273. | Raise e ->
  274. let val_e = Ident.create "ve" in
  275. let hx = Ident.create "hx" in
  276. let hf = Ident.create "hf" in
  277. lam [k] @@
  278. cont (cps e) (lam [val_e]
  279. (lam [hx; hf] (app (Var hx) [Var val_e])))
  280.  
  281. | _ -> failwith "cps: unhandled term"
  282.  
  283. let unhandled_effect ?(cps=false) e k =
  284. let f = function
  285. | [e; k] ->
  286. Format.printf "Unhandled effect: %a\n%!" print_t e;
  287. if cps then
  288. let _k = Ident.create "_" in
  289. lam [_k] unit
  290. else unit
  291. | _ -> raise (Invalid_argument "unhandled_effect") in
  292. Prim ("unhandled_effect", f, [e; k])
  293.  
  294. let unhandled_exn ?(cps=false) e =
  295. let f = function
  296. | [e] ->
  297. Format.printf "Unhandled exception: %a\n%!" print_t e;
  298. if cps then
  299. let _k = Ident.create "_" in
  300. lam [_k] unit
  301. else unit
  302. | _ -> raise (Invalid_argument "unhandled_exn") in
  303. Prim ("unhandled_exception", f, [e])
  304.  
  305. (* CPS transformation for a toplevel term: CPS transforms it, and
  306. applies it to "identity" continuations. *)
  307. let cps_main e =
  308. Ident.id := 0;
  309. let x = Ident.create "x" in
  310. let k = Ident.create "k" in
  311. let kv = Ident.create "kv" in
  312. let _1 = Ident.create "hx" in
  313. let _2 = Ident.create "hf" in
  314. let res =
  315. app (cps e) [
  316. lam [x; _1; _2; k] (app (Var k) [Var x]);
  317. lam [x] (unhandled_exn ~cps:true (Var x));
  318. lam [x; kv] (unhandled_effect ~cps:true (Var x) (Var kv));
  319. lam [x] (Var x)
  320. ]
  321. in
  322. res
  323.  
  324. (* Interpreter ****************************************************************)
  325.  
  326. let rec eval env = function
  327. | Var v ->
  328. begin try Ident.Map.find v env
  329. with Not_found ->
  330. Printf.printf "DEBUG: %s\n%!" v;
  331. failwith "Unbound identifier"
  332. end
  333. | Lambda (_, _) | Atom _ as e -> Closure (env, e)
  334. | Prim (name, f, args) ->
  335. let args_values_r =
  336. List.fold_left (fun args_values_r arg ->
  337. let Closure (_, arg_val) = eval env arg in
  338. arg_val :: args_values_r) [] args
  339. in
  340. let ret = f (List.rev args_values_r) in
  341. eval env ret
  342. | App (u, v) ->
  343. let f = eval env u in
  344. let x = eval env v in
  345. apply f x
  346. | _ -> failwith ("not handled by the interpreter")
  347.  
  348. and apply (Closure (envu, u)) (Closure (envv, v) as cv) =
  349. match u with
  350. | Lambda (x, e) -> eval (Ident.Map.add x cv envu) e
  351. | _ ->
  352. Format.eprintf "DEBUG: %a\n" print_t u;
  353. failwith "trying to apply a value that is not a function"
  354.  
  355. (* CEK machine *******************************************************************)
  356.  
  357. module Cek_machine = struct
  358.  
  359. type nonrec environment = environment
  360.  
  361. type prim =
  362. { prim : term list -> term;
  363. todo_args : term list;
  364. done_args_r : term list }
  365.  
  366. type continuation =
  367. | Done
  368. | EvalArg of term * environment * continuation
  369. | Call of term * environment * continuation
  370. | CallPrim of prim * environment * continuation
  371. | CallRaise
  372. | CallPerform of continuation
  373.  
  374. type handler = {
  375. hv : term;
  376. hx : term;
  377. hf : term;
  378. env : environment;
  379. k : continuation
  380. }
  381.  
  382. type term += Continue of Ident.t * handler
  383.  
  384. type control = term
  385.  
  386. type machine = control * environment * handler list * continuation
  387.  
  388. type step_result =
  389. | Todo of machine
  390. | Done of value
  391.  
  392. let step : machine -> step_result = function
  393.  
  394. | Var x, e, h, k ->
  395. begin match Ident.Map.find x e with
  396. | Closure (e', t) -> Todo (t, e', h, k)
  397. | exception Not_found ->
  398. Printf.printf "Cek_machine.step.Var: %s\n%!" x;
  399. failwith "Unbound identifier"
  400. end
  401.  
  402. | App (t1,t2), e, h, k ->
  403. Todo (t1, e, h, EvalArg(t2,e,k))
  404.  
  405. | Prim (_, prim, arg::todo_args), e, h, k ->
  406. let p = {prim; todo_args; done_args_r = []} in
  407. Todo (arg, e, h, CallPrim (p, e, k))
  408.  
  409. | Handle (body, {hv = v,vv; hx = x, vx; hf = f, vk, vf}), e, h, k ->
  410. let h' = {hv = lam [v] vv; hx = lam [x] vx;
  411. hf = lam [f;vk] vf; env = e; k}
  412. in
  413. Todo (body, e, h'::h, Done)
  414.  
  415. | Continue (x, h), e, hs, k ->
  416. let e' = Ident.Map.add x (Ident.Map.find x e) h.env in
  417. Todo (Var x, e', {h with k = k; env = e}::hs, h.k)
  418.  
  419. | Raise t, e, h, k -> Todo (t, e, h, CallRaise)
  420.  
  421. | Perform t, e, h, k -> Todo (t, e, h, CallPerform k)
  422.  
  423. | Lambda (x,t), e, h, EvalArg (t',e',k) ->
  424. Todo (t', e', h, Call(Lambda(x,t), e, k))
  425.  
  426. | t, e, h, Call(Lambda(x',t'),e',k) ->
  427. let e'' = Ident.Map.add x' (Closure(e, t)) e' in
  428. Todo (t', e'', h, k)
  429.  
  430. | t, _, h, CallPrim ({prim; todo_args; done_args_r}, e', k) ->
  431. begin match todo_args with
  432. | [] -> Todo (prim (List.rev (t::done_args_r)), e', h, k)
  433. | x::xs ->
  434. let p = {prim; todo_args = xs; done_args_r = t::done_args_r} in
  435. Todo (x, e', h, CallPrim (p, e', k))
  436. end
  437.  
  438. | t, _, h::hs, CallRaise -> Todo (App (h.hx, t), h.env, hs, h.k)
  439.  
  440. | t, e, h::hs, CallPerform k ->
  441. let x = Ident.create "cv" in
  442. let cont = lam [x] (Continue (x, {h with k = k; env = e})) in
  443. Todo (app h.hf [t; cont], h.env, hs, h.k)
  444.  
  445. | t, e, [], Done -> Done (Closure (e,t))
  446.  
  447. | t, e, h::hs, Done -> Todo (App (h.hv, t), h.env, hs, h.k)
  448.  
  449. | t,_,_,_ ->
  450. Format.eprintf "DEBUG: %a\n" print_t t;
  451. failwith "Cek_machine.step: no step defined"
  452.  
  453. let default_handler =
  454. let x = Ident.create "x" in
  455. let k = Ident.create "k" in
  456. { hv = lam [x] (Var x);
  457. hx = lam [x] (unhandled_exn (Var x));
  458. hf = lam [x; k] (unhandled_effect (Var x) (Var k));
  459. env = Ident.Map.empty;
  460. k = Done}
  461.  
  462. let rec eval p =
  463. let rec loop i m =
  464. match step m with
  465. | Todo m -> loop (i+1) m
  466. | Done v -> v
  467. in
  468. loop 0 (p,Ident.Map.empty,[default_handler],Done)
  469. end
  470.  
  471. (* Examples *******************************************************************)
  472.  
  473. let eval = eval Ident.Map.empty
  474.  
  475. (* Prints a term, evaluates it, and prints the result. *)
  476. let ev t =
  477. Format.printf "%a\n" print_t t;
  478. let Closure (_, res) = eval t in
  479. Format.printf "\n>> %a\n%!" print_t res
  480.  
  481. let rec check_scope env = function
  482. | Var v -> (try Ident.Map.find v env; [] with Not_found -> [Var v])
  483. | Lambda (x, e) -> check_scope (Ident.Map.add x () env) e
  484. | App (e1, e2) ->
  485. (check_scope env e1) @ (check_scope env e2)
  486. | Atom _ -> []
  487. | Prim (_,_,_) -> []
  488. | _ -> failwith "not handled"
  489.  
  490. (* default handlers *)
  491.  
  492. let identity =
  493. let v = Ident.create "v" in
  494. v, Var v
  495.  
  496. let reraise =
  497. let vx = Ident.create "vx" in
  498. let f = function
  499. | [e] -> Raise e
  500. | _ -> raise (Invalid_argument "reraise") in
  501. vx, Prim ("reraise", f, [Var vx])
  502.  
  503. let test s p ret out =
  504. assert (!debug = true);
  505. Printf.printf "(** Test %s **)\n%!" s;
  506. let run k e p =
  507. Printf.printf "%s: %!" k;
  508. let Closure (_,x) = e p in
  509. assert (x = ret);
  510. let out_seen = (Format.flush_str_formatter ()) in
  511. assert (String.equal out out_seen);
  512. print_endline "success"
  513. in
  514. run "simple" eval (cps_main p);
  515. run "cek" Cek_machine.eval p
  516.  
  517. (** Examples *)
  518.  
  519. let ex0 =
  520. let x = Ident.create "x" in
  521. app (lam [x] (Var x)) [int 3]
  522.  
  523. let _ = test "ex0" ex0 (int 3) ""
  524.  
  525. let ex01 = int 3
  526.  
  527. let _ = test "ex01" ex01 (int 3) ""
  528.  
  529.  
  530. let ex1 =
  531. let x = Ident.create "x" in
  532. printl (app (lam [x] (Var x)) [Atom (Int 3)])
  533.  
  534. let _ = test "ex1" ex1 unit "3
  535. "
  536.  
  537. let ex11 =
  538. seq [printl (string "a"); printl (string "b")]
  539.  
  540. let _ = test "ex11" ex11 unit "a
  541. b
  542. "
  543.  
  544. let ex12 =
  545. let x = Ident.create "x" in
  546. app (lam [x] (Var x)) [app (lam [x] (Var x)) [int 3]]
  547.  
  548. let _ = test "ex12" ex12 (int 3) ""
  549.  
  550. let ex13 = Raise (int 0)
  551.  
  552. let _ = test "ex13" ex13 unit ""
  553.  
  554. let ex14 = Perform (int 0)
  555.  
  556. let _ = test "ex14" ex14 unit ""
  557.  
  558. let ex2 =
  559. seq [printl (int 3);
  560. printl (string "abc");
  561. printl (string "def")]
  562.  
  563. let _ = test "ex2" ex2 unit "3
  564. abc
  565. def
  566. "
  567.  
  568. let ex30 =
  569. let e = Ident.create "my_e" in
  570. let k = Ident.create "my_k" in
  571. handle
  572. (seq [printl (string "abc")])
  573. { hv = identity;
  574. hx = reraise;
  575. hf = e, k, continue (Var k) (int 18) }
  576.  
  577. let _ = test "ex30" ex30 unit "abc
  578. "
  579.  
  580. let ex31 =
  581. let e = Ident.create "my_e" in
  582. let k = Ident.create "my_k" in
  583. handle
  584. (seq [printl (Perform (int 0))])
  585. { hv = identity;
  586. hx = reraise;
  587. hf = e, k, int 18 }
  588.  
  589. let _ = test "ex31" ex31 (int 18) ""
  590.  
  591. let ex32 =
  592. let e = Ident.create "my_e" in
  593. let k = Ident.create "my_k" in
  594. handle
  595. (Perform (int 0))
  596. { hv = identity;
  597. hx = reraise;
  598. hf = e, k, continue (Var k) (int 18) }
  599.  
  600. let _ = test "ex32" ex32 (int 18) ""
  601.  
  602. let ex3 =
  603. let e = Ident.create "my_e" in
  604. let k = Ident.create "my_k" in
  605. handle
  606. (seq [printl (string "abc");
  607. printl (Perform (int 0));
  608. printl (string "def")])
  609. { hv = identity;
  610. hx = reraise;
  611. hf = e, k, continue (Var k) (int 18) }
  612.  
  613. let _ = test "ex3" ex3 unit "abc
  614. 18
  615. def
  616. "
  617.  
  618. let ex4 =
  619. let e = Ident.create "my_e" in
  620. let k = Ident.create "my_k" in
  621. handle
  622. (handle
  623. (seq [printl (string "abc");
  624. printl (Perform (int 0));
  625. printl (string "def")])
  626. { hv = identity;
  627. hx = reraise;
  628. hf = delegate; })
  629. { hv = identity;
  630. hx = reraise;
  631. hf = e, k, continue (Var k) (int 18) }
  632.  
  633. let _ = test "ex4" ex4 unit "abc
  634. 18
  635. def
  636. "
  637.  
  638. let ex5 =
  639. let e = Ident.create "my_e" in
  640. let k = Ident.create "my_k" in
  641. handle
  642. (seq [printl (string "abc");
  643. printl (Perform (int 0));
  644. printl (string "def")])
  645. { hv = identity;
  646. hx = reraise;
  647. hf = e, k, seq [continue (Var k) (int 18);
  648. printl (string "handler end")] }
  649.  
  650. let _ = test "ex5" ex5 unit "abc
  651. 18
  652. def
  653. handler end
  654. "
  655.  
  656. let ex6 =
  657. seq [
  658. handle unit
  659. { hv = identity;
  660. hx = reraise;
  661. hf = delegate; };
  662. printl (string "abc")
  663. ]
  664.  
  665. let _ = test "ex6" ex6 unit "abc
  666. "
  667.  
  668. let ex7 =
  669. let e = Ident.create "my_e" in
  670. let k = Ident.create "my_k" in
  671. let v = Ident.create "my_v" in
  672. handle
  673. (seq [Perform unit; Perform unit])
  674. { hv = v, seq [printl (string "hv"); Var v];
  675. hx = reraise;
  676. hf = e, k, seq [
  677. printl (string "hf1");
  678. continue (Var k) unit;
  679. printl (string "hf2")
  680. ]
  681. }
  682.  
  683. let _ = test "ex7" ex7 unit "hf1
  684. hf1
  685. hv
  686. hf2
  687. hf2
  688. "
  689.  
  690. let ex8 =
  691. let e = Ident.create "my_e" in
  692. let k = Ident.create "my_k" in
  693. handle
  694. (seq [printl (string "a");
  695. printl (Perform (int 0));
  696. printl (string "b")])
  697. { hv = identity;
  698. hx = reraise;
  699. hf = e, k, continue (seq [printl ex31; Var k]) (int 19) }
  700.  
  701. let _ = test "ex8" ex8 unit "a
  702. 18
  703. 19
  704. b
  705. "
  706.  
  707. (* Evaluates to 1 *)
  708. let ex9 =
  709. let e = Ident.create "my_e" in
  710. let k = Ident.create "my_k" in
  711. let v = Ident.create "my_v" in
  712. handle
  713. (handle
  714. (Perform unit)
  715. { hv = identity;
  716. hx = v, int 0;
  717. hf = e, k, Raise unit; };)
  718. { hv = identity;
  719. hx = v, int 1;
  720. hf = delegate; }
  721.  
  722. let _ = test "ex9" ex9 (int 1) ""
  723.  
  724. let ex10 =
  725. let v = Ident.create "my_v" in
  726. let e = Ident.create "my_e" in
  727. let k = Ident.create "my_k" in
  728. printl
  729. (handle
  730. (handle
  731. unit
  732. { hv = v, Perform unit;
  733. hx = reraise;
  734. hf = delegate })
  735. { hv = v, printl (Var v);
  736. hx = reraise;
  737. hf = e, k, int 3 }
  738. )
  739.  
  740. let _ = test "ex10" ex10 unit "3
  741. "
  742.  
  743. let debug = ref false
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement