diff --git a/compiler/global/idents.ml b/compiler/global/idents.ml index 1092c47..d78524b 100644 --- a/compiler/global/idents.ml +++ b/compiler/global/idents.ml @@ -18,6 +18,8 @@ type ident = { type var_ident = ident +let num = ref 0 + let compare id1 id2 = compare id1.num id2.num let sourcename id = id.source let name id = @@ -29,15 +31,6 @@ let name id = let set_sourcename id v = { id with source = v } -let num = ref 0 -let fresh s = - num := !num + 1; - { num = !num; source = s; is_generated = true } - -let ident_of_name s = - num := !num + 1; - { num = !num; source = s; is_generated = false } - let fprint_t ff id = Format.fprintf ff "%s" (name id) module M = struct @@ -84,26 +77,47 @@ end module S = Set.Make (struct type t = string let compare = Pervasives.compare end) -(** @return a unique string for each identifier. Idents corresponding - to variables defined in the source file have the same name unless - there is a collision. *) -let name = - let used_names = ref S.empty in - let env = ref Env.empty in - let rec fresh_string base = - let base = name (fresh base) in - if S.mem base !used_names then fresh_string base else base - in - let unique_name n = - if Env.mem n !env then - Env.find n !env - else - let s = name n in - let s = if S.mem s !used_names then fresh_string s else s in - used_names := S.add s !used_names; - env := Env.add n s !env; - s - in - unique_name +module UniqueNames = +struct + let used_names = ref S.empty + let env = ref Env.empty + + let new_function () = + used_names := S.empty + + (** @return a unique string for each identifier. Idents corresponding + to variables defined in the source file have the same name unless + there is a collision. *) + let assign_name n = + let fresh s = + num := !num + 1; + s ^ "_" ^ (string_of_int !num) + in + let rec fresh_string base = + let base = fresh base in + if S.mem base !used_names then fresh_string base else base + in + if not (Env.mem n !env) then + let s = name n in + let s = if S.mem s !used_names then fresh_string s else s in + used_names := S.add s !used_names; + env := Env.add n s !env + + let name id = + Env.find id !env +end + +let fresh s = + num := !num + 1; + let id = { num = !num; source = s; is_generated = true } in + UniqueNames.assign_name id; id + +let ident_of_name s = + num := !num + 1; + let id = { num = !num; source = s; is_generated = false } in + UniqueNames.assign_name id; id + +let name id = UniqueNames.name id +let new_function () = UniqueNames.new_function () let print_ident ff id = Format.fprintf ff "%s" (name id) diff --git a/compiler/global/idents.mli b/compiler/global/idents.mli index c2f297d..4ce8c6e 100644 --- a/compiler/global/idents.mli +++ b/compiler/global/idents.mli @@ -22,6 +22,9 @@ val fresh : string -> ident (** [ident_of_name n] returns an identifier corresponding to a _source_ variable (do not use it for generated variables). *) val ident_of_name : string -> ident +(** Resets the sets that makes sure that idents are mapped to unique + identifiers. Should be called when scoping a new function. *) +val new_function : unit -> unit (** Maps taking an identifier as a key. *) module Env : diff --git a/compiler/heptagon/parsing/hept_scoping.ml b/compiler/heptagon/parsing/hept_scoping.ml index e845560..b7458de 100644 --- a/compiler/heptagon/parsing/hept_scoping.ml +++ b/compiler/heptagon/parsing/hept_scoping.ml @@ -391,6 +391,7 @@ let args_of_var_decs local_const = (translate_type vd.v_loc local_const vd.v_type)) let translate_node node = + Idents.new_function (); (* Node's params go to local_const env *) let local_const = build_const node.n_loc node.n_params in (* Inputs and outputs define the initial local env *)