Skip to content

Commit 126dc73

Browse files
committed
🚧 Pluggable recorder module for the interpreter
1 parent 813d881 commit 126dc73

File tree

14 files changed

+170
-46
lines changed

14 files changed

+170
-46
lines changed

bin/js/dune

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(executable
2+
(name main)
3+
(modes js)
4+
(preprocess
5+
(pps ppx_jane js_of_ocaml-ppx))
6+
(libraries react_trace base logs logs.fmt fmt fmt.tty js_of_ocaml))

bin/js/main.ml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
open! Core
2+
open React_trace
3+
4+
let position (lexbuf : Lexing.lexbuf) : string =
5+
let open Lexing in
6+
let pos = lexbuf.lex_curr_p in
7+
sprintf "%s:%d:%d" pos.pos_fname pos.pos_lnum (pos.pos_cnum - pos.pos_bol + 1)
8+
9+
let parse_with_error (lexbuf : Lexing.lexbuf) : Syntax.Prog.t =
10+
Parser.prog Lexer.read lexbuf
11+
12+
let parse_program_str (program_str : string) : (Syntax.Prog.t, string) result =
13+
let lexbuf = Lexing.from_string program_str in
14+
match parse_with_error lexbuf with
15+
| prog -> Ok prog
16+
| exception Parser.Error ->
17+
Error (sprintf "%s: syntax error" (position lexbuf))
18+
19+
let () =
20+
Fmt_tty.setup_std_outputs ();
21+
Logs.set_reporter (Logs_fmt.reporter ());
22+
Logs.set_level (Some Logs.Info);
23+
24+
let open Js_of_ocaml in
25+
Js.export_all
26+
(object%js
27+
method run (fuel : int) program_str =
28+
(let open Result.Let_syntax in
29+
let%bind prog = parse_program_str program_str in
30+
let Interp.{ recording; _ } =
31+
Interp.run
32+
?fuel:(if fuel < 1 then None else Some fuel)
33+
~recorder:(module Recorder)
34+
prog
35+
in
36+
if Logs.err_count () > 0 then Error "error" else Ok recording)
37+
|> (function Ok s -> s | Error s -> s)
38+
|> Js.string
39+
end)

bin/js/recorder.ml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
open Stdlib.Effect
2+
open Stdlib.Effect.Deep
3+
open React_trace
4+
include Recorder_intf
5+
6+
(* TODO: Replace the dummy string with an actual recording type *)
7+
type recording = string
8+
9+
let emp_recording = "empty recording"
10+
11+
let event_h =
12+
{
13+
retc = (fun v ~recording -> (v, recording));
14+
exnc = raise;
15+
effc =
16+
(fun (type a) (eff : a t) ->
17+
match eff with
18+
| Evt_update_st (path, label, (v, q)) ->
19+
Some
20+
(fun (k : (a, _) continuation) ~(recording : recording) ->
21+
ignore (path, label, v, q);
22+
continue k () ~recording)
23+
| Evt_set_dec (path, dec) ->
24+
Some
25+
(fun (k : (a, _) continuation) ~(recording : recording) ->
26+
ignore (path, dec);
27+
continue k () ~recording)
28+
| Evt_enq_eff (path, clos) ->
29+
Some
30+
(fun (k : (a, _) continuation) ~(recording : recording) ->
31+
ignore (path, clos);
32+
continue k () ~recording)
33+
| Evt_alloc_pt path ->
34+
Some
35+
(fun (k : (a, _) continuation) ~(recording : recording) ->
36+
ignore path;
37+
continue k () ~recording)
38+
| _ -> None);
39+
}

bin/js/recorder.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include React_trace.Recorder_intf.Intf with type recording = string
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
(executable
22
(public_name react_trace)
33
(name main)
4-
(modes exe js)
54
(preprocess
65
(pps ppx_jane))
76
(libraries react_trace base logs logs.fmt fmt fmt.tty))

bin/main.ml renamed to bin/native/main.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ let () =
7474
Sexp.pp_hum Stdlib.Format.std_formatter (Syntax.Prog.sexp_of_t prog)
7575
else
7676
let { Interp.steps; _ } =
77-
Interp.run ?fuel:!opt_fuel ~report:!opt_report prog
77+
Interp.run ?fuel:!opt_fuel ~report:!opt_report
78+
~recorder:(module Default_recorder)
79+
prog
7880
in
7981
printf "\nSteps: %d\n" steps;
8082
Stdlib.exit (if Logs.err_count () > 0 then 1 else 0))

dune-project

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
(ocaml-base-compiler
2828
(= 5.2.0))
2929
core
30-
js_of_ocaml-compiler
30+
js_of_ocaml
31+
js_of_ocaml-ppx
3132
flow_parser
3233
fmt
3334
logs

lib/default_recorder.ml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
open Stdlib.Effect
2+
open Stdlib.Effect.Deep
3+
include Recorder_intf
4+
5+
type recording = unit
6+
7+
let emp_recording = ()
8+
9+
let event_h =
10+
{
11+
retc = (fun v ~recording -> (v, recording));
12+
exnc = raise;
13+
effc =
14+
(fun (type a) (eff : a t) ->
15+
match eff with
16+
| Evt_update_st (path, label, (v, q)) ->
17+
Some
18+
(fun (k : (a, _) continuation) ~(recording : recording) ->
19+
ignore (path, label, v, q);
20+
continue k () ~recording)
21+
| Evt_set_dec (path, dec) ->
22+
Some
23+
(fun (k : (a, _) continuation) ~(recording : recording) ->
24+
ignore (path, dec);
25+
continue k () ~recording)
26+
| Evt_enq_eff (path, clos) ->
27+
Some
28+
(fun (k : (a, _) continuation) ~(recording : recording) ->
29+
ignore (path, clos);
30+
continue k () ~recording)
31+
| Evt_alloc_pt path ->
32+
Some
33+
(fun (k : (a, _) continuation) ~(recording : recording) ->
34+
ignore path;
35+
continue k () ~recording)
36+
| _ -> None);
37+
}

lib/default_recorder.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include Recorder_intf.Intf

lib/interp.ml

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -572,10 +572,16 @@ let step_path (path : Path.t) : bool =
572572

573573
has_updates
574574

575-
type run_info = { steps : int; mem : Memory.t; treemem : Tree_mem.t }
576-
577-
let run ?(fuel : int option) ?(report : bool = false) (prog : Prog.t) : run_info
578-
=
575+
type 'recording run_info = {
576+
steps : int;
577+
mem : Memory.t;
578+
treemem : Tree_mem.t;
579+
recording : 'recording;
580+
}
581+
582+
let run (type recording) ?(fuel : int option) ?(report : bool = false)
583+
~(recorder : (module Recorder_intf.Intf with type recording = recording))
584+
(prog : Prog.t) : recording run_info =
579585
Logger.run prog;
580586

581587
let driver () =
@@ -592,9 +598,15 @@ let run ?(fuel : int option) ?(report : bool = false) (prog : Prog.t) : run_info
592598
loop ();
593599
!cnt
594600
in
601+
602+
let driver () =
603+
let open (val recorder) in
604+
match_with driver () event_h ~recording:emp_recording
605+
in
595606
(* TODO: Integrate Report_box with (WIP) Recorder API *)
596607
let driver () = try_with driver () (Report_box.log_h report) in
608+
597609
let driver () = match_with driver () treemem_h ~treemem:Tree_mem.empty in
598610
let driver () = match_with driver () mem_h ~mem:Memory.empty in
599-
let (steps, treemem), mem = driver () in
600-
{ steps; mem; treemem }
611+
let ((steps, recording), treemem), mem = driver () in
612+
{ steps; mem; treemem; recording }

0 commit comments

Comments
 (0)