qse/ase/stx/symbol.c

95 lines
1.9 KiB
C
Raw Normal View History

2005-05-17 16:18:56 +00:00
/*
2005-08-11 09:57:54 +00:00
* $Id: symbol.c,v 1.21 2005-08-11 09:57:54 bacon Exp $
2005-05-17 16:18:56 +00:00
*/
#include <xp/stx/symbol.h>
#include <xp/stx/object.h>
#include <xp/stx/misc.h>
2005-08-11 09:57:54 +00:00
static void __grow_symtab (xp_stx_t* stx)
2005-05-17 16:18:56 +00:00
{
2005-08-11 09:57:54 +00:00
xp_word_t capa, ncapa, i, j;
xp_word_t* nspace;
2005-05-17 16:18:56 +00:00
2005-08-11 09:57:54 +00:00
capa = stx->symtab.capacity;
ncapa = capa << 1;
2005-05-17 16:18:56 +00:00
2005-08-11 09:57:54 +00:00
nspace = (xp_word_t*)xp_malloc(xp_sizeof(xp_word_t) * ncapa);
if (nspace == XP_NULL) {
/* TODO: handle memory error */
}
2005-05-17 16:18:56 +00:00
2005-08-11 09:57:54 +00:00
for (i = 0; i < capa; i++) {
xp_word_t x = stx->symtab.datum[i];
if (x == stx->nil) continue;
2005-05-23 14:43:03 +00:00
2005-08-11 09:57:54 +00:00
j = xp_stx_strxhash (
XP_STX_DATA(stx,x), XP_STX_SIZE(stx,x)) % ncapa;
2005-05-23 14:43:03 +00:00
2005-08-11 09:57:54 +00:00
while (1) {
if (nspace[j] == stx->nil) {
nspace[j] = x;
2005-05-23 14:43:03 +00:00
break;
}
2005-08-11 09:57:54 +00:00
j = (j % ncapa) + 1;
}
2005-05-23 14:43:03 +00:00
}
2005-08-11 09:57:54 +00:00
stx->symtab.capacity = ncapa;
xp_free (stx->symtab.datum);
stx->symtab.datum = nspace;
2005-05-17 16:18:56 +00:00
}
2005-08-11 09:57:54 +00:00
xp_word_t xp_stx_new_symbol (xp_stx_t* stx, const xp_char_t* name)
2005-05-18 04:01:51 +00:00
{
2005-08-11 09:57:54 +00:00
return xp_stx_new_symbolx (stx, name, xp_strlen(name));
2005-05-18 04:01:51 +00:00
}
2005-08-03 16:00:01 +00:00
xp_word_t xp_stx_new_symbolx (
xp_stx_t* stx, const xp_char_t* name, xp_word_t len)
{
2005-08-11 09:57:54 +00:00
xp_word_t capa, hash, index, size, x;
2005-08-03 16:00:01 +00:00
capa = stx->symtab.capacity;
size = stx->symtab.size;
if (capa <= size + 1) {
__grow_symtab (stx);
2005-08-11 09:57:54 +00:00
capa = stx->symtab.capacity;
2005-08-03 16:00:01 +00:00
}
hash = xp_stx_strxhash(name,len);
index = hash % stx->symtab.capacity;
while (1) {
2005-08-11 09:57:54 +00:00
x = stx->symtab.datum[index];
if (x == stx->nil) {
/* insert a new item into an empty slot */
x = xp_stx_alloc_char_objectx (stx, name, len);
XP_STX_CLASS(stx,x) = stx->class_symbol;
stx->symtab.datum[index] = x;
stx->symtab.size++;
break;
}
2005-08-03 16:00:01 +00:00
if (xp_strxncmp(name, len,
2005-08-11 09:57:54 +00:00
XP_STX_DATA(stx,x), XP_STX_SIZE(stx,x)) == 0) break;
2005-08-03 16:00:01 +00:00
2005-08-11 09:57:54 +00:00
index = (index % stx->symtab.capacity) + 1;
2005-08-03 16:00:01 +00:00
}
2005-08-11 09:57:54 +00:00
return x;
2005-08-03 16:00:01 +00:00
}
2005-08-11 09:57:54 +00:00
void xp_stx_traverse_symbol_table (
xp_stx_t* stx, void (*func) (xp_stx_t*,xp_word_t,void*), void* data)
{
xp_word_t index, x;
for (index = 0; index < stx->symtab.capacity; index++) {
x = stx->symtab.datum[index];
if (x != stx->nil) func (stx, x, data);
}
}