Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

sym.c (6883B)


      1 #include "c.h"
      2 #include <stdio.h>
      3 
      4 
      5 #define equalp(x) v.x == p->sym.u.c.v.x
      6 
      7 struct table {
      8 	int level;
      9 	Table previous;
     10 	struct entry {
     11 		struct symbol sym;
     12 		struct entry *link;
     13 	} *buckets[256];
     14 	Symbol all;
     15 };
     16 #define HASHSIZE NELEMS(((Table)0)->buckets)
     17 static struct table
     18 	cns = { CONSTANTS },
     19 	ext = { GLOBAL },
     20 	ids = { GLOBAL },
     21 	tys = { GLOBAL };
     22 Table constants   = &cns;
     23 Table externals   = &ext;
     24 Table identifiers = &ids;
     25 Table globals     = &ids;
     26 Table types       = &tys;
     27 Table labels;
     28 int level = GLOBAL;
     29 static int tempid;
     30 List loci, symbols;
     31 
     32 Table table(Table tp, int level) {
     33 	Table new;
     34 
     35 	NEW0(new, FUNC);
     36 	new->previous = tp;
     37 	new->level = level;
     38 	if (tp)
     39 		new->all = tp->all;
     40 	return new;
     41 }
     42 void foreach(Table tp, int lev, void (*apply)(Symbol, void *), void *cl) {
     43 	assert(tp);
     44 	while (tp && tp->level > lev)
     45 		tp = tp->previous;
     46 	if (tp && tp->level == lev) {
     47 		Symbol p;
     48 		Coordinate sav;
     49 		sav = src;
     50 		for (p = tp->all; p && p->scope == lev; p = p->up) {
     51 			src = p->src;
     52 			(*apply)(p, cl);
     53 		}
     54 		src = sav;
     55 	}
     56 }
     57 void enterscope(void) {
     58 	if (++level == LOCAL)
     59 		tempid = 0;
     60 }
     61 void exitscope(void) {
     62 	rmtypes(level);
     63 	if (types->level == level)
     64 		types = types->previous;
     65 	if (identifiers->level == level) {
     66 		if (Aflag >= 2) {
     67 			int n = 0;
     68 			Symbol p;
     69 			for (p = identifiers->all; p && p->scope == level; p = p->up)
     70 				if (++n > 127) {
     71 					warning("more than 127 identifiers declared in a block\n");
     72 					break;
     73 				}
     74 		}
     75 		identifiers = identifiers->previous;
     76 	}
     77 	assert(level >= GLOBAL);
     78 	--level;
     79 }
     80 Symbol install(const char *name, Table *tpp, int level, int arena) {
     81 	Table tp = *tpp;
     82 	struct entry *p;
     83 	unsigned h = (unsigned long)name&(HASHSIZE-1);
     84 
     85 	assert(level == 0 || level >= tp->level);
     86 	if (level > 0 && tp->level < level)
     87 		tp = *tpp = table(tp, level);
     88 	NEW0(p, arena);
     89 	p->sym.name = (char *)name;
     90 	p->sym.scope = level;
     91 	p->sym.up = tp->all;
     92 	tp->all = &p->sym;
     93 	p->link = tp->buckets[h];
     94 	tp->buckets[h] = p;
     95 	return &p->sym;
     96 }
     97 Symbol relocate(const char *name, Table src, Table dst) {
     98 	struct entry *p, **q;
     99 	Symbol *r;
    100 	unsigned h = (unsigned long)name&(HASHSIZE-1);
    101 
    102 	for (q = &src->buckets[h]; *q; q = &(*q)->link)
    103 		if (name == (*q)->sym.name)
    104 			break;
    105 	assert(*q);
    106 	/*
    107 	 Remove the entry from src's hash chain
    108 	  and from its list of all symbols.
    109 	*/
    110 	p = *q;
    111 	*q = (*q)->link;
    112 	for (r = &src->all; *r && *r != &p->sym; r = &(*r)->up)
    113 		;
    114 	assert(*r == &p->sym);
    115 	*r = p->sym.up;
    116 	/*
    117 	 Insert the entry into dst's hash chain
    118 	  and into its list of all symbols.
    119 	  Return the symbol-table entry.
    120 	*/
    121 	p->link = dst->buckets[h];
    122 	dst->buckets[h] = p;
    123 	p->sym.up = dst->all;
    124 	dst->all = &p->sym;
    125 	return &p->sym;
    126 }
    127 Symbol lookup(const char *name, Table tp) {
    128 	struct entry *p;
    129 	unsigned h = (unsigned long)name&(HASHSIZE-1);
    130 
    131 	assert(tp);
    132 	do
    133 		for (p = tp->buckets[h]; p; p = p->link)
    134 			if (name == p->sym.name)
    135 				return &p->sym;
    136 	while ((tp = tp->previous) != NULL);
    137 	return NULL;
    138 }
    139 int genlabel(int n) {
    140 	static int label = 1;
    141 
    142 	label += n;
    143 	return label - n;
    144 }
    145 Symbol findlabel(int lab) {
    146 	struct entry *p;
    147 	unsigned h = lab&(HASHSIZE-1);
    148 
    149 	for (p = labels->buckets[h]; p; p = p->link)
    150 		if (lab == p->sym.u.l.label)
    151 			return &p->sym;
    152 	NEW0(p, FUNC);
    153 	p->sym.name = stringd(lab);
    154 	p->sym.scope = LABELS;
    155 	p->sym.up = labels->all;
    156 	labels->all = &p->sym;
    157 	p->link = labels->buckets[h];
    158 	labels->buckets[h] = p;
    159 	p->sym.generated = 1;
    160 	p->sym.u.l.label = lab;
    161 	(*IR->defsymbol)(&p->sym);
    162 	return &p->sym;
    163 }
    164 Symbol constant(Type ty, Value v) {
    165 	struct entry *p;
    166 	unsigned h = v.u&(HASHSIZE-1);
    167 
    168 	ty = unqual(ty);
    169 	for (p = constants->buckets[h]; p; p = p->link)
    170 		if (eqtype(ty, p->sym.type, 1))
    171 			switch (ty->op) {
    172 			case INT:      if (equalp(i)) return &p->sym; break;
    173 			case UNSIGNED: if (equalp(u)) return &p->sym; break;
    174 			case FLOAT:    if (equalp(d)) return &p->sym; break;
    175 			case FUNCTION: if (equalp(g)) return &p->sym; break;
    176 			case ARRAY:
    177 			case POINTER:  if (equalp(p)) return &p->sym; break;
    178 			default: assert(0);
    179 			}
    180 	NEW0(p, PERM);
    181 	p->sym.name = vtoa(ty, v);
    182 	p->sym.scope = CONSTANTS;
    183 	p->sym.type = ty;
    184 	p->sym.sclass = STATIC;
    185 	p->sym.u.c.v = v;
    186 	p->link = constants->buckets[h];
    187 	p->sym.up = constants->all;
    188 	constants->all = &p->sym;
    189 	constants->buckets[h] = p;
    190 	if (ty->u.sym && !ty->u.sym->addressed)
    191 		(*IR->defsymbol)(&p->sym);
    192 	p->sym.defined = 1;
    193 	return &p->sym;
    194 }
    195 Symbol intconst(int n) {
    196 	Value v;
    197 
    198 	v.i = n;
    199 	return constant(inttype, v);
    200 }
    201 Symbol genident(int scls, Type ty, int lev) {
    202 	Symbol p;
    203 
    204 	NEW0(p, lev >= LOCAL ? FUNC : PERM);
    205 	p->name = stringd(genlabel(1));
    206 	p->scope = lev;
    207 	p->sclass = scls;
    208 	p->type = ty;
    209 	p->generated = 1;
    210 	if (lev == GLOBAL)
    211 		(*IR->defsymbol)(p);
    212 	return p;
    213 }
    214 
    215 Symbol temporary(int scls, Type ty) {
    216 	Symbol p;
    217 
    218 	NEW0(p, FUNC);
    219 	p->name = stringd(++tempid);
    220 	p->scope = level < LOCAL ? LOCAL : level;
    221 	p->sclass = scls;
    222 	p->type = ty;
    223 	p->temporary = 1;
    224 	p->generated = 1;
    225 	return p;
    226 }
    227 Symbol newtemp(int sclass, int tc, int size) {
    228 	Symbol p = temporary(sclass, btot(tc, size));
    229 
    230 	(*IR->local)(p);
    231 	p->defined = 1;
    232 	return p;
    233 }
    234 
    235 Symbol allsymbols(Table tp) {
    236 	return tp->all;
    237 }
    238 
    239 void locus(Table tp, Coordinate *cp) {
    240 	loci    = append(cp, loci);
    241 	symbols = append(allsymbols(tp), symbols);
    242 }
    243 
    244 void use(Symbol p, Coordinate src) {
    245 	Coordinate *cp;
    246 
    247 	NEW(cp, PERM);
    248 	*cp = src;
    249 	p->uses = append(cp, p->uses);
    250 }
    251 /* findtype - find type ty in identifiers */
    252 Symbol findtype(Type ty) {
    253 	Table tp = identifiers;
    254 	int i;
    255 	struct entry *p;
    256 
    257 	assert(tp);
    258 	do
    259 		for (i = 0; i < HASHSIZE; i++)
    260 			for (p = tp->buckets[i]; p; p = p->link)
    261 				if (p->sym.type == ty && p->sym.sclass == TYPEDEF)
    262 					return &p->sym;
    263 	while ((tp = tp->previous) != NULL);
    264 	return NULL;
    265 }
    266 
    267 /* mkstr - make a string constant */
    268 Symbol mkstr(char *str) {
    269 	Value v;
    270 	Symbol p;
    271 
    272 	v.p = str;
    273 	p = constant(array(chartype, strlen(v.p) + 1, 0), v);
    274 	if (p->u.c.loc == NULL)
    275 		p->u.c.loc = genident(STATIC, p->type, GLOBAL);
    276 	return p;
    277 }
    278 
    279 /* mksymbol - make a symbol for name, install in &globals if sclass==EXTERN */
    280 Symbol mksymbol(int sclass, const char *name, Type ty) {
    281 	Symbol p;
    282 
    283 	if (sclass == EXTERN)
    284 		p = install(string(name), &globals, GLOBAL, PERM);
    285 	else {
    286 		NEW0(p, PERM);
    287 		p->name = string(name);
    288 		p->scope = GLOBAL;
    289 	}
    290 	p->sclass = sclass;
    291 	p->type = ty;
    292 	(*IR->defsymbol)(p);
    293 	p->defined = 1;
    294 	return p;
    295 }
    296 
    297 /* vtoa - return string for the constant v of type ty */
    298 char *vtoa(Type ty, Value v) {
    299 	char buf[50];
    300 
    301 	ty = unqual(ty);
    302 	switch (ty->op) {
    303 	case INT:      return stringd(v.i);
    304 	case UNSIGNED: return stringf((v.u&~0x7FFF) ? "0x%X" : "%U", v.u);
    305 	case FLOAT:    return stringf("%g", (double)v.d);
    306 	case ARRAY:
    307 		if (ty->type == chartype || ty->type == signedchar
    308 		||  ty->type == unsignedchar)
    309 			return v.p;
    310 		return stringf("%p", v.p);
    311 	case POINTER:  return stringf("%p", v.p);
    312 	case FUNCTION: return stringf("%p", v.g);
    313 	}
    314 	assert(0); return NULL;
    315 }