File misc.c changed (mode: 100644) (index bbc8363..99b33ba) |
... |
... |
int inloop; |
35 |
35 |
int afterendglobals; |
int afterendglobals; |
36 |
36 |
int *showerrorlevel; |
int *showerrorlevel; |
37 |
37 |
|
|
38 |
|
int hashfunc(const char *name); |
|
|
38 |
|
uint32_t hashfunc(const char *name, int size); |
39 |
39 |
struct hashtable functions, globals, locals, params, types, initialized; |
struct hashtable functions, globals, locals, params, types, initialized; |
40 |
40 |
struct hashtable *curtab; |
struct hashtable *curtab; |
41 |
41 |
struct typenode *retval, *retcheck; |
struct typenode *retval, *retcheck; |
|
... |
... |
void addPrimitiveType(const char *name, struct typenode **toSave) |
52 |
52 |
void init(int argc, char **argv) |
void init(int argc, char **argv) |
53 |
53 |
{ |
{ |
54 |
54 |
int i; |
int i; |
|
55 |
|
|
|
56 |
|
inittable(&functions, 8191); |
|
57 |
|
inittable(&globals, 8191); |
|
58 |
|
inittable(&locals, 11); |
|
59 |
|
inittable(¶ms, 11); |
|
60 |
|
inittable(&types, 511); |
|
61 |
|
inittable(&initialized, 23); |
|
62 |
|
|
55 |
63 |
addPrimitiveType("handle", &gHandle); |
addPrimitiveType("handle", &gHandle); |
56 |
64 |
addPrimitiveType("integer", &gInteger); |
addPrimitiveType("integer", &gInteger); |
57 |
65 |
addPrimitiveType("real", &gReal); |
addPrimitiveType("real", &gReal); |
58 |
66 |
addPrimitiveType("boolean", &gBoolean); |
addPrimitiveType("boolean", &gBoolean); |
59 |
67 |
addPrimitiveType("string", &gString); |
addPrimitiveType("string", &gString); |
60 |
68 |
addPrimitiveType("code", &gCode); |
addPrimitiveType("code", &gCode); |
|
69 |
|
|
61 |
70 |
gNothing = newtypenode("nothing", NULL); |
gNothing = newtypenode("nothing", NULL); |
62 |
71 |
gNull = newtypenode("null", NULL); |
gNull = newtypenode("null", NULL); |
63 |
72 |
gAny = newtypenode("any", NULL); |
gAny = newtypenode("any", NULL); |
64 |
73 |
gNone = newtypenode("none", NULL); |
gNone = newtypenode("none", NULL); |
65 |
74 |
gEmpty = newtypenode("gempty", NULL); |
gEmpty = newtypenode("gempty", NULL); |
|
75 |
|
|
66 |
76 |
curtab = &globals; |
curtab = &globals; |
67 |
77 |
fno = 0; |
fno = 0; |
68 |
78 |
strict = 0; |
strict = 0; |
|
... |
... |
void getsuggestions(const char *name, char *buff, int buffsize, int nTables, ... |
176 |
186 |
struct hashtable *ht = va_arg(ap, struct hashtable*); |
struct hashtable *ht = va_arg(ap, struct hashtable*); |
177 |
187 |
|
|
178 |
188 |
int x; |
int x; |
179 |
|
for(x = 0; x != BUCKETS; x++){ |
|
180 |
|
struct hashnode *hn; |
|
181 |
|
hn = ht->h[x]; |
|
182 |
|
while (hn) { |
|
183 |
|
int dist = editdistance(hn->name, name, cutoff); |
|
|
189 |
|
for(x = 0; x != ht->size; x++){ |
|
190 |
|
if(ht->bucket[x].name){ |
|
191 |
|
int dist = editdistance(ht->bucket[x].name, name, cutoff); |
184 |
192 |
if(dist <= cutoff){ |
if(dist <= cutoff){ |
185 |
193 |
count++; |
count++; |
186 |
194 |
int j; |
int j; |
|
... |
... |
void getsuggestions(const char *name, char *buff, int buffsize, int nTables, ... |
193 |
201 |
suggestions[2] = suggestions[1]; |
suggestions[2] = suggestions[1]; |
194 |
202 |
} |
} |
195 |
203 |
suggestions[j].distance = dist; |
suggestions[j].distance = dist; |
196 |
|
suggestions[j].name = hn->name; |
|
|
204 |
|
suggestions[j].name = ht->bucket[x].name; |
197 |
205 |
|
|
198 |
206 |
break; |
break; |
199 |
207 |
} |
} |
200 |
208 |
} |
} |
201 |
209 |
|
|
202 |
210 |
} |
} |
203 |
|
hn = hn->next; |
|
204 |
211 |
} |
} |
205 |
212 |
} |
} |
206 |
213 |
|
|
|
... |
... |
struct typeandname *newtypeandname(const struct typenode *ty, const char *name) |
264 |
271 |
struct typenode *newtypenode(const char *typename, const struct typenode *superclass) |
struct typenode *newtypenode(const char *typename, const struct typenode *superclass) |
265 |
272 |
{ |
{ |
266 |
273 |
struct typenode *result; |
struct typenode *result; |
267 |
|
#if defined __CYGWIN__ |
|
|
274 |
|
#if defined __CYGWIN__ || defined linux |
268 |
275 |
result = memalign(8, sizeof(struct typenode)); |
result = memalign(8, sizeof(struct typenode)); |
269 |
276 |
#else |
#else |
270 |
277 |
result = _aligned_malloc(8, sizeof(struct typenode)); |
result = _aligned_malloc(8, sizeof(struct typenode)); |
|
... |
... |
void showfuncdecl(struct funcdecl *fd) |
349 |
356 |
} |
} |
350 |
357 |
|
|
351 |
358 |
|
|
352 |
|
int hashfunc(const char *name) |
|
353 |
|
{ |
|
354 |
|
int h = 0; |
|
355 |
|
const unsigned char *s; |
|
356 |
|
for (s = name; *s; ++s) |
|
357 |
|
h = ((811 * h + (*s)) % 19205861); |
|
358 |
|
return ((h % BUCKETS) + BUCKETS) % BUCKETS; |
|
|
359 |
|
uint32_t hashfunc(const char *key, int size) { |
|
360 |
|
//murmur3_32 |
|
361 |
|
static const uint32_t c1 = 0xcc9e2d51; |
|
362 |
|
static const uint32_t c2 = 0x1b873593; |
|
363 |
|
static const uint32_t r1 = 15; |
|
364 |
|
static const uint32_t r2 = 13; |
|
365 |
|
static const uint32_t m = 5; |
|
366 |
|
static const uint32_t n = 0xe6546b64; |
|
367 |
|
|
|
368 |
|
uint32_t len = strlen(key); |
|
369 |
|
uint32_t hash = 0; |
|
370 |
|
|
|
371 |
|
const int nblocks = len / 4; |
|
372 |
|
const uint32_t *blocks = (const uint32_t *) key; |
|
373 |
|
int i; |
|
374 |
|
for (i = 0; i < nblocks; i++) { |
|
375 |
|
uint32_t k = blocks[i]; |
|
376 |
|
k *= c1; |
|
377 |
|
k = (k << r1) | (k >> (32 - r1)); |
|
378 |
|
k *= c2; |
|
379 |
|
|
|
380 |
|
hash ^= k; |
|
381 |
|
hash = ((hash << r2) | (hash >> (32 - r2))) * m + n; |
|
382 |
|
} |
|
383 |
|
|
|
384 |
|
const uint8_t *tail = (const uint8_t *) (key + nblocks * 4); |
|
385 |
|
uint32_t k1 = 0; |
|
386 |
|
|
|
387 |
|
switch (len & 3) { |
|
388 |
|
case 3: |
|
389 |
|
k1 ^= tail[2] << 16; |
|
390 |
|
case 2: |
|
391 |
|
k1 ^= tail[1] << 8; |
|
392 |
|
case 1: |
|
393 |
|
k1 ^= tail[0]; |
|
394 |
|
|
|
395 |
|
k1 *= c1; |
|
396 |
|
k1 = (k1 << r1) | (k1 >> (32 - r1)); |
|
397 |
|
k1 *= c2; |
|
398 |
|
hash ^= k1; |
|
399 |
|
} |
|
400 |
|
|
|
401 |
|
hash ^= len; |
|
402 |
|
hash ^= (hash >> 16); |
|
403 |
|
hash *= 0x85ebca6b; |
|
404 |
|
hash ^= (hash >> 13); |
|
405 |
|
hash *= 0xc2b2ae35; |
|
406 |
|
hash ^= (hash >> 16); |
|
407 |
|
|
|
408 |
|
return hash; |
|
409 |
|
} |
|
410 |
|
|
|
411 |
|
void inittable(struct hashtable *h, int size){ |
|
412 |
|
h->count = 0; |
|
413 |
|
h->size = size; |
|
414 |
|
h->bucket = malloc(h->size * sizeof(struct hashnode)); |
|
415 |
|
memset(h->bucket, 0, h->size * sizeof(struct hashnode)); |
|
416 |
|
assert(h->count == 0); |
|
417 |
|
assert(h->size == size); |
359 |
418 |
} |
} |
360 |
419 |
|
|
361 |
420 |
void *lookup(struct hashtable *h, const char *name) |
void *lookup(struct hashtable *h, const char *name) |
362 |
421 |
{ |
{ |
363 |
|
struct hashnode *hn; |
|
364 |
|
int hf = hashfunc(name); |
|
365 |
|
hn = h->h[hf]; |
|
366 |
|
while (hn) { |
|
367 |
|
if (strcmp(hn->name, name) == 0) |
|
368 |
|
return hn->val; |
|
369 |
|
hn = hn->next; |
|
|
422 |
|
int start = hashfunc(name, h->size); |
|
423 |
|
int idx = (start + 1) % h->size; |
|
424 |
|
for(; idx != start; idx = (idx + 1) % h->size){ |
|
425 |
|
if(h->bucket[idx].name){ |
|
426 |
|
if(!strcmp(h->bucket[idx].name, name)){ |
|
427 |
|
return h->bucket[idx].val; |
|
428 |
|
} |
|
429 |
|
}else{ |
|
430 |
|
break; |
|
431 |
|
} |
370 |
432 |
} |
} |
371 |
433 |
return NULL; |
return NULL; |
372 |
434 |
} |
} |
373 |
435 |
|
|
|
436 |
|
void resize(struct hashtable *h){ |
|
437 |
|
struct hashtable new; |
|
438 |
|
inittable(&new, h->size*2 +1); |
|
439 |
|
int i; |
|
440 |
|
for(i = 0; i != h->size; i++){ |
|
441 |
|
if(h->bucket[i].name){ |
|
442 |
|
put(&new, h->bucket[i].name, h->bucket[i].val); |
|
443 |
|
} |
|
444 |
|
} |
|
445 |
|
free(h->bucket); |
|
446 |
|
h->bucket = new.bucket; |
|
447 |
|
h->size = new.size; |
|
448 |
|
h->count = new.count; |
|
449 |
|
} |
|
450 |
|
|
374 |
451 |
void put(struct hashtable *h, const char *name, void *val) |
void put(struct hashtable *h, const char *name, void *val) |
375 |
452 |
{ |
{ |
376 |
|
struct hashnode *hn; |
|
377 |
|
int hf; |
|
378 |
|
|
|
|
453 |
|
|
379 |
454 |
if (lookup(h, name) != NULL) { |
if (lookup(h, name) != NULL) { |
380 |
455 |
char ebuf[1024]; |
char ebuf[1024]; |
381 |
456 |
snprintf(ebuf, 1024, "Symbol %s multiply defined", name); |
snprintf(ebuf, 1024, "Symbol %s multiply defined", name); |
382 |
457 |
yyerrorline(3, islinebreak ? lineno - 1 : lineno, ebuf); |
yyerrorline(3, islinebreak ? lineno - 1 : lineno, ebuf); |
383 |
458 |
return; |
return; |
384 |
459 |
} |
} |
385 |
|
hf = hashfunc(name); |
|
386 |
|
hn = calloc(sizeof(struct hashnode), 1); |
|
387 |
|
hn->name = strdup(name); |
|
388 |
|
hn->val = val; |
|
389 |
|
hn->next = h->h[hf]; |
|
390 |
|
h->h[hf] = hn; |
|
|
460 |
|
|
|
461 |
|
int start = hashfunc(name, h->size); |
|
462 |
|
int idx = (start + 1) % h->size; |
|
463 |
|
for(; /*idx != start*/; idx = (idx + 1) % h->size){ |
|
464 |
|
if(!h->bucket[idx].name){ |
|
465 |
|
h->bucket[idx].name = name; |
|
466 |
|
h->bucket[idx].val = val; |
|
467 |
|
break; |
|
468 |
|
} |
|
469 |
|
} |
|
470 |
|
h->count++; |
|
471 |
|
if(h->count*3/2 > h->size){ |
|
472 |
|
resize(h); |
|
473 |
|
} |
391 |
474 |
} |
} |
392 |
475 |
|
|
393 |
476 |
void clear(struct hashtable *h) |
void clear(struct hashtable *h) |
394 |
477 |
{ |
{ |
395 |
|
int i; |
|
396 |
|
struct hashnode *hn; |
|
397 |
|
for (i = 0; i < BUCKETS; ++i) { |
|
398 |
|
hn = h->h[i]; |
|
399 |
|
while (hn) { |
|
400 |
|
struct hashnode *tofree = hn; |
|
401 |
|
hn = hn->next; |
|
402 |
|
free(tofree->name); |
|
403 |
|
free(tofree); |
|
404 |
|
} |
|
405 |
|
h->h[i] = NULL; |
|
406 |
|
} |
|
|
478 |
|
memset(h->bucket, 0, h->size*sizeof(struct hashnode)); |
|
479 |
|
h->count = 0; |
407 |
480 |
} |
} |
408 |
481 |
|
|
409 |
482 |
struct typenode *binop(const struct typenode *a, const struct typenode *b) |
struct typenode *binop(const struct typenode *a, const struct typenode *b) |