Added support for do/while loops.
Added support for do/while loops.
1.1 --- a/jitcraft/AST.h Thu Jun 28 00:26:55 2012 -0700
1.2 +++ b/jitcraft/AST.h Thu Jun 28 00:54:45 2012 -0700
1.3 @@ -40,7 +40,8 @@
1.4 _(CallExpression) \
1.5 _(IfStatement) \
1.6 _(IndexExpression) \
1.7 - _(EnumStatement)
1.8 + _(EnumStatement) \
1.9 + _(WhileStatement)
1.10
1.11 // Forward declarations.
1.12 #define _(name) class name;
1.13 @@ -370,6 +371,37 @@
1.14 }
1.15 };
1.16
1.17 +class WhileStatement : public Statement
1.18 +{
1.19 + TokenKind token_;
1.20 + Expression *condition_;
1.21 + Statement *body_;
1.22 +
1.23 + public:
1.24 + WhileStatement(TokenKind kind, Expression *condition, Statement *body)
1.25 + : token_(kind),
1.26 + condition_(condition),
1.27 + body_(body)
1.28 + {
1.29 + }
1.30 +
1.31 + Kind kind() const {
1.32 + return kWhileStatement;
1.33 + }
1.34 + TokenKind token() const {
1.35 + return token_;
1.36 + }
1.37 + Expression *condition() const {
1.38 + return condition_;
1.39 + }
1.40 + Statement *body() const {
1.41 + return body_;
1.42 + }
1.43 + void accept(AstVisitor *visitor) {
1.44 + visitor->visit(this);
1.45 + }
1.46 +};
1.47 +
1.48 class ReturnStatement : public Statement
1.49 {
1.50 Expression *expression_;
2.1 --- a/jitcraft/BytecodeCompiler.cpp Thu Jun 28 00:26:55 2012 -0700
2.2 +++ b/jitcraft/BytecodeCompiler.cpp Thu Jun 28 00:54:45 2012 -0700
2.3 @@ -270,6 +270,25 @@
2.4 }
2.5
2.6 void
2.7 +BytecodeCompiler::visit(WhileStatement *node)
2.8 +{
2.9 + Label header;
2.10 +
2.11 + __ bind(&header);
2.12 +
2.13 + if (node->token() == TOK_WHILE) {
2.14 + Label join;
2.15 + visitForTest(node->condition(), &join, false);
2.16 + node->body()->accept(this);
2.17 + __ jump(&header);
2.18 + __ bind(&join);
2.19 + } else {
2.20 + node->body()->accept(this);
2.21 + visitForTest(node->condition(), &header, true);
2.22 + }
2.23 +}
2.24 +
2.25 +void
2.26 BytecodeCompiler::visit(BlockStatement *node)
2.27 {
2.28 AutoEnterScope blockScope(this, node->scope());
3.1 --- a/jitcraft/BytecodeCompiler.h Thu Jun 28 00:26:55 2012 -0700
3.2 +++ b/jitcraft/BytecodeCompiler.h Thu Jun 28 00:54:45 2012 -0700
3.3 @@ -80,6 +80,7 @@
3.4 void visit(IfStatement *node);
3.5 void visit(IndexExpression *node);
3.6 void visit(EnumStatement *node);
3.7 + void visit(WhileStatement *node);
3.8 };
3.9
3.10 }
4.1 --- a/jitcraft/Parser.cpp Thu Jun 28 00:26:55 2012 -0700
4.2 +++ b/jitcraft/Parser.cpp Thu Jun 28 00:54:45 2012 -0700
4.3 @@ -347,6 +347,49 @@
4.4 }
4.5
4.6 Statement *
4.7 +Parser::while_()
4.8 +{
4.9 + scanner_.scan();
4.10 +
4.11 + if (!expect(TOK_LPAREN))
4.12 + return NULL;
4.13 + Expression *condition = expression();
4.14 + if (!condition)
4.15 + return NULL;
4.16 + if (!expect(TOK_RPAREN))
4.17 + return NULL;
4.18 +
4.19 + Statement *body = localStatement();
4.20 + if (!body)
4.21 + return NULL;
4.22 +
4.23 + return new (pool_) WhileStatement(TOK_WHILE, condition, body);
4.24 +}
4.25 +
4.26 +Statement *
4.27 +Parser::do_()
4.28 +{
4.29 + scanner_.scan();
4.30 +
4.31 + Statement *body = block();
4.32 + if (!body)
4.33 + return NULL;
4.34 +
4.35 + if (!expect(TOK_WHILE))
4.36 + return NULL;
4.37 +
4.38 + if (!expect(TOK_LPAREN))
4.39 + return NULL;
4.40 + Expression *condition = expression();
4.41 + if (!condition)
4.42 + return NULL;
4.43 + if (!expect(TOK_RPAREN))
4.44 + return NULL;
4.45 +
4.46 + return new (pool_) WhileStatement(TOK_DO, condition, body);
4.47 +}
4.48 +
4.49 +Statement *
4.50 Parser::forStatement()
4.51 {
4.52 scanner_.scan();
4.53 @@ -567,6 +610,14 @@
4.54 case TOK_FOR:
4.55 return forStatement();
4.56
4.57 + case TOK_WHILE:
4.58 + return while_();
4.59 +
4.60 + case TOK_DO:
4.61 + if ((statement = do_()) == NULL)
4.62 + return NULL;
4.63 + break;
4.64 +
4.65 case TOK_RETURN:
4.66 statement = returnStatement();
4.67 break;
4.68 @@ -888,6 +939,20 @@
4.69 }
4.70 unindent();
4.71 }
4.72 + void visit(WhileStatement *node) {
4.73 + prefix();
4.74 + fprintf(fp_, "[ WhileStatement (%s)\n",
4.75 + (node->token() == TOK_DO) ? "do" : "while");
4.76 + indent();
4.77 + if (node->token() == TOK_DO) {
4.78 + node->condition()->accept(this);
4.79 + node->body()->accept(this);
4.80 + } else {
4.81 + node->condition()->accept(this);
4.82 + node->body()->accept(this);
4.83 + }
4.84 + unindent();
4.85 + }
4.86 };
4.87
4.88 void
5.1 --- a/jitcraft/Parser.h Thu Jun 28 00:26:55 2012 -0700
5.2 +++ b/jitcraft/Parser.h Thu Jun 28 00:54:45 2012 -0700
5.3 @@ -69,6 +69,8 @@
5.4 Statement *block();
5.5 Statement *function();
5.6 Statement *expressionStatement();
5.7 + Statement *while_();
5.8 + Statement *do_();
5.9 Statement *forStatement();
5.10 Statement *localStatement();
5.11 Statement *globalStatement();
6.1 --- a/jitcraft/Scanner.cpp Thu Jun 28 00:26:55 2012 -0700
6.2 +++ b/jitcraft/Scanner.cpp Thu Jun 28 00:54:45 2012 -0700
6.3 @@ -225,6 +225,10 @@
6.4 return TOK_ELSE;
6.5 if (literal_ == "enum")
6.6 return TOK_ENUM;
6.7 + if (literal_ == "while")
6.8 + return TOK_WHILE;
6.9 + if (literal_ == "do")
6.10 + return TOK_DO;
6.11 return (c == ':') ? TOK_LABEL : TOK_NAME;
6.12 }
6.13
7.1 --- a/jitcraft/SemanticAnalysis.cpp Thu Jun 28 00:26:55 2012 -0700
7.2 +++ b/jitcraft/SemanticAnalysis.cpp Thu Jun 28 00:54:45 2012 -0700
7.3 @@ -211,6 +211,13 @@
7.4 node->body()->accept(this);
7.5 }
7.6
7.7 +void
7.8 +SemanticAnalysis::visit(WhileStatement *node)
7.9 +{
7.10 + node->condition()->accept(this);
7.11 + node->body()->accept(this);
7.12 +}
7.13 +
7.14 void
7.15 SemanticAnalysis::visit(BlockStatement *node)
7.16 {
8.1 --- a/jitcraft/SemanticAnalysis.h Thu Jun 28 00:26:55 2012 -0700
8.2 +++ b/jitcraft/SemanticAnalysis.h Thu Jun 28 00:54:45 2012 -0700
8.3 @@ -57,6 +57,7 @@
8.4 void visit(IndexExpression *node);
8.5 void visit(EnumStatement *node);
8.6 void visit(FloatLiteral *node);
8.7 + void visit(WhileStatement *node);
8.8 };
8.9
8.10 } // namespace jc
9.1 --- a/jitcraft/Token.h Thu Jun 28 00:26:55 2012 -0700
9.2 +++ b/jitcraft/Token.h Thu Jun 28 00:54:45 2012 -0700
9.3 @@ -32,6 +32,8 @@
9.4 _(ELSE, "<else>") \
9.5 _(ENUM, "<enum>") \
9.6 _(LABEL, "<label>") \
9.7 + _(WHILE, "<while>") \
9.8 + _(DO, "<do>") \
9.9 _(PLUS, "+") \
9.10 _(MINUS, "-") \
9.11 _(STAR, "*") \
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/tests/prototype/do.sp Thu Jun 28 00:54:45 2012 -0700
10.3 @@ -0,0 +1,8 @@
10.4 +main()
10.5 +{
10.6 + new i = 0;
10.7 + do {
10.8 + i = i + 37;
10.9 + } while (i < 5);
10.10 + return i;
10.11 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/tests/prototype/while.sp Thu Jun 28 00:54:45 2012 -0700
11.3 @@ -0,0 +1,8 @@
11.4 +main()
11.5 +{
11.6 + new i = 0;
11.7 + while (i < 100) {
11.8 + i = i + 37;
11.9 + }
11.10 + return i;
11.11 +}