# HG changeset patch # User David Anderson # Date 1353218528 28800 # Node ID 7c5be05296e3b109af3dd05060f06a94da14671a # Parent 04ce04a54936f0d7bccc36998ba756b186c40864 Re-add support for |if|, |continue|, |break|. diff -r 04ce04a54936 -r 7c5be05296e3 src/Interpreter.cpp --- a/src/Interpreter.cpp Sat Nov 17 20:23:36 2012 -0800 +++ b/src/Interpreter.cpp Sat Nov 17 22:02:08 2012 -0800 @@ -757,6 +757,12 @@ break; } +case OP_CVT_I2B: +{ + top.sp[-1].i32 = !!top.sp[-1].i32; + break; +} + case OP_NEWFIXED: { Heap::Tenure tenure = (Heap::Tenure)top.pc[1]; diff -r 04ce04a54936 -r 7c5be05296e3 src/Opcodes.tbl --- a/src/Opcodes.tbl Sat Nov 17 20:23:36 2012 -0800 +++ b/src/Opcodes.tbl Sat Nov 17 22:02:08 2012 -0800 @@ -116,6 +116,7 @@ // Converts an integer to a 32-bit IEEE-754 floating point immediate. OPDEF(OP_CVT_I2F, "cvt.i2f", 1, 1, 1) +OPDEF(OP_CVT_I2B, "cvt.i2b", 1, 1, 1) // Stack transitions for these binary operators: // rhs = pop() diff -r 04ce04a54936 -r 7c5be05296e3 src/compiler/NameBinding.cpp --- a/src/compiler/NameBinding.cpp Sat Nov 17 20:23:36 2012 -0800 +++ b/src/compiler/NameBinding.cpp Sat Nov 17 22:02:08 2012 -0800 @@ -582,7 +582,8 @@ void visitIfStatement(IfStatement *node) { node->condition()->accept(this); node->ifTrue()->accept(this); - node->ifFalse()->accept(this); + if (node->ifFalse()) + node->ifFalse()->accept(this); } void visitIndexExpression(IndexExpression *node) { node->left()->accept(this); diff -r 04ce04a54936 -r 7c5be05296e3 src/compiler/SemanticAnalysis.cpp --- a/src/compiler/SemanticAnalysis.cpp Sat Nov 17 20:23:36 2012 -0800 +++ b/src/compiler/SemanticAnalysis.cpp Sat Nov 17 22:02:08 2012 -0800 @@ -206,6 +206,31 @@ } void +SemanticAnalysis::visitIfStatement(IfStatement *node) +{ + Label join; + + if (!node->ifFalse()) { + Label success; + + visitForTest(node->condition(), &success, &join, &success); + __ bind(&success); + node->ifTrue()->accept(this); + } else { + Label success, next; + + visitForTest(node->condition(), &success, &next, &success); + __ bind(&success); + node->ifTrue()->accept(this); + __ jump(&join); + __ bind(&next); + node->ifFalse()->accept(this); + } + + __ bind(&join); +} + +void SemanticAnalysis::visitForStatement(ForStatement *node) { AutoEnterScope scope(&scope_, node->scope()); @@ -475,6 +500,30 @@ hir_ = new (pool_) HStore(lval, hir); } +void +SemanticAnalysis::visitBreakStatement(BreakStatement *node) +{ + if (!loop_) { + cc_.reportError(node->pos(), Message_BreakOutsideLoop); + return; + } + + // Note, if we re-introduce LIFO allocs, we need to unwind here. + __ jump(loop_->break_()); +} + +void +SemanticAnalysis::visitContinueStatement(ContinueStatement *node) +{ + if (!loop_) { + cc_.reportError(node->pos(), Message_ContinueOutsideLoop); + return; + } + + // Note, if we re-introduce LIFO allocs, we need to unwind here. + __ jump(loop_->continue_()); +} + Type * SemanticAnalysis::coercionType(TokenKind token, HIR *left, HIR *right) { @@ -503,6 +552,8 @@ if (from->isInt32() && to->isFloat()) return new (pool_) HConvert(to, OP_CVT_I2F, hir); + if (from->isInt32() && to->isBool()) + return new (pool_) HConvert(to, OP_CVT_I2B, hir); assert(from == to); @@ -585,10 +636,29 @@ Label *falseBranch, Label *fallthrough) { + Local boolType(zone_, zone_->types()->getPrimitive(PrimitiveType_Bool)); + TokenKind token = ToCompare(expr); if (token == TOK_EOF || token == TOK_NOT) { - assert(false); - //visitForUnaryTest(expr, trueBranch, falseBranch, fallthrough); + HIR *hir; + if (token == TOK_EOF) + hir = eval(expr); + else + hir = eval(expr->toUnaryExpression()->expression()); + if (!hir) + return; + if ((hir = coerce(hir, boolType, Coerce_Assign)) == NULL) + return; + + discharge(hir); + + bool jumpOnTrue = (fallthrough == falseBranch) ^ (token == TOK_NOT); + Opcode op = jumpOnTrue ? OP_JT : OP_JF; + + if (fallthrough == falseBranch) + __ j(op, trueBranch); + else + __ j(op, falseBranch); return; } @@ -607,6 +677,8 @@ HIR *hir = binary(bin->token(), left, right); if (!hir) return; + if ((hir = coerce(hir, boolType, Coerce_Assign)) == NULL) + return; discharge(hir); if (fallthrough == trueBranch) diff -r 04ce04a54936 -r 7c5be05296e3 src/compiler/SemanticAnalysis.h --- a/src/compiler/SemanticAnalysis.h Sat Nov 17 20:23:36 2012 -0800 +++ b/src/compiler/SemanticAnalysis.h Sat Nov 17 22:02:08 2012 -0800 @@ -58,19 +58,19 @@ void visitWhileStatement(WhileStatement *node); void visitAssignment(Assignment *node); void visitBinaryExpression(BinaryExpression *node); + void visitBreakStatement(BreakStatement *node); + void visitContinueStatement(ContinueStatement *node); + void visitIfStatement(IfStatement *node); #if 0 void visitFunctionTypeStatement(FunctionTypeStatement *node); void visitImportStatement(ImportStatement *node); void visitExpressionStatement(ExpressionStatement *node); void visitEnumStatement(EnumStatement *node); - void visitBreakStatement(BreakStatement *node); - void visitContinueStatement(ContinueStatement *node); void visitStructureStatement(StructureStatement *node); void visitSwitchStatement(SwitchStatement *node); void visitBinaryExpression(BinaryExpression *node); void visitCallExpression(CallExpression *node); - void visitIfStatement(IfStatement *node); void visitIndexExpression(IndexExpression *node); void visitStringLiteral(StringLiteral *node); void visitIncDecExpression(IncDecExpression *node); diff -r 04ce04a54936 -r 7c5be05296e3 tests/basic/continue-in-while.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/continue-in-while.out Sat Nov 17 22:02:08 2012 -0800 @@ -0,0 +1,1 @@ +222 diff -r 04ce04a54936 -r 7c5be05296e3 tests/basic/continue-in-while.sp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/continue-in-while.sp Sat Nov 17 22:02:08 2012 -0800 @@ -0,0 +1,13 @@ +native PrintNum(num); + +public main() +{ + new i = 0; + while (1) { + i = i + 37; + if (i < 200) + continue; + break; + } + PrintNum(i); +} diff -r 04ce04a54936 -r 7c5be05296e3 tests/prototype/continue-in-while.sp --- a/tests/prototype/continue-in-while.sp Sat Nov 17 20:23:36 2012 -0800 +++ b/tests/prototype/continue-in-while.sp Sat Nov 17 22:02:08 2012 -0800 @@ -1,4 +1,6 @@ -main() +native PrintNum(num); + +public main() { new i = 0; do { @@ -6,5 +8,5 @@ continue; i = i + 37; } while (i < 5); - return i; + PrintNum(i); }