@@ -25,6 +25,7 @@ type t =
25
25
| Predef of { name : string ; stamp : int }
26
26
(* the stamp is here only for fast comparison, but the name of
27
27
predefined identifiers is always unique. *)
28
+ | Instance of string * string list
28
29
29
30
(* A stamp of 0 denotes a persistent identifier *)
30
31
@@ -46,11 +47,19 @@ let create_predef s =
46
47
let create_persistent s =
47
48
Global s
48
49
50
+ let create_instance f args =
51
+ Instance (f, args)
52
+
53
+ let format_instance f args =
54
+ let args_with_brackets = List. map (Format. sprintf " [%s]" ) args in
55
+ String. concat " " (f :: args_with_brackets)
56
+
49
57
let name = function
50
58
| Local { name; _ }
51
59
| Scoped { name; _ }
52
60
| Global name
53
61
| Predef { name; _ } -> name
62
+ | Instance (f , args ) -> format_instance f args
54
63
55
64
let rename = function
56
65
| Local { name; stamp = _ }
@@ -72,12 +81,14 @@ let unique_name = function
72
81
(* we know that none of the predef names (currently) finishes in
73
82
"_<some number>", and that their name is unique. *)
74
83
name
84
+ | Instance _ as i -> name i
75
85
76
86
let unique_toplevel_name = function
77
87
| Local { name; stamp }
78
88
| Scoped { name; stamp } -> name ^ " /" ^ Int. to_string stamp
79
89
| Global name
80
90
| Predef { name; _ } -> name
91
+ | Instance _ as i -> name i
81
92
82
93
let equal i1 i2 =
83
94
match i1, i2 with
@@ -88,6 +99,8 @@ let equal i1 i2 =
88
99
| Predef { stamp = s1 ; _ } , Predef { stamp = s2 } ->
89
100
(* if they don't have the same stamp, they don't have the same name *)
90
101
s1 = s2
102
+ | Instance (f1 , args1 ), Instance (f2 , args2 ) ->
103
+ String. equal f1 f2 && List. equal String. equal args1 args2
91
104
| _ ->
92
105
false
93
106
@@ -99,6 +112,8 @@ let same i1 i2 =
99
112
s1 = s2
100
113
| Global name1 , Global name2 ->
101
114
name1 = name2
115
+ | Instance (f1 , args1 ), Instance (f2 , args2 ) ->
116
+ String. equal f1 f2 && List. equal String. equal args1 args2
102
117
| _ ->
103
118
false
104
119
@@ -110,7 +125,7 @@ let stamp = function
110
125
let scope = function
111
126
| Scoped { scope; _ } -> scope
112
127
| Local _ -> highest_scope
113
- | Global _ | Predef _ -> lowest_scope
128
+ | Global _ | Predef _ | Instance _ -> lowest_scope
114
129
115
130
let reinit_level = ref (- 1 )
116
131
@@ -121,18 +136,28 @@ let reinit () =
121
136
122
137
let is_global = function
123
138
| Global _ -> true
139
+ | Instance _ -> true
124
140
| _ -> false
125
141
126
142
let is_global_or_predef = function
127
143
| Local _
128
144
| Scoped _ -> false
129
145
| Global _
130
- | Predef _ -> true
146
+ | Predef _
147
+ | Instance _ -> true
131
148
132
149
let is_predef = function
133
150
| Predef _ -> true
134
151
| _ -> false
135
152
153
+ let is_instance = function
154
+ | Instance _ -> true
155
+ | _ -> false
156
+
157
+ let split_instance = function
158
+ | Instance (f , args ) -> Some (f, args)
159
+ | _ -> None
160
+
136
161
let print ~with_scope ppf =
137
162
let open Format in
138
163
function
@@ -147,6 +172,9 @@ let print ~with_scope ppf =
147
172
fprintf ppf " %s%s%s" name
148
173
(if ! Clflags. unique_ids then sprintf " /%i" n else " " )
149
174
(if with_scope then sprintf " [%i]" scope else " " )
175
+ | Instance (f , args ) ->
176
+ fprintf ppf " %s!" f;
177
+ List. iter (fprintf ppf " [%s!]" ) args
150
178
151
179
let print_with_scope ppf id = print ~with_scope: true ppf id
152
180
@@ -343,6 +371,12 @@ let compare x y =
343
371
| Global x , Global y -> compare x y
344
372
| Global _ , _ -> 1
345
373
| _ , Global _ -> (- 1 )
374
+ | Instance (f1 , args1 ), Instance (f2 , args2 ) ->
375
+ let c = String. compare f1 f2 in
376
+ if c <> 0 then c
377
+ else List. compare String. compare args1 args2
378
+ | Instance _ , _ -> 1
379
+ | _ , Instance _ -> (- 1 )
346
380
| Predef { stamp = s1 ; _ } , Predef { stamp = s2 ; _ } -> compare s1 s2
347
381
348
382
let output oc id = output_string oc (unique_name id)
0 commit comments