aboutsummaryrefslogtreecommitdiff
path: root/kernel/names.ml
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/names.ml')
-rw-r--r--kernel/names.ml253
1 files changed, 97 insertions, 156 deletions
diff --git a/kernel/names.ml b/kernel/names.ml
index 4965a733c9..c4ced8e999 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -11,101 +11,16 @@
open Pp
open Util
+(*s Identifiers *)
+
(* Utilities *)
let code_of_0 = Char.code '0'
let code_of_9 = Char.code '9'
-(* This checks that a string is acceptable as an ident, i.e. starts
- with a letter and contains only letters, digits or "'" *)
-
-let check_ident_suffix i l s =
- for i=1 to l-1 do
- let c = String.get s i in
- if not (is_letter c or is_digit c or c = '\'') then
- error
- ("Character "^(String.sub s i 1)^" is not allowed in an identifier")
- done
-
-let check_ident s =
- let l = String.length s in
- if l = 0 then error "The empty string is not an identifier";
- let c = String.get s 0 in
- if not (is_letter c) then error "An identifier starts with a letter";
- check_ident_suffix 1 l s
-
-let check_suffix s = check_ident_suffix 0 (String.length s) s
-
-let is_ident s = try check_ident s; true with _ -> false
-
(* Identifiers *)
-(*
-module Ident = struct
-
-type t = {
- atom : string ;
- index : int }
-
-let repr_ident { atom = sa; index = n } =
- if n = -1 then (sa,None) else (sa,Some n)
-
-let make_ident sa = function
- | Some n ->
- let c = Char.code (String.get sa (String.length sa -1)) in
- if c < code_of_0 or c > code_of_9 then { atom = sa; index = n }
- else { atom = sa^"_"; index = n }
- | None -> { atom = sa; index = -1 }
-
-let string_of_id id = match repr_ident id with
- | (s,None) -> s
- | (s,Some n) -> s ^ (string_of_int n)
-
-let id_of_string s =
- let slen = String.length s in
- (* [n'] is the position of the first non nullary digit *)
- let rec numpart n n' =
- if n = 0 then
- failwith
- ("The string " ^ s ^ " is not an identifier: it contains only digits")
- else
- let c = Char.code (String.get s (n-1)) in
- if c = code_of_0 && n <> slen then
- numpart (n-1) n'
- else if code_of_0 <= c && c <= code_of_9 then
- numpart (n-1) (n-1)
- else
- n'
- in
- let numstart = numpart slen slen in
- if numstart = slen then
- { atom = s; index = -1 }
- else
- { atom = String.sub s 0 numstart;
- index = int_of_string (String.sub s numstart (slen - numstart)) }
-
-let first_char id =
- assert (id.atom <> "");
- String.make 1 id.atom.[0]
-
-let id_ord { atom = s1; index = n1 } { atom = s2; index = n2 } =
- let s_bit = Pervasives.compare s1 s2 in
- if s_bit = 0 then n1 - n2 else s_bit
-(* Rem : if an ident starts with toto00 then after successive
- renamings it comes to toto09, then it goes on with toto010 *)
-let lift_ident { atom = str; index = i } = { atom = str; index = i+1 }
-let restart_ident id = { id with index = 0 }
-let has_index id = (id.index <> -1)
-
-let hash_sub hstr id = { atom = hstr id.atom; index = id.index }
-let equal id1 id2 = id1.atom == id2.atom && id1.index = id2.index
-
-end (* End of module Ident *)
-*)
-(* Second implementation *)
-module Ident = struct
-
-type t = string
+type identifier = string
let cut_ident s =
let slen = String.length s in
@@ -139,13 +54,7 @@ let make_ident sa = function
let c = Char.code (String.get sa (String.length sa -1)) in
if c < code_of_0 or c > code_of_9 then sa ^ (string_of_int n)
else sa ^ "_" ^ (string_of_int n)
- | None -> sa
-
-let add_suffix id s = check_suffix s; id^s
-let add_prefix s id = check_ident s; s^id
-
-let string_of_id id = id
-let id_of_string s = s
+ | None -> String.copy sa
let first_char id =
assert (id <> "");
@@ -155,7 +64,7 @@ let id_ord = Pervasives.compare
(* Rem: semantics is a bit different, if an ident starts with toto00 then
after successive renamings it comes to toto09, then it goes on with toto10 *)
-let lift_ident id =
+let lift_subscript id =
let len = String.length id in
let rec add carrypos =
let c = id.[carrypos] in
@@ -180,28 +89,52 @@ let lift_ident id =
end
in add (len-1)
-let has_index id = is_digit (id.[String.length id - 1])
+let has_subscript id = is_digit (id.[String.length id - 1])
-let restart_ident id =
+let forget_subscript id =
let len = String.length id in
let numstart = cut_ident id in
let newid = String.make (numstart+1) '0' in
String.blit id 0 newid 0 numstart;
newid
-let hash_sub hstr id = hstr id
-let equal id1 id2 = id1 == id2
+(* This checks that a string is acceptable as an ident, i.e. starts
+ with a letter and contains only letters, digits or "'" *)
+
+let check_ident_suffix i l s =
+ for i=1 to l-1 do
+ let c = String.get s i in
+ if not (is_letter c or is_digit c or c = '\'' or c = '_' or c = '@') then
+ error
+ ("Character "^(String.sub s i 1)^" is not allowed in an identifier")
+ done
+
+let check_ident s =
+ let l = String.length s in
+ if l = 0 then error "The empty string is not an identifier";
+ let c = String.get s 0 in
+ if (is_letter c) or c = '_' or c = '$' then check_ident_suffix 1 l s
+ else error (s^": an identifier starts with a letter")
+
+let is_ident s = try check_ident s; true with _ -> false
-end (* End of module Ident *)
+let check_suffix s = check_ident_suffix 0 (String.length s) s
-type identifier = Ident.t
-let repr_ident = Ident.repr_ident
-let make_ident = Ident.make_ident
let add_suffix id s = check_suffix s; id^s
let add_prefix s id = check_ident s; s^id
-let string_of_id = Ident.string_of_id
-let id_of_string = Ident.id_of_string
-let id_ord = Ident.id_ord
+
+let string_of_id id = String.copy id
+let id_of_string s = check_ident s; String.copy s
+
+(* Hash-consing of identifier *)
+module Hident = Hashcons.Make(
+ struct
+ type t = string
+ type u = string -> string
+ let hash_sub hstr id = hstr id
+ let equal id1 id2 = id1 == id2
+ let hash = Hashtbl.hash
+ end)
module IdOrdered =
struct
@@ -216,18 +149,18 @@ let atompart_of_id id = fst (repr_ident id)
let index_of_id id = snd (repr_ident id)
let pr_id id = [< 'sTR (string_of_id id) >]
-let first_char = Ident.first_char
+let wildcard = id_of_string "_"
(* Fresh names *)
-let lift_ident = Ident.lift_ident
+let lift_ident = lift_subscript
let next_ident_away id avoid =
if List.mem id avoid then
- let id0 = if not (Ident.has_index id) then id else
+ let id0 = if not (has_subscript id) then id else
(* Ce serait sans doute mieux avec quelque chose inspiré de
*** make_ident id (Some 0) *** mais ça brise la compatibilité... *)
- Ident.restart_ident id in
+ forget_subscript id in
let rec name_rec id =
if List.mem id avoid then name_rec (lift_ident id) else id in
name_rec id0
@@ -272,30 +205,25 @@ let kind_of_string = function
| _ -> invalid_arg "kind_of_string"
(*s Directory paths = section names paths *)
-type dir_path = string list
-
-(*s Section paths are absolute names *)
+type module_ident = identifier
+type dir_path = module_ident list
-type section_path = {
- dirpath : dir_path ;
- basename : identifier ;
- kind : path_kind }
+module ModIdOrdered =
+ struct
+ type t = identifier
+ let compare = Pervasives.compare
+ end
-let make_path pa id k = { dirpath = pa; basename = id; kind = k }
-let repr_path { dirpath = pa; basename = id; kind = k} = (pa,id,k)
+module ModIdmap = Map.Make(ModIdOrdered)
-let kind_of_path sp = sp.kind
-let basename sp = sp.basename
-let dirpath sp = sp.dirpath
+let make_dirpath x = x
+let repr_dirpath x = x
-(* parsing and printing of section paths *)
-let string_of_dirpath sl = String.concat "." sl
+let dirpath_prefix = function
+ | [] -> anomaly "dirpath_prefix: empty dirpath"
+ | l -> snd (list_sep_last l)
-let string_of_path sp =
- let (sl,id,k) = repr_path sp in
- String.concat ""
- (List.flatten (List.map (fun s -> [s;"."]) sl)
- @ [ string_of_id id ])
+let split_dirpath d = let (b,d) = list_sep_last d in (d,b)
let parse_sp s =
let len = String.length s in
@@ -304,37 +232,60 @@ let parse_sp s =
let pos = String.index_from s n '.' in
let dir = String.sub s n (pos-n) in
let dirs,n' = decoupe_dirs (succ pos) in
- dir::dirs,n'
+ (id_of_string dir)::dirs,n'
with
| Not_found -> [],n
in
if len = 0 then invalid_arg "parse_section_path";
let dirs,n = decoupe_dirs 0 in
let id = String.sub s n (len-n) in
- dirs,id
+ dirs, (id_of_string id)
-let path_of_string s =
+let dirpath_of_string s =
try
let sl,s = parse_sp s in
- make_path sl (id_of_string s) CCI
+ sl @ [s]
with
- | Invalid_argument _ -> invalid_arg "path_of_string"
+ | Invalid_argument _ -> invalid_arg "dirpath_of_string"
-let dirpath_of_string s =
+let string_of_dirpath sl = String.concat "." (List.map string_of_id sl)
+
+let pr_dirpath sl = [< 'sTR (string_of_dirpath sl) >]
+
+(*s Section paths are absolute names *)
+
+type section_path = {
+ dirpath : dir_path ;
+ basename : identifier ;
+ kind : path_kind }
+
+let make_path pa id k = { dirpath = pa; basename = id; kind = k }
+let repr_path { dirpath = pa; basename = id; kind = k} = (pa,id,k)
+
+let kind_of_path sp = sp.kind
+let basename sp = sp.basename
+let dirpath sp = sp.dirpath
+
+(* parsing and printing of section paths *)
+let string_of_path sp =
+ let (sl,id,k) = repr_path sp in
+ (string_of_dirpath sl) ^ "." ^ (string_of_id id)
+
+let path_of_string s =
try
let sl,s = parse_sp s in
- sl @ [s]
+ make_path sl s CCI
with
- | Invalid_argument _ -> invalid_arg "dirpath_of_string"
+ | Invalid_argument _ -> invalid_arg "path_of_string"
let pr_sp sp = [< 'sTR (string_of_path sp) >]
let sp_of_wd = function
| [] -> invalid_arg "Names.sp_of_wd"
- | l -> let (bn,dp) = list_sep_last l in make_path dp (id_of_string bn) OBJ
+ | l -> let (bn,dp) = list_sep_last l in make_path dp bn OBJ
let wd_of_sp sp =
- let (sp,id,_) = repr_path sp in sp @ [string_of_id id]
+ let (sp,id,_) = repr_path sp in sp @ [id]
let sp_ord sp1 sp2 =
let (p1,id1,k) = repr_path sp1
@@ -346,7 +297,7 @@ let sp_ord sp1 sp2 =
else
ck
-let dirpath_prefix_of = list_prefix_of
+let is_dirpath_prefix_of = list_prefix_of
module SpOrdered =
struct
@@ -366,16 +317,6 @@ type inductive_path = section_path * int
type constructor_path = inductive_path * int
type mutual_inductive_path = section_path
-(* Hash-consing of identifier *)
-module Hident = Hashcons.Make(
- struct
- type t = Ident.t
- type u = string -> string
- let hash_sub = Ident.hash_sub
- let equal = Ident.equal
- let hash = Hashtbl.hash
- end)
-
(* Hash-consing of name objects *)
module Hname = Hashcons.Make(
struct
@@ -395,9 +336,9 @@ module Hname = Hashcons.Make(
module Hsp = Hashcons.Make(
struct
type t = section_path
- type u = (identifier -> identifier) * (string -> string)
- let hash_sub (hident,hstr) sp =
- { dirpath = List.map hstr sp.dirpath;
+ type u = identifier -> identifier
+ let hash_sub hident sp =
+ { dirpath = List.map hident sp.dirpath;
basename = hident sp.basename;
kind = sp.kind }
let equal sp1 sp2 =
@@ -411,6 +352,6 @@ let hcons_names () =
let hstring = Hashcons.simple_hcons Hashcons.Hstring.f () in
let hident = Hashcons.simple_hcons Hident.f hstring in
let hname = Hashcons.simple_hcons Hname.f hident in
- let hspcci = Hashcons.simple_hcons Hsp.f (hident,hstring) in
- let hspfw = Hashcons.simple_hcons Hsp.f (hident,hstring) in
+ let hspcci = Hashcons.simple_hcons Hsp.f hident in
+ let hspfw = Hashcons.simple_hcons Hsp.f hident in
(hspcci,hspfw,hname,hident,hstring)