Skip to content

Commit fe95d6a

Browse files
authored
Merge pull request #1077 from ejgallego/vof
[fcc] Allow to save a Fleche cache .vof file
2 parents 5a9658d + 38cb698 commit fe95d6a

File tree

10 files changed

+107
-4
lines changed

10 files changed

+107
-4
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@
8181
- [fcc] New option `--trace-file` that will generate trace data for
8282
visualizing with perfetto.dev (@ejgallego, AlexJ, Gaëtan Gilbert,
8383
#1076)
84+
- [fcc] New options `--save_vof` and `--load_vof` that can save a
85+
Fleche version of a document to a `.vof` file, thus avoiding
86+
`.vo` recompilation for example when calling `fcc --plugin=...` for a given file (@ejgallego, Alexj, #, )
8487

8588
# coq-lsp 0.2.4: (W)Activation
8689
------------------------------

compiler/args.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ type t =
2828
; coq_diags_level : int
2929
(** Whether to include feedback messages in the diagnostics *)
3030
; record_comments : bool (** Record comments (experimental) *)
31+
; save_vof : bool (** Save a vof file *)
32+
; load_vof : bool (** Load a vof file instead of compiling *)
3133
}
3234

3335
let compute_default_plugins ~no_vo ~plugins =

compiler/cc.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ type t =
55
; default : Coq.Workspace.t
66
; io : Fleche.Io.CallBack.t
77
; token : Coq.Limits.Token.t
8+
; save_vof : bool
89
}

compiler/compile.ml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,22 @@ let guess_languageId file =
4949
| ".v.tex" -> "latex"
5050
| _ -> "rocq"
5151

52+
let do_save_vof ~io ~token ~doc =
53+
match Doc.save_vof ~token ~doc with
54+
| Coq.Protect.E.{ r = Coq.Protect.R.Completed (Ok ()); feedback } ->
55+
Io.Log.feedback "vof safe" feedback;
56+
Io.Report.msg ~io ~lvl:Info "vof file saved"
57+
| Coq.Protect.E.{ r = Completed (Error (User msg)); feedback }
58+
| Coq.Protect.E.{ r = Completed (Error (Anomaly msg)); feedback } ->
59+
Io.Log.feedback "vof safe" feedback;
60+
Io.Report.msg ~io ~lvl:Error "error saving vof file %a" Coq.Pp_t.pp_with
61+
msg.msg
62+
| Coq.Protect.E.{ r = Interrupted; feedback } ->
63+
Io.Log.feedback "vof safe" feedback;
64+
Io.Report.msg ~io ~lvl:Error "saving vof file interrupted"
65+
5266
let compile_file ~cc file : int =
53-
let { Cc.io; root_state; workspaces; default; token } = cc in
67+
let { Cc.io; root_state; workspaces; default; token; save_vof } = cc in
5468
Io.Report.msg ~io ~lvl:Info "compiling file %s" file;
5569
match Lang.LUri.(File.of_uri (of_string file)) with
5670
| Error _ -> 222
@@ -67,6 +81,7 @@ let compile_file ~cc file : int =
6781
save_diags_file ~doc;
6882
(* Vo file saving is now done by a plugin *)
6983
Theory.close ~uri;
84+
if save_vof then do_save_vof ~io ~token ~doc;
7085
status_of_doc doc)
7186

7287
let compile_file ~cc file : int =

compiler/driver.ml

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ let go ~int_backend args =
4747
; max_errors
4848
; coq_diags_level
4949
; record_comments
50+
; save_vof
51+
; load_vof = _
5052
} =
5153
args
5254
in
@@ -65,7 +67,44 @@ let go ~int_backend args =
6567
let workspaces = List.map make_ws roots in
6668
List.iter (log_workspace ~io) workspaces;
6769
let () = apply_config ~max_errors in
68-
let cc = Cc.{ root_state; workspaces; default; io; token } in
70+
let cc = Cc.{ root_state; workspaces; default; io; token; save_vof } in
6971
(* Initialize plugins *)
7072
plugin_init plugins;
7173
Compile.compile ~cc ~trace_file files
74+
75+
let go_vof args =
76+
let { Args.cmdline = _
77+
; roots = _
78+
; display
79+
; debug = _
80+
; files
81+
; plugins
82+
; trace_file = _
83+
; max_errors = _
84+
; coq_diags_level
85+
; record_comments = _
86+
; save_vof = _
87+
; load_vof = _
88+
} =
89+
args
90+
in
91+
let open Fleche in
92+
(* Initialize logging; we skip Rocq's init *)
93+
let fb_handler = Coq.Init.mk_fb_handler Coq.Protect.fb_queue in
94+
ignore (Feedback.add_feeder fb_handler);
95+
plugin_init plugins;
96+
let perfData = Option.is_empty fcc_test in
97+
let io = Output.init ~display ~perfData ~coq_diags_level in
98+
let in_file = List.nth files 0 in
99+
let in_vof = Filename.(remove_extension in_file) ^ ".vof" in
100+
let doc = Doc.doc_of_disk ~in_file:in_vof in
101+
Io.Report.msg ~io ~lvl:Info "vof file loaded";
102+
Io.Report.msg ~io ~lvl:Info "document has %d nodes" (List.length doc.nodes);
103+
Io.Report.msg ~io ~lvl:Info "calling plugins for [Theory.Register.Completed]";
104+
(* Call plugins for the .vof file *)
105+
let token = Coq.Limits.Token.create () in
106+
Theory.Register.Completed.fire ~io ~token ~doc;
107+
0
108+
109+
let go ~int_backend (args : Args.t) =
110+
if args.load_vof then go_vof args else go ~int_backend args

compiler/fcc.ml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ open Fcc_lib
44

55
let fcc_main int_backend roots display debug plugins trace_file files coqlib
66
findlib_config ocamlpath rload_path load_path require_libraries no_vo
7-
max_errors coq_diags_level record_comments =
7+
max_errors coq_diags_level record_comments save_vof load_vof =
88
let vo_load_path = rload_path @ load_path in
99
let args = [] in
1010
let cmdline =
@@ -29,6 +29,8 @@ let fcc_main int_backend roots display debug plugins trace_file files coqlib
2929
; max_errors
3030
; coq_diags_level
3131
; record_comments
32+
; save_vof
33+
; load_vof
3234
}
3335
in
3436
Driver.go ~int_backend args
@@ -61,6 +63,14 @@ let no_vo : bool Term.t =
6163
let doc = "Don't generate .vo files at the end of compilation" in
6264
Arg.(value & flag & info [ "no_vo" ] ~doc)
6365

66+
let save_vof : bool Term.t =
67+
let doc = "Save a .vof file with Fleche-specific metadata" in
68+
Arg.(value & flag & info [ "vof" ] ~doc)
69+
70+
let load_vof : bool Term.t =
71+
let doc = "Save a .vof file with Fleche-specific metadata" in
72+
Arg.(value & flag & info [ "load_vof" ] ~doc)
73+
6474
let max_errors : int option Term.t =
6575
let doc = "Maximum errors in files before aborting" in
6676
Arg.(
@@ -106,7 +116,7 @@ let fcc_cmd : int Cmd.t =
106116
const fcc_main $ int_backend $ roots $ display $ debug $ plugins
107117
$ trace_file $ file $ coqlib $ findlib_config $ ocamlpath $ rload_paths
108118
$ qload_paths $ ri_from $ no_vo $ max_errors $ coq_diags_level
109-
$ record_comments)
119+
$ record_comments $ save_vof $ load_vof)
110120
in
111121
let exits = Exit_codes.[ fatal; stopped; scheduled; uri_failed ] in
112122
Cmd.(v (Cmd.info "fcc" ~exits ~version ~doc ~man) fcc_term)

coq/init.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,6 @@ val doc_init :
3737
-> workspace:Workspace.t
3838
-> uri:Lang.LUri.File.t
3939
-> (State.t, Loc.t) Protect.E.t
40+
41+
val mk_fb_handler :
42+
(int * Loc.t Message.Payload.t) list ref -> Feedback.feedback -> unit

fleche/doc.ml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,28 @@ let save ~token ~doc =
12121212
let error = Coq.Pp_t.(str "Can't save document that failed to check") in
12131213
Coq.Protect.E.error error
12141214

1215+
let doc_to_disk ~doc ~in_file : unit =
1216+
let out_vof = Filename.(remove_extension in_file) ^ ".vof" in
1217+
Coq.Compat.Ocaml_414.Out_channel.with_open_bin out_vof (fun oc ->
1218+
Marshal.to_channel oc doc [])
1219+
1220+
let doc_of_disk ~in_file : t =
1221+
let out_vof = Filename.(remove_extension in_file) ^ ".vof" in
1222+
Stdlib.In_channel.with_open_bin out_vof (fun ic -> Marshal.from_channel ic)
1223+
1224+
let save_vof ~token ~doc =
1225+
match doc.completed with
1226+
| Yes _ ->
1227+
let st =
1228+
Util.last doc.nodes |> Stdlib.Option.fold ~some:Node.state ~none:doc.root
1229+
in
1230+
let uri = doc.uri in
1231+
let in_file = Lang.LUri.File.to_string_file uri in
1232+
Coq.State.in_state ~token ~st ~f:(fun () -> doc_to_disk ~doc ~in_file) ()
1233+
| _ ->
1234+
let error = Coq.Pp_t.(str "Can't save document that failed to check") in
1235+
Coq.Protect.E.error error
1236+
12151237
(* run api, experimental *)
12161238

12171239
(* Adaptor, should be supported in memo directly *)

fleche/doc.mli

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ val check :
170170
val save :
171171
token:Coq.Limits.Token.t -> doc:t -> (unit, Coq.Loc_t.t) Coq.Protect.E.t
172172

173+
(** [save_vof ~doc ... *)
174+
val save_vof :
175+
token:Coq.Limits.Token.t -> doc:t -> (unit, Coq.Loc_t.t) Coq.Protect.E.t
176+
177+
(** Pass .v file *)
178+
val doc_of_disk : in_file:string -> t
179+
173180
(** [run ~token ?loc ?memo ~st cmds] run commands [cmds] starting on state [st],
174181
without commiting changes to the document. [loc] can be used to seed an
175182
initial location if desired, if not the locations will be considered

fleche/theory.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,6 @@ module Register : sig
9292
type t = io:Io.CallBack.t -> token:Coq.Limits.Token.t -> doc:Doc.t -> unit
9393

9494
val add : t -> unit
95+
val fire : io:Io.CallBack.t -> token:Coq.Limits.Token.t -> doc:Doc.t -> unit
9596
end
9697
end

0 commit comments

Comments
 (0)