scc

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

commit ebe3eda8ec61484d26bdbb754431a19ecdaa32b4
parent e96a66c1e82580dcb57e90482ef25d25336ac5dc
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 12 Mar 2014 11:21:44 +0100

Remove defined field from ctype

It can be known that a type is not defined is the value of type
is 0, so this field is no needed anymore.

Diffstat:
Mdecl.c | 281+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mexpr.c | 2+-
Mmain.c | 2+-
Msymbol.h | 1-
Msyntax.h | 1+
Mtypes.c | 6------
6 files changed, 157 insertions(+), 136 deletions(-)

diff --git a/decl.c b/decl.c @@ -33,7 +33,7 @@ directdcl(register struct ctype *tp, unsigned char ns, unsigned char isfun) } else if (ns != NS_TYPE) { if (yytoken == IDEN) { sym = lookup(yytext, ns); - if (!sym->ctype.defined) + if (!sym->ctype.type) sym->ctx = curctx; else if (sym->ctx == curctx) goto redeclared; @@ -72,107 +72,10 @@ expected: error: error(err, yytext); } -static unsigned char -newtag(unsigned char type) -{ - if (type == ENUM) - return 0; - if (nr_tags == NS_TAG + NR_MAXSTRUCTS) - error("too much structs/unions defined"); - return ++nr_tags; -} - -static struct symbol * -aggregate(register struct ctype *tp) -{ - struct symbol *sym = NULL; - - tp->forward = 1; - if (yytoken == IDEN) { - register struct ctype *aux; - - sym = lookup(yytext, NS_TAG); - aux = &sym->ctype; - if (aux->defined) { - if (aux->type != tp->type) - goto bad_type; - *tp = *aux; - } else { - tp->tag = sym->name; - tp->ns = newtag(tp->type); - sym->ctype = *tp; - } - next(); - } else { - tp->ns = newtag(tp->type); - } - - return sym; - -bad_type: - error("'%s' defined as wrong kind of tag", yytext); -} - -static void -structdcl(register struct ctype *tp) -{ - struct symbol *sym; - - sym = aggregate(tp); - - if (!accept('{')) - return; - - if (sym && !sym->ctype.forward) - error("struct/union already defined"); - - if (nested_tags == NR_STRUCT_LEVEL) - error("too much nested structs/unions"); - - ++nested_tags; - while (!accept('}')) - decl(tp->ns); - --nested_tags; - - if (sym) - sym->ctype.forward = 0; - tp->forward = 0; -} +static void structdcl(register struct ctype *tp); +static void enumdcl(struct ctype *base); static void -enumdcl(struct ctype *base) -{ - static int val; - - aggregate(base); - if (!accept('{')) - return; - val = 0; - - do { - register struct symbol *sym; - register struct ctype *tp; - - if (yytoken != IDEN) - break; - sym = lookup(yytext, NS_IDEN); - tp = &sym->ctype; - if (tp->defined && sym->ctx == curctx) - error("'%s' redefined", yytext); - next(); - if (accept('=')) { - expect(CONSTANT); - val = yyval->i; - } - ctype(tp, INT); - tp->base = base; - sym->i = val++; - } while (accept(',')); - - expect('}'); -} - -static bool specifier(register struct ctype *tp, char *store, char *qlf) { unsigned char tok; @@ -201,7 +104,7 @@ specifier(register struct ctype *tp, char *store, char *qlf) enumdcl(tp); else structdcl(tp); - return true; + return; case TYPENAME: tp->base = &yyval->ctype; break; @@ -213,16 +116,6 @@ specifier(register struct ctype *tp, char *store, char *qlf) } check_type: - if (!tp->defined) { - if (*store && *qlf && - curctx != CTX_OUTER && - nested_tags == 0) { - return false; - } - warn(options.implicit, - "type defaults to 'int' in declaration"); - } - if (!tp->c_signed && !tp->c_unsigned) { switch (tp->type) { case CHAR: @@ -233,8 +126,10 @@ check_type: case INT: case SHORT: case LONG: case LLONG: tp->c_signed = 1; } + } else if (!tp->type) { + tp->type = INT; } - return true; + return; } static struct symbol * @@ -294,6 +189,9 @@ listdcl(struct ctype *base, c.tree = NULL; + if (yytoken == ';') + return NULL; + do { struct node *np, *aux; register struct ctype *tp; @@ -344,7 +242,6 @@ listdcl(struct ctype *base, } } while (accept(',')); - expect(';'); return c.tree; bad_type: @@ -358,27 +255,134 @@ incomplete: error: error(err); } +static unsigned char +newtag(unsigned char type) +{ + if (type == ENUM) + return 0; + if (nr_tags == NS_TAG + NR_MAXSTRUCTS) + error("too much structs/unions defined"); + return ++nr_tags; +} + +static struct symbol * +aggregate(register struct ctype *tp) +{ + struct symbol *sym = NULL; + + tp->forward = 1; + if (yytoken == IDEN) { + register struct ctype *aux; + + sym = lookup(yytext, NS_TAG); + aux = &sym->ctype; + if (aux->type) { + if (aux->type != tp->type) + goto bad_type; + *tp = *aux; + } else { + tp->tag = sym->name; + tp->ns = newtag(tp->type); + sym->ctype = *tp; + } + next(); + } else { + tp->ns = newtag(tp->type); + } + + return sym; + +bad_type: + error("'%s' defined as wrong kind of tag", yytext); +} + +static void +structdcl(register struct ctype *tp) +{ + struct symbol *sym; + + sym = aggregate(tp); + + if (!accept('{')) + return; + + if (sym && !sym->ctype.forward) + error("struct/union already defined"); + + if (nested_tags == NR_STRUCT_LEVEL) + error("too much nested structs/unions"); + + ++nested_tags; + while (!accept('}')) { + struct ctype base; + struct node *np; + char store = 0, qlf = 0; + + initctype(&base); + specifier(&base, &store, &qlf); + + if (store) + error("storage specifier in a struct/union field declaration"); + + listdcl(&base, store, qlf, tp->ns, 0); + expect(';'); + } + --nested_tags; + + if (sym) + sym->ctype.forward = 0; + tp->forward = 0; +} + +static void +enumdcl(struct ctype *base) +{ + static int val; + + aggregate(base); + if (!accept('{')) + return; + val = 0; + + do { + register struct symbol *sym; + register struct ctype *tp; + + if (yytoken != IDEN) + break; + sym = lookup(yytext, NS_IDEN); + tp = &sym->ctype; + if (tp->type && sym->ctx == curctx) + error("'%s' redefined", yytext); + next(); + if (accept('=')) { + expect(CONSTANT); + val = yyval->i; + } + ctype(tp, INT); + tp->base = base; + sym->i = val++; + } while (accept(',')); + + expect('}'); +} + struct node * decl(unsigned char ns) { struct ctype base; + struct node *np; char store = 0, qlf = 0; initctype(&base); - - if (!specifier(&base, &store, &qlf)) - return NULL; + specifier(&base, &store, &qlf); if (store && ns != NS_IDEN) error("storage specifier in a struct/union field declaration"); - switch (base.type) { - case STRUCT: case UNION: case ENUM: - if (yytoken == ';') - return NULL; - default: - return listdcl(&base, store, qlf, ns, 0); - } + np = listdcl(&base, store, qlf, ns, 0); + expect(';'); + return np; } void @@ -387,11 +391,33 @@ type_name(struct ctype *tp) char store = 0, qlf = 0; initctype(tp); - - if (!specifier(tp, &store, &qlf)) - return; - + specifier(tp, &store, &qlf); declarator(tp, NS_TYPE, 0); return; } +struct node * +extdecl(void) +{ + struct ctype base; + struct node *np; + char store = 0, qlf = 0; + + initctype(&base); + + switch (yytoken) { + case IDEN: + warn(options.implicit, + "type defaults to 'int' in declaration"); + base.type = INT; + break; + case TYPE: case STORAGE: case TQUALIFIER: + specifier(&base, &store, &qlf); + break; + default: + error("declaration expected"); + } + + np = listdcl(&base, store, qlf, 0, 0); + expect(';'); +} +\ No newline at end of file diff --git a/expr.c b/expr.c @@ -18,7 +18,7 @@ primary(void) switch (yytoken) { case IDEN: sym = lookup(yytext, NS_IDEN); - if (!sym->ctype.defined) + if (!sym->ctype.type) error("'%s' undeclared", yytext); next(); np = nodesym(sym); diff --git a/main.c b/main.c @@ -19,7 +19,7 @@ main(int argc, char *argv[]) init_keywords(); open_file(NULL); for (next(); yytoken != EOFTOK; run(np)) - np = decl(0); + np = extdecl(); return 0; } diff --git a/symbol.h b/symbol.h @@ -26,7 +26,6 @@ struct ctype { bool c_unsigned : 1; bool c_signed : 1; bool forward : 1; - bool defined: 1; union { struct { unsigned char ns; diff --git a/syntax.h b/syntax.h @@ -29,6 +29,7 @@ struct compound { }; extern struct node *expr(void); +extern struct node *extdecl(void); extern struct node *decl(unsigned char ns); extern void type_name(struct ctype *tp); extern struct node *function(struct symbol *sym); diff --git a/types.c b/types.c @@ -16,7 +16,6 @@ struct ctype * initctype(register struct ctype *tp) { memset(tp, 0, sizeof(*tp)); - tp->type = INT; tp->forward = 1; return tp; } @@ -62,7 +61,6 @@ mktype(register struct ctype *tp, unsigned char op) default: assert(0); } - tp->defined = 1; return tp; } @@ -91,10 +89,6 @@ ctype(struct ctype *tp, unsigned char tok) register unsigned char type; static char *err; - if (!tp->defined) { - tp->type = 0; - tp->defined = 1; - } type = tp->type;