ref: bae05fff3765490d73e5e69945d2ff9a5ffdb2ee
dir: /symbol.c/
#include <assert.h> #include <stdlib.h> #include <string.h> #include "cc.h" #include "symbol.h" #include "tokens.h" #define NR_SYM_HASH 32 unsigned char curctx; static struct symbol *htab[NR_SYM_HASH]; static struct symbol *head, *headfun; unsigned char hash(register const char *s) { register unsigned char h, ch; for (h = 0; ch = *s++; h += ch) /* nothing */; return h; } void new_ctx(void) { ++curctx; } void del_ctx(void) { register struct symbol *sym, *next; static char *s; for (sym = head; sym; sym = next) { if (sym->ctx <= curctx) break; if ((s = sym->name) != NULL) htab[hash(s) & NR_SYM_HASH - 1] = sym->hash; next = sym->next; sym->next = headfun; headfun = sym; } --curctx; } void freesyms(void) { register struct symbol *sym, *next; if (curctx == CTX_OUTER) { for (sym = headfun; sym; sym = next) { next = sym->next; free(sym->name); free(sym); } } } struct symbol * lookup(register const char *s, signed char ns) { register struct symbol *sym; static unsigned char key; register char *t; if (s == NULL) { sym = xcalloc(1, sizeof(*sym)); sym->next = head; return sym; } key = hash(s) & NR_SYM_HASH - 1; for (sym = htab[key]; sym; sym = sym->hash) { t = sym->name; if (ns == sym->ns && *t == *s && !strcmp(t, s)) return sym; } sym = xcalloc(1, sizeof(*sym)); sym->name = xstrdup(s); sym->next = head; sym->ctx = curctx; sym->ns = ns; sym->tok = IDEN; head = sym; sym->hash = htab[key]; htab[key] = sym; return sym; } void insert(struct symbol *sym, unsigned char ctx) { register struct symbol *p, *q; for (q = p = head; p; q = p, p = p->next) { if (p == sym) break; } assert(p); /* sym must be in the list */ q->next = p->next; /* remove from the list */ for (q = p = head; p; q = p, p = p->next) { if (p->ctx <= ctx) break; } if (q == NULL) { head = sym; sym->next = NULL; } else { q->next = sym; sym->next = p; } }