ref: e24bcc37239283534785e2e2a31393f20ae6c9b7
dir: /parse/stab.c/
#include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <stdarg.h> #include <ctype.h> #include <string.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "parse.h" typedef struct Tydefn Tydefn; typedef struct Cstrdefn Cstrdefn; struct Tydefn { int line; Node *name; Type *type; }; struct Cstrdefn { int line; Node *name; Cstr *cstr; }; #define Maxstabdepth 128 static Stab *stabstk[Maxstabdepth]; static int stabstkoff; Stab *curstab() { return stabstk[stabstkoff - 1]; } void pushstab(Stab *st) { stabstk[stabstkoff++] = st; } void popstab(void) { stabstkoff--; } static ulong namehash(void *n) { return strhash(namestr(n)); } static int nameeq(void *a, void *b) { return a == b || !strcmp(namestr(a), namestr(b)); } Stab *mkstab() { Stab *st; st = zalloc(sizeof(Stab)); st->ns = mkht(namehash, nameeq); st->dcl = mkht(namehash, nameeq); st->ty = mkht(namehash, nameeq); st->uc = mkht(namehash, nameeq); return st; } /* FIXME: do namespaces */ Node *getdcl(Stab *st, Node *n) { Node *s; Stab *orig; orig = st; do { if ((s = htget(st->dcl, n))) { /* record that this is in the closure of this scope */ if (!st->closure) st->closure = mkht(namehash, nameeq); if (st != orig && !n->decl.isglobl) htput(st->closure, s->decl.name, s); return s; } st = st->super; } while (st); return NULL; } Type *gettype(Stab *st, Node *n) { Tydefn *t; do { if ((t = htget(st->ty, n))) return t->type; st = st->super; } while (st); return NULL; } Ucon *getucon(Stab *st, Node *n) { Ucon *uc; do { if ((uc = htget(st->uc, n))) return uc; st = st->super; } while (st); return NULL; } Cstr *getcstr(Stab *st, Node *n) { Cstrdefn *c; do { if ((c = htget(st->ty, n))) return c->cstr; st = st->super; } while (st); return NULL; } Stab *getns(Stab *st, Node *n) { Stab *s; do { if ((s = htget(st->ns, n))) return s; st = st->super; } while (st); return NULL; } void putdcl(Stab *st, Node *s) { Node *d; d = getdcl(st, s->decl.name); if (d) fatal(s->line, "%s already declared (on line %d)", namestr(s->decl.name), d->line); if (st->name) setns(s->decl.name, namestr(st->name)); htput(st->dcl, s->decl.name, s); } void updatetype(Stab *st, Node *n, Type *t) { Tydefn *td; td = htget(st->ty, n); if (!td) die("No type %s to update", namestr(n)); td->type = t; } void puttype(Stab *st, Node *n, Type *t) { Tydefn *td; if (gettype(st, n)) fatal(n->line, "Type %s already defined", namestr(n)); td = xalloc(sizeof(Tydefn)); td->line = n->line; td->name = n; td->type = t; htput(st->ty, td->name, td); } void putucon(Stab *st, Ucon *uc) { if (getucon(st, uc->name)) fatal(uc->line, "union constructor %s already defined", namestr(uc->name)); htput(st->uc, uc->name, uc); } void putcstr(Stab *st, Node *n, Cstr *c) { Cstrdefn *cd; if (gettype(st, n)) fatal(n->line, "Type %s already defined", namestr(n)); cd = xalloc(sizeof(Tydefn)); cd->line = n->line; cd->name = n; cd->cstr = c; htput(st->ty, cd->name, cd); } void putns(Stab *st, Stab *scope) { Stab *s; s = getns(st, scope->name); if (s) fatal(scope->name->line, "Ns %s already defined", namestr(s->name)); htput(st->ns, scope->name, scope); } void updatens(Stab *st, char *name) { void **k; size_t i, nk; if (st->name) die("Stab %s already has namespace; Can't set to %s", namestr(st->name), name); st->name = mkname(-1, name); k = htkeys(st->dcl, &nk); for (i = 0; i < nk; i++) setns(k[i], name); free(k); k = htkeys(st->ty, &nk); for (i = 0; i < nk; i++) setns(k[i], name); free(k); k = htkeys(st->ns, &nk); for (i = 0; i < nk; i++) setns(k[i], name); free(k); }