shithub: scc

Download patch

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