Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From c2179b338925399f22cf9cd3e99dc7c5ee36853b Mon Sep 17 00:00:00 2001
- From: Pierre Chambart <pierre.chambart@ocamlpro.com>
- Date: Thu, 19 Jun 2014 21:01:03 +0200
- Subject: [PATCH 1/4] toplevel: allows the extension of 'genprintval.ml' with
- parameterised printer.
- ---
- toplevel/genprintval.ml | 129 ++++++++++++++++++++++++++++++++++++-----------
- toplevel/genprintval.mli | 14 +++++
- toplevel/toploop.ml | 6 +++
- toplevel/toploop.mli | 11 ++++
- 4 files changed, 130 insertions(+), 30 deletions(-)
- diff --git a/toplevel/genprintval.ml b/toplevel/genprintval.ml
- index 625a0a5..2aec7aa 100644
- --- a/toplevel/genprintval.ml
- +++ b/toplevel/genprintval.ml
- @@ -37,11 +37,25 @@ module type EVALPATH =
- val same_value: valu -> valu -> bool
- end
- +type ('a, 'b) gen_printer =
- + | Zero of 'b
- + | Succ of ('a -> ('a, 'b) gen_printer)
- +
- module type S =
- sig
- type t
- val install_printer :
- Path.t -> Types.type_expr -> (formatter -> t -> unit) -> unit
- + val install_generic_printer :
- + Path.t -> Path.t ->
- + (int -> (int -> t -> Outcometree.out_value,
- + t -> Outcometree.out_value) gen_printer) ->
- + unit
- + val install_generic_printer' :
- + Path.t -> Path.t ->
- + (formatter -> t -> unit,
- + formatter -> t -> unit) gen_printer ->
- + unit
- val remove_printer : Path.t -> unit
- val outval_of_untyped_exception : t -> Outcometree.out_value
- val outval_of_value :
- @@ -104,47 +118,73 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct
- (* The user-defined printers. Also used for some builtin types. *)
- + type printer =
- + | Simple of Types.type_expr * (O.t -> Outcometree.out_value)
- + | Generic of Path.t * (int -> (int -> O.t -> Outcometree.out_value,
- + O.t -> Outcometree.out_value) gen_printer)
- +
- let printers = ref ([
- - Pident(Ident.create "print_int"), Predef.type_int,
- - (fun x -> Oval_int (O.obj x : int));
- - Pident(Ident.create "print_float"), Predef.type_float,
- - (fun x -> Oval_float (O.obj x : float));
- - Pident(Ident.create "print_char"), Predef.type_char,
- - (fun x -> Oval_char (O.obj x : char));
- - Pident(Ident.create "print_string"), Predef.type_string,
- - (fun x -> Oval_string (O.obj x : string));
- - Pident(Ident.create "print_int32"), Predef.type_int32,
- - (fun x -> Oval_int32 (O.obj x : int32));
- - Pident(Ident.create "print_nativeint"), Predef.type_nativeint,
- - (fun x -> Oval_nativeint (O.obj x : nativeint));
- - Pident(Ident.create "print_int64"), Predef.type_int64,
- - (fun x -> Oval_int64 (O.obj x : int64))
- - ] : (Path.t * type_expr * (O.t -> Outcometree.out_value)) list)
- + ( Pident(Ident.create "print_int"),
- + Simple (Predef.type_int,
- + (fun x -> Oval_int (O.obj x : int))) );
- + ( Pident(Ident.create "print_float"),
- + Simple (Predef.type_float,
- + (fun x -> Oval_float (O.obj x : float))) );
- + ( Pident(Ident.create "print_char"),
- + Simple (Predef.type_char,
- + (fun x -> Oval_char (O.obj x : char))) );
- + ( Pident(Ident.create "print_string"),
- + Simple (Predef.type_string,
- + (fun x -> Oval_string (O.obj x : string))) );
- + ( Pident(Ident.create "print_int32"),
- + Simple (Predef.type_int32,
- + (fun x -> Oval_int32 (O.obj x : int32))) );
- + ( Pident(Ident.create "print_nativeint"),
- + Simple (Predef.type_nativeint,
- + (fun x -> Oval_nativeint (O.obj x : nativeint))) );
- + ( Pident(Ident.create "print_int64"),
- + Simple (Predef.type_int64,
- + (fun x -> Oval_int64 (O.obj x : int64)) ))
- + ] : (Path.t * printer) list)
- +
- + let exn_printer ppf path =
- + fprintf ppf "<printer %a raised an exception>" Printtyp.path path
- +
- + let out_exn path =
- + Oval_printer (fun ppf -> exn_printer ppf path)
- let install_printer path ty fn =
- let print_val ppf obj =
- - try fn ppf obj with
- - | exn ->
- - fprintf ppf "<printer %a raised an exception>" Printtyp.path path in
- + try fn ppf obj with exn -> exn_printer ppf path in
- let printer obj = Oval_printer (fun ppf -> print_val ppf obj) in
- - printers := (path, ty, printer) :: !printers
- + printers := (path, Simple (ty, printer)) :: !printers
- +
- + let install_generic_printer path ty_path fn =
- + printers := (path, Generic (ty_path, fn)) :: !printers
- +
- + let install_generic_printer' path ty_path fn =
- + let rec build gp depth =
- + match gp with
- + | Zero fn ->
- + let out_printer obj =
- + let printer ppf = try fn ppf obj with _ -> exn_printer ppf path in
- + Oval_printer printer in
- + Zero out_printer
- + | Succ fn ->
- + let print_val fn_arg =
- + let print_arg ppf o =
- + !Oprint.out_value ppf (fn_arg (depth+1) o) in
- + build (fn print_arg) depth in
- + Succ print_val in
- + printers := (path, Generic (ty_path, build fn)) :: !printers
- let remove_printer path =
- let rec remove = function
- | [] -> raise Not_found
- - | (p, ty, fn as printer) :: rem ->
- + | ((p, _) as printer) :: rem ->
- if Path.same p path then rem else printer :: remove rem in
- printers := remove !printers
- - let find_printer env ty =
- - let rec find = function
- - | [] -> raise Not_found
- - | (name, sch, printer) :: remainder ->
- - if Ctype.moregeneral env false sch ty
- - then printer
- - else find remainder
- - in find !printers
- -
- (* Print a constructor or label, giving it the same prefix as the type
- it comes from. Attempt to omit the prefix if the type comes from
- a module that has been opened. *)
- @@ -205,7 +245,7 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct
- if !printer_steps < 0 || depth < 0 then Oval_ellipsis
- else begin
- try
- - find_printer env ty obj
- + find_printer depth env ty obj
- with Not_found ->
- match (Ctype.repr ty).desc with
- | Tvar _ | Tunivar _ ->
- @@ -416,6 +456,35 @@ module Make(O : OBJ)(EVP : EVALPATH with type valu = O.t) = struct
- | None ->
- Oval_stuff "<extension>"
- + and find_printer depth env ty =
- + let rec find = function
- + | [] -> raise Not_found
- + | (name, Simple (sch, printer)) :: remainder ->
- + if Ctype.moregeneral env false sch ty
- + then printer
- + else find remainder
- + | (name, Generic (path, fn)) :: remainder ->
- + begin match (Ctype.expand_head env ty).desc with
- + | Tconstr (p, args, _) when Path.same p path ->
- + begin try apply_generic_printer path (fn depth) args
- + with _ -> (fun obj -> out_exn path) end
- + | _ -> find remainder end in
- + find !printers
- +
- + and apply_generic_printer path printer args =
- + match (printer, args) with
- + | (Zero fn, []) -> (fun (obj : O.t)-> try fn obj with _ -> out_exn path)
- + | (Succ fn, arg :: args) ->
- + let printer = fn (fun depth obj -> tree_of_val depth obj arg) in
- + apply_generic_printer path printer args
- + | _ ->
- + (fun obj ->
- + let printer ppf =
- + fprintf ppf "<internal error: incorrect arity for '%a'>"
- + Printtyp.path path in
- + Oval_printer printer)
- +
- +
- in nest tree_of_val max_depth obj ty
- end
- diff --git a/toplevel/genprintval.mli b/toplevel/genprintval.mli
- index 3f7b85a..a1cd6b9 100644
- --- a/toplevel/genprintval.mli
- +++ b/toplevel/genprintval.mli
- @@ -33,11 +33,25 @@ module type EVALPATH =
- val same_value: valu -> valu -> bool
- end
- +type ('a, 'b) gen_printer =
- + | Zero of 'b
- + | Succ of ('a -> ('a, 'b) gen_printer)
- +
- module type S =
- sig
- type t
- val install_printer :
- Path.t -> Types.type_expr -> (formatter -> t -> unit) -> unit
- + val install_generic_printer :
- + Path.t -> Path.t ->
- + (int -> (int -> t -> Outcometree.out_value,
- + t -> Outcometree.out_value) gen_printer) ->
- + unit
- + val install_generic_printer' :
- + Path.t -> Path.t ->
- + (formatter -> t -> unit,
- + formatter -> t -> unit) gen_printer ->
- + unit
- val remove_printer : Path.t -> unit
- val outval_of_untyped_exception : t -> Outcometree.out_value
- val outval_of_value :
- diff --git a/toplevel/toploop.ml b/toplevel/toploop.ml
- index 2261dcc..0ee8799 100644
- --- a/toplevel/toploop.ml
- +++ b/toplevel/toploop.ml
- @@ -96,7 +96,13 @@ let outval_of_value env obj ty =
- let print_value env obj ppf ty =
- !print_out_value ppf (outval_of_value env obj ty)
- +type ('a, 'b) gen_printer = ('a, 'b) Genprintval.gen_printer =
- + | Zero of 'b
- + | Succ of ('a -> ('a, 'b) gen_printer)
- +
- let install_printer = Printer.install_printer
- +let install_generic_printer = Printer.install_generic_printer
- +let install_generic_printer' = Printer.install_generic_printer'
- let remove_printer = Printer.remove_printer
- (* Hooks for parsing functions *)
- diff --git a/toplevel/toploop.mli b/toplevel/toploop.mli
- index 5f0b86e..5ebfec3 100644
- --- a/toplevel/toploop.mli
- +++ b/toplevel/toploop.mli
- @@ -68,8 +68,19 @@ val eval_path: Env.t -> Path.t -> Obj.t
- val print_value: Env.t -> Obj.t -> formatter -> Types.type_expr -> unit
- val print_untyped_exception: formatter -> Obj.t -> unit
- +type ('a, 'b) gen_printer =
- + | Zero of 'b
- + | Succ of ('a -> ('a, 'b) gen_printer)
- +
- val install_printer :
- Path.t -> Types.type_expr -> (formatter -> Obj.t -> unit) -> unit
- +val install_generic_printer :
- + Path.t -> Path.t ->
- + (int -> (int -> Obj.t -> Outcometree.out_value,
- + Obj.t -> Outcometree.out_value) gen_printer) -> unit
- +val install_generic_printer' :
- + Path.t -> Path.t -> (formatter -> Obj.t -> unit,
- + formatter -> Obj.t -> unit) gen_printer -> unit
- val remove_printer : Path.t -> unit
- val max_printer_depth: int ref
- --
- 2.0.0
Add Comment
Please, Sign In to add comment