shithub: scc

Download patch

ref: f2eaad8b7bfd3d9bd01a032b9ee1c5b2ab630207
parent: 0dc51a53f9e0728586d36fe4f39402f91defe4e7
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Apr 8 18:07:02 EDT 2014

Add cast()

--- a/decl.c
+++ b/decl.c
@@ -136,7 +136,8 @@
 {
 	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 @@
 			break;
 		}
 	}
+	if (!sym)
+		sym = &dummy;
 	sym->type = tp;
 	return sym;
 }
@@ -440,11 +443,18 @@
 	}
 }
 
-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
--- a/expr.c
+++ b/expr.c
@@ -210,15 +210,11 @@
 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();
@@ -225,6 +221,27 @@
 	}
 }
 
+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)
 {
@@ -231,7 +248,7 @@
 	Node *np;
 
 	do
-		np = unary();
+		np = cast();
 	while (yytoken == ',');
 	return np;
 }
--