Added support for do/while loops.
authorDavid Anderson <dvander@alliedmods.net>
Thu Jun 28 00:54:45 2012 -0700 (2012-06-28)
changeset 973781c5a59d7
parent 8 069d207a8f2a
child 10 0c3bcd50e361
Added support for do/while loops.
jitcraft/AST.h
jitcraft/BytecodeCompiler.cpp
jitcraft/BytecodeCompiler.h
jitcraft/Parser.cpp
jitcraft/Parser.h
jitcraft/Scanner.cpp
jitcraft/SemanticAnalysis.cpp
jitcraft/SemanticAnalysis.h
jitcraft/Token.h
tests/prototype/do.sp
tests/prototype/while.sp
     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 +}