scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 824cc5f2899438f5865d942e855f907e26a5106c
parent 8d3c95abbdf285aa5a820607c5d4c32ab3dff70d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 24 Apr 2014 17:44:40 +0200

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.

Diffstat:
Mstmt.c | 27++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)

diff --git 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,6 +222,31 @@ Switch(Symbol *lcont) 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 @@ -258,6 +282,7 @@ repeat: 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();