diff options
| author | Pierre-Marie Pédrot | 2017-09-07 23:45:26 +0200 |
|---|---|---|
| committer | Pierre-Marie Pédrot | 2017-09-08 01:36:52 +0200 |
| commit | bdd594093b4fb7e46a6cae0135b6630d75bae6f6 (patch) | |
| tree | 7c59b547c765f61d3de89e6cc71283694089d9d8 /src | |
| parent | 643832c053e0255dd356231f4e5887db0228c2cd (diff) | |
Fix coq/ltac2#22: Argument to Tactic_failure should be printed.
We implement a printer for toplevel values and use it for exceptions in
particular.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ltac2_plugin.mlpack | 2 | ||||
| -rw-r--r-- | src/tac2entries.ml | 7 | ||||
| -rw-r--r-- | src/tac2print.ml | 123 | ||||
| -rw-r--r-- | src/tac2print.mli | 9 |
4 files changed, 133 insertions, 8 deletions
diff --git a/src/ltac2_plugin.mlpack b/src/ltac2_plugin.mlpack index 00ba5bc58e..70f97b9d1e 100644 --- a/src/ltac2_plugin.mlpack +++ b/src/ltac2_plugin.mlpack @@ -1,8 +1,8 @@ Tac2dyn Tac2env +Tac2ffi Tac2print Tac2intern -Tac2ffi Tac2interp Tac2entries Tac2quote diff --git a/src/tac2entries.ml b/src/tac2entries.ml index 7cffdc6590..9a2693379b 100644 --- a/src/tac2entries.ml +++ b/src/tac2entries.ml @@ -768,8 +768,11 @@ let pr_frame = function obj.Tac2env.ml_print (Global.env ()) arg let () = register_handler begin function -| Tac2interp.LtacError (kn, _, bt) -> - let c = Tac2print.pr_constructor kn in (** FIXME *) +| Tac2interp.LtacError (kn, args, bt) -> + let t_exn = KerName.make2 Tac2env.coq_prefix (Label.make "exn") in + let v = ValOpn (kn, args) in + let t = GTypRef (Other t_exn, []) in + let c = Tac2print.pr_valexpr (Global.env ()) Evd.empty v t in let bt = if !Tac2interp.print_ltac2_backtrace then fnl () ++ str "Backtrace:" ++ fnl () ++ prlist_with_sep fnl pr_frame bt diff --git a/src/tac2print.ml b/src/tac2print.ml index 75ad2082d4..fd1d759cce 100644 --- a/src/tac2print.ml +++ b/src/tac2print.ml @@ -112,14 +112,14 @@ let pr_name = function let find_constructor n empty def = let rec find n = function | [] -> assert false - | (id, []) :: rem -> + | (id, []) as ans :: rem -> if empty then - if Int.equal n 0 then id + if Int.equal n 0 then ans else find (pred n) rem else find n rem - | (id, _ :: _) :: rem -> + | (id, _ :: _) as ans :: rem -> if not empty then - if Int.equal n 0 then id + if Int.equal n 0 then ans else find (pred n) rem else find n rem in @@ -130,7 +130,7 @@ let pr_internal_constructor tpe n is_const = | (_, GTydAlg data) -> data | _ -> assert false in - let id = find_constructor n is_const data.galg_constructors in + let (id, _) = find_constructor n is_const data.galg_constructors in let kn = change_kn_label tpe id in pr_constructor kn @@ -302,3 +302,116 @@ let pr_glbexpr_gen lvl c = let pr_glbexpr c = pr_glbexpr_gen E5 c + +(** Toplevel printers *) + +let rec subst_type subst (t : 'a glb_typexpr) = match t with +| GTypVar id -> subst.(id) +| GTypArrow (t1, t2) -> GTypArrow (subst_type subst t1, subst_type subst t2) +| GTypRef (qid, args) -> + GTypRef (qid, List.map (fun t -> subst_type subst t) args) + +let unfold kn args = + let (nparams, def) = Tac2env.interp_type kn in + match def with + | GTydDef (Some def) -> + let args = Array.of_list args in + Some (subst_type args def) + | _ -> None + +let rec kind t = match t with +| GTypVar id -> GTypVar id +| GTypRef (Other kn, tl) -> + begin match unfold kn tl with + | None -> t + | Some t -> kind t + end +| GTypArrow _ | GTypRef (Tuple _, _) -> t + +type val_printer = + { val_printer : 'a. Environ.env -> Evd.evar_map -> valexpr -> 'a glb_typexpr list -> Pp.t } + +let printers = ref KNmap.empty + +let register_val_printer kn pr = + printers := KNmap.add kn pr !printers + +open Tac2ffi + +let rec pr_valexpr env sigma v t = match kind t with +| GTypVar _ -> str "<poly>" +| GTypRef (Other kn, params) -> + let pr = try Some (KNmap.find kn !printers) with Not_found -> None in + begin match pr with + | Some pr -> pr.val_printer env sigma v params + | None -> + let n, repr = Tac2env.interp_type kn in + match repr with + | GTydDef None -> str "<abstr>" + | GTydDef (Some _) -> + (** Shouldn't happen thanks to kind *) + assert false + | GTydAlg alg -> + begin match v with + | ValInt n -> pr_internal_constructor kn n true + | ValBlk (n, args) -> + let (id, tpe) = find_constructor n false alg.galg_constructors in + let knc = change_kn_label kn id in + let args = pr_constrargs env sigma params args tpe in + hv 2 (pr_constructor knc ++ spc () ++ str "(" ++ args ++ str ")") + | _ -> str "<unknown>" + end + | GTydRec rcd -> str "{}" + | GTydOpn -> + begin match v with + | ValOpn (knc, [||]) -> pr_constructor knc + | ValOpn (knc, args) -> + let data = Tac2env.interp_constructor knc in + let args = pr_constrargs env sigma params args data.Tac2env.cdata_args in + hv 2 (pr_constructor knc ++ spc () ++ str "(" ++ args ++ str ")") + | _ -> str "<unknown>" + end + end +| GTypArrow _ -> str "<fun>" +| GTypRef (Tuple _, tl) -> + let blk = Array.to_list (block.r_to v) in + if List.length blk == List.length tl then + let prs = List.map2 (fun v t -> pr_valexpr env sigma v t) blk tl in + hv 2 (str "(" ++ prlist_with_sep pr_comma (fun p -> p) prs ++ str ")") + else + str "<unknown>" + +and pr_constrargs env sigma params args tpe = + let subst = Array.of_list params in + let tpe = List.map (fun t -> subst_type subst t) tpe in + let args = Array.to_list args in + let args = List.combine args tpe in + prlist_with_sep pr_comma (fun (v, t) -> pr_valexpr env sigma v t) args + +let register_init n f = + let kn = KerName.make2 Tac2env.coq_prefix (Label.make n) in + register_val_printer kn { val_printer = fun _ _ v _ -> f v } + +let () = register_init "int" begin fun n -> + let n = to_int n in + Pp.int n +end + +let () = register_init "string" begin fun s -> + let s = to_string s in + Pp.quote (Pp.str s) +end + +let () = register_init "ident" begin fun id -> + let id = to_ident id in + Pp.str "@" ++ Id.print id +end + +let () = register_init "message" begin fun pp -> + str "message:(" ++ to_pp pp ++ str ")" +end + +let () = register_init "err" begin fun e -> + let (e, _) = to_ext val_exn e in + str "err:(" ++ CErrors.print_no_report e ++ str ")" +end diff --git a/src/tac2print.mli b/src/tac2print.mli index 737e813ed3..01abd1efb1 100644 --- a/src/tac2print.mli +++ b/src/tac2print.mli @@ -29,6 +29,15 @@ val pr_projection : ltac_projection -> Pp.t val pr_glbexpr_gen : exp_level -> glb_tacexpr -> Pp.t val pr_glbexpr : glb_tacexpr -> Pp.t +(** {5 Printing values}*) + +type val_printer = + { val_printer : 'a. Environ.env -> Evd.evar_map -> valexpr -> 'a glb_typexpr list -> Pp.t } + +val register_val_printer : type_constant -> val_printer -> unit + +val pr_valexpr : Environ.env -> Evd.evar_map -> valexpr -> 'a glb_typexpr -> Pp.t + (** {5 Utilities} *) val int_name : unit -> (int -> string) |
