scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit e61db29e0aed115dc504d337b8006e869cc5040c
parent 449b361b5e44127d7ca45773cab7d8f4c4b496df
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun,  9 Mar 2014 11:24:01 +0100

Add a first version of type_name

This version is not real functional, but it is a base of something
that is really working.

Diffstat:
decl.c | 52++++++++++++++++++++++++++++++++++++----------------
expr.c | 10+++++++---
symbol.h | 1+
syntax.h | 3++-
4 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/decl.c b/decl.c @@ -24,28 +24,30 @@ static struct symbol * directdcl(register struct ctype *tp, unsigned char ns) { register struct symbol *sym; + register char *err; if (accept('(')) { sym = declarator(tp, ns); expect(')'); - } else if (yytoken == IDEN) { - sym = lookup(yytext, ns); - if (!sym->ctype.defined) - sym->ctx = curctx; - else if (sym->ctx == curctx) - error("redeclaration of '%s'", yytext); - next(); - } else { - error("expected '(' or identifier before of '%s'", yytext); + } else if (ns != NS_TYPE) { + if (yytoken == IDEN) { + sym = lookup(yytext, ns); + if (!sym->ctype.defined) + sym->ctx = curctx; + else if (sym->ctx == curctx) + goto redeclared; + next(); + } else { + goto expected; + } } for (;;) { if (accept('(')) { pushtype(FTN); - if (accept(')')) - ; /* TODO: k&r function */ - else - /* TODO: prototyped function */; + if (yytoken != ')') + ; /* TODO: prototyped function */; + expect(')'); } else if (accept('[')) { unsigned len = '0'; @@ -57,9 +59,16 @@ directdcl(register struct ctype *tp, unsigned char ns) pushtype(len); pushtype(ARY); } else { - return sym; + return sym; } } + +redeclared: + err = "redeclaration of '%s'"; + goto error; +expected: + err = "expected '(' or identifier before of '%s'"; +error: error(err, yytext); } static unsigned char @@ -404,8 +413,19 @@ repeat: initctype(&base); return listdcl(&base, &store, &qlf, ns); } -void -type_name() +bool +type_name(struct ctype *tp) { + struct storage store; + struct qualifier qlf; + initctype(tp); + initstore(&store); + initqlf(&qlf); + + if (!specifier(tp, &store, &qlf)) + return false; + + declarator(tp, NS_TYPE); + return true; } diff --git a/expr.c b/expr.c @@ -92,7 +92,9 @@ unary(void) case SIZEOF: /* TODO: Implement sizeof */ next(); if (accept('(')) { - type_name(); + struct ctype type; + if (!type_name(&type)) + expr(); expect(')'); } else { unary(); @@ -121,8 +123,10 @@ call_unary: static struct node * cast(void) { - while (accept('(')) { /* TODO: Implement casts */ - type_name(); /* check if it really is a type name */ + while (accept('(')) { + struct ctype type; + if (!type_name(&type)) + error("expected a type name"); expect(')'); } return unary(); diff --git a/symbol.h b/symbol.h @@ -12,6 +12,7 @@ enum { NS_IDEN = 0, + NS_TYPE, NS_KEYWORD, NS_LABEL, NS_TAG diff --git a/syntax.h b/syntax.h @@ -21,6 +21,7 @@ enum opcode { struct node; struct symbol; +struct ctype; struct compound { struct node *tree; @@ -29,7 +30,7 @@ struct compound { extern struct node *expr(void); extern struct node *decl(unsigned char ns); -extern void type_name(void); +extern bool type_name(struct ctype *tp); extern struct node *function(struct symbol *sym); extern struct node *node(unsigned char op, struct node *l, struct node *r);