scc

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

commit f2eaad8b7bfd3d9bd01a032b9ee1c5b2ab630207
parent 0dc51a53f9e0728586d36fe4f39402f91defe4e7
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  8 Apr 2014 22:07:02 +0200

Add cast()

Diffstat:
Mdecl.c | 18++++++++++++++----
Mexpr.c | 29+++++++++++++++++++++++------
2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/decl.c b/decl.c @@ -136,7 +136,8 @@ declarator(Type *tp, uint8_t ns, int8_t flags) { struct dcldata data[NR_DECLARATORS+1]; register struct dcldata *bp; - Symbol *sym; + Symbol *sym = NULL; + static Symbol dummy; memset(data, 0, sizeof(data)); data[NR_DECLARATORS].op = 255; @@ -156,6 +157,8 @@ declarator(Type *tp, uint8_t ns, int8_t flags) break; } } + if (!sym) + sym = &dummy; sym->type = tp; return sym; } @@ -440,11 +443,18 @@ decl(void) } } -struct node * +Type * typename(void) { - declarator(specifier(NULL), NS_IDEN, 0); - return NULL; + uint8_t sclass; + Type *tp; + Symbol *sym; + + tp = specifier(&sclass); + if (sclass) + error("class storage in type name"); + sym = declarator(tp, NS_IDEN, 0); + return sym->type; } void diff --git a/expr.c b/expr.c @@ -210,28 +210,45 @@ static Node * unary(void) { Node *np; - char op; switch (yytoken) { case INC: case DEC: - op = (yytoken == INC) ? OINC : ODEC; - /* TODO: check that the the base type is a complete type */ + np = incdec(unary(), (yytoken == INC) ? OINC : ODEC); next(); - np = unary(); - return unarycode(op, np->type, np); break; default: return postfix(); } } +static struct node * +cast(void) +{ + Type *tp; + extern Type *typename(void); + + if (yytoken == '(') { + switch(ahead()) { + case TQUALIFIER: case TYPE: + next(); + tp = typename(); + expect(')'); + return castcode(cast(), tp); + default: + break; + } + } + + return unary(); +} + Node * expr(void) { Node *np; do - np = unary(); + np = cast(); while (yytoken == ','); return np; }