shithub: scc

Download patch

ref: 5cc0256ea7e075ec951904e3cfcfcd30e0df31d4
parent: eb12bd70592fe92197ceec3bbfd8d064ad273a33
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed Jul 9 08:25:34 EDT 2014

Simplify stmt

We can use a function pointer for this function, but then we need
to pass the state to all the possible statements. This is not a
problem, because we can ignore the parameters we are not using,
and the code of stmt will be smaller because we have only one
function call.

--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -43,7 +43,7 @@
 }
 
 static void
-stmtexp(void)
+stmtexp(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	if (yytoken != ';')
 		emitexp(expr());
@@ -62,7 +62,7 @@
 }
 
 static void
-While(Caselist *lswitch)
+While(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	Symbol *begin, *cond, *end;
 	Node *np;
@@ -84,7 +84,7 @@
 }
 
 static void
-For(Caselist *lswitch)
+For(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	Symbol *begin, *cond, *end;
 	Node *econd = NULL, *einc = NULL;
@@ -117,7 +117,7 @@
 }
 
 static void
-Dowhile(Caselist *lswitch)
+Dowhile(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	Symbol *begin = label("", 1), *end = label("", 1);
 
@@ -132,7 +132,7 @@
 }
 
 static void
-Return(void)
+Return(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	Node *np;
 	Type *tp = curfun->type->type;
@@ -155,7 +155,7 @@
 }
 
 static void
-Break(Symbol *lbreak)
+Break(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	expect(BREAK);
 	if (!lbreak)
@@ -164,17 +164,20 @@
 	expect(';');
 }
 
+static void stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
+
 static void
-Label(void)
+Label(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	emitlabel(label(yytext, 1));
 
 	expect(IDEN);
 	expect(':');
+	stmt(lbreak, lcont, lswitch);
 }
 
 static void
-Continue(Symbol *lcont)
+Continue(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	expect(CONTINUE);
 	if (!lcont)
@@ -184,7 +187,7 @@
 }
 
 static void
-Goto(void)
+Goto(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	expect(GOTO);
 
@@ -196,13 +199,14 @@
 }
 
 static void
-Switch(Symbol *lcont)
+Switch(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	Caselist lcase = {.nr = 0, .head = NULL, .deflabel = NULL};
 	struct scase *p;
-	Symbol *lbreak = label("", 1), *lcond = label("", 1);
 	Node *cond;
+	Symbol *lcond = label("", 1);
 
+	lbreak = label("", 1);
 	expect(SWITCH);
 	expect ('(');
 	cond = eval(expr());
@@ -298,27 +302,24 @@
 static void
 stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
+	void (*fun)(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
 
-repeat:
 	switch (yytoken) {
-	case '{':      context(lbreak, lcont, lswitch); break;
-	case RETURN:   Return(); break;
-	case WHILE:    While(lswitch); break;
-	case FOR:      For(lswitch); break;
-	case DO:       Dowhile(lswitch); break;
-	case IF:       If(lbreak, lcont, lswitch); break;
-	case BREAK:    Break(lbreak); break;
-	case CONTINUE: Continue(lcont); break;
-	case GOTO:     Goto(); break;
-	case SWITCH:   Switch(lcont); break;
-	case CASE:     Case(lbreak, lcont, lswitch); break;
-	case DEFAULT:  Default(lbreak, lcont, lswitch); break;
-	case IDEN:
-		if (ahead() == ':') {
-			Label();
-			goto repeat;
-		}
-	default:       stmtexp(); break;
+	case '{':      fun = context;  break;
+	case RETURN:   fun = Return;   break;
+	case WHILE:    fun = While;    break;
+	case FOR:      fun = For;      break;
+	case DO:       fun = Dowhile;  break;
+	case IF:       fun = If;       break;
+	case BREAK:    fun = Break;    break;
+	case CONTINUE: fun = Continue; break;
+	case GOTO:     fun = Goto;     break;
+	case SWITCH:   fun = Switch;   break;
+	case CASE:     fun = Case;     break;
+	case DEFAULT:  fun = Default;  break;
+	default:       fun = stmtexp;  break;
+	case IDEN:     fun = (ahead() == ':') ? Label : stmtexp; break;
 	}
+	(*fun)(lbreak, lcont, lswitch);
 }