shithub: scc

Download patch

ref: 7a66e2a3991b2b7d203d1a8290951bbfd2db9511
parent: 5956b8e016a018b2701f8651e328f7ddae62084f
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu Jul 10 17:26:52 EDT 2014

Remove prefecthing of tokens

This technique was generating a lot of problems in different situations.
For example the value of a symbol was calculated before of the end
of the previous statement, so blocks like:

	typedef int pepe;
	pepe j;

failed, because in the moment of the prefetch of second pepe, the
previous typedef was not finished.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -138,7 +138,7 @@
 #define REGISTER      5
 
 #define accept(t) ((yytoken == (t)) ? next() : 0)
-#define ahead()   yyntoken
+extern uint8_t ahead(void);
 
 enum tokens {
 	TQUALIFIER = 128, TYPE, IDEN, SCLASS,
@@ -152,14 +152,14 @@
 	CONTINUE, BREAK, RETURN, EOFTOK, NOTOK
 };
 
-union yystype {
+struct yystype {
 	Symbol *sym;
 	uint8_t token;
 };
 
-extern union yystype yylval;
+extern struct yystype yylval;
 extern char yytext[];
-extern uint8_t yytoken, yyntoken;
+extern uint8_t yytoken;
 
 extern uint8_t next(void);
 extern void expect(uint8_t tok);
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -468,6 +468,28 @@
 	}
 }
 
+static Node *unary(void);
+
+static Node *
+Sizeof(void)
+{
+	Type *tp;
+	Node *np;
+	bool paren = accept(')');
+
+	if (paren && yytoken == IDEN) {
+		tp = typename();
+	} else {
+		Node *np = unary();
+		tp = np->type;
+		/* TODO: free np */
+	}
+	np = sizeofcode(tp);
+	if (paren)
+		expect(')');
+	return np;
+}
+
 static Node *cast(void);
 
 static Node *
@@ -480,15 +502,7 @@
 	switch (yytoken) {
 	case SIZEOF:
 		next();
-		if (yytoken == '(' && ahead() == TYPE) {
-			next();
-			tp = typename();
-			expect(')');
-		} else {
-			tp = unary()->type;
-			/* TODO: Free memory */
-		}
-		return sizeofcode(tp);
+		return Sizeof();
 	case INC: case DEC:
 		op = (yytoken == INC) ? OA_ADD : OA_SUB;
 		next();
@@ -507,28 +521,37 @@
 }
 
 static Node *
-cast(void)
+cast2(void)
 {
-	Type *tp;
 	register Node *np1, *np2;
+	register Type *tp;
 
-	if (yytoken == '(') {
-		switch(ahead()) {
-		case TQUALIFIER: case TYPE:
-			next();
-			tp = typename();
-			expect(')');
-			np1 = eval(cast());
-			if ((np2 = convert(np1,  tp, 1)) == NULL)
-				error("bad type convertion requested");
-			np2->b.lvalue = np1->b.lvalue;
-			return np2;
-		default:
-			break;
-		}
+	switch(yytoken) {
+	case TQUALIFIER: case TYPE:
+		tp = typename();
+		expect(')');
+		np1 = eval(cast());
+		if ((np2 = convert(np1,  tp, 1)) == NULL)
+			error("bad type convertion requested");
+		np2->b.lvalue = np1->b.lvalue;
+		return np2;
+	default:
+		return unary();
 	}
+}
 
-	return unary();
+static Node *
+cast(void)
+{
+	register Node *np;
+
+	if (accept('(')) {
+		np = cast2();
+		expect('(');
+	} else {
+		np = unary();
+	}
+	return np;
 }
 
 static Node *
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -13,13 +13,10 @@
 const char *filename;
 unsigned linenum;
 
-uint8_t yytoken, yyntoken;;
-union yystype yylval;
+uint8_t yytoken;
+struct yystype yylval;
 char yytext[IDENTSIZ + 1];
 
-static union yystype yynlval;
-static char yybuf[IDENTSIZ + 1];
-
 static uint8_t
 integer(char *s, char base)
 {
@@ -50,10 +47,10 @@
 
 	sym = install("", NS_IDEN);
 	sym->type = tp;
-	v = strtol(yybuf, NULL, base);
+	v = strtol(yytext, NULL, base);
 	if (tp == inttype)
 		sym->u.i = v;
-	yynlval.sym = sym;
+	yylval.sym = sym;
 	return CONSTANT;
 }
 
@@ -75,7 +72,7 @@
 		ungetc(ch, yyin);
 	}
 
-	for (bp = yybuf ; bp < &yybuf[IDENTSIZ]; *bp++ = ch) {
+	for (bp = yytext ; bp < &yytext[IDENTSIZ]; *bp++ = ch) {
 		ch = getc(yyin);
 		switch (base) {
 		case 8:
@@ -94,11 +91,11 @@
 	}
 
 end:
-	if (bp == &yybuf[IDENTSIZ])
-		error("identifier too long %s", yybuf);
+	if (bp == &yytext[IDENTSIZ])
+		error("identifier too long %s", yytext);
 	*bp = '\0';
 	ungetc(ch, yyin);
-	return integer(yybuf, base);
+	return integer(yytext, base);
 }
 
 static char *
@@ -150,7 +147,7 @@
 	sym = install("", NS_IDEN);
 	sym->u.i = c;
 	sym->type = inttype;
-	yynlval.sym = sym;
+	yylval.sym = sym;
 	return CONSTANT;
 }
 
@@ -185,7 +182,7 @@
 	sym = install("", NS_IDEN);
 	sym->u.s = xstrdup(buf);
 	sym->type = mktype(chartype, PTR, 0);
-	yynlval.sym = sym;
+	yylval.sym = sym;
 	return STRING;
 }
 
@@ -248,23 +245,21 @@
 {
 	register char *bp;
 	register int c;
-	Symbol *sym;
+	register Symbol *sym;
 
-	for (bp = yybuf; bp < &yybuf[IDENTSIZ]; *bp++ = c) {
+	for (bp = yytext; bp < &yytext[IDENTSIZ]; *bp++ = c) {
 		if (!isalnum(c = getc(yyin)) && c != '_')
 			break;
 	}
-	if (bp == &yybuf[IDENTSIZ])
-		error("identifier too long %s", yybuf);
+	if (bp == &yytext[IDENTSIZ])
+		error("identifier too long %s", yytext);
 	*bp = '\0';
 	ungetc(c, yyin);
 
-	sym = lookup(yybuf, NS_IDEN);
-	if (!sym || sym->token == IDEN) {
-		yynlval.sym = sym;
+	sym = yylval.sym = lookup(yytext, NS_IDEN);
+	if (!sym || sym->token == IDEN)
 		return IDEN;
-	}
-	yynlval.token = sym->u.token;
+	yylval.token = sym->u.token;
 	return sym->token;
 }
 
@@ -274,8 +269,8 @@
 	register int c = getc(yyin);
 
 	if (c == expect) {
-		yybuf[1] = c;
-		yybuf[2] = 0;
+		yytext[1] = c;
+		yytext[2] = 0;
 		return ifyes;
 	}
 	ungetc(c, yyin);
@@ -287,14 +282,14 @@
 {
 	register int c = getc(yyin);
 
-	yybuf[1] = c;
-	yybuf[2] = '\0';
+	yytext[1] = c;
+	yytext[2] = '\0';
 	switch (c) {
 	case '-': return DEC;
 	case '>': return INDIR;
 	case '=': return SUB_EQ;
 	default:
-		yybuf[1] = '\0';
+		yytext[1] = '\0';
 		ungetc(c, yyin);
 		return '-';
 	}
@@ -305,13 +300,13 @@
 {
 	register int c = getc(yyin);
 
-	yybuf[1] = c;
-	yybuf[2] = '\0';
+	yytext[1] = c;
+	yytext[2] = '\0';
 	switch (c) {
 	case '+': return INC;
 	case '=': return ADD_EQ;
 	default:
-		yybuf[1] = '\0';
+		yytext[1] = '\0';
 		ungetc(c, yyin);
 		return '+';
 	}
@@ -322,8 +317,8 @@
 {
 	register int c = getc(yyin);
 
-	yybuf[1] = c;
-	yybuf[2] = '\0';
+	yytext[1] = c;
+	yytext[2] = '\0';
 
 	if (c == '=')
 		return equal;
@@ -330,7 +325,7 @@
 	if (c == op)
 		return follow('=', assig, shift);
 	ungetc(c, yyin);
-	yybuf[1] = '\0';
+	yytext[1] = '\0';
 	return op;
 }
 
@@ -339,8 +334,8 @@
 {
 	register int c = getc(yyin);
 
-	yybuf[1] = c;
-	yybuf[2] = '\0';
+	yytext[1] = c;
+	yytext[2] = '\0';
 
 	if (c == '=')
 		return equal;
@@ -347,7 +342,7 @@
 	if (c == op)
 		return logic;
 	ungetc(c, yyin);
-	yybuf[1] = '\0';
+	yytext[1] = '\0';
 	return op;
 }
 
@@ -356,8 +351,8 @@
 {
 	register uint8_t c = getc(yyin);
 
-	yybuf[0] = c;
-	yybuf[1] = '\0';
+	yytext[0] = c;
+	yytext[1] = '\0';
 	switch (c) {
 	case '<': return relational('<', LE, SHL, SHL_EQ);
 	case '>': return relational('>', GE, SHR, SHR_EQ);
@@ -374,40 +369,43 @@
 	}
 }
 
-uint8_t
-next(void)
+static int
+skipspaces(void)
 {
-	static int c;
 
-	strcpy(yytext, yybuf);
-	yylval = yynlval;
-	if ((yytoken = yyntoken) == EOFTOK)
-		goto ret;
+	register int c;
 
 	while (isspace(c = getc(yyin))) {
 		if (c == '\n')
 			++linenum;
 	}
+	return c;
+}
 
+uint8_t
+next(void)
+{
+	register int c;
+
+	ungetc(c = skipspaces(), yyin);
+
 	if (c == EOF) {
-		strcpy(yybuf, "EOF");
-		yyntoken = EOFTOK;
+		strcpy(yytext, "EOF");
+		yytoken = EOFTOK;
 		goto ret;
+	} else if (isalpha(c) || c == '_') {
+		yytoken = iden();
+	} else if (isdigit(c)) {
+		yytoken = number();
+	} else if (c == '"') {
+		yytoken = string();
+	} else if (c == '\'') {
+		yytoken = character();
+	} else {
+		yytoken = operator();
 	}
-
-	ungetc(c, yyin);
-	if (isalpha(c) || c == '_')
-		yyntoken = iden();
-	else if (isdigit(c))
-		yyntoken = number();
-	else if (c == '"')
-		yyntoken = string();
-	else if (c == '\'')
-		yyntoken = character();
-	else
-		yyntoken = operator();
-
-ret:	return yytoken;
+ret:
+	return yytoken;
 }
 
 void
@@ -418,6 +416,16 @@
 	next();
 }
 
+uint8_t
+ahead(void)
+{
+	register int c;
+	
+	ungetc(c = skipspaces(), yyin);
+
+	return c;
+}
+
 void
 open_file(register const char *file)
 {
@@ -432,5 +440,5 @@
 		filename = file;
 	}
 	linenum = 1;
-	next();      /* prefetch first token */
 }
+