scc

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

commit 951024c4481a3f63bfab9a83364d6861f16ee5d9
parent d247bc3fa770720335e31b8d3c735200b2484c30
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 11 Mar 2014 17:36:05 +0100

Change storage codification

This form of codificate storage makes trivial all the checks in
declarations.

Diffstat:
Mdecl.c | 31++++++++++++++++---------------
Mexpr.c | 11+++++------
Msymbol.h | 13+------------
Mtokens.h | 12+++++++++---
Mtypes.c | 53+----------------------------------------------------
5 files changed, 32 insertions(+), 88 deletions(-)

diff --git a/decl.c b/decl.c @@ -172,9 +172,9 @@ enumdcl(struct ctype *base) expect('}'); } -bool +static bool specifier(register struct ctype *tp, - struct storage *store, struct qualifier *qlf) + char *store, struct qualifier *qlf) { unsigned char tok; @@ -184,7 +184,10 @@ specifier(register struct ctype *tp, qlf = qualifier(qlf, yyval->c); break; case STORAGE: - store = storage(store, yyval->c); + if (*store) + error("two or more storage specifier"); + /* TODO: check bad storage in file-scope */ + *store |= yyval->c; break; case TYPE: tp = ctype(tp, tok = yyval->c); @@ -196,7 +199,7 @@ specifier(register struct ctype *tp, else structdcl(tp); return true; - case TYPEDEF: + case TYPENAME: tp->base = &yyval->ctype; break; } @@ -208,7 +211,7 @@ specifier(register struct ctype *tp, check_type: if (!tp->defined) { - if (!store->defined && + if (*store && !qlf->defined && curctx != CTX_OUTER && nested_tags == 0) { @@ -285,7 +288,7 @@ initializer(register struct ctype *tp) static struct node * listdcl(struct ctype *base, - struct storage *store, + char store, struct qualifier *qlf, unsigned char ns, unsigned char isfun) { @@ -300,12 +303,12 @@ listdcl(struct ctype *base, register struct symbol *sym; sym = declarator(base, ns, isfun); - sym->store = *store; + sym->store = store; sym->qlf = *qlf; sym->ctype = *decl_type(base); - if (sym->store.c_typedef) { + if (sym->store) { sym->tok = TYPE; - sym->c = TYPEDEF; + sym->c = TYPENAME; } tp = &sym->ctype; aux = NULL; @@ -362,17 +365,16 @@ struct node * decl(unsigned char ns) { struct ctype base; - struct storage store; + char store = 0; struct qualifier qlf; initctype(&base); - initstore(&store); initqlf(&qlf); if (!specifier(&base, &store, &qlf)) return NULL; - if (store.defined && ns != NS_IDEN) + if (store && ns != NS_IDEN) error("storage specifier in a struct/union field declaration"); switch (base.type) { @@ -380,18 +382,17 @@ decl(unsigned char ns) if (yytoken == ';') return NULL; default: - return listdcl(&base, &store, &qlf, ns, 0); + return listdcl(&base, store, &qlf, ns, 0); } } void type_name(struct ctype *tp) { - struct storage store; struct qualifier qlf; + char store = 0; initctype(tp); - initstore(&store); initqlf(&qlf); if (!specifier(tp, &store, &qlf)) diff --git a/expr.c b/expr.c @@ -129,19 +129,18 @@ call_unary: static struct node * cast(void) { - register struct node *np; struct ctype type; - while (accept('(')) { - switch (yytoken) { +repeat: if (yytoken == '(') { + switch (ahead()) { case STORAGE: case TQUALIFIER: case TYPE: + next(); type_name(&type); /* TODO: type_name should return a np*/ - break; + expect(')'); + goto repeat; default: - np = expr(); break; } - expect(')'); } return unary(); } diff --git a/symbol.h b/symbol.h @@ -23,15 +23,6 @@ struct qualifier { bool defined: 1; }; -struct storage { - bool c_typedef : 1; - bool c_extern : 1; - bool c_static : 1; - bool c_auto : 1; - bool c_register : 1; - bool defined: 1; -}; - struct ctype { unsigned type : 5; bool c_const : 1; @@ -53,7 +44,7 @@ struct ctype { struct symbol { struct ctype ctype; - struct storage store; + char store; struct qualifier qlf; unsigned char ctx; unsigned char ns; @@ -82,12 +73,10 @@ extern void del_ctx(void); extern void freesyms(void); extern struct symbol *lookup(const char *s, signed char ns); extern void insert(struct symbol *sym, unsigned char ctx); -extern struct storage *storage(struct storage *tp, unsigned char mod); extern struct qualifier *qualifier(register struct qualifier *, unsigned char); extern void delctype(struct ctype *tp); extern unsigned char hash(register const char *s); extern struct ctype *initctype(register struct ctype *tp); -extern struct storage *initstore(register struct storage *store); extern struct qualifier * initqlf(struct qualifier *qlf); #ifndef NDEBUG diff --git a/tokens.h b/tokens.h @@ -11,13 +11,13 @@ enum tokens { /* types */ INT = 1, CHAR, FLOAT, LONG, LLONG, SHORT, VOID, DOUBLE, LDOUBLE, STRUCT, UNION, ENUM, BOOL, ARY, PTR, FTN, - COMPLEX, IMAGINARY, BITFLD, TYPE, - /* storage specifier */ - TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, STORAGE, + COMPLEX, IMAGINARY, BITFLD, TYPENAME, TYPE, /* type qualifier */ VOLATILE, CONST, RESTRICT, TQUALIFIER, /* sign specifier */ UNSIGNED, SIGNED, + /* storage specifier */ + STORAGE, /* other tokens */ IDEN = 128, CONSTANT, SIZEOF, INDIR, INC, DEC, SHL, SHR, @@ -29,6 +29,12 @@ enum tokens { CONTINUE, BREAK, RETURN, EOFTOK, NOTOK }; +#define TYPEDEF (1<<0) +#define EXTERN (1<<1) +#define STATIC (1<<2) +#define AUTO (1<<3) +#define REGISTER (1<<4) +#define STORAGE (1<<5) struct symbol; extern struct symbol *yyval; diff --git a/types.c b/types.c @@ -28,17 +28,6 @@ initctype(register struct ctype *tp) return tp; } -struct storage * -initstore(register struct storage *store) -{ - extern unsigned char curctx; - memset(store, 0, sizeof(*store)); - - if (curctx != CTX_OUTER) - store->c_auto = 1; - return store; -} - void delctype(register struct ctype *tp) { @@ -188,7 +177,7 @@ check_sign: switch (type) { goto invalid_sign; } break; - case TYPEDEF: + case TYPENAME: assert(!type); if (tp->c_signed || tp->c_unsigned) goto invalid_sign; @@ -238,46 +227,6 @@ duplicated: error("duplicated '%s'", yytext); } -struct storage * -storage(register struct storage *sp, unsigned char mod) -{ - extern unsigned char curctx; - - if (!sp->defined) - sp->c_auto = 0; - else - error("Two or more storage specifier"); - - switch (mod) { - case TYPEDEF: - sp->c_typedef = 1; - break; - case EXTERN: - sp->c_extern = 1; - break; - case STATIC: - sp->c_static = 1; - break; - case AUTO: - if (curctx == CTX_OUTER) - goto bad_file_scope_storage; - sp->c_auto = 1; - break; - case REGISTER: - if (curctx == CTX_OUTER) - goto bad_file_scope_storage; - sp->c_register = 1; - break; - default: - assert(0); - } - sp->defined = 1; - return sp; - -bad_file_scope_storage: - error("file-scope declaration specifies '%s'", yytext); -} - #ifndef NDEBUG #include <stdio.h>