Re-add support for |if|, |continue|, |break|.
Re-add support for |if|, |continue|, |break|.
1.1 --- a/src/Interpreter.cpp Sat Nov 17 20:23:36 2012 -0800
1.2 +++ b/src/Interpreter.cpp Sat Nov 17 22:02:08 2012 -0800
1.3 @@ -757,6 +757,12 @@
1.4 break;
1.5 }
1.6
1.7 +case OP_CVT_I2B:
1.8 +{
1.9 + top.sp[-1].i32 = !!top.sp[-1].i32;
1.10 + break;
1.11 +}
1.12 +
1.13 case OP_NEWFIXED:
1.14 {
1.15 Heap::Tenure tenure = (Heap::Tenure)top.pc[1];
2.1 --- a/src/Opcodes.tbl Sat Nov 17 20:23:36 2012 -0800
2.2 +++ b/src/Opcodes.tbl Sat Nov 17 22:02:08 2012 -0800
2.3 @@ -116,6 +116,7 @@
2.4
2.5 // Converts an integer to a 32-bit IEEE-754 floating point immediate.
2.6 OPDEF(OP_CVT_I2F, "cvt.i2f", 1, 1, 1)
2.7 +OPDEF(OP_CVT_I2B, "cvt.i2b", 1, 1, 1)
2.8
2.9 // Stack transitions for these binary operators:
2.10 // rhs = pop()
3.1 --- a/src/compiler/NameBinding.cpp Sat Nov 17 20:23:36 2012 -0800
3.2 +++ b/src/compiler/NameBinding.cpp Sat Nov 17 22:02:08 2012 -0800
3.3 @@ -582,7 +582,8 @@
3.4 void visitIfStatement(IfStatement *node) {
3.5 node->condition()->accept(this);
3.6 node->ifTrue()->accept(this);
3.7 - node->ifFalse()->accept(this);
3.8 + if (node->ifFalse())
3.9 + node->ifFalse()->accept(this);
3.10 }
3.11 void visitIndexExpression(IndexExpression *node) {
3.12 node->left()->accept(this);
4.1 --- a/src/compiler/SemanticAnalysis.cpp Sat Nov 17 20:23:36 2012 -0800
4.2 +++ b/src/compiler/SemanticAnalysis.cpp Sat Nov 17 22:02:08 2012 -0800
4.3 @@ -206,6 +206,31 @@
4.4 }
4.5
4.6 void
4.7 +SemanticAnalysis::visitIfStatement(IfStatement *node)
4.8 +{
4.9 + Label join;
4.10 +
4.11 + if (!node->ifFalse()) {
4.12 + Label success;
4.13 +
4.14 + visitForTest(node->condition(), &success, &join, &success);
4.15 + __ bind(&success);
4.16 + node->ifTrue()->accept(this);
4.17 + } else {
4.18 + Label success, next;
4.19 +
4.20 + visitForTest(node->condition(), &success, &next, &success);
4.21 + __ bind(&success);
4.22 + node->ifTrue()->accept(this);
4.23 + __ jump(&join);
4.24 + __ bind(&next);
4.25 + node->ifFalse()->accept(this);
4.26 + }
4.27 +
4.28 + __ bind(&join);
4.29 +}
4.30 +
4.31 +void
4.32 SemanticAnalysis::visitForStatement(ForStatement *node)
4.33 {
4.34 AutoEnterScope scope(&scope_, node->scope());
4.35 @@ -475,6 +500,30 @@
4.36 hir_ = new (pool_) HStore(lval, hir);
4.37 }
4.38
4.39 +void
4.40 +SemanticAnalysis::visitBreakStatement(BreakStatement *node)
4.41 +{
4.42 + if (!loop_) {
4.43 + cc_.reportError(node->pos(), Message_BreakOutsideLoop);
4.44 + return;
4.45 + }
4.46 +
4.47 + // Note, if we re-introduce LIFO allocs, we need to unwind here.
4.48 + __ jump(loop_->break_());
4.49 +}
4.50 +
4.51 +void
4.52 +SemanticAnalysis::visitContinueStatement(ContinueStatement *node)
4.53 +{
4.54 + if (!loop_) {
4.55 + cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
4.56 + return;
4.57 + }
4.58 +
4.59 + // Note, if we re-introduce LIFO allocs, we need to unwind here.
4.60 + __ jump(loop_->continue_());
4.61 +}
4.62 +
4.63 Type *
4.64 SemanticAnalysis::coercionType(TokenKind token, HIR *left, HIR *right)
4.65 {
4.66 @@ -503,6 +552,8 @@
4.67
4.68 if (from->isInt32() && to->isFloat())
4.69 return new (pool_) HConvert(to, OP_CVT_I2F, hir);
4.70 + if (from->isInt32() && to->isBool())
4.71 + return new (pool_) HConvert(to, OP_CVT_I2B, hir);
4.72
4.73 assert(from == to);
4.74
4.75 @@ -585,10 +636,29 @@
4.76 Label *falseBranch,
4.77 Label *fallthrough)
4.78 {
4.79 + Local<Type> boolType(zone_, zone_->types()->getPrimitive(PrimitiveType_Bool));
4.80 +
4.81 TokenKind token = ToCompare(expr);
4.82 if (token == TOK_EOF || token == TOK_NOT) {
4.83 - assert(false);
4.84 - //visitForUnaryTest(expr, trueBranch, falseBranch, fallthrough);
4.85 + HIR *hir;
4.86 + if (token == TOK_EOF)
4.87 + hir = eval(expr);
4.88 + else
4.89 + hir = eval(expr->toUnaryExpression()->expression());
4.90 + if (!hir)
4.91 + return;
4.92 + if ((hir = coerce(hir, boolType, Coerce_Assign)) == NULL)
4.93 + return;
4.94 +
4.95 + discharge(hir);
4.96 +
4.97 + bool jumpOnTrue = (fallthrough == falseBranch) ^ (token == TOK_NOT);
4.98 + Opcode op = jumpOnTrue ? OP_JT : OP_JF;
4.99 +
4.100 + if (fallthrough == falseBranch)
4.101 + __ j(op, trueBranch);
4.102 + else
4.103 + __ j(op, falseBranch);
4.104 return;
4.105 }
4.106
4.107 @@ -607,6 +677,8 @@
4.108 HIR *hir = binary(bin->token(), left, right);
4.109 if (!hir)
4.110 return;
4.111 + if ((hir = coerce(hir, boolType, Coerce_Assign)) == NULL)
4.112 + return;
4.113
4.114 discharge(hir);
4.115 if (fallthrough == trueBranch)
5.1 --- a/src/compiler/SemanticAnalysis.h Sat Nov 17 20:23:36 2012 -0800
5.2 +++ b/src/compiler/SemanticAnalysis.h Sat Nov 17 22:02:08 2012 -0800
5.3 @@ -58,19 +58,19 @@
5.4 void visitWhileStatement(WhileStatement *node);
5.5 void visitAssignment(Assignment *node);
5.6 void visitBinaryExpression(BinaryExpression *node);
5.7 + void visitBreakStatement(BreakStatement *node);
5.8 + void visitContinueStatement(ContinueStatement *node);
5.9 + void visitIfStatement(IfStatement *node);
5.10 #if 0
5.11 void visitFunctionTypeStatement(FunctionTypeStatement *node);
5.12 void visitImportStatement(ImportStatement *node);
5.13 void visitExpressionStatement(ExpressionStatement *node);
5.14 void visitEnumStatement(EnumStatement *node);
5.15 - void visitBreakStatement(BreakStatement *node);
5.16 - void visitContinueStatement(ContinueStatement *node);
5.17 void visitStructureStatement(StructureStatement *node);
5.18 void visitSwitchStatement(SwitchStatement *node);
5.19
5.20 void visitBinaryExpression(BinaryExpression *node);
5.21 void visitCallExpression(CallExpression *node);
5.22 - void visitIfStatement(IfStatement *node);
5.23 void visitIndexExpression(IndexExpression *node);
5.24 void visitStringLiteral(StringLiteral *node);
5.25 void visitIncDecExpression(IncDecExpression *node);
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tests/basic/continue-in-while.out Sat Nov 17 22:02:08 2012 -0800
6.3 @@ -0,0 +1,1 @@
6.4 +222
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/tests/basic/continue-in-while.sp Sat Nov 17 22:02:08 2012 -0800
7.3 @@ -0,0 +1,13 @@
7.4 +native PrintNum(num);
7.5 +
7.6 +public main()
7.7 +{
7.8 + new i = 0;
7.9 + while (1) {
7.10 + i = i + 37;
7.11 + if (i < 200)
7.12 + continue;
7.13 + break;
7.14 + }
7.15 + PrintNum(i);
7.16 +}
8.1 --- a/tests/prototype/continue-in-while.sp Sat Nov 17 20:23:36 2012 -0800
8.2 +++ b/tests/prototype/continue-in-while.sp Sat Nov 17 22:02:08 2012 -0800
8.3 @@ -1,4 +1,6 @@
8.4 -main()
8.5 +native PrintNum(num);
8.6 +
8.7 +public main()
8.8 {
8.9 new i = 0;
8.10 do {
8.11 @@ -6,5 +8,5 @@
8.12 continue;
8.13 i = i + 37;
8.14 } while (i < 5);
8.15 - return i;
8.16 + PrintNum(i);
8.17 }