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