2 * Right now the symbol table is just a representation of strings.
4 * ----------------------------------------------------------------
6 * Copyright (C) 1999-2002-2005 Mojave Group, Caltech
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation,
11 * version 2.1 of the License.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * Additional permission is given to link this library with the
23 * OpenSSL project's "OpenSSL" library, and with the OCaml runtime,
24 * and you may distribute the linked executables. See the file
25 * LICENSE.libmojave for more details.
27 * Author: Jason Hickey
30 * ----------------------------------------------------------------
33 * 2002 Dec 4 Michael Maire Added SymbolIndex
34 * Added sets, tables, indices for
35 * symbol pairs and triples
41 let debug_symbol = ref false
44 * Hash-cons the symbols.
47 module SymbolHashArg
=
53 let hash = Hashtbl.hash
55 let compare (i1
, s1
) (i2
, s2
) =
61 Lm_string_util.string_compare s1 s2
67 module SymbolHash
= Lm_hash.MakeHashMarshal
(SymbolHashArg
);;
69 type symbol
= SymbolHash.t
73 * We no longer use a hashtable.
74 * Symbols with a 0 index are interned.
78 (* An "empty" variable name *)
79 let empty_var = SymbolHash.create
(0, "")
81 let new_number, make
=
82 let count = ref 100 in
83 let lock = Mutex.create
() in
91 if i >= !count then begin
93 count := max
(!count) (succ
i);
96 SymbolHash.create
(i, s
))
99 * Get the integer prefix.
102 fst
(SymbolHash.get v
)
105 * Get the string suffix.
108 snd
(SymbolHash.get v
)
111 * Mangle a string so it uses printable characters.
114 let len = String.length s
in
132 let rec buffer_mangle buf s
i len =
141 Buffer.add_char buf
c
143 Buffer.add_char buf '
.'
;
144 Buffer.add_string buf
(string_of_int
(Char.code
c))
146 buffer_mangle buf s
(succ
i) (pred
len)
149 let len = String.length s
in
150 let buf = Buffer.create
len in
151 buffer_mangle buf s
0 len;
156 * Add a symbol to the table.
159 eprintf
"Bogus symbol %s@." s
;
162 let char0 = Char.code '
0'
165 (i < 0) || match s
.[i] with
167 | '
0'
-> zeros s
(pred
i)
170 let rec all_digits s
i =
171 (i<0) || match s
.[i] with
172 '
0'
.. '
9'
-> all_digits s
(pred
i)
175 let rec pad_with_underscore n s
i =
181 '
_'
-> pad_with_underscore n s
i
182 | '
0'
-> not
(zeros s
(pred
i)) && ((n
>0) || not
(all_digits s
(pred
i)))
183 | '
1'
.. '
9'
-> (n
>0) || not
(all_digits s
(pred
i))
187 let rec loop s fact n
i =
189 SymbolHash.create
(0, s
)
193 make
(String.sub s
0 (if pad_with_underscore n s
i then i else i + 1)) n
194 | '
0'
when zeros s
(i - 1) ->
195 make
(String.sub s
0 (succ
i)) n
197 loop s
(fact
* 10) (n
+ fact
* (Char.code
c - char0)) (pred
i)
199 make
(String.sub s
0 (succ
i)) n
201 (fun s
-> loop s
1 0 (String.length s
- 1))
206 let reintern = SymbolHash.reintern
208 let is_numeric_symbol v
=
209 match SymbolHash.get v
with
210 (0, s
) -> all_digits s
(String.length s
- 1)
214 * Create a new symbol.
215 * Don't add it to the table.
217 let new_symbol_string s
=
218 SymbolHash.create
(new_number (), s
)
221 new_symbol_string (to_string v
)
223 let new_symbol_pre pre v
=
224 let v = to_string v in
226 if debug debug_symbol then
234 * Create a new symbol, avoiding the ones defined by the predicate.
236 let new_name v pred
=
237 let v = to_string v in
248 * Create a new symbol, calling the function f until it
251 let new_name_gen v f
=
252 let v = to_string v in
264 * Check if the symbol is in the table.
271 * If the symbol is not a defined symbol,
274 let string_of_symbol v =
275 let i, s = SymbolHash.get
v in
276 let len = String.length
s in
277 let s = if pad_with_underscore i s len then s ^
"_" else s in
283 let output_symbol out
v =
284 Lm_printf.output_string out
(string_of_symbol v)
286 let rec output_symbol_list out vl
=
291 Lm_printf.fprintf out
"%a, %a" output_symbol v output_symbol_list vl
296 * Print extended symbols. Used in FIR printing.
300 let string_of_ext_symbol v =
301 let i, s = SymbolHash.get
v in
302 let has_special_char s =
304 for i = 0 to String.length
s - 1 do
305 let c = Char.lowercase
(String.get
s i) in
306 if not
((Char.code
c >= Char.code 'a'
&& Char.code
c <= Char.code 'z'
)
307 || (Char.code
c >= Char.code '
0'
&& Char.code
c <= Char.code '
9'
)
323 if has_special_char s then
328 let pp_print_ext_symbol buf v =
329 pp_print_string
buf (string_of_ext_symbol v)
331 let pp_print_symbol buf v =
332 pp_print_string
buf (string_of_symbol v)
334 let rec pp_print_symbol_list buf vl
=
337 pp_print_symbol buf v
339 fprintf
buf "%a, %a" pp_print_symbol v pp_print_symbol_list vl
344 * Compare for equality.
346 let eq = SymbolHash.equal
348 let compare = SymbolHash.compare
350 let hash = SymbolHash.hash
353 * Compare pair of symbols for equality.
355 let compare_pair (s1
, s2
) (s1'
, s2'
) =
356 let cmp = compare s1 s1'
in
363 * Compare triple of symbols for equality.
365 let compare_triple (s1
, s2
, s3
) (s1'
, s2'
, s3'
) =
366 let cmp = compare s1 s1'
in
368 let cmp = compare s2 s2'
in
377 * Compare lists of symbols for equality.
379 let rec compare_lists sl1 sl2
=
381 s1
:: sl1
, s2
:: sl2
->
382 let cmp = compare s1 s2
in
384 compare_lists sl1 sl2
395 * Build sets, tables, indices where the keys are symbols,
396 * ordered symbol pairs, or orderd symbol triples.
401 let compare = compare
406 type t
= symbol
* symbol
407 let compare = compare_pair
412 type t
= symbol
* symbol
* symbol
413 let compare = compare_triple
416 module SymbolSet
= Lm_set.LmMake
(Base
)
417 module SymbolTable
= Lm_map.LmMake
(Base
)
418 module SymbolMTable
= Lm_map.LmMakeList
(Base
)
419 module SymbolIndex
= Lm_index.LmMake
(Base
)
421 module SymbolPairSet
= Lm_set.LmMake
(PairBase
)
422 module SymbolPairTable
= Lm_map.LmMake
(PairBase
)
423 module SymbolPairMTable
= Lm_map.LmMakeList
(PairBase
)
424 module SymbolPairIndex
= Lm_index.LmMake
(PairBase
)
426 module SymbolTripleSet
= Lm_set.LmMake
(TripleBase
)
427 module SymbolTripleTable
= Lm_map.LmMake
(TripleBase
)
428 module SymbolTripleMTable
= Lm_map.LmMakeList
(TripleBase
)
429 module SymbolTripleIndex
= Lm_index.LmMake
(TripleBase
)
432 * Symbol lists are also useful.
434 module SymbolListCompare
=
438 let rec compare l1 l2
=
440 v1
:: l1
, v2
:: l2
->
441 let cmp = Base.compare v1 v2
in
454 module SymbolListSet
= Lm_set.LmMake
(SymbolListCompare
)
455 module SymbolListTable
= Lm_map.LmMake
(SymbolListCompare
)
457 let output_symbol_set out
s =
458 output_symbol_list out
(SymbolSet.to_list
s)
460 let pp_print_symbol_set buf s =
461 pp_print_symbol_list buf (SymbolSet.to_list
s)