commit f2eaad8b7bfd3d9bd01a032b9ee1c5b2ab630207
parent 0dc51a53f9e0728586d36fe4f39402f91defe4e7
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 8 Apr 2014 22:07:02 +0200
Add cast()
Diffstat:
M | decl.c | | | 18 | ++++++++++++++---- |
M | expr.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;
}