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:
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);