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