shithub: scc

Download patch

ref: 824cc5f2899438f5865d942e855f907e26a5106c
parent: 8d3c95abbdf285aa5a820607c5d4c32ab3dff70d
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu Apr 24 13:44:40 EDT 2014

Add case statement

This version of case is a first version, where there are some
checks that are not done (for example type of the expression),
but is good enough for us now.

--- a/stmt.c
+++ b/stmt.c
@@ -6,7 +6,6 @@
 #include "cc1.h"
 
 struct scase {
-	int val;
 	Symbol *label;
 	Node *expr;
 	struct scase *next;
@@ -223,8 +222,33 @@
 	if (lcase.deflabel)
 		emitdefault(lcase.deflabel);
 	emitlabel(lbreak);
+	/* TODO: free memory */
 }
 
+static void
+Case(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
+{
+	Node *np;
+	Symbol *lcase = label(NULL, 1);
+	struct scase *pcase;
+
+	if (!lswitch)
+		error("case label not within a switch statement");
+	expect(CASE);
+	if (yytoken == ':')
+		error("expected expression before ':'");
+	np = eval(expr());
+	/* TODO: check integer type */
+	expect(':');
+	emitlabel(lcase);
+	pcase = xmalloc(sizeof(*pcase));
+	pcase->expr = np;
+	pcase->label = lcase;
+	pcase->next = lswitch->head;
+	lswitch->head = pcase;
+	++lswitch->nr;
+}
+
 void
 compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
@@ -258,6 +282,7 @@
 	case CONTINUE: Continue(lcont); break;
 	case GOTO:     Goto(); break;
 	case SWITCH:   Switch(lcont); break;
+	case CASE:     Case(lbreak, lcont, lswitch); break;
 	case IDEN:
 		if (ahead() == ':') {
 			Label();