ref: e61db29e0aed115dc504d337b8006e869cc5040c
parent: 449b361b5e44127d7ca45773cab7d8f4c4b496df
author: Roberto E. Vargas Caballero <[email protected]>
date: Sun Mar 9 07:24:01 EDT 2014
Add a first version of type_name This version is not real functional, but it is a base of something that is really working.
--- a/decl.c
+++ b/decl.c
@@ -24,28 +24,30 @@
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 @@
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 @@
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;
}
--- a/expr.c
+++ b/expr.c
@@ -92,7 +92,9 @@
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 @@
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();
--- a/symbol.h
+++ b/symbol.h
@@ -12,6 +12,7 @@
enum {
NS_IDEN = 0,
+ NS_TYPE,
NS_KEYWORD,
NS_LABEL,
NS_TAG
--- a/syntax.h
+++ b/syntax.h
@@ -21,6 +21,7 @@
struct node;
struct symbol;
+struct ctype;
struct compound {
struct node *tree;
@@ -29,7 +30,7 @@
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);