commit 588948f9dc4651080d0d664b10cc62274614b706
parent 5182ec4cbc4178dc5a7eba8ef21b210a6977c0cb
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 24 Apr 2014 09:02:53 +0200
Add For statement
Diffstat:
M | stmt.c | | | 41 | ++++++++++++++++++++++++++++++++++++----- |
1 file changed, 36 insertions(+), 5 deletions(-)
diff --git a/stmt.c b/stmt.c
@@ -22,12 +22,13 @@ label(char *s)
return install(s, NS_LABEL);
}
-static Node *
+static void
stmtexp(void)
{
- Node *np = expr();
+ if (accept(';'))
+ return;
+ emitexp(expr());
expect(';');
- return np;
}
static Node *
@@ -59,13 +60,42 @@ While(Symbol *lswitch)
}
static void
+For(Symbol *lswitch)
+{
+ Symbol *begin= label(NULL), *cond = label(NULL), *end = label(NULL);
+ Node *econd = NULL, *einc = NULL;
+
+ expect(FOR);
+ expect('(');
+ stmtexp();
+
+ if (yytoken != ';')
+ econd = expr();
+ expect(';');
+ if (yytoken != ')')
+ einc = expr();
+ expect(')');
+
+ emitjump(cond, NULL);
+ emitbloop();
+ emitlabel(begin);
+ stmt(begin, end, lswitch);
+ if (einc)
+ emitexp(einc);
+ emitlabel(cond);
+ emitjump(begin, econd);
+ emiteloop();
+}
+
+static void
Return(void)
{
Node *np;
Type *tp = curfun->type->type;
expect(RETURN);
- np = stmtexp();
+ np = expr();
+ expect(';');
if (np->type != tp) {
if (tp == voidtype)
warn(1, "function returning void returns a value");
@@ -101,7 +131,8 @@ stmt(Symbol *lbreak, Symbol *lcont, Symbol *lswitch)
case '{': compound(lbreak, lcont, lswitch); break;
case RETURN: Return(); break;
case WHILE: While(lswitch); break;
- default: emitexp(stmtexp()); break;
+ case FOR: For(lswitch); break;
+ default: stmtexp(); break;
}
}