Files
oplevel/examples.ml

232 lines
4.5 KiB
OCaml

(** Overview *)
let x = 10 + 10
let y = x * 3
let c = String.make x 'a'
let sin1 = sin 1.
let rec fact n = if n = 0 then 1. else float n *. fact (n - 1)
let _ = Printf.printf "fact 20 = %f\n" (fact 20)
let _ = "abc" < "def"
(** Mutually recursive function *)
let rec even n =
match n with
| 0 -> true
| x -> odd (x - 1)
and odd n =
match n with
| 0 -> false
| x -> even (x - 1)
(** Mutually recursive module *)
module rec Odd : sig
val odd : int -> bool
end = struct
let odd x = if x = 0 then false else Even.even (pred x)
end
and Even : sig
val even : int -> bool
end = struct
let even x = if x = 0 then true else Odd.odd (pred x)
end
(** Reactive dom *)
open Js_of_ocaml
open Js_of_ocaml_lwt
open Js_of_ocaml_tyxml
let display x =
Dom.appendChild (Dom_html.getElementById "output") (Tyxml_js.To_dom.of_element x)
module RList = ReactiveData.RList
let rl, rhandle = RList.create []
let li_rl = RList.map (fun x -> Tyxml_js.Html.(li [ txt x ])) rl
let ul_elt = Tyxml_js.R.Html.ul li_rl
let init =
let _ = RList.snoc "# cons \"some string\"" rhandle in
let _ = RList.snoc "# snoc \"some other\"" rhandle in
let _ = RList.snoc "# insert \"anywhere\" 1" rhandle in
let _ = RList.snoc "# remove 1" rhandle in
()
let snoc s = RList.snoc s rhandle
let cons s = RList.cons s rhandle
let insert s pos = RList.insert s pos rhandle
let remove pos = RList.remove pos rhandle
let time_signal =
let s, set = React.S.create (Sys.time ()) in
let rec loop () : unit Lwt.t =
set (Sys.time ());
Lwt.bind (Lwt_js.sleep 1.) loop
in
Lwt.async loop;
s
let div_elt =
Tyxml_js.(
Html.(
div
[ h4
[ txt "Uptime is "
; R.Html.txt
(React.S.map (fun s -> string_of_int (int_of_float s)) time_signal)
; txt " s"
]
; ul_elt
]))
let _ = display div_elt
(** Graphics: Draw *)
open Graphics_js
let () =
loop [ Mouse_motion ] (function { mouse_x = x; mouse_y = y } -> fill_circle x y 5)
(** Graphics: Draw chars*)
open Graphics_js
let () =
loop [ Mouse_motion; Key_pressed ] (function
| { key = '\000'; _ } -> ()
| { mouse_x = x; mouse_y = y; key } ->
moveto x y;
draw_char key)
(** Graphics: PingPong *)
open Js_of_ocaml_lwt
open Graphics_js
let c = 3
let x0 = 0
and x1 = size_x ()
and y0 = 0
and y1 = size_y ()
let draw_ball x y =
set_color foreground;
fill_circle x y c
let state = ref (Lwt.task ())
let wait () = fst !state
let rec pong_aux x y dx dy =
draw_ball x y;
let new_x = x + dx and new_y = y + dy in
let new_dx = if new_x - c <= x0 || new_x + c >= x1 then -dx else dx
and new_dy = if new_y - c <= y0 || new_y + c >= y1 then -dy else dy in
Lwt.bind (wait ()) (fun () -> pong_aux new_x new_y new_dx new_dy)
let rec start () =
let t = Lwt.task () in
let _, w = !state in
state := t;
clear_graph ();
Lwt.wakeup w ();
Lwt.bind (Lwt_js.sleep (1. /. 60.)) start
let pong x y dx dy = pong_aux x y dx dy
let _ = pong 111 87 2 3
let _ = pong 28 57 5 3
let _ = start ()
(** Effect handler *)
module Txn : sig
type 'a t
val atomically : (unit -> unit) -> unit
val ref : 'a -> 'a t
val ( ! ) : 'a t -> 'a
val ( := ) : 'a t -> 'a -> unit
end = struct
open Effect
open Effect.Deep
type 'a t = 'a ref
type _ Effect.t += Update : 'a t * 'a -> unit Effect.t
let atomically f =
let comp =
match_with
f
()
{ retc = (fun x _ -> x)
; exnc =
(fun e rb ->
rb ();
raise e)
; effc =
(fun (type a) (e : a Effect.t) ->
match e with
| Update (r, v) ->
Some
(fun (k : (a, _) continuation) rb ->
let old_v = !r in
r := v;
continue k () (fun () ->
r := old_v;
rb ()))
| _ -> None)
}
in
comp (fun () -> ())
let ref = ref
let ( ! ) = ( ! )
let ( := ) r v = perform (Update (r, v))
end
let example () =
let open Txn in
let exception Res of int in
let r = ref 10 in
Printf.printf "T0: %d\n" !r;
try
atomically (fun () ->
r := 20;
r := 21;
Printf.printf "T1: Before abort %d\n" !r;
raise (Res !r) |> ignore;
Printf.printf "T1: After abort %d\n" !r;
r := 30)
with Res v ->
Printf.printf "T0: T1 aborted with %d\n" v;
Printf.printf "T0: %d\n" !r