Re-add support for |if|, |continue|, |break|.
authorDavid Anderson <dvander@alliedmods.net>
Sat Nov 17 22:02:08 2012 -0800 (2012-11-17)
changeset 2087c5be05296e3
parent 207 04ce04a54936
child 209 5cbec15fadfe
Re-add support for |if|, |continue|, |break|.
src/Interpreter.cpp
src/Opcodes.tbl
src/compiler/NameBinding.cpp
src/compiler/SemanticAnalysis.cpp
src/compiler/SemanticAnalysis.h
tests/basic/continue-in-while.out
tests/basic/continue-in-while.sp
tests/prototype/continue-in-while.sp
     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  }