jitcraft/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Sun Jul 01 14:52:57 2012 -0700 (2012-07-01)
changeset 21 af5d8e985502
parent 14 0784ac5cc347
child 22 765ab1b672a3
permissions -rw-r--r--
Added initial String: support.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #include "Zone.h"
    19 #include "Parser.h"
    20 #include "FixedArray.h"
    21 #include "Heap.h"
    22 #include "Heap-inl.h"
    23 
    24 using namespace jc;
    25 
    26 Parser::Parser(const char *stream, size_t length)
    27   : pool_(ZONE()->pool()),
    28     strings_(pool_),
    29     scanner_(stream, length),
    30     scope_(NULL),
    31     unbound_(NULL)
    32 {
    33     unbound_ = new std::vector<NameProxy *>();
    34 }
    35 
    36 bool
    37 Parser::match(TokenKind kind)
    38 {
    39     if (scanner_.peek() != kind)
    40         return false;
    41     scanner_.scan();
    42     return true;
    43 }
    44 
    45 bool
    46 Parser::expect(TokenKind kind)
    47 {
    48     TokenKind got = scanner_.scan();
    49     if (got == kind)
    50         return true;
    51     fprintf(stderr, "error: expected %s, got %s\n", TokenNames[kind], TokenNames[got]);
    52     return false;
    53 }
    54 
    55 Scope *
    56 Parser::enterScope(Scope::Kind kind)
    57 {
    58     scope_ = new (pool_) Scope(pool_, kind, scope_);
    59     if (!scope_->initialize())
    60         return NULL;
    61     return scope_;
    62 }
    63 
    64 NameProxy *
    65 Parser::bind(Name *name)
    66 {
    67     BoundName *bound = scope_->lookup(name);
    68     NameProxy *proxy = new (pool_) NameProxy(name, bound);
    69     if (!bound)
    70         unbound_->push_back(proxy);
    71     return proxy;
    72 }
    73 
    74 bool
    75 Parser::matchName(Name **name, TokenKind kind)
    76 {
    77     assert(kind == TOK_NAME || kind == TOK_LABEL);
    78     *name = NULL;
    79     if (!match(kind))
    80         return false;
    81     *name = strings_.add(scanner_.literal());
    82     return true;
    83 }
    84 
    85 Name *
    86 Parser::expectName()
    87 {
    88     if (!expect(TOK_NAME))
    89         return NULL;
    90     return strings_.add(scanner_.literal());
    91 }
    92 
    93 Expression *
    94 Parser::primitive()
    95 {
    96     switch (scanner_.peek()) {
    97       case TOK_NAME:
    98       {
    99         scanner_.scan();
   100         Name *name = strings_.add(scanner_.literal());
   101         return bind(name);
   102       }
   103 
   104       case TOK_FLOAT_LITERAL:
   105       {
   106         scanner_.scan();
   107         double value = Scanner::ParseDouble(scanner_.literal());
   108         return new (pool_) FloatLiteral(value);
   109       }
   110 
   111       case TOK_INTEGER_LITERAL:
   112       {
   113         scanner_.scan();
   114         int value = atoi(scanner_.literal());
   115         return new (pool_) IntegerLiteral(value);
   116       }
   117 
   118       case TOK_STRING_LITERAL:
   119       {
   120         // :TODO: Local
   121         scanner_.scan();
   122         ByteArray *array = ByteArray::New(ZONE(), scanner_.literal_length());
   123         if (!array)
   124             return NULL;
   125         memcpy(array->raw(), scanner_.literal(), scanner_.literal_length());
   126 
   127         return new (pool_) StringLiteral(array);
   128       }
   129 
   130       default:
   131       {
   132         fprintf(stderr, "error: expected expression!\n");
   133         return NULL;
   134       }
   135     }
   136 }
   137 
   138 Expression *
   139 Parser::prefix()
   140 {
   141     switch (scanner_.peek()) {
   142       case TOK_LPAREN:
   143       {
   144         scanner_.scan();
   145         Expression *expr = expression();
   146         if (!expr)
   147             return NULL;
   148         if (!expect(TOK_RPAREN))
   149             return NULL;
   150         return expr;
   151       }
   152 
   153       default:
   154         return primitive();
   155     }
   156 }
   157 
   158 Expression *
   159 Parser::call(Expression *callee)
   160 {
   161     ExpressionList *arguments = new ExpressionList();
   162 
   163     expect(TOK_LPAREN);
   164     
   165     if (!match(TOK_RPAREN)) {
   166         while (true) {
   167             Expression *expr = expression();
   168             if (!expr)
   169                 return NULL;
   170 
   171             arguments->push_back(expr);
   172 
   173             if (!match(TOK_COMMA))
   174                 break;
   175         }
   176 
   177         if (!expect(TOK_RPAREN))
   178             return NULL;
   179     }
   180 
   181     return new (pool_) CallExpression(callee, arguments);
   182 }
   183 
   184 Expression *
   185 Parser::index(Expression *left)
   186 {
   187     expect(TOK_LBRACKET);
   188     
   189     Expression *expr = expression();
   190     if (!expr)
   191         return NULL;
   192 
   193     if (!expect(TOK_RBRACKET))
   194         return NULL;
   195 
   196     return new (pool_) IndexExpression(left, expr);
   197 }
   198 
   199 Expression *
   200 Parser::primary()
   201 {
   202     Expression *expr = prefix();
   203     if (!expr)
   204         return NULL;
   205 
   206     for (;;) {
   207         switch (scanner_.peek()) {
   208           case TOK_LPAREN:
   209             expr = call(expr);
   210             if (!expr)
   211                 return NULL;
   212             break;
   213 
   214           case TOK_LBRACKET:
   215             expr = index(expr);
   216             if (!expr)
   217                 return NULL;
   218             break;
   219 
   220           default:
   221             return expr;
   222         }
   223     }
   224 }
   225 
   226 Expression *
   227 Parser::unary()
   228 {
   229     return primary();
   230 }
   231 
   232 Expression *
   233 Parser::multiplication()
   234 {
   235     Expression *left = unary();
   236     do {
   237         if (!match(TOK_SLASH) && !match(TOK_STAR))
   238             break;
   239         TokenKind kind = scanner_.last();
   240         Expression *right = unary();
   241         if (!right)
   242             return NULL;
   243         left = new (pool_) BinaryExpression(kind, left, right);
   244     } while (left);
   245     return left;
   246 }
   247 
   248 Expression *
   249 Parser::addition()
   250 {
   251     Expression *left = multiplication();
   252     while (left) {
   253         if (!match(TOK_PLUS) && !match(TOK_MINUS))
   254             break;
   255         TokenKind kind = scanner_.last();
   256         Expression *right = multiplication();
   257         if (!right)
   258             return NULL;
   259         left = new (pool_) BinaryExpression(kind, left, right);
   260     }
   261     return left;
   262 }
   263 
   264 Expression *
   265 Parser::shift()
   266 {
   267     Expression *left = addition();
   268     while (left) {
   269         if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
   270             break;
   271         TokenKind kind = scanner_.last();
   272         Expression *right = addition();
   273         if (!right)
   274             return NULL;
   275         left = new (pool_) BinaryExpression(kind, left, right);
   276     }
   277     return left;
   278 }
   279 
   280 Expression *
   281 Parser::bitand()
   282 {
   283     Expression *left = shift();
   284     while (left) {
   285         if (!match(TOK_BITAND))
   286             break;
   287         Expression *right = shift();
   288         if (!right)
   289             return NULL;
   290         left = new (pool_) BinaryExpression(TOK_BITAND, left, right);
   291     }
   292     return left;
   293 }
   294 
   295 Expression *
   296 Parser::bitxor()
   297 {
   298     Expression *left = bitand();
   299     while (left) {
   300         if (!match(TOK_BITXOR))
   301             break;
   302         Expression *right = shift();
   303         if (!right)
   304             return NULL;
   305         left = new (pool_) BinaryExpression(TOK_BITXOR, left, right);
   306     }
   307     return left;
   308 }
   309 
   310 Expression *
   311 Parser::bitor()
   312 {
   313     Expression *left = bitxor();
   314     while (left) {
   315         if (!match(TOK_BITOR))
   316             break;
   317         Expression *right = shift();
   318         if (!right)
   319             return NULL;
   320         left = new (pool_) BinaryExpression(TOK_BITOR, left, right);
   321     }
   322     return left;
   323 }
   324 
   325 Expression *
   326 Parser::relational()
   327 {
   328     Expression *left = bitor();
   329     while (left) {
   330         TokenKind kind = scanner_.peek();
   331         if (kind < TOK_LT || kind > TOK_GE)
   332             break;
   333         scanner_.scan();
   334         Expression *right = shift();
   335         if (!right)
   336             return NULL;
   337         left = new (pool_) BinaryExpression(kind, left, right);
   338     }
   339     return left;
   340 }
   341 
   342 Expression *
   343 Parser::equals()
   344 {
   345     Expression *left = relational();
   346     while (left) {
   347         if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   348             break;
   349         TokenKind kind = scanner_.last();
   350         Expression *right = relational();
   351         if (!right)
   352             return NULL;
   353         left = new (pool_) BinaryExpression(kind, left, right);
   354     }
   355     return left;
   356 }
   357 
   358 Expression *
   359 Parser::expression()
   360 {
   361     return equals();
   362 }
   363 
   364 Statement *
   365 Parser::while_()
   366 {
   367     scanner_.scan();
   368 
   369     if (!expect(TOK_LPAREN))
   370         return NULL;
   371     Expression *condition = expression();
   372     if (!condition)
   373         return NULL;
   374     if (!expect(TOK_RPAREN))
   375         return NULL;
   376 
   377     Statement *body = localStatement();
   378     if (!body)
   379         return NULL;
   380 
   381     return new (pool_) WhileStatement(TOK_WHILE, condition, body);
   382 }
   383 
   384 Statement *
   385 Parser::do_()
   386 {
   387     scanner_.scan();
   388 
   389     Statement *body = block();
   390     if (!body)
   391         return NULL;
   392 
   393     if (!expect(TOK_WHILE))
   394         return NULL;
   395 
   396     if (!expect(TOK_LPAREN))
   397         return NULL;
   398     Expression *condition = expression();
   399     if (!condition)
   400         return NULL;
   401     if (!expect(TOK_RPAREN))
   402         return NULL;
   403 
   404     return new (pool_) WhileStatement(TOK_DO, condition, body);
   405 }
   406 
   407 Statement *
   408 Parser::forStatement()
   409 {
   410     scanner_.scan();
   411     if (!expect(TOK_LPAREN))
   412         return NULL;
   413 
   414     VariableDeclaration *decl = NULL;
   415     if (!match(TOK_SEMICOLON)) {
   416         if (!enterScope(Scope::BLOCK))
   417             return NULL;
   418         if ((decl = variableDeclaration()) == NULL)
   419             return NULL;
   420         if (!expect(TOK_SEMICOLON))
   421             return NULL;
   422     }
   423 
   424     Expression *condition = NULL;
   425     if (!match(TOK_SEMICOLON)) {
   426         if ((condition = expression()) == NULL)
   427             return NULL;
   428         if (!expect(TOK_SEMICOLON))
   429             return NULL;
   430     }
   431 
   432     Statement *update = NULL;
   433     if (!match(TOK_RPAREN)) {
   434         if ((update = expressionStatement()) == NULL)
   435             return NULL;
   436         if (!expect(TOK_RPAREN))
   437             return NULL;
   438     }
   439 
   440     Statement *body = localStatement();
   441     if (!body)
   442         return NULL;
   443 
   444     Scope *blockScope = NULL;
   445     if (decl) {
   446         blockScope = scope_->unlinkIfEmpty();
   447         scope_ = scope_->enclosing();
   448     }
   449     return new (pool_) ForStatement(blockScope, decl, condition, update, body);
   450 }
   451 
   452 VariableDeclaration *
   453 Parser::variableDeclaration()
   454 {
   455     if (!expect(TOK_NEW))
   456         return NULL;
   457 
   458     Name *tag;
   459     if (matchName(&tag, TOK_LABEL) && !tag)
   460         return NULL;
   461 
   462     Name *name = expectName();
   463     if (!name)
   464         return NULL;
   465 
   466     ExpressionList *postDimensions = NULL;
   467     if (scanner_.peek() == TOK_LBRACKET) {
   468         postDimensions = new ExpressionList();
   469         while (match(TOK_LBRACKET)) {
   470             Expression *dim = expression();
   471             if (!dim)
   472                 return NULL;
   473 
   474             if (!expect(TOK_RBRACKET))
   475                 return NULL;
   476 
   477             postDimensions->push_back(dim);
   478         }
   479     }
   480     
   481     Expression *expr = NULL;
   482     if (match(TOK_ASSIGN)) {
   483         if ((expr = expression()) == NULL)
   484             return NULL;
   485     }
   486     
   487     if (scope_->localLookup(name)) {
   488         redeclarationError();
   489         return NULL;
   490     }
   491 
   492     Variable *var = scope_->declareVariable(name);
   493     VariableDeclaration *decl = new (pool_) VariableDeclaration(var, tag, postDimensions, expr);
   494 
   495     return decl;
   496 }
   497 
   498 Statement *
   499 Parser::returnStatement()
   500 {
   501     if (!expect(TOK_RETURN))
   502         return NULL;
   503 
   504     Expression *expr = expression();
   505     if (!expr)
   506         return NULL;
   507 
   508     return new (pool_) ReturnStatement(expr);
   509 }
   510 
   511 Statement *
   512 Parser::expressionStatement()
   513 {
   514     Expression *left = primary();
   515     if (!left)
   516         return NULL;
   517 
   518     if (match(TOK_ASSIGN)) {
   519         Expression *expr = expression();
   520         if (!expr)
   521             return NULL;
   522 
   523         left = new (pool_) Assignment(left, expr);
   524     }
   525 
   526     return new (pool_) ExpressionStatement(left);
   527 }
   528 
   529 Statement *
   530 Parser::block()
   531 {
   532     if (!expect(TOK_LBRACE))
   533         return NULL;
   534 
   535     if (!enterScope(Scope::BLOCK))
   536         return NULL;
   537 
   538     StatementList *statements = new (pool_) StatementList();
   539     while (!match(TOK_RBRACE)) {
   540         Statement *statement = localStatement();
   541         if (statement == NULL)
   542             return NULL;
   543         statements->append(pool_, statement);
   544     }
   545 
   546     Scope *blockScope = scope_->unlinkIfEmpty();
   547     BlockStatement *block = new (pool_) BlockStatement(blockScope, statements);
   548 
   549     scope_ = scope_->enclosing();
   550     return block;
   551 }
   552 
   553 Statement *
   554 Parser::if_()
   555 {
   556     expect(TOK_IF);
   557 
   558     if (!expect(TOK_LPAREN))
   559         return NULL;
   560 
   561     Expression *cond = expression();
   562     if (!cond)
   563         return NULL;
   564 
   565     if (!expect(TOK_RPAREN))
   566         return NULL;
   567 
   568     Statement *ifTrue = localStatement();
   569     if (!ifTrue)
   570         return NULL;
   571 
   572     IfStatement *outer = new (pool_) IfStatement(cond, ifTrue);
   573 
   574     IfStatement *last = outer;
   575     while (match(TOK_ELSE)) {
   576         if (!match(TOK_IF)) {
   577             Statement *ifFalse = localStatement();
   578             if (!ifFalse)
   579                 return NULL;
   580 
   581             last->setIfFalse(ifFalse);
   582             break;
   583         }
   584 
   585         if (!expect(TOK_IF))
   586             return false;
   587 
   588         if (!expect(TOK_LPAREN))
   589             return NULL;
   590 
   591         Expression *otherCond = expression();
   592         if (!otherCond)
   593             return NULL;
   594 
   595         if (!expect(TOK_RPAREN))
   596             return NULL;
   597 
   598         Statement *otherIfTrue = localStatement();
   599         if (!otherIfTrue)
   600             return NULL;
   601 
   602         IfStatement *inner = new (pool_) IfStatement(otherCond, otherIfTrue);
   603         last->setIfFalse(inner);
   604         last = inner;
   605     }
   606 
   607     return outer;
   608 }
   609 
   610 Statement *
   611 Parser::localStatement()
   612 {
   613     Statement *statement = NULL;
   614 
   615     // Statements which must be followed by a semicolon will break out of the
   616     // switch. If they may end in BlockStatements, they'll immediately return.
   617 
   618     switch (scanner_.peek()) {
   619         case TOK_NEW:
   620           if ((statement = variableDeclaration()) == NULL)
   621               return NULL;
   622           break;
   623 
   624         case TOK_FOR:
   625           return forStatement();
   626 
   627         case TOK_WHILE:
   628           return while_();
   629 
   630         case TOK_BREAK:
   631           scanner_.scan();
   632           statement = new (pool_) BreakStatement();
   633           break;
   634 
   635         case TOK_CONTINUE:
   636           scanner_.scan();
   637           statement = new (pool_) ContinueStatement();
   638           break;
   639 
   640         case TOK_DO:
   641           if ((statement = do_()) == NULL)
   642               return NULL;
   643           break;
   644 
   645         case TOK_RETURN:
   646           if ((statement = returnStatement()) == NULL)
   647               return NULL;
   648           break;
   649 
   650         case TOK_ENUM:
   651           if ((statement = enum_()) == NULL)
   652               return NULL;
   653           break;
   654 
   655         case TOK_IF:
   656           return if_();
   657 
   658         case TOK_LBRACE:
   659           return block();
   660     }
   661 
   662     if (!statement) {
   663         if ((statement = expressionStatement()) == NULL)
   664             return NULL;
   665     }
   666 
   667     if (!expect(TOK_SEMICOLON))
   668         return NULL;
   669 
   670     return statement;
   671 }
   672 
   673 Statement *
   674 Parser::enum_()
   675 {
   676     expect(TOK_ENUM);
   677 
   678     Name *name = NULL;
   679     if (match(TOK_NAME)) {
   680         if ((name = strings_.add(scanner_.literal())) == NULL)
   681             return NULL;
   682 
   683         if (scope_->localLookup(name)) {
   684             redeclarationError();
   685             return NULL;
   686         }
   687 
   688         NamedEnum *e = scope_->declareEnum(name);
   689         if (!e)
   690             return NULL;
   691     }
   692 
   693     EnumStatement::EntryList *entries = new EnumStatement::EntryList();
   694 
   695     if (!expect(TOK_LBRACE))
   696         return NULL;
   697 
   698     do {
   699         if (scanner_.peek() == TOK_RBRACE)
   700             break;
   701 
   702         Name *name = expectName();
   703         if (!name)
   704             return NULL;
   705 
   706         if (scope_->localLookup(name)) {
   707             redeclarationError();
   708             return NULL;
   709         }
   710 
   711         NamedConstant *constant = scope_->declareConstant(name);
   712         if (!constant)
   713             return NULL;
   714 
   715         Expression *expr = NULL;
   716         if (match(TOK_ASSIGN)) {
   717             if ((expr = expression()) == NULL)
   718                 return NULL;
   719         }
   720 
   721         entries->push_back(EnumStatement::Entry(constant, expr));
   722     } while (match(TOK_COMMA));
   723     if (!expect(TOK_RBRACE))
   724         return NULL;
   725 
   726     return new (pool_) EnumStatement(name, entries);
   727 }
   728 
   729 Statement *
   730 Parser::function()
   731 {
   732     Name *name = expectName();
   733     if (!name)
   734         return NULL;
   735 
   736     // The function name goes into the outer (global) scope.
   737     assert(!scope_->enclosing());
   738 
   739     if (scope_->localLookup(name)) {
   740         redeclarationError();
   741         return NULL;
   742     }
   743     NamedFunction *fun = scope_->declareFunction(name);
   744     if (!fun)
   745         return NULL;
   746 
   747     Scope *scope = enterScope(Scope::FUNCTION);
   748     if (!scope)
   749         return NULL;
   750 
   751     ParameterList *parameters = new ParameterList();
   752 
   753     if (!expect(TOK_LPAREN))
   754         return NULL;
   755     if (!match(TOK_RPAREN)) {
   756         while (true) {
   757             bool ref = match(TOK_AMPERSAND);
   758 
   759             Name *name = expectName();
   760             if (!name)
   761                 return NULL;
   762 
   763             if (scope_->localLookup(name)) {
   764                 redeclarationError();
   765                 return NULL;
   766             }
   767             Variable *arg = scope_->declareArgument(name);
   768             if (!arg)
   769                 return NULL;
   770 
   771             Parameter *parameter = new (pool_) Parameter(arg, NULL, ref);
   772             parameters->push_back(parameter);
   773 
   774             if (!match(TOK_COMMA))
   775                 break;
   776         }
   777         if (!expect(TOK_RPAREN))
   778             return NULL;
   779     }
   780 
   781     Statement *body = block();
   782     if (!body)
   783         return NULL;
   784 
   785     scope_ = scope_->enclosing();
   786     return new (pool_) FunctionStatement(scope, fun, body, parameters);
   787 }
   788 
   789 ParseTree *
   790 Parser::parse()
   791 {
   792     StatementList *statements = new (pool_) StatementList();
   793 
   794     if (!enterScope(Scope::GLOBAL))
   795         return NULL;
   796 
   797     for (;;) {
   798         Statement *statement = NULL;
   799 
   800         switch (scanner_.peek()) {
   801           case TOK_ERROR:
   802             return NULL;
   803 
   804           case TOK_EOF:
   805             break;
   806 
   807           case TOK_NAME:
   808             if ((statement = function()) == NULL)
   809                 return NULL;
   810             break;
   811 
   812           case TOK_ENUM:
   813             if ((statement = enum_()) == NULL)
   814                 return NULL;
   815             // :TODO: require semicolon
   816             break;
   817 
   818           default:
   819             fprintf(stderr, "expected function or global variable\n");
   820             return NULL;
   821         }
   822 
   823         if (!statement)
   824             break;
   825 
   826         statements->append(pool_, statement);
   827     }
   828 
   829     return new (pool_) ParseTree(scope_, statements, unbound_);
   830 }
   831 
   832 class AstPrinter : public AstVisitor
   833 {
   834     FILE *fp_;
   835     size_t level_;
   836 
   837   private:
   838     void prefix() {
   839         for (size_t i = 0; i < level_; i++)
   840             fprintf(fp_, "  ");
   841     }
   842     void indent() {
   843         level_++;
   844     }
   845     void unindent() {
   846         level_--;
   847     }
   848 
   849   public:
   850     AstPrinter(FILE *fp)
   851       : fp_(fp),
   852         level_(0)
   853     {
   854     }
   855 
   856     void visit(NameProxy *name) {
   857         prefix();
   858         fprintf(fp_, "[ NameProxy (%s)%s\n", name->name(),
   859                 (name->binding() ? "" : " unbound"));
   860     }
   861     void visit(CallExpression *node) {
   862         prefix();
   863         fprintf(fp_, "[ CallExpression\n");
   864         indent();
   865         node->callee()->accept(this);
   866         for (size_t i = 0; i < node->arguments()->size(); i++)
   867             node->arguments()->at(i)->accept(this);
   868         unindent();
   869     }
   870     void visit(FunctionStatement *node) {
   871         prefix();
   872         fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name());
   873         indent();
   874         node->body()->accept(this);
   875         unindent();
   876     }
   877     void visit(ExpressionStatement *node) {
   878         prefix();
   879         fprintf(fp_, "[ ExpressionStatement\n");
   880         indent();
   881         node->expression()->accept(this);
   882         unindent();
   883     }
   884     void visit(Assignment *node) {
   885         prefix();
   886         fprintf(fp_, "[ Assignment\n");
   887         indent();
   888         node->lvalue()->accept(this);
   889         node->expression()->accept(this);
   890         unindent();
   891     }
   892     void visit(BinaryExpression *node) {
   893         prefix();
   894         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
   895         indent();
   896         node->left()->accept(this);
   897         node->right()->accept(this);
   898         unindent();
   899     }
   900     void visit(ReturnStatement *node) {
   901         prefix();
   902         fprintf(fp_, "[ ReturnStatement\n");
   903         indent();
   904         node->expression()->accept(this);
   905         unindent();
   906     }
   907     void visit(ForStatement *node) {
   908         prefix();
   909         fprintf(fp_, "[ ForStatement\n");
   910         indent();
   911         if (node->declaration())
   912             node->declaration()->accept(this);
   913         if (node->condition())
   914             node->condition()->accept(this);
   915         if (node->update())
   916             node->update()->accept(this);
   917         node->body()->accept(this);
   918         unindent();
   919     }
   920     void visit(BlockStatement *node) {
   921         prefix();
   922         fprintf(fp_, "[ BlockStatement\n");
   923         indent();
   924         for (size_t i = 0; i < node->statements()->length(); i++)
   925             node->statements()->at(i)->accept(this);
   926         unindent();
   927     }
   928     void visit(VariableDeclaration *node) {
   929         prefix();
   930         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name());
   931         indent();
   932         if (node->initialization())
   933             node->initialization()->accept(this);
   934         unindent();
   935     }
   936     void visit(IntegerLiteral *node) {
   937         prefix();
   938         fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
   939     }
   940     void visit(FloatLiteral *node) {
   941         prefix();
   942         fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
   943     }
   944     void visit(IfStatement *node) {
   945         prefix();
   946         fprintf(fp_, "[ IfStatement\n");
   947         indent();
   948         node->ifTrue()->accept(this);
   949         if (node->ifFalse())
   950             node->ifFalse()->accept(this);
   951         unindent();
   952     }
   953     void visit(IndexExpression *node) {
   954         prefix();
   955         fprintf(fp_, "[ IndexExpression\n");
   956         indent();
   957         node->left()->accept(this);
   958         node->right()->accept(this);
   959         unindent();
   960     }
   961     void visit(EnumStatement *node) {
   962         prefix();
   963         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name() : "<anonymous>");
   964         indent();
   965         for (size_t i = 0; i < node->entries()->size(); i++) {
   966             prefix();
   967             fprintf(fp_, "%s =\n", node->entries()->at(i).name->name());
   968             if (node->entries()->at(i).expr) {
   969                 indent();
   970                 node->entries()->at(i).expr->accept(this);
   971                 unindent();
   972             }
   973         }
   974         unindent();
   975     }
   976     void visit(WhileStatement *node) {
   977         prefix();
   978         fprintf(fp_, "[ WhileStatement (%s)\n",
   979                 (node->token() == TOK_DO) ? "do" : "while");
   980         indent();
   981         if (node->token() == TOK_DO) {
   982             node->condition()->accept(this);
   983             node->body()->accept(this);
   984         } else {
   985             node->condition()->accept(this);
   986             node->body()->accept(this);
   987         }
   988         unindent();
   989     }
   990     void visit(BreakStatement *node) {
   991         prefix();
   992         fprintf(fp_, "[ BreakStatement\n");
   993     }
   994     void visit(ContinueStatement *node) {
   995         prefix();
   996         fprintf(fp_, "[ ContinueStatement\n");
   997     }
   998     void visit(StringLiteral *node) {
   999         prefix();
  1000         fprintf(fp_, "[ StringLiteral\n");
  1001     }
  1002 };
  1003 
  1004 void
  1005 ParseTree::dump(FILE *fp)
  1006 {
  1007     AstPrinter printer(fp);
  1008 
  1009     for (size_t i = 0; i < statements_->length(); i++)
  1010         statements_->at(i)->accept(&printer);
  1011 }