ref: 7ae2f8e3d575dd2e918c3b389779415e63902d8b
dir: /symbol.c/
#include <stddef.h> #include "symbol.h" #define NR_SYM_HASH 32 struct symhash { struct symbol *buf[NR_SYM_HASH]; struct symbol *top; }; struct symctx { struct symbol *siden; struct symbol *sstruct; struct symbol *sgoto; struct symctx *next; }; static struct symctx global_ctx; static struct symctx *ctxp = &global_ctx; struct symhash siden, sgoto, sstruct; unsigned char hashfun(register const char *s) { register unsigned char h, ch; for (h = 0; ch = *s++; h += ch) /* nothing */; return h & NR_SYM_HASH - 1; } void new_ctx(struct symctx *ctx) { ctx->siden = siden.top; ctx->sstruct = sstruct.top; ctx->sgoto = sgoto.top; ctx->next = ctxp; ctxp = ctx; } /* * WARNING: This function is not portable and waits that incremental calls * to alloca return decremented address */ static void del_hash_ctx(struct symhash *h, struct symbol *const top) { register struct symbol **bp; static struct symbol **lim; lim = h->buf + NR_SYM_HASH; for (bp = h->buf; bp < lim; bp++) { register struct symbol *aux; for (aux = *bp; aux < top; *bp = aux = aux->next) if (aux == h->top) h->top = aux; } } void del_ctx(void) { del_hash_ctx(&siden, ctxp->siden); del_hash_ctx(&sstruct, ctxp->sstruct); del_hash_ctx(&sgoto, ctxp->sgoto); /* TODO: correct handling in goto */ } struct symbol *pushsym(struct symhash *h, struct symbol *sym) { static unsigned char key; key = hashfun(sym->str); h->top = sym; sym->next = h->buf[key]; return h->buf[key] = sym; } struct symbol *findsym(struct symhash *h, char *s) { register struct symbol *bp; static unsigned char key; key = hashfun(s); for (bp = h->buf[key]; bp; bp = bp->next) { if (!strcmp(bp->str, s)) return bp; } return NULL; }