1 /* Copyright (C) 2003,2004,2005,2006,2013 MORIOKA Tomohiko
2 This file is part of the CONCORD Library.
4 The CONCORD Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The CONCORD Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the CONCORD Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 unsigned long concord_hash_c_string (const unsigned char *ptr);
24 unsigned long cos_hash_c_string_n (const unsigned char *ptr, size_t size);
25 unsigned long cos_symbol_hash_string (COS_String string);
28 COS_String_ent cos_string_ent_nil = { {COS_OBJECT_PREFIX_OBJECT,
29 COS_Object_Type_String,
33 COS_Symbol_ent cos_symbol_ent_nil = { {COS_OBJECT_PREFIX_OBJECT,
34 COS_Object_Type_Symbol,
39 COS_Symbol cos_Qnil = &cos_symbol_ent_nil;
42 COS_String_ent cos_string_ent_t = { {COS_OBJECT_PREFIX_OBJECT,
43 COS_Object_Type_String,
47 COS_Symbol_ent cos_symbol_ent_t = { {COS_OBJECT_PREFIX_OBJECT,
48 COS_Object_Type_Symbol,
53 COS_Symbol cos_Qt = &cos_symbol_ent_t;
56 COS_String_ent cos_string_ent_composition = { {COS_OBJECT_PREFIX_OBJECT,
57 COS_Object_Type_String,
61 COS_Symbol_ent cos_symbol_ent_composition = { {COS_OBJECT_PREFIX_OBJECT,
62 COS_Object_Type_Symbol,
64 &cos_string_ent_composition,
67 COS_Symbol cos_Qcomposition = &cos_symbol_ent_composition;
70 COS_Symbol_Table cos_default_symbol_table = NULL;
74 cos_make_symbol (COS_String string)
76 COS_Symbol obj = COS_ALLOCATE_OBJECT (Symbol);
83 cos_retain_object (string);
88 cos_retain_symbol (COS_Object obj)
90 //cos_retain_object (((COS_Symbol)obj)->value);
91 //cos_retain_object (((COS_Symbol)obj)->name);
96 cos_release_symbol (COS_Object obj)
101 if ( (obj == cos_Qnil) || (obj == cos_Qt) ||
102 (obj == cos_Qcomposition) )
105 if ( ((COS_Symbol)obj)->value != NULL)
106 cos_release_object (((COS_Symbol)obj)->value);
108 cos_release_object (((COS_Symbol)obj)->name);
114 cos_symbol_p (COS_object obj)
116 return COS_OBJECT_SYMBOL_P (obj);
120 cos_symbol_table_intern (COS_Symbol_Table table, COS_object name)
123 COS_String key_string;
124 unsigned long i, index;
130 if (COS_OBJECT_C_STRING_P (name))
132 key_string = cos_build_string ((char*)name);
136 key_string = (COS_String)name;
138 key = key_string->data;
139 index = cos_symbol_hash_string (key_string) % table->size;
140 for (i = index; i < table->size; i++)
142 entry = table->data[i];
145 entry = cos_make_symbol (key_string);
146 cos_retain_object ((COS_object)entry);
147 table->data[i] = entry;
150 else if ( COS_OBJECT_SYMBOL_P (entry)
151 && COS_OBJECT_STRING_P (entry->name)
152 && (entry->name->size == key_string->size)
153 && (memcmp (entry->name->data,
154 key_string->data, key_string->size) == 0) )
156 cos_retain_object ((COS_object)entry);
160 if (cos_symbol_table_grow (table) == 0)
161 return cos_symbol_table_intern (table, key_string);
166 cos_symbol_name (COS_Symbol symbol)
172 COS_Symbol_Table cos_make_symbol_table_0 (size_t size);
173 void cos_destroy_symbol_table_0 (COS_Symbol_Table hash);
176 /* derived from hashpjw, Dragon Book P436. */
178 cos_hash_c_string_n (const unsigned char *ptr, size_t size)
180 unsigned long hash = 0;
183 for ( i = 0; i < size; i++ )
186 hash = (hash << 4) + ptr[i];
187 g = hash & 0xf0000000;
189 hash = (hash ^ (g >> 24)) ^ g;
191 return hash & 07777777777;
195 cos_symbol_hash_string (COS_String string)
197 return cos_hash_c_string_n (string->data, string->size);
202 cos_make_symbol_table_0 (size_t size)
204 COS_Symbol_Table hash
205 = (COS_Symbol_Table)malloc (sizeof (COS_Symbol_Table_ent));
211 = (COS_Symbol*) malloc (sizeof (COS_Symbol) * size);
212 if (hash->data == NULL)
219 memset (hash->data, 0, sizeof (COS_Symbol) * size);
224 cos_destroy_symbol_table_0 (COS_Symbol_Table table)
234 cos_make_symbol_table ()
236 return cos_make_symbol_table_0 (2 /* 256 */);
240 cos_destroy_symbol_table (COS_Symbol_Table table)
244 for (i = 0; i < table->size; i++)
246 COS_Symbol entry = table->data[i];
250 if (entry->name != NULL)
251 cos_release_object (entry->name);
252 if (entry->value != NULL)
253 cos_release_object (entry->value);
257 cos_destroy_symbol_table_0 (table);
261 cos_intern (COS_object name)
263 if (cos_default_symbol_table == NULL)
265 cos_default_symbol_table = cos_make_symbol_table();
266 cos_symbol_table_set (cos_default_symbol_table, cos_Qnil);
267 cos_symbol_table_set (cos_default_symbol_table, cos_Qt);
268 cos_symbol_table_set (cos_default_symbol_table, cos_Qcomposition);
270 return cos_symbol_table_intern (cos_default_symbol_table, name);
274 cos_symbol_table_set (COS_Symbol_Table table, COS_Symbol symbol)
282 index = cos_symbol_hash_string (symbol->name) % table->size;
283 for (i = index; i < table->size; i++)
285 entry = table->data[i];
289 cos_retain_object ((COS_object)entry);
290 table->data[i] = entry;
293 else if (entry == symbol)
298 if (cos_symbol_table_grow (table) == 0)
299 return cos_symbol_table_set (table, symbol);
304 cos_print_symbol_table (COS_Symbol_Table table)
310 table = cos_default_symbol_table;
312 printf ("#[symbol_table %lX\tsize = %d", table->size);
313 for (i = 0; i < table->size; i++)
315 entry = table->data[i];
316 printf ("\n\t%d : ", i);
317 cos_print_object (entry);
324 cos_symbol_table_grow (COS_Symbol_Table table)
326 COS_Symbol_Table new_table
327 = cos_make_symbol_table_0 ( table->size * 2
328 /* - (table->size * 4 / 5) */ );
331 if (new_table == NULL)
334 //printf ("\n(old table is ");
335 //cos_print_symbol_table (table);
336 for (i = 0; i < table->size; i++)
338 COS_Symbol entry = table->data[i];
342 int status = cos_symbol_table_set (new_table, entry);
346 cos_destroy_symbol_table_0 (new_table);
352 table->size = new_table->size;
353 table->data = new_table->data;
355 //printf ("\t)\n(new table is ");
356 //cos_print_symbol_table (table);