scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 5ebf7e680f7738d2a2f5580982b179a21240b6b2
parent 7edc7e439ca0f0a7240f716e9312b477ff7aaed7
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 25 Oct 2013 17:24:35 +0200

Remove namespace function

These function was a big mess, and it was used only because
having the keywords in the symbol table caused a lot of problems.
This new version allows don't use yyval anymore, which is good
because it was generating some dependencies problems.
Due to these changes label definition was also affected, so
newlabel is no longer needed because lookup does perfectly
this job.

Diffstat:
Mdecl.c | 50+++++++++++++-------------------------------------
Mexpr.c | 12+++++++++---
Mflow.c | 28++++++----------------------
Mlex.c | 9+--------
Msymbol.c | 10+++-------
Msymbol.h | 3+--
Mtokens.h | 4----
7 files changed, 33 insertions(+), 83 deletions(-)

diff --git a/decl.c b/decl.c @@ -8,9 +8,6 @@ #include "syntax.h" #include "symbol.h" -#define NOALLOC_NS 0 -#define ALLOCDUP_NS 1 -#define ALLOC_NS 2 char parser_out_home; static struct symbol *cursym; @@ -19,32 +16,6 @@ static unsigned char structbuf[NR_STRUCT_LEVEL], *structp = &structbuf[0]; static void declarator(struct ctype *tp, unsigned char ns); -static struct symbol * -namespace(register unsigned char ns, char alloc) -{ - register struct symbol *sym = yyval.sym; - unsigned char yyns = sym->ns; - - if (alloc == NOALLOC_NS) { - if (yyns == NS_ANY) - return NULL; - else if (yyns == ns) - return sym; - else /* don't create new symbol */ - return lookup(yytext, NOINSERT(ns)); - } else { - if (yyns == NS_ANY) { - sym->ns = ns; - return sym; - } else if (yyns == ns && sym->ctx == curctx) { - if (alloc == ALLOCDUP_NS) - return sym; - error("redeclaration of '%s'", yytext); - } - return lookup(yytext, ns); - } -} - static void dirdcl(register struct ctype *tp, unsigned char ns) { @@ -52,7 +23,11 @@ dirdcl(register struct ctype *tp, unsigned char ns) declarator(tp, ns); expect(')'); } else if (yytoken == IDEN) { - cursym = namespace(ns, ALLOC_NS); + cursym = lookup(yytext, ns); + if (!cursym->ctype) + cursym->ctx = curctx; + else if (cursym->ctx == curctx) + error("redeclaration of '%s'", yytext); next(); } else { error("expected '(' or identifier before of '%s'", yytext); @@ -73,7 +48,7 @@ dirdcl(register struct ctype *tp, unsigned char ns) len = 0; } else { expect(CONSTANT); - len = yyval.sym->val; + len = atoi(yytext); expect(']'); } pushtype(len); @@ -91,7 +66,7 @@ new_struct(register struct ctype *tp) struct symbol *sym = NULL; if (yytoken == IDEN) { - sym = namespace(NS_STRUCT, ALLOCDUP_NS); + sym = lookup(yytext, NS_STRUCT); sym->ctype = tp; next(); } @@ -128,7 +103,7 @@ field_dcl(unsigned char ns) switch (tp->type) { case INT: case BOOL: tp = btype(NULL, BITFLD); - tp->len = yyval.sym->val; + tp->len = atoi(yytext); break; default: error("bit-field '%s' has invalid type", @@ -178,11 +153,11 @@ enum_dcl(struct ctype *base) break; expect(IDEN); - sym = namespace(NS_IDEN, ALLOC_NS); + sym = lookup(yytext, NS_IDEN); sym->ctype = tp; if (accept('=')) { expect(CONSTANT); - val = yyval.sym->val; + val = atoi(yytext); } sym->val = val++; } while (accept(',')); @@ -223,8 +198,9 @@ spec(void) struct symbol *sym; unsigned char tok = ahead(); - sym = namespace(NS_TYPEDEF, NOALLOC_NS); - if (sym && tok != ';' && tok != ',') { + sym = lookup(yytext, NS_TYPEDEF); + if (sym && sym->ctype && + tok != ';' && tok != ',') { if (!tp) tp = newctype(); tp->type = TYPEDEF; diff --git a/expr.c b/expr.c @@ -14,14 +14,20 @@ static struct node * primary(void) { register struct node *np; + register struct symbol *sym; switch (yytoken) { case IDEN: - if (!yyval.sym) + sym = lookup(yytext, NS_IDEN); + if (!sym->ctype) error("'%s' undeclared", yytext); + next(); + np = nodesym(sym); + break; case CONSTANT: + sym = lookup(NULL, NS_IDEN); next(); - np = nodesym(yyval.sym); + np = nodesym(sym); break; case '(': next(); @@ -68,7 +74,7 @@ postfix(void) expect_iden: next(); expect(IDEN); - np1 = node(op, np1, nodesym(yyval.sym)); + np1 = node(op, np1, nodesym(lookup(yytext, NS_IDEN))); continue; next: np1 = node(op, np1, NULL); diff --git a/flow.c b/flow.c @@ -30,23 +30,6 @@ pop(void) --blockp; } -static struct symbol* -newlabel(struct symbol *sym, char *s) -{ - switch (sym->ns) { - case NS_LABEL: - error("label '%s' already defined", yytext); - case NS_ANY: - sym->ns = NS_LABEL; - break; - default: - lookup(s, NS_LABEL); - } - - insert(sym, CTX_FUNC); - return sym; -} - static struct node * Goto(void) { @@ -56,9 +39,7 @@ Goto(void) expect(GOTO); expect(IDEN); - sym = yyval.sym; - if (sym->ns != NS_LABEL) - sym = newlabel(sym, yytext); + sym = lookup(yytext, NS_LABEL); np = node(OGOTO, nodesym(sym), NULL); expect(';'); @@ -156,9 +137,12 @@ Switch(void) static struct node * label(void) { - register struct symbol *sym = yyval.sym; + register struct symbol *sym = lookup(yytext, NS_LABEL); - sym = newlabel(sym, yytext); + if (sym->label) + error("label '%s' already defined", yytext); + insert(sym, CTX_FUNC); + sym->label = 1; next(), next(); /* skip IDEN and ':' */ return node(OLABEL, nodesym(sym), stmt()); } diff --git a/lex.c b/lex.c @@ -11,7 +11,6 @@ #define NR_KEYW_HASH 16 -union yyval yyval; unsigned char yytoken; char yytext[IDENTSIZ + 1]; unsigned linenum; @@ -68,8 +67,6 @@ end: if (bp == yytext + IDENTSIZ) error("identifier too long %s", yytext); *bp = '\0'; ungetc(ch, yyin); - yyval.sym = lookup(NULL, NS_ANY); - yyval.sym->val = strtol(yytext, NULL, base); return CONSTANT; } @@ -153,11 +150,7 @@ iden(void) *bp = '\0'; ungetc(ch, yyin); - if (tok = keyword(yytext)) - return tok; - - yyval.sym = lookup(yytext, NS_ANY); - return IDEN; + return (tok = keyword(yytext)) ? tok : IDEN; } static unsigned char diff --git a/symbol.c b/symbol.c @@ -66,19 +66,17 @@ struct symbol * lookup(register const char *s, signed char ns) { register struct symbol *sym; - static unsigned char key, l, ins; + static unsigned char key, l; if (s == NULL) { - sym = xmalloc(sizeof(*sym)); + sym = xcalloc(1, sizeof(*sym)); sym->next = head; return sym; } l = strlen(s); key = hash(s) & NR_SYM_HASH - 1; - if (!(ins = ns >= 0)) - ns = -ns; for (sym = htab[key]; sym; sym = sym->hash) { if (ns != NS_ANY && ns != sym->ns) @@ -87,9 +85,7 @@ lookup(register const char *s, signed char ns) return sym; } - if (!ins) - return NULL; - sym = xmalloc(sizeof(*sym)); + sym = xcalloc(1, sizeof(*sym)); sym->name = xstrdup(s); sym->next = head; sym->ctx = curctx; diff --git a/symbol.h b/symbol.h @@ -10,8 +10,6 @@ #define CTX_OUTER 0 #define CTX_FUNC 1 -#define NOINSERT(x) (-x) - enum { NS_IDEN, NS_KEYWORD, @@ -52,6 +50,7 @@ struct symbol { struct { union { short val; /* used in integer constant */ + unsigned char label; }; }; struct symbol *next; diff --git a/tokens.h b/tokens.h @@ -31,12 +31,8 @@ enum tokens { struct symbol; -union yyval { - struct symbol *sym; -}; -extern union yyval yyval; extern char yytext[]; extern size_t yylen; extern unsigned char yytoken;