зеркало из https://github.com/mozilla/pjs.git
115 строки
1.9 KiB
C
115 строки
1.9 KiB
C
char rcsid_map[] = "$Id: map.c,v 1.1 1998-12-17 06:36:48 fur%netscape.com Exp $";
|
|
|
|
#include "b.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
Mapping globalMap;
|
|
|
|
static void growMapping ARGS((Mapping));
|
|
static int hash ARGS((Item_Set, int));
|
|
|
|
Mapping
|
|
newMapping(size) int size;
|
|
{
|
|
Mapping m;
|
|
|
|
m = (Mapping) zalloc(sizeof(struct mapping));
|
|
assert(m);
|
|
|
|
m->count = 0;
|
|
m->hash = (List*) zalloc(size * sizeof(List));
|
|
m->hash_size = size;
|
|
m->max_size = STATES_INCR;
|
|
m->set = (Item_Set*) zalloc(m->max_size * sizeof(Item_Set));
|
|
assert(m->set);
|
|
|
|
return m;
|
|
}
|
|
|
|
static void
|
|
growMapping(m) Mapping m;
|
|
{
|
|
Item_Set *tmp;
|
|
|
|
m->max_size += STATES_INCR;
|
|
tmp = (Item_Set*) zalloc(m->max_size * sizeof(Item_Set));
|
|
memcpy(tmp, m->set, m->count * sizeof(Item_Set));
|
|
zfree(m->set);
|
|
m->set = tmp;
|
|
}
|
|
|
|
static int
|
|
hash(ts, mod) Item_Set ts; int mod;
|
|
{
|
|
register Item *p = ts->virgin;
|
|
register int v;
|
|
register Relevant r = ts->relevant;
|
|
register int nt;
|
|
|
|
if (!ts->op) {
|
|
return 0;
|
|
}
|
|
|
|
v = 0;
|
|
for (; (nt = *r) != 0; r++) {
|
|
v ^= ((int)p[nt].rule) + (PRINCIPLECOST(p[nt].delta)<<4);
|
|
}
|
|
v >>= 4;
|
|
v &= (mod-1);
|
|
return v;
|
|
}
|
|
|
|
Item_Set
|
|
encode(m, ts, new) Mapping m; Item_Set ts; int *new;
|
|
{
|
|
int h;
|
|
List l;
|
|
|
|
assert(m);
|
|
assert(ts);
|
|
assert(m->count <= m->max_size);
|
|
|
|
*new = 0;
|
|
h = hash(ts, m->hash_size);
|
|
for (l = m->hash[h]; l; l = l->next) {
|
|
Item_Set s = (Item_Set) l->x;
|
|
if (ts->op == s->op && equivSet(ts, s)) {
|
|
ts->num = s->num;
|
|
return s;
|
|
}
|
|
}
|
|
if (m->count >= m->max_size) {
|
|
growMapping(m);
|
|
}
|
|
assert(m->count < m->max_size);
|
|
m->set[m->count] = ts;
|
|
ts->num = m->count++;
|
|
*new = 1;
|
|
m->hash[h] = newList(ts, m->hash[h]);
|
|
return ts;
|
|
}
|
|
|
|
Item_Set
|
|
decode(m, t) Mapping m; ItemSetNum t;
|
|
{
|
|
assert(m);
|
|
assert(t);
|
|
assert(m->count < m->max_size);
|
|
assert(t < m->count);
|
|
|
|
return m->set[t];
|
|
}
|
|
|
|
void
|
|
dumpMapping(m) Mapping m;
|
|
{
|
|
int i;
|
|
|
|
printf("BEGIN Mapping: Size=%d\n", m->count);
|
|
for (i = 0; i < m->count; i++) {
|
|
dumpItem_Set(m->set[i]);
|
|
}
|
|
printf("END Mapping\n");
|
|
}
|