1995-08-09 08:06:35 -07:00
|
|
|
(***********************************************************************)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Objective Caml *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
1999-11-17 10:59:06 -08:00
|
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
|
|
(* under the terms of the Q Public License version 1.0. *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
|
|
|
(* $Id$ *)
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
(* Substitutions *)
|
|
|
|
|
1995-08-23 04:55:54 -07:00
|
|
|
open Misc
|
1995-05-04 03:15:53 -07:00
|
|
|
open Path
|
1996-09-23 04:33:27 -07:00
|
|
|
open Types
|
1997-03-24 12:12:16 -08:00
|
|
|
open Btype
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
type t =
|
1996-05-16 07:16:34 -07:00
|
|
|
{ types: (Ident.t, Path.t) Tbl.t;
|
|
|
|
modules: (Ident.t, Path.t) Tbl.t;
|
1997-03-24 12:12:16 -08:00
|
|
|
modtypes: (Ident.t, module_type) Tbl.t }
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let identity =
|
1997-03-24 12:12:16 -08:00
|
|
|
{ types = Tbl.empty; modules = Tbl.empty; modtypes = Tbl.empty }
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let add_type id p s =
|
1996-05-16 07:16:34 -07:00
|
|
|
{ types = Tbl.add id p s.types;
|
1995-05-04 03:15:53 -07:00
|
|
|
modules = s.modules;
|
1997-03-24 12:12:16 -08:00
|
|
|
modtypes = s.modtypes }
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let add_module id p s =
|
|
|
|
{ types = s.types;
|
1996-05-16 07:16:34 -07:00
|
|
|
modules = Tbl.add id p s.modules;
|
1997-03-24 12:12:16 -08:00
|
|
|
modtypes = s.modtypes }
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let add_modtype id ty s =
|
|
|
|
{ types = s.types;
|
|
|
|
modules = s.modules;
|
1997-03-24 12:12:16 -08:00
|
|
|
modtypes = Tbl.add id ty s.modtypes }
|
1996-05-16 07:16:34 -07:00
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
let rec module_path s = function
|
|
|
|
Pident id as p ->
|
1996-05-16 07:16:34 -07:00
|
|
|
begin try Tbl.find id s.modules with Not_found -> p end
|
1995-05-04 03:15:53 -07:00
|
|
|
| Pdot(p, n, pos) ->
|
|
|
|
Pdot(module_path s p, n, pos)
|
1995-08-23 04:55:54 -07:00
|
|
|
| Papply(p1, p2) ->
|
|
|
|
Papply(module_path s p1, module_path s p2)
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let type_path s = function
|
|
|
|
Pident id as p ->
|
1996-05-16 07:16:34 -07:00
|
|
|
begin try Tbl.find id s.types with Not_found -> p end
|
1995-05-04 03:15:53 -07:00
|
|
|
| Pdot(p, n, pos) ->
|
|
|
|
Pdot(module_path s p, n, pos)
|
1995-08-23 04:55:54 -07:00
|
|
|
| Papply(p1, p2) ->
|
|
|
|
fatal_error "Subst.type_path"
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1997-03-09 11:08:14 -08:00
|
|
|
(* Similar to [Ctype.nondep_type_rec]. *)
|
|
|
|
let rec typexp s ty =
|
1996-04-22 04:15:41 -07:00
|
|
|
let ty = repr ty in
|
1999-11-30 08:07:38 -08:00
|
|
|
match ty.desc with
|
|
|
|
Tvar ->
|
|
|
|
ty
|
|
|
|
| Tsubst ty ->
|
|
|
|
ty
|
|
|
|
| _ ->
|
1997-03-09 11:08:14 -08:00
|
|
|
let desc = ty.desc in
|
1997-03-24 12:12:16 -08:00
|
|
|
save_desc ty desc;
|
1999-11-30 08:07:38 -08:00
|
|
|
let ty' = newgenvar () in (* Stub *)
|
|
|
|
ty.desc <- Tsubst ty';
|
1997-03-09 11:08:14 -08:00
|
|
|
ty'.desc <-
|
|
|
|
begin match desc with
|
|
|
|
Tvar | Tlink _ ->
|
|
|
|
fatal_error "Subst.typexp"
|
2001-04-19 01:34:21 -07:00
|
|
|
| Tarrow(l, t1, t2, c) ->
|
|
|
|
let c =
|
|
|
|
if commu_repr c = Cok then Cok else Clink (ref Cunknown) in
|
|
|
|
Tarrow(l, typexp s t1, typexp s t2, c)
|
1997-03-09 11:08:14 -08:00
|
|
|
| Ttuple tl ->
|
|
|
|
Ttuple(List.map (typexp s) tl)
|
|
|
|
| Tconstr(p, tl, abbrev) ->
|
|
|
|
Tconstr(type_path s p, List.map (typexp s) tl, ref Mnil)
|
|
|
|
| Tobject (t1, name) ->
|
|
|
|
Tobject (typexp s t1,
|
|
|
|
ref (match !name with
|
|
|
|
None -> None
|
|
|
|
| Some (p, tl) ->
|
|
|
|
Some (type_path s p, List.map (typexp s) tl)))
|
1999-11-30 08:07:38 -08:00
|
|
|
| Tvariant row ->
|
|
|
|
let row = row_repr row in
|
|
|
|
let more = repr row.row_more in
|
|
|
|
(* We must substitute in a subtle way *)
|
|
|
|
begin match more.desc with
|
|
|
|
Tsubst ty2 ->
|
|
|
|
(* This variant type has been already copied *)
|
|
|
|
ty.desc <- Tsubst ty2; (* avoid Tlink in the new type *)
|
|
|
|
Tlink ty2
|
|
|
|
| _ ->
|
|
|
|
(* We create a new copy *)
|
|
|
|
let bound = ref [] in
|
|
|
|
let fields =
|
|
|
|
List.map
|
|
|
|
(fun (l,fi) -> l,
|
|
|
|
match row_field_repr fi with
|
|
|
|
Rpresent (Some ty) -> Rpresent(Some (typexp s ty))
|
2001-03-02 16:14:35 -08:00
|
|
|
| Reither(c, l, m, _) ->
|
1999-11-30 08:07:38 -08:00
|
|
|
let l = List.map (typexp s) l in
|
|
|
|
bound := l @ !bound;
|
2001-03-02 16:14:35 -08:00
|
|
|
Reither(c, l, m, ref None)
|
1999-11-30 08:07:38 -08:00
|
|
|
| fi -> fi)
|
|
|
|
row.row_fields
|
|
|
|
and name =
|
2001-02-21 02:29:43 -08:00
|
|
|
may_map
|
|
|
|
(fun (p,l) -> type_path s p, List.map (typexp s) l)
|
|
|
|
row.row_name in
|
1999-11-30 08:07:38 -08:00
|
|
|
let var =
|
|
|
|
Tvariant { row_fields = fields; row_more = newgenvar();
|
|
|
|
row_bound = !bound;
|
|
|
|
row_closed = row.row_closed; row_name = name }
|
|
|
|
in
|
|
|
|
(* Remember it for other occurences *)
|
|
|
|
save_desc more more.desc;
|
|
|
|
more.desc <- ty.desc;
|
|
|
|
var
|
|
|
|
end
|
1997-05-11 14:48:21 -07:00
|
|
|
| Tfield(label, kind, t1, t2) ->
|
|
|
|
begin match field_kind_repr kind with
|
|
|
|
Fpresent ->
|
|
|
|
Tfield(label, Fpresent, typexp s t1, typexp s t2)
|
1998-06-24 12:22:26 -07:00
|
|
|
| Fabsent ->
|
|
|
|
Tlink (typexp s t2)
|
|
|
|
| Fvar _ (* {contents = None} *) as k ->
|
|
|
|
Tfield(label, k, typexp s t1, typexp s t2)
|
1997-05-11 14:48:21 -07:00
|
|
|
end
|
1997-03-09 11:08:14 -08:00
|
|
|
| Tnil ->
|
|
|
|
Tnil
|
1999-11-30 08:07:38 -08:00
|
|
|
| Tsubst _ ->
|
|
|
|
assert false
|
1997-03-09 11:08:14 -08:00
|
|
|
end;
|
|
|
|
ty'
|
1996-04-22 04:15:41 -07:00
|
|
|
|
1997-03-13 13:11:19 -08:00
|
|
|
(*
|
1997-03-18 13:05:49 -08:00
|
|
|
Always make a copy of the type. If this is not done, type levels
|
|
|
|
might not be correct.
|
1997-03-13 13:11:19 -08:00
|
|
|
*)
|
1996-04-22 04:15:41 -07:00
|
|
|
let type_expr s ty =
|
1997-03-09 11:08:14 -08:00
|
|
|
let ty' = typexp s ty in
|
|
|
|
cleanup_types ();
|
|
|
|
ty'
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let type_declaration s decl =
|
1997-03-09 11:08:14 -08:00
|
|
|
let decl =
|
|
|
|
{ type_params = List.map (typexp s) decl.type_params;
|
|
|
|
type_arity = decl.type_arity;
|
|
|
|
type_kind =
|
|
|
|
begin match decl.type_kind with
|
|
|
|
Type_abstract -> Type_abstract
|
|
|
|
| Type_variant cstrs ->
|
|
|
|
Type_variant(
|
|
|
|
List.map (fun (n, args) -> (n, List.map (typexp s) args))
|
|
|
|
cstrs)
|
2000-03-21 06:43:25 -08:00
|
|
|
| Type_record(lbls, rep) ->
|
1997-03-09 11:08:14 -08:00
|
|
|
Type_record(
|
|
|
|
List.map (fun (n, mut, arg) -> (n, mut, typexp s arg))
|
2000-03-21 06:43:25 -08:00
|
|
|
lbls,
|
|
|
|
rep)
|
1997-03-09 11:08:14 -08:00
|
|
|
end;
|
|
|
|
type_manifest =
|
|
|
|
begin match decl.type_manifest with
|
|
|
|
None -> None
|
|
|
|
| Some ty -> Some(typexp s ty)
|
2000-09-06 03:21:07 -07:00
|
|
|
end;
|
|
|
|
type_variance = decl.type_variance;
|
1997-03-09 11:08:14 -08:00
|
|
|
}
|
|
|
|
in
|
|
|
|
cleanup_types ();
|
|
|
|
decl
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1998-06-24 12:22:26 -07:00
|
|
|
let class_signature s sign =
|
|
|
|
{ cty_self = typexp s sign.cty_self;
|
|
|
|
cty_vars = Vars.map (function (m, t) -> (m, typexp s t)) sign.cty_vars;
|
|
|
|
cty_concr = sign.cty_concr }
|
|
|
|
|
|
|
|
let rec class_type s =
|
|
|
|
function
|
|
|
|
Tcty_constr (p, tyl, cty) ->
|
|
|
|
Tcty_constr (type_path s p, List.map (typexp s) tyl, class_type s cty)
|
|
|
|
| Tcty_signature sign ->
|
|
|
|
Tcty_signature (class_signature s sign)
|
1999-11-30 08:07:38 -08:00
|
|
|
| Tcty_fun (l, ty, cty) ->
|
|
|
|
Tcty_fun (l, typexp s ty, class_type s cty)
|
1998-06-24 12:22:26 -07:00
|
|
|
|
|
|
|
let class_declaration s decl =
|
1996-04-22 04:15:41 -07:00
|
|
|
let decl =
|
1997-03-09 11:08:14 -08:00
|
|
|
{ cty_params = List.map (typexp s) decl.cty_params;
|
1998-06-24 12:22:26 -07:00
|
|
|
cty_type = class_type s decl.cty_type;
|
|
|
|
cty_path = type_path s decl.cty_path;
|
1996-04-22 04:15:41 -07:00
|
|
|
cty_new =
|
|
|
|
begin match decl.cty_new with
|
1997-05-19 08:42:21 -07:00
|
|
|
None -> None
|
1997-03-09 11:08:14 -08:00
|
|
|
| Some ty -> Some (typexp s ty)
|
1997-05-19 08:42:21 -07:00
|
|
|
end }
|
1996-04-22 04:15:41 -07:00
|
|
|
in
|
1997-03-09 11:08:14 -08:00
|
|
|
cleanup_types ();
|
|
|
|
decl
|
|
|
|
|
1998-06-24 12:22:26 -07:00
|
|
|
let cltype_declaration s decl =
|
|
|
|
let decl =
|
|
|
|
{ clty_params = List.map (typexp s) decl.clty_params;
|
|
|
|
clty_type = class_type s decl.clty_type;
|
|
|
|
clty_path = type_path s decl.clty_path }
|
|
|
|
in
|
|
|
|
cleanup_types ();
|
|
|
|
decl
|
|
|
|
|
|
|
|
let class_type s cty =
|
|
|
|
let cty = class_type s cty in
|
|
|
|
cleanup_types ();
|
|
|
|
cty
|
|
|
|
|
1997-03-09 11:08:14 -08:00
|
|
|
let value_description s descr =
|
|
|
|
{ val_type = type_expr s descr.val_type;
|
|
|
|
val_kind = descr.val_kind }
|
|
|
|
|
|
|
|
let exception_declaration s tyl =
|
|
|
|
List.map (type_expr s) tyl
|
1996-04-22 04:15:41 -07:00
|
|
|
|
2000-07-27 05:40:43 -07:00
|
|
|
let rec rename_bound_idents s idents = function
|
|
|
|
[] -> (List.rev idents, s)
|
|
|
|
| Tsig_type(id, d) :: sg ->
|
|
|
|
let id' = Ident.rename id in
|
|
|
|
rename_bound_idents (add_type id (Pident id') s) (id' :: idents) sg
|
|
|
|
| Tsig_module(id, mty) :: sg ->
|
|
|
|
let id' = Ident.rename id in
|
|
|
|
rename_bound_idents (add_module id (Pident id') s) (id' :: idents) sg
|
|
|
|
| Tsig_modtype(id, d) :: sg ->
|
|
|
|
let id' = Ident.rename id in
|
|
|
|
rename_bound_idents (add_modtype id (Tmty_ident(Pident id')) s)
|
|
|
|
(id' :: idents) sg
|
2001-07-05 05:23:52 -07:00
|
|
|
| (Tsig_value(id, _) | Tsig_exception(id, _) |
|
|
|
|
Tsig_class(id, _) | Tsig_cltype(id, _)) :: sg ->
|
|
|
|
let id' = Ident.rename id in
|
|
|
|
rename_bound_idents s (id' :: idents) sg
|
2000-07-27 05:40:43 -07:00
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
let rec modtype s = function
|
|
|
|
Tmty_ident p as mty ->
|
|
|
|
begin match p with
|
|
|
|
Pident id ->
|
1996-05-16 07:16:34 -07:00
|
|
|
begin try Tbl.find id s.modtypes with Not_found -> mty end
|
1995-05-04 03:15:53 -07:00
|
|
|
| Pdot(p, n, pos) ->
|
|
|
|
Tmty_ident(Pdot(module_path s p, n, pos))
|
1995-08-23 04:55:54 -07:00
|
|
|
| Papply(p1, p2) ->
|
|
|
|
fatal_error "Subst.modtype"
|
1995-05-04 03:15:53 -07:00
|
|
|
end
|
|
|
|
| Tmty_signature sg ->
|
|
|
|
Tmty_signature(signature s sg)
|
|
|
|
| Tmty_functor(id, arg, res) ->
|
2000-05-15 23:28:21 -07:00
|
|
|
let id' = Ident.rename id in
|
|
|
|
Tmty_functor(id', modtype s arg,
|
|
|
|
modtype (add_module id (Pident id') s) res)
|
1995-05-04 03:15:53 -07:00
|
|
|
|
2000-07-27 05:40:43 -07:00
|
|
|
and signature s sg =
|
|
|
|
(* Components of signature may be mutually recursive (e.g. type declarations
|
|
|
|
or class and type declarations), so first build global renaming
|
|
|
|
substitution... *)
|
|
|
|
let (new_idents, s') = rename_bound_idents s [] sg in
|
|
|
|
(* ... then apply it to each signature component in turn *)
|
2001-07-05 05:23:52 -07:00
|
|
|
List.map2 (signature_component s') sg new_idents
|
2000-07-27 05:40:43 -07:00
|
|
|
|
2001-07-05 05:23:52 -07:00
|
|
|
and signature_component s comp newid =
|
|
|
|
match comp with
|
|
|
|
Tsig_value(id, d) ->
|
|
|
|
Tsig_value(newid, value_description s d)
|
|
|
|
| Tsig_type(id, d) ->
|
|
|
|
Tsig_type(newid, type_declaration s d)
|
|
|
|
| Tsig_exception(id, d) ->
|
|
|
|
Tsig_exception(newid, exception_declaration s d)
|
|
|
|
| Tsig_module(id, mty) ->
|
|
|
|
Tsig_module(newid, modtype s mty)
|
|
|
|
| Tsig_modtype(id, d) ->
|
|
|
|
Tsig_modtype(newid, modtype_declaration s d)
|
|
|
|
| Tsig_class(id, d) ->
|
|
|
|
Tsig_class(newid, class_declaration s d)
|
|
|
|
| Tsig_cltype(id, d) ->
|
|
|
|
Tsig_cltype(newid, cltype_declaration s d)
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
and modtype_declaration s = function
|
|
|
|
Tmodtype_abstract -> Tmodtype_abstract
|
|
|
|
| Tmodtype_manifest mty -> Tmodtype_manifest(modtype s mty)
|