summaryrefslogtreecommitdiff
path: root/toplevel/genprintval.ml
diff options
context:
space:
mode:
Diffstat (limited to 'toplevel/genprintval.ml')
-rw-r--r--toplevel/genprintval.ml363
1 files changed, 0 insertions, 363 deletions
diff --git a/toplevel/genprintval.ml b/toplevel/genprintval.ml
deleted file mode 100644
index 1f8766c804..0000000000
--- a/toplevel/genprintval.ml
+++ /dev/null
@@ -1,363 +0,0 @@
-(***********************************************************************)
-(* *)
-(* Objective Caml *)
-(* *)
-(* Xavier Leroy and Jerome Vouillon, projet Cristal, INRIA Rocquencourt*)
-(* *)
-(* Copyright 1996 Institut National de Recherche en Informatique et *)
-(* en Automatique. All rights reserved. This file is distributed *)
-(* under the terms of the Q Public License version 1.0. *)
-(* *)
-(***********************************************************************)
-
-(* $Id$ *)
-
-(* To print values *)
-
-open Misc
-open Format
-open Longident
-open Path
-open Types
-open Outcometree
-
-module type OBJ =
- sig
- type t
- val obj : t -> 'a
- val is_block : t -> bool
- val tag : t -> int
- val size : t -> int
- val field : t -> int -> t
- end
-
-module type EVALPATH =
- sig
- type value
- val eval_path: Path.t -> value
- exception Error
- val same_value: value -> value -> bool
- end
-
-module type S =
- sig
- type t
- val install_printer :
- Path.t -> Types.type_expr -> (formatter -> t -> unit) -> unit
- val remove_printer : Path.t -> unit
- val outval_of_untyped_exception : t -> Outcometree.out_value
- val outval_of_value :
- int -> int ->
- (int -> t -> Types.type_expr -> Outcometree.out_value option) ->
- Env.t -> t -> type_expr -> Outcometree.out_value
- end
-
-module Make(O : OBJ)(EVP : EVALPATH with type value = O.t) = struct
-
- type t = O.t
-
- (* Given an exception value, we cannot recover its type,
- hence we cannot print its arguments in general.
- Here, we do a feeble attempt to print
- integer, string and float arguments... *)
- let outval_of_untyped_exception_args obj start_offset =
- if O.size obj > start_offset then begin
- let list = ref [] in
- for i = start_offset to O.size obj - 1 do
- let arg = O.field obj i in
- if not (O.is_block arg) then
- list := Oval_int (O.obj arg : int) :: !list
- (* Note: this could be a char or a constant constructor... *)
- else if O.tag arg = Obj.string_tag then
- list :=
- Oval_string (String.escaped (O.obj arg : string)) :: !list
- else if O.tag arg = Obj.double_tag then
- list := Oval_float (O.obj arg : float) :: !list
- else
- list := Oval_constr (Oide_ident "_", []) :: !list
- done;
- List.rev !list
- end
- else []
-
- let outval_of_untyped_exception bucket =
- let name = (O.obj(O.field(O.field bucket 0) 0) : string) in
- let args =
- if (name = "Match_failure"
- || name = "Assert_failure"
- || name = "Undefined_recursive_module")
- && O.size bucket = 2
- && O.tag(O.field bucket 1) = 0
- then outval_of_untyped_exception_args (O.field bucket 1) 0
- else outval_of_untyped_exception_args bucket 1 in
- Oval_constr (Oide_ident name, args)
-
- (* The user-defined printers. Also used for some builtin types. *)
-
- 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)
-
- 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
- let printer obj = Oval_printer (fun ppf -> print_val ppf obj) in
- printers := (path, ty, printer) :: !printers
-
- let remove_printer path =
- let rec remove = function
- | [] -> raise Not_found
- | (p, ty, fn 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. *)
-
- let tree_of_qualified lookup_fun env ty_path name =
- match ty_path with
- | Pident id ->
- Oide_ident name
- | Pdot(p, s, pos) ->
- if try
- match (lookup_fun (Lident name) env).desc with
- | Tconstr(ty_path', _, _) -> Path.same ty_path ty_path'
- | _ -> false
- with Not_found -> false
- then Oide_ident name
- else Oide_dot (Printtyp.tree_of_path p, name)
- | Papply(p1, p2) ->
- Printtyp.tree_of_path ty_path
-
- let tree_of_constr =
- tree_of_qualified
- (fun lid env -> (Env.lookup_constructor lid env).cstr_res)
-
- and tree_of_label =
- tree_of_qualified (fun lid env -> (Env.lookup_label lid env).lbl_res)
-
- (* An abstract type *)
-
- let abstract_type =
- Ctype.newty (Tconstr (Pident (Ident.create "abstract"), [], ref Mnil))
-
- (* The main printing function *)
-
- let outval_of_value max_steps max_depth check_depth env obj ty =
-
- let printer_steps = ref max_steps in
-
- let rec tree_of_val depth obj ty =
- decr printer_steps;
- if !printer_steps < 0 || depth < 0 then Oval_ellipsis
- else begin
- try
- find_printer env ty obj
- with Not_found ->
- match (Ctype.repr ty).desc with
- | Tvar ->
- Oval_stuff "<poly>"
- | Tarrow(_, ty1, ty2, _) ->
- Oval_stuff "<fun>"
- | Ttuple(ty_list) ->
- Oval_tuple (tree_of_val_list 0 depth obj ty_list)
- | Tconstr(path, [], _) when Path.same path Predef.path_exn ->
- tree_of_exception depth obj
- | Tconstr(path, [ty_arg], _)
- when Path.same path Predef.path_list ->
- if O.is_block obj then
- match check_depth depth obj ty with
- Some x -> x
- | None ->
- let rec tree_of_conses tree_list obj =
- if !printer_steps < 0 || depth < 0 then
- Oval_ellipsis :: tree_list
- else if O.is_block obj then
- let tree =
- tree_of_val (depth - 1) (O.field obj 0) ty_arg in
- let next_obj = O.field obj 1 in
- tree_of_conses (tree :: tree_list) next_obj
- else tree_list
- in
- Oval_list (List.rev (tree_of_conses [] obj))
- else
- Oval_list []
- | Tconstr(path, [ty_arg], _)
- when Path.same path Predef.path_array ->
- let length = O.size obj in
- if length > 0 then
- match check_depth depth obj ty with
- Some x -> x
- | None ->
- let rec tree_of_items tree_list i =
- if !printer_steps < 0 || depth < 0 then
- Oval_ellipsis :: tree_list
- else if i < length then
- let tree =
- tree_of_val (depth - 1) (O.field obj i) ty_arg in
- tree_of_items (tree :: tree_list) (i + 1)
- else tree_list
- in
- Oval_array (List.rev (tree_of_items [] 0))
- else
- Oval_array []
- | Tconstr (path, [ty_arg], _)
- when Path.same path Predef.path_lazy_t ->
- if Lazy.lazy_is_val (O.obj obj)
- then let v = tree_of_val depth (Lazy.force (O.obj obj)) ty_arg in
- Oval_constr (Oide_ident "lazy", [v])
- else Oval_stuff "<lazy>"
- | Tconstr(path, ty_list, _) ->
- begin try
- let decl = Env.find_type path env in
- match decl with
- | {type_kind = Type_abstract; type_manifest = None} ->
- Oval_stuff "<abstr>"
- | {type_kind = Type_abstract; type_manifest = Some body} ->
- tree_of_val depth obj
- (try Ctype.apply env decl.type_params body ty_list with
- Ctype.Cannot_apply -> abstract_type)
- | {type_kind = Type_variant(constr_list, priv)} ->
- let tag =
- if O.is_block obj
- then Cstr_block(O.tag obj)
- else Cstr_constant(O.obj obj) in
- let (constr_name, constr_args) =
- Datarepr.find_constr_by_tag tag constr_list in
- let ty_args =
- List.map
- (function ty ->
- try Ctype.apply env decl.type_params ty ty_list with
- Ctype.Cannot_apply -> abstract_type)
- constr_args in
- tree_of_constr_with_args (tree_of_constr env path)
- constr_name 0 depth obj ty_args
- | {type_kind = Type_record(lbl_list, rep, priv)} ->
- begin match check_depth depth obj ty with
- Some x -> x
- | None ->
- let rec tree_of_fields pos = function
- | [] -> []
- | (lbl_name, _, lbl_arg) :: remainder ->
- let ty_arg =
- try
- Ctype.apply env decl.type_params lbl_arg
- ty_list
- with
- Ctype.Cannot_apply -> abstract_type in
- let lid = tree_of_label env path lbl_name in
- let v =
- tree_of_val (depth - 1) (O.field obj pos)
- ty_arg
- in
- (lid, v) :: tree_of_fields (pos + 1) remainder
- in
- Oval_record (tree_of_fields 0 lbl_list)
- end
- with
- Not_found -> (* raised by Env.find_type *)
- Oval_stuff "<abstr>"
- | Datarepr.Constr_not_found -> (* raised by find_constr_by_tag *)
- Oval_stuff "<unknown constructor>"
- end
- | Tvariant row ->
- let row = Btype.row_repr row in
- if O.is_block obj then
- let tag : int = O.obj (O.field obj 0) in
- let rec find = function
- | (l, f) :: fields ->
- if Btype.hash_variant l = tag then
- match Btype.row_field_repr f with
- | Rpresent(Some ty) ->
- let args =
- tree_of_val (depth - 1) (O.field obj 1) ty in
- Oval_variant (l, Some args)
- | _ -> find fields
- else find fields
- | [] -> Oval_stuff "<variant>" in
- find row.row_fields
- else
- let tag : int = O.obj obj in
- let rec find = function
- | (l, _) :: fields ->
- if Btype.hash_variant l = tag then
- Oval_variant (l, None)
- else find fields
- | [] -> Oval_stuff "<variant>" in
- find row.row_fields
- | Tobject (_, _) ->
- Oval_stuff "<obj>"
- | Tsubst ty ->
- tree_of_val (depth - 1) obj ty
- | Tfield(_, _, _, _) | Tnil | Tlink _ ->
- fatal_error "Printval.outval_of_value"
- | Tpoly (ty, _) ->
- tree_of_val (depth - 1) obj ty
- | Tunivar ->
- Oval_stuff "<poly>"
- end
-
- and tree_of_val_list start depth obj ty_list =
- let rec tree_list i = function
- | [] -> []
- | ty :: ty_list ->
- let tree = tree_of_val (depth - 1) (O.field obj i) ty in
- tree :: tree_list (i + 1) ty_list in
- tree_list start ty_list
-
- and tree_of_constr_with_args
- tree_of_cstr cstr_name start depth obj ty_args =
- let lid = tree_of_cstr cstr_name in
- let args = tree_of_val_list start depth obj ty_args in
- Oval_constr (lid, args)
-
- and tree_of_exception depth bucket =
- let name = (O.obj(O.field(O.field bucket 0) 0) : string) in
- let lid = Longident.parse name in
- try
- (* Attempt to recover the constructor description for the exn
- from its name *)
- let cstr = Env.lookup_constructor lid env in
- let path =
- match cstr.cstr_tag with
- Cstr_exception p -> p | _ -> raise Not_found in
- (* Make sure this is the right exception and not an homonym,
- by evaluating the exception found and comparing with the
- identifier contained in the exception bucket *)
- if not (EVP.same_value (O.field bucket 0) (EVP.eval_path path))
- then raise Not_found;
- tree_of_constr_with_args
- (fun x -> Oide_ident x) name 1 depth bucket cstr.cstr_args
- with Not_found | EVP.Error ->
- match check_depth depth obj ty with
- Some x -> x
- | None -> outval_of_untyped_exception obj
-
- in tree_of_val max_depth obj ty
-
-end