summaryrefslogtreecommitdiff
path: root/src/PureToExtract.ml
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/PureToExtract.ml188
1 files changed, 93 insertions, 95 deletions
diff --git a/src/PureToExtract.ml b/src/PureToExtract.ml
index b9f5a9a1..d5fd4432 100644
--- a/src/PureToExtract.ml
+++ b/src/PureToExtract.ml
@@ -25,18 +25,6 @@ type extraction_ctx = {
functions, etc.
*)
-(** We use identifiers to look for name clashes *)
-type id =
- | FunId of FunDefId.id * RegionGroupId.id option
- | TypeId of TypeDefId.id
- | VarId of VarId.id
- | UnknownId
- (** Used for stored various strings like keywords, definitions which
- should always be in context, etc. and which can't be linked to one
- of the above.
- *)
-[@@deriving show, ord]
-
type region_group_info = {
id : RegionGroupId.id;
(** The id of the region group.
@@ -49,6 +37,9 @@ type region_group_info = {
*)
}
+module StringSet = Collections.MakeSet (Collections.OrderedString)
+module StringMap = Collections.MakeMap (Collections.OrderedString)
+
type name = Identifiers.name
type name_formatter = {
@@ -66,11 +57,18 @@ type name_formatter = {
- region group information in case of a backward function
(`None` if forward function)
*)
- var_basename : name -> string;
+ var_basename : StringSet.t -> ty -> string;
(** Generates a variable basename.
+
+ Inputs:
+ - the set of names used in the context so far
+ - the type of the variable (can be useful for heuristics, in order
+ not to always use "x" for instance, whenever naming anonymous
+ variables)
Note that once the formatter generated a basename, we add an index
- if necessary to prevent name clashes.
+ if necessary to prevent name clashes: the burden of name clashes checks
+ is thus on the caller's side.
*)
}
(** A name formatter's role is to come up with name suggestions.
@@ -148,84 +146,84 @@ let compute_fun_def_name (ctx : extraction_ctx) (fmt : name_formatter)
in
fmt.fun_name fun_id basename num_region_groups rg_info
-(*
- let name_to_string (n : name) : string = show_name n
-
- module NameOrderedType = struct
- type t = name
-
- let compare = compare_name
-
- let to_string = name_to_string
-
- let pp_t = pp_name
-
- let show_t = show_name
- end
-
- module NameMap = Collections.MakeMapInj (NameOrderedType) (Id.NameOrderedType)
- (** Notice that we use the *injective* map to map identifiers to names.
-
- Of course, even if those names (which are string lists) don't collide,
- when converting them to strings we can still introduce collisions: we
- check that later.
-
- Note that we use injective maps for sanity: though we write the name
- generation with collision in mind, it is always good to have such checks.
- *)*)
-
-(*let translate_fun_name (fdef : A.fun_def) (bid : T.RegionGroupId.id option) :
- Id.name =
- let sg = fdef.signature in
- (* General function to generate a suffix for a region group
- * (i.e., an abstraction)*)
- let rg_to_string (rg : T.region_var_group) : string =
- (* We are just a little bit smart:
- - if there is exactly one region id in the region group and this region
- has a name, we use this name
- - otherwise, we use the region number (note that region names shouldn't
- start with numbers)
- *)
- match rg.T.regions with
- | [ rid ] -> (
- let rvar = T.RegionVarId.nth sg.region_params rid in
- match rvar.name with
- | None -> T.RegionGroupId.to_string rg.T.id
- | Some name -> name)
- | _ -> T.RegionGroupId.to_string rg.T.id
- in
- (* There are several cases:
- - this is a forward function: we add "_fwd"
- - this is a backward function:
- - this function has one backward function: we add "_back"
- - this function has several backward function: we add "_back" and an
- additional suffix to identify the precise backward function
- *)
- let suffix =
- match bid with
- | None -> "_fwd"
- | Some bid -> (
- match sg.regions_hierarchy with
- | [] ->
- failwith "Unreachable"
- (* we can't get there if we ask for a back function *)
- | [ _ ] ->
- (* Exactly one backward function *)
- "_back"
- | _ ->
- (* Several backward functions *)
- let rg = T.RegionGroupId.nth sg.regions_hierarchy bid in
- "_back" ^ rg_to_string rg)
- in
- (* Final name *)
- let rec add_to_last (n : Id.name) : Id.name =
- match n with
- | [] -> failwith "Unreachable"
- | [ x ] -> [ x ^ suffix ]
- | x :: n -> x :: add_to_last n
- in
- add_to_last fdef.name
-
- (** Generates a name for a type (simply reuses the name in the definition) *)
- let translate_type_name (def : T.type_def) : Id.name = def.T.name
-*)
+(** We use identifiers to look for name clashes *)
+type id =
+ | FunId of A.fun_id * RegionGroupId.id option
+ | TypeId of type_id
+ | VarId of VarId.id
+ | UnknownId
+ (** Used for stored various strings like keywords, definitions which
+ should always be in context, etc. and which can't be linked to one
+ of the above.
+ *)
+[@@deriving show, ord]
+
+module IdOrderedType = struct
+ type t = id
+
+ let compare = compare_id
+
+ let to_string = show_id
+
+ let pp_t = pp_id
+
+ let show_t = show_id
+end
+
+module IdMap = Collections.MakeMap (IdOrderedType)
+
+type names_map = {
+ id_to_name : string IdMap.t;
+ name_to_id : id StringMap.t;
+ (** The name to id map is used to look for name clashes, and generate nice
+ debugging messages: if there is a name clash, it is useful to know
+ precisely which identifiers are mapped to the same name...
+ *)
+ names_set : StringSet.t;
+}
+(** The names map stores the mappings from names to identifiers and vice-versa.
+
+ We use it for lookups (during the translation) and to check for name clashes.
+ *)
+
+let names_map_add (id : id) (name : string) (nm : names_map) : names_map =
+ (* Sanity check: no clashes *)
+ assert (not (StringSet.mem name nm.names_set));
+ (* Insert *)
+ let id_to_name = IdMap.add id name nm.id_to_name in
+ let name_to_id = StringMap.add name id nm.name_to_id in
+ let names_set = StringSet.add name nm.names_set in
+ { id_to_name; name_to_id; names_set }
+
+let names_map_find (id : id) (nm : names_map) : string =
+ IdMap.find id nm.id_to_name
+
+let names_map_find_function (id : A.fun_id) (rg : RegionGroupId.id option)
+ (nm : names_map) : string =
+ names_map_find (FunId (id, rg)) nm
+
+let names_map_find_local_function (id : FunDefId.id)
+ (rg : RegionGroupId.id option) (nm : names_map) : string =
+ names_map_find_function (A.Local id) rg nm
+
+let names_map_find_type (id : type_id) (nm : names_map) : string =
+ assert (id <> Tuple);
+ names_map_find (TypeId id) nm
+
+let names_map_find_local_type (id : TypeDefId.id) (nm : names_map) : string =
+ names_map_find_type (AdtId id) nm
+
+(** Make a basename unique (by adding an index).
+
+ We do this in an inefficient manner (by testing all indices starting from
+ 0) but it shouldn't be a bottleneck.
+
+ [add_index]: concatenates a given index to the variable's basename.
+ *)
+let var_basename_to_unique (names_set : StringSet.t) (add_index : int -> string)
+ : string =
+ let rec gen (i : int) : string =
+ let s = add_index i in
+ if StringSet.mem s names_set then gen (i + 1) else s
+ in
+ gen 0