aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib/serialize.ml211
-rw-r--r--lib/serialize.mli3
-rw-r--r--toplevel/coqtop.ml1
-rw-r--r--toplevel/usage.ml1
4 files changed, 157 insertions, 59 deletions
diff --git a/lib/serialize.ml b/lib/serialize.ml
index 37856b527..2b46df60b 100644
--- a/lib/serialize.ml
+++ b/lib/serialize.ml
@@ -401,6 +401,13 @@ module ReifType : sig (* {{{ *)
val print : 'a val_t -> 'a -> string
+ type value_type
+ val erase : 'a val_t -> value_type
+ val print_type : value_type -> string
+ val same_type : 'a val_t -> value_type -> bool
+
+ val document_type_encoding : (xml -> string) -> unit
+
end = struct
type value_type =
@@ -417,6 +424,9 @@ end = struct
| Search_cst
type 'a val_t = value_type
+
+ let erase (x : 'a val_t) : value_type = x
+ let same_type (x : 'a val_t) (y : value_type) = Pervasives.compare (erase x) y = 0
let unit_t = Unit
let string_t = String
@@ -553,9 +563,116 @@ end = struct
| Union (t1,t2) -> Obj.magic (pr_union (print t1) (print t2))
| State_id -> Obj.magic pr_int
+ (* This is to break if a rename/refactoring makes the strings below outdated *)
+ type 'a exists = bool
+
+ let rec print_type = function
+ | Unit -> "unit"
+ | Bool -> "bool"
+ | String -> "string"
+ | Int -> "int"
+ | State -> assert(true : status exists); "Interface.status"
+ | Option_state -> assert(true : option_state exists); "Interface.option_state"
+ | Option_value -> assert(true : option_value exists); "Interface.option_value"
+ | Search_cst -> assert(true : search_constraint exists); "Interface.search_constraint"
+ | Coq_info -> assert(true : coq_info exists); "Interface.coq_info"
+ | Goals -> assert(true : goals exists); "Interface.goals"
+ | Evar -> assert(true : evar exists); "Interface.evar"
+ | List t -> Printf.sprintf "(%s list)" (print_type t)
+ | Option t -> Printf.sprintf "(%s option)" (print_type t)
+ | Coq_object t -> assert(true : 'a coq_object exists);
+ Printf.sprintf "(%s Interface.coq_object)" (print_type t)
+ | Pair (t1,t2) -> Printf.sprintf "(%s * %s)" (print_type t1) (print_type t2)
+ | Union (t1,t2) -> assert(true : ('a,'b) CSig.union exists);
+ Printf.sprintf "((%s, %s) CSig.union)" (print_type t1) (print_type t2)
+ | State_id -> assert(true : Stateid.t exists); "Stateid.t"
+
+ let document_type_encoding pr_xml =
+ Printf.printf "\n=== Data encoding by examples ===\n\n";
+ Printf.printf "%s:\n\n%s\n\n" (print_type Unit) (pr_xml (of_unit ()));
+ Printf.printf "%s:\n\n%s\n%s\n\n" (print_type Bool)
+ (pr_xml (of_bool true)) (pr_xml (of_bool false));
+ Printf.printf "%s:\n\n%s\n\n" (print_type String) (pr_xml (of_string "hello"));
+ Printf.printf "%s:\n\n%s\n\n" (print_type Int) (pr_xml (of_int 256));
+ Printf.printf "%s:\n\n%s\n\n" (print_type State_id) (pr_xml (of_state_id Stateid.initial));
+ Printf.printf "%s:\n\n%s\n\n" (print_type (List Int)) (pr_xml (of_list of_int [3;4;5]));
+ Printf.printf "%s:\n\n%s\n%s\n\n" (print_type (Option Int))
+ (pr_xml (of_option of_int (Some 3))) (pr_xml (of_option of_int None));
+ Printf.printf "%s:\n\n%s\n\n" (print_type (Pair (Bool,Int)))
+ (pr_xml (of_pair of_bool of_int (false,3)));
+ Printf.printf "%s:\n\n%s\n\n" (print_type (Union (Bool,Int)))
+ (pr_xml (of_union of_bool of_int (Inl false)));
+ print_endline ("All other types are records represented by a node named like the OCaml\n"^
+ "type which contains a flattened n-tuple. We provide one example.\n");
+ Printf.printf "%s:\n\n%s\n\n" (print_type Option_state)
+ (pr_xml (of_option_state { opt_sync = true; opt_depr = false;
+ opt_name = "name1"; opt_value = IntValue (Some 37) }));
+
end (* }}} *)
open ReifType
+(** Types reification, checked with explicit casts *)
+let add_sty_t : add_sty val_t =
+ pair_t (pair_t string_t int_t) (pair_t state_id_t bool_t)
+let edit_at_sty_t : edit_at_sty val_t = state_id_t
+let query_sty_t : query_sty val_t = pair_t string_t state_id_t
+let goals_sty_t : goals_sty val_t = unit_t
+let evars_sty_t : evars_sty val_t = unit_t
+let hints_sty_t : hints_sty val_t = unit_t
+let status_sty_t : status_sty val_t = bool_t
+let search_sty_t : search_sty val_t = list_t (pair_t search_cst_t bool_t)
+let get_options_sty_t : get_options_sty val_t = unit_t
+let set_options_sty_t : set_options_sty val_t =
+ list_t (pair_t (list_t string_t) option_value_t)
+let inloadpath_sty_t : inloadpath_sty val_t = string_t
+let mkcases_sty_t : mkcases_sty val_t = string_t
+let quit_sty_t : quit_sty val_t = unit_t
+let about_sty_t : about_sty val_t = unit_t
+let init_sty_t : init_sty val_t = unit_t
+let interp_sty_t : interp_sty val_t = pair_t (pair_t bool_t bool_t) string_t
+
+let add_rty_t : add_rty val_t =
+ pair_t state_id_t (pair_t (union_t unit_t state_id_t) string_t)
+let edit_at_rty_t : edit_at_rty val_t =
+ union_t unit_t (pair_t state_id_t (pair_t state_id_t state_id_t))
+let query_rty_t : query_rty val_t = string_t
+let goals_rty_t : goals_rty val_t = option_t goals_t
+let evars_rty_t : evars_rty val_t = option_t (list_t evar_t)
+let hints_rty_t : hints_rty val_t =
+ let hint = list_t (pair_t string_t string_t) in
+ option_t (pair_t (list_t hint) hint)
+let status_rty_t : status_rty val_t = state_t
+let search_rty_t : search_rty val_t = list_t (coq_object_t string_t)
+let get_options_rty_t : get_options_rty val_t =
+ list_t (pair_t (list_t string_t) option_state_t)
+let set_options_rty_t : set_options_rty val_t = unit_t
+let inloadpath_rty_t : inloadpath_rty val_t = bool_t
+let mkcases_rty_t : mkcases_rty val_t = list_t (list_t string_t)
+let quit_rty_t : quit_rty val_t = unit_t
+let about_rty_t : about_rty val_t = coq_info_t
+let init_rty_t : init_rty val_t = state_id_t
+let interp_rty_t : interp_rty val_t = union_t string_t string_t
+
+let ($) x = erase x
+let calls = [|
+ "Add", ($)add_sty_t, ($)add_rty_t;
+ "Edit_at", ($)edit_at_sty_t, ($)edit_at_rty_t;
+ "Query", ($)query_sty_t, ($)query_rty_t;
+ "Goal", ($)goals_sty_t, ($)goals_rty_t;
+ "Evars", ($)evars_sty_t, ($)evars_rty_t;
+ "Hints", ($)hints_sty_t, ($)hints_rty_t;
+ "Status", ($)status_sty_t, ($)status_rty_t;
+ "Search", ($)search_sty_t, ($)search_rty_t;
+ "GetOptions", ($)get_options_sty_t, ($)get_options_rty_t;
+ "SetOptions", ($)set_options_sty_t, ($)set_options_rty_t;
+ "InLoadPath", ($)inloadpath_sty_t, ($)inloadpath_rty_t;
+ "MkCases", ($)mkcases_sty_t, ($)mkcases_rty_t;
+ "Quit", ($)quit_sty_t, ($)quit_rty_t;
+ "About", ($)about_sty_t, ($)about_rty_t;
+ "Init", ($)init_sty_t, ($)init_rty_t;
+ "Interp", ($)interp_sty_t, ($)interp_rty_t;
+|]
+
type 'a call =
| Add of add_sty
| Edit_at of edit_at_sty
@@ -575,23 +692,25 @@ type 'a call =
(* retrocompatibility *)
| Interp of interp_sty
-let str_of_call = function
- | Add _ -> "Add"
- | Edit_at _ -> "Edit_at"
- | Query _ -> "Query"
- | Goal _ -> "Goal"
- | Evars _ -> "Evars"
- | Hints _ -> "Hints"
- | Status _ -> "Status"
- | Search _ -> "Search"
- | GetOptions _ -> "GetOptions"
- | SetOptions _ -> "SetOptions"
- | InLoadPath _ -> "InLoadPath"
- | MkCases _ -> "MkCases"
- | Quit _ -> "Quit"
- | About _ -> "About"
- | Init _ -> "Init"
- | Interp _ -> "Interp"
+let id_of_call = function
+ | Add _ -> 0
+ | Edit_at _ -> 1
+ | Query _ -> 2
+ | Goal _ -> 3
+ | Evars _ -> 4
+ | Hints _ -> 5
+ | Status _ -> 6
+ | Search _ -> 7
+ | GetOptions _ -> 8
+ | SetOptions _ -> 9
+ | InLoadPath _ -> 10
+ | MkCases _ -> 11
+ | Quit _ -> 12
+ | About _ -> 13
+ | Init _ -> 14
+ | Interp _ -> 15
+
+let str_of_call c = pi1 calls.(id_of_call c)
type unknown
@@ -635,48 +754,6 @@ let abstract_eval_call handler (c : 'a call) : 'a value =
with any ->
Fail (handler.handle_exn any)
-(** Types reification, checked with explicit casts *)
-let add_sty_t : add_sty val_t =
- pair_t (pair_t string_t int_t) (pair_t state_id_t bool_t)
-let edit_at_sty_t : edit_at_sty val_t = state_id_t
-let query_sty_t : query_sty val_t = pair_t string_t state_id_t
-let goals_sty_t : goals_sty val_t = unit_t
-let evars_sty_t : evars_sty val_t = unit_t
-let hints_sty_t : hints_sty val_t = unit_t
-let status_sty_t : status_sty val_t = bool_t
-let search_sty_t : search_sty val_t = list_t (pair_t search_cst_t bool_t)
-let get_options_sty_t : get_options_sty val_t = unit_t
-let set_options_sty_t : set_options_sty val_t =
- list_t (pair_t (list_t string_t) option_value_t)
-let inloadpath_sty_t : inloadpath_sty val_t = string_t
-let mkcases_sty_t : mkcases_sty val_t = string_t
-let quit_sty_t : quit_sty val_t = unit_t
-let about_sty_t : about_sty val_t = unit_t
-let init_sty_t : init_sty val_t = unit_t
-let interp_sty_t : interp_sty val_t = pair_t (pair_t bool_t bool_t) string_t
-
-let add_rty_t : add_rty val_t =
- pair_t state_id_t (pair_t (union_t unit_t state_id_t) string_t)
-let edit_at_rty_t : edit_at_rty val_t =
- union_t unit_t (pair_t state_id_t (pair_t state_id_t state_id_t))
-let query_rty_t : query_rty val_t = string_t
-let goals_rty_t : goals_rty val_t = option_t goals_t
-let evars_rty_t : evars_rty val_t = option_t (list_t evar_t)
-let hints_rty_t : hints_rty val_t =
- let hint = list_t (pair_t string_t string_t) in
- option_t (pair_t (list_t hint) hint)
-let status_rty_t : status_rty val_t = state_t
-let search_rty_t : search_rty val_t = list_t (coq_object_t string_t)
-let get_options_rty_t : get_options_rty val_t =
- list_t (pair_t (list_t string_t) option_state_t)
-let set_options_rty_t : set_options_rty val_t = unit_t
-let inloadpath_rty_t : inloadpath_rty val_t = bool_t
-let mkcases_rty_t : mkcases_rty val_t = list_t (list_t string_t)
-let quit_rty_t : quit_rty val_t = unit_t
-let about_rty_t : about_rty val_t = coq_info_t
-let init_rty_t : init_rty val_t = state_id_t
-let interp_rty_t : interp_rty val_t = union_t string_t string_t
-
(** brain dead code, edit if protocol messages are added/removed {{{ *)
let of_answer (q : 'a call) (v : 'a value) : xml = match q with
| Add _ -> of_value (of_value_type add_rty_t ) (Obj.magic v)
@@ -809,4 +886,20 @@ let pr_call call = match call with
(* }}} *)
+let document to_string_fmt =
+ Printf.printf "=== Available calls ===\n\n";
+ Array.iter (fun (cname, csty, crty) ->
+ Printf.printf "%12s : %s\n %14s %s\n"
+ ("\""^cname^"\"") (print_type csty) "->" (print_type crty))
+ calls;
+ Printf.printf "\n=== Calls XML encoding ===\n\n";
+ Printf.printf "A call \"C\" carrying input a is encoded as:\n\n%s\n\n"
+ (to_string_fmt (constructor "call" "C" [PCData "a"]));
+ Printf.printf "A response carrying output b can either be:\n\n%s\n\n"
+ (to_string_fmt (of_value (fun _ -> PCData "b") (Good ())));
+ Printf.printf "or:\n\n%s\n\nwhere the attributes loc_s and loc_c are optional.\n"
+ (to_string_fmt (of_value (fun _ -> PCData "b")
+ (Fail (Stateid.initial,Some (15,34),"error message"))));
+ document_type_encoding to_string_fmt
+
(* vim: set foldmethod=marker: *)
diff --git a/lib/serialize.mli b/lib/serialize.mli
index e74946208..4e5cb2d15 100644
--- a/lib/serialize.mli
+++ b/lib/serialize.mli
@@ -56,6 +56,9 @@ val is_feedback : xml -> bool
val of_answer : 'a call -> 'a value -> xml
val to_answer : 'a call -> xml -> 'a value
+(* Prints the documentation of this module *)
+val document : (xml -> string) -> unit
+
(** * Debug printing *)
val pr_call : 'a call -> string
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index b97042ede..f3bcee128 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -298,6 +298,7 @@ let parse_args arglist =
|"-filteropts" -> filter_opts := true
|"-force-load-proofs" -> Flags.load_proofs := Flags.Force
|"-h"|"-H"|"-?"|"-help"|"--help" -> usage ()
+ |"--help-XML-protocol" -> Serialize.document Xml_printer.to_string_fmt; exit 0
|"-ideslave" -> Flags.ide_slave := true
|"-impredicative-set" -> set_engagement Declarations.ImpredicativeSet
|"-just-parsing" -> Vernac.just_parsing := true
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index e9e576962..b8e94c9cc 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -74,6 +74,7 @@ let print_usage_channel co command =
\n some tactics\
\n -time display the time taken by each command\
\n -h, --help print this list of options\
+\n --help-XML-protocol print the documentation of the XML protocol used by CoqIDE\
\n"
(* print the usage on standard error *)