diff options
Diffstat (limited to 'lcc/src/sym.c')
-rwxr-xr-x | lcc/src/sym.c | 630 |
1 files changed, 315 insertions, 315 deletions
diff --git a/lcc/src/sym.c b/lcc/src/sym.c index 1d754d4..723cdd4 100755 --- a/lcc/src/sym.c +++ b/lcc/src/sym.c @@ -1,315 +1,315 @@ -#include "c.h"
-#include <stdio.h>
-
-
-#define equalp(x) v.x == p->sym.u.c.v.x
-
-struct table {
- int level;
- Table previous;
- struct entry {
- struct symbol sym;
- struct entry *link;
- } *buckets[256];
- Symbol all;
-};
-#define HASHSIZE NELEMS(((Table)0)->buckets)
-static struct table
- cns = { CONSTANTS },
- ext = { GLOBAL },
- ids = { GLOBAL },
- tys = { GLOBAL };
-Table constants = &cns;
-Table externals = &ext;
-Table identifiers = &ids;
-Table globals = &ids;
-Table types = &tys;
-Table labels;
-int level = GLOBAL;
-static int tempid;
-List loci, symbols;
-
-Table table(Table tp, int level) {
- Table new;
-
- NEW0(new, FUNC);
- new->previous = tp;
- new->level = level;
- if (tp)
- new->all = tp->all;
- return new;
-}
-void foreach(Table tp, int lev, void (*apply)(Symbol, void *), void *cl) {
- assert(tp);
- while (tp && tp->level > lev)
- tp = tp->previous;
- if (tp && tp->level == lev) {
- Symbol p;
- Coordinate sav;
- sav = src;
- for (p = tp->all; p && p->scope == lev; p = p->up) {
- src = p->src;
- (*apply)(p, cl);
- }
- src = sav;
- }
-}
-void enterscope(void) {
- if (++level == LOCAL)
- tempid = 0;
-}
-void exitscope(void) {
- rmtypes(level);
- if (types->level == level)
- types = types->previous;
- if (identifiers->level == level) {
- if (Aflag >= 2) {
- int n = 0;
- Symbol p;
- for (p = identifiers->all; p && p->scope == level; p = p->up)
- if (++n > 127) {
- warning("more than 127 identifiers declared in a block\n");
- break;
- }
- }
- identifiers = identifiers->previous;
- }
- assert(level >= GLOBAL);
- --level;
-}
-Symbol install(const char *name, Table *tpp, int level, int arena) {
- Table tp = *tpp;
- struct entry *p;
- unsigned h = (unsigned long)name&(HASHSIZE-1);
-
- assert(level == 0 || level >= tp->level);
- if (level > 0 && tp->level < level)
- tp = *tpp = table(tp, level);
- NEW0(p, arena);
- p->sym.name = (char *)name;
- p->sym.scope = level;
- p->sym.up = tp->all;
- tp->all = &p->sym;
- p->link = tp->buckets[h];
- tp->buckets[h] = p;
- return &p->sym;
-}
-Symbol relocate(const char *name, Table src, Table dst) {
- struct entry *p, **q;
- Symbol *r;
- unsigned h = (unsigned long)name&(HASHSIZE-1);
-
- for (q = &src->buckets[h]; *q; q = &(*q)->link)
- if (name == (*q)->sym.name)
- break;
- assert(*q);
- /*
- Remove the entry from src's hash chain
- and from its list of all symbols.
- */
- p = *q;
- *q = (*q)->link;
- for (r = &src->all; *r && *r != &p->sym; r = &(*r)->up)
- ;
- assert(*r == &p->sym);
- *r = p->sym.up;
- /*
- Insert the entry into dst's hash chain
- and into its list of all symbols.
- Return the symbol-table entry.
- */
- p->link = dst->buckets[h];
- dst->buckets[h] = p;
- p->sym.up = dst->all;
- dst->all = &p->sym;
- return &p->sym;
-}
-Symbol lookup(const char *name, Table tp) {
- struct entry *p;
- unsigned h = (unsigned long)name&(HASHSIZE-1);
-
- assert(tp);
- do
- for (p = tp->buckets[h]; p; p = p->link)
- if (name == p->sym.name)
- return &p->sym;
- while ((tp = tp->previous) != NULL);
- return NULL;
-}
-int genlabel(int n) {
- static int label = 1;
-
- label += n;
- return label - n;
-}
-Symbol findlabel(int lab) {
- struct entry *p;
- unsigned h = lab&(HASHSIZE-1);
-
- for (p = labels->buckets[h]; p; p = p->link)
- if (lab == p->sym.u.l.label)
- return &p->sym;
- NEW0(p, FUNC);
- p->sym.name = stringd(lab);
- p->sym.scope = LABELS;
- p->sym.up = labels->all;
- labels->all = &p->sym;
- p->link = labels->buckets[h];
- labels->buckets[h] = p;
- p->sym.generated = 1;
- p->sym.u.l.label = lab;
- (*IR->defsymbol)(&p->sym);
- return &p->sym;
-}
-Symbol constant(Type ty, Value v) {
- struct entry *p;
- unsigned h = v.u&(HASHSIZE-1);
-
- ty = unqual(ty);
- for (p = constants->buckets[h]; p; p = p->link)
- if (eqtype(ty, p->sym.type, 1))
- switch (ty->op) {
- case INT: if (equalp(i)) return &p->sym; break;
- case UNSIGNED: if (equalp(u)) return &p->sym; break;
- case FLOAT: if (equalp(d)) return &p->sym; break;
- case FUNCTION: if (equalp(g)) return &p->sym; break;
- case ARRAY:
- case POINTER: if (equalp(p)) return &p->sym; break;
- default: assert(0);
- }
- NEW0(p, PERM);
- p->sym.name = vtoa(ty, v);
- p->sym.scope = CONSTANTS;
- p->sym.type = ty;
- p->sym.sclass = STATIC;
- p->sym.u.c.v = v;
- p->link = constants->buckets[h];
- p->sym.up = constants->all;
- constants->all = &p->sym;
- constants->buckets[h] = p;
- if (ty->u.sym && !ty->u.sym->addressed)
- (*IR->defsymbol)(&p->sym);
- p->sym.defined = 1;
- return &p->sym;
-}
-Symbol intconst(int n) {
- Value v;
-
- v.i = n;
- return constant(inttype, v);
-}
-Symbol genident(int scls, Type ty, int lev) {
- Symbol p;
-
- NEW0(p, lev >= LOCAL ? FUNC : PERM);
- p->name = stringd(genlabel(1));
- p->scope = lev;
- p->sclass = scls;
- p->type = ty;
- p->generated = 1;
- if (lev == GLOBAL)
- (*IR->defsymbol)(p);
- return p;
-}
-
-Symbol temporary(int scls, Type ty) {
- Symbol p;
-
- NEW0(p, FUNC);
- p->name = stringd(++tempid);
- p->scope = level < LOCAL ? LOCAL : level;
- p->sclass = scls;
- p->type = ty;
- p->temporary = 1;
- p->generated = 1;
- return p;
-}
-Symbol newtemp(int sclass, int tc, int size) {
- Symbol p = temporary(sclass, btot(tc, size));
-
- (*IR->local)(p);
- p->defined = 1;
- return p;
-}
-
-Symbol allsymbols(Table tp) {
- return tp->all;
-}
-
-void locus(Table tp, Coordinate *cp) {
- loci = append(cp, loci);
- symbols = append(allsymbols(tp), symbols);
-}
-
-void use(Symbol p, Coordinate src) {
- Coordinate *cp;
-
- NEW(cp, PERM);
- *cp = src;
- p->uses = append(cp, p->uses);
-}
-/* findtype - find type ty in identifiers */
-Symbol findtype(Type ty) {
- Table tp = identifiers;
- int i;
- struct entry *p;
-
- assert(tp);
- do
- for (i = 0; i < HASHSIZE; i++)
- for (p = tp->buckets[i]; p; p = p->link)
- if (p->sym.type == ty && p->sym.sclass == TYPEDEF)
- return &p->sym;
- while ((tp = tp->previous) != NULL);
- return NULL;
-}
-
-/* mkstr - make a string constant */
-Symbol mkstr(char *str) {
- Value v;
- Symbol p;
-
- v.p = str;
- p = constant(array(chartype, strlen(v.p) + 1, 0), v);
- if (p->u.c.loc == NULL)
- p->u.c.loc = genident(STATIC, p->type, GLOBAL);
- return p;
-}
-
-/* mksymbol - make a symbol for name, install in &globals if sclass==EXTERN */
-Symbol mksymbol(int sclass, const char *name, Type ty) {
- Symbol p;
-
- if (sclass == EXTERN)
- p = install(string(name), &globals, GLOBAL, PERM);
- else {
- NEW0(p, PERM);
- p->name = string(name);
- p->scope = GLOBAL;
- }
- p->sclass = sclass;
- p->type = ty;
- (*IR->defsymbol)(p);
- p->defined = 1;
- return p;
-}
-
-/* vtoa - return string for the constant v of type ty */
-char *vtoa(Type ty, Value v) {
- char buf[50];
-
- ty = unqual(ty);
- switch (ty->op) {
- case INT: return stringd(v.i);
- case UNSIGNED: return stringf((v.u&~0x7FFF) ? "0x%X" : "%U", v.u);
- case FLOAT: return stringf("%g", (double)v.d);
- case ARRAY:
- if (ty->type == chartype || ty->type == signedchar
- || ty->type == unsignedchar)
- return v.p;
- return stringf("%p", v.p);
- case POINTER: return stringf("%p", v.p);
- case FUNCTION: return stringf("%p", v.g);
- }
- assert(0); return NULL;
-}
+#include "c.h" +#include <stdio.h> + + +#define equalp(x) v.x == p->sym.u.c.v.x + +struct table { + int level; + Table previous; + struct entry { + struct symbol sym; + struct entry *link; + } *buckets[256]; + Symbol all; +}; +#define HASHSIZE NELEMS(((Table)0)->buckets) +static struct table + cns = { CONSTANTS }, + ext = { GLOBAL }, + ids = { GLOBAL }, + tys = { GLOBAL }; +Table constants = &cns; +Table externals = &ext; +Table identifiers = &ids; +Table globals = &ids; +Table types = &tys; +Table labels; +int level = GLOBAL; +static int tempid; +List loci, symbols; + +Table table(Table tp, int level) { + Table new; + + NEW0(new, FUNC); + new->previous = tp; + new->level = level; + if (tp) + new->all = tp->all; + return new; +} +void foreach(Table tp, int lev, void (*apply)(Symbol, void *), void *cl) { + assert(tp); + while (tp && tp->level > lev) + tp = tp->previous; + if (tp && tp->level == lev) { + Symbol p; + Coordinate sav; + sav = src; + for (p = tp->all; p && p->scope == lev; p = p->up) { + src = p->src; + (*apply)(p, cl); + } + src = sav; + } +} +void enterscope(void) { + if (++level == LOCAL) + tempid = 0; +} +void exitscope(void) { + rmtypes(level); + if (types->level == level) + types = types->previous; + if (identifiers->level == level) { + if (Aflag >= 2) { + int n = 0; + Symbol p; + for (p = identifiers->all; p && p->scope == level; p = p->up) + if (++n > 127) { + warning("more than 127 identifiers declared in a block\n"); + break; + } + } + identifiers = identifiers->previous; + } + assert(level >= GLOBAL); + --level; +} +Symbol install(const char *name, Table *tpp, int level, int arena) { + Table tp = *tpp; + struct entry *p; + unsigned h = (unsigned long)name&(HASHSIZE-1); + + assert(level == 0 || level >= tp->level); + if (level > 0 && tp->level < level) + tp = *tpp = table(tp, level); + NEW0(p, arena); + p->sym.name = (char *)name; + p->sym.scope = level; + p->sym.up = tp->all; + tp->all = &p->sym; + p->link = tp->buckets[h]; + tp->buckets[h] = p; + return &p->sym; +} +Symbol relocate(const char *name, Table src, Table dst) { + struct entry *p, **q; + Symbol *r; + unsigned h = (unsigned long)name&(HASHSIZE-1); + + for (q = &src->buckets[h]; *q; q = &(*q)->link) + if (name == (*q)->sym.name) + break; + assert(*q); + /* + Remove the entry from src's hash chain + and from its list of all symbols. + */ + p = *q; + *q = (*q)->link; + for (r = &src->all; *r && *r != &p->sym; r = &(*r)->up) + ; + assert(*r == &p->sym); + *r = p->sym.up; + /* + Insert the entry into dst's hash chain + and into its list of all symbols. + Return the symbol-table entry. + */ + p->link = dst->buckets[h]; + dst->buckets[h] = p; + p->sym.up = dst->all; + dst->all = &p->sym; + return &p->sym; +} +Symbol lookup(const char *name, Table tp) { + struct entry *p; + unsigned h = (unsigned long)name&(HASHSIZE-1); + + assert(tp); + do + for (p = tp->buckets[h]; p; p = p->link) + if (name == p->sym.name) + return &p->sym; + while ((tp = tp->previous) != NULL); + return NULL; +} +int genlabel(int n) { + static int label = 1; + + label += n; + return label - n; +} +Symbol findlabel(int lab) { + struct entry *p; + unsigned h = lab&(HASHSIZE-1); + + for (p = labels->buckets[h]; p; p = p->link) + if (lab == p->sym.u.l.label) + return &p->sym; + NEW0(p, FUNC); + p->sym.name = stringd(lab); + p->sym.scope = LABELS; + p->sym.up = labels->all; + labels->all = &p->sym; + p->link = labels->buckets[h]; + labels->buckets[h] = p; + p->sym.generated = 1; + p->sym.u.l.label = lab; + (*IR->defsymbol)(&p->sym); + return &p->sym; +} +Symbol constant(Type ty, Value v) { + struct entry *p; + unsigned h = v.u&(HASHSIZE-1); + + ty = unqual(ty); + for (p = constants->buckets[h]; p; p = p->link) + if (eqtype(ty, p->sym.type, 1)) + switch (ty->op) { + case INT: if (equalp(i)) return &p->sym; break; + case UNSIGNED: if (equalp(u)) return &p->sym; break; + case FLOAT: if (equalp(d)) return &p->sym; break; + case FUNCTION: if (equalp(g)) return &p->sym; break; + case ARRAY: + case POINTER: if (equalp(p)) return &p->sym; break; + default: assert(0); + } + NEW0(p, PERM); + p->sym.name = vtoa(ty, v); + p->sym.scope = CONSTANTS; + p->sym.type = ty; + p->sym.sclass = STATIC; + p->sym.u.c.v = v; + p->link = constants->buckets[h]; + p->sym.up = constants->all; + constants->all = &p->sym; + constants->buckets[h] = p; + if (ty->u.sym && !ty->u.sym->addressed) + (*IR->defsymbol)(&p->sym); + p->sym.defined = 1; + return &p->sym; +} +Symbol intconst(int n) { + Value v; + + v.i = n; + return constant(inttype, v); +} +Symbol genident(int scls, Type ty, int lev) { + Symbol p; + + NEW0(p, lev >= LOCAL ? FUNC : PERM); + p->name = stringd(genlabel(1)); + p->scope = lev; + p->sclass = scls; + p->type = ty; + p->generated = 1; + if (lev == GLOBAL) + (*IR->defsymbol)(p); + return p; +} + +Symbol temporary(int scls, Type ty) { + Symbol p; + + NEW0(p, FUNC); + p->name = stringd(++tempid); + p->scope = level < LOCAL ? LOCAL : level; + p->sclass = scls; + p->type = ty; + p->temporary = 1; + p->generated = 1; + return p; +} +Symbol newtemp(int sclass, int tc, int size) { + Symbol p = temporary(sclass, btot(tc, size)); + + (*IR->local)(p); + p->defined = 1; + return p; +} + +Symbol allsymbols(Table tp) { + return tp->all; +} + +void locus(Table tp, Coordinate *cp) { + loci = append(cp, loci); + symbols = append(allsymbols(tp), symbols); +} + +void use(Symbol p, Coordinate src) { + Coordinate *cp; + + NEW(cp, PERM); + *cp = src; + p->uses = append(cp, p->uses); +} +/* findtype - find type ty in identifiers */ +Symbol findtype(Type ty) { + Table tp = identifiers; + int i; + struct entry *p; + + assert(tp); + do + for (i = 0; i < HASHSIZE; i++) + for (p = tp->buckets[i]; p; p = p->link) + if (p->sym.type == ty && p->sym.sclass == TYPEDEF) + return &p->sym; + while ((tp = tp->previous) != NULL); + return NULL; +} + +/* mkstr - make a string constant */ +Symbol mkstr(char *str) { + Value v; + Symbol p; + + v.p = str; + p = constant(array(chartype, strlen(v.p) + 1, 0), v); + if (p->u.c.loc == NULL) + p->u.c.loc = genident(STATIC, p->type, GLOBAL); + return p; +} + +/* mksymbol - make a symbol for name, install in &globals if sclass==EXTERN */ +Symbol mksymbol(int sclass, const char *name, Type ty) { + Symbol p; + + if (sclass == EXTERN) + p = install(string(name), &globals, GLOBAL, PERM); + else { + NEW0(p, PERM); + p->name = string(name); + p->scope = GLOBAL; + } + p->sclass = sclass; + p->type = ty; + (*IR->defsymbol)(p); + p->defined = 1; + return p; +} + +/* vtoa - return string for the constant v of type ty */ +char *vtoa(Type ty, Value v) { + char buf[50]; + + ty = unqual(ty); + switch (ty->op) { + case INT: return stringd(v.i); + case UNSIGNED: return stringf((v.u&~0x7FFF) ? "0x%X" : "%U", v.u); + case FLOAT: return stringf("%g", (double)v.d); + case ARRAY: + if (ty->type == chartype || ty->type == signedchar + || ty->type == unsignedchar) + return v.p; + return stringf("%p", v.p); + case POINTER: return stringf("%p", v.p); + case FUNCTION: return stringf("%p", v.g); + } + assert(0); return NULL; +} |