src/compiler/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Mon Dec 24 02:49:20 2012 -0800 (2012-12-24)
changeset 234 26e3035cdffc
parent 233 bbb498ccb4ac
child 238 e9bec7549c28
permissions -rw-r--r--
Get string literals working again.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include <string.h>
    20 #include "../Zone.h"
    21 #include "../FixedArray.h"
    22 #include "../Heap.h"
    23 #include "../Strings.h"
    24 #include "../TypeManager.h"
    25 #include "Parser.h"
    26 #include "../Heap-inl.h"
    27 
    28 using namespace ke;
    29 
    30 Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
    31   : zone_(zone),
    32     cc_(cc),
    33     pool_(zone_->pool()),
    34     scanner_(cc, stream, length),
    35     unbound_(NULL)
    36 {
    37     unbound_ = new (pool_) PoolList<NameProxy *>();
    38     imports_ = new (pool_) PoolList<ImportStatement *>();
    39 }
    40 
    41 bool
    42 Parser::peek(TokenKind kind)
    43 {
    44     return scanner_.peek() == kind;
    45 }
    46 
    47 bool
    48 Parser::match(TokenKind kind)
    49 {
    50     if (!peek(kind))
    51         return false;
    52     scanner_.scan();
    53     return true;
    54 }
    55 
    56 bool
    57 Parser::matchSemicolon()
    58 {
    59     return expect(TOK_SEMICOLON);
    60 }
    61 
    62 bool
    63 Parser::expect(TokenKind kind)
    64 {
    65     TokenKind got = scanner_.scan();
    66     if (got == kind)
    67         return true;
    68     cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
    69     return false;
    70 }
    71 
    72 bool
    73 Parser::matchName(String **name, TokenKind kind)
    74 {
    75     assert(kind == TOK_NAME || kind == TOK_LABEL);
    76     *name = NULL;
    77     if (!match(kind))
    78         return false;
    79     *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
    80     return true;
    81 }
    82 
    83 String *
    84 Parser::expectName()
    85 {
    86     if (!expect(TOK_NAME))
    87         return NULL;
    88     return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
    89 }
    90 
    91 Expression *
    92 Parser::primitive()
    93 {
    94     TokenKind kind = scanner_.peek();
    95     switch (kind) {
    96       case TOK_FLOAT_LITERAL:
    97       {
    98         scanner_.scan();
    99         double value = Scanner::ParseDouble(scanner_.literal());
   100         return new (pool_) FloatLiteral(scanner_.begin(), value);
   101       }
   102 
   103       case TOK_HEX_LITERAL:
   104       {
   105         scanner_.scan();
   106         int value = strtol(scanner_.literal(), NULL, 16);
   107         return new (pool_) IntegerLiteral(scanner_.begin(), value);
   108       }
   109 
   110       case TOK_INTEGER_LITERAL:
   111       {
   112         scanner_.scan();
   113         int value = atoi(scanner_.literal());
   114         return new (pool_) IntegerLiteral(scanner_.begin(), value);
   115       }
   116 
   117       case TOK_TRUE:
   118       case TOK_FALSE:
   119         scanner_.scan();
   120         return new (pool_) BooleanLiteral(scanner_.begin(), kind);
   121 
   122       case TOK_STRING_LITERAL:
   123       {
   124         scanner_.scan();
   125         Local<String> string(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   126         return new (pool_) StringLiteral(scanner_.begin(), string);
   127       }
   128 
   129       default:
   130       {
   131         if (kind != TOK_ERROR)
   132             cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
   133         return NULL;
   134       }
   135     }
   136 }
   137 
   138 Expression *
   139 Parser::fixedArrayLiteral()
   140 {
   141     SourcePosition pos = scanner_.begin();
   142 
   143     ExpressionList *list = new (pool_) ExpressionList();
   144     do {
   145         // { } is an illegal array literal.
   146         if (list->length() > 0 && match(TOK_LBRACE))
   147             break;
   148 
   149         Expression *expr = NULL;
   150         if (peek(TOK_LBRACE))
   151             expr = fixedArrayLiteral();
   152         else
   153             expr = primitive();
   154         if (!expr)
   155             return NULL;
   156 
   157         if (!list->append(expr))
   158             return NULL;
   159 
   160         if (!match(TOK_COMMA)) {
   161             if (!expect(TOK_RBRACE))
   162                 return NULL;
   163             break;
   164         }
   165     } while (true);
   166 
   167     return new (pool_) ArrayLiteral(pos, TOK_LBRACE, list);
   168 }
   169 
   170 Expression *
   171 Parser::prefix()
   172 {
   173     switch (scanner_.peek()) {
   174       case TOK_LPAREN:
   175       {
   176         scanner_.scan();
   177         Expression *expr = expression();
   178         if (!expr)
   179             return NULL;
   180         if (!expect(TOK_RPAREN))
   181             return NULL;
   182         return expr;
   183       }
   184 
   185       case TOK_NAME:
   186       {
   187         Local<String> name(zone_, expectName());
   188         if (!name)
   189             return NULL;
   190         return new (pool_) NameProxy(scanner_.begin(), name);
   191       }
   192 
   193       default:
   194         return primitive();
   195     }
   196 }
   197 
   198 // Parses only old-style declarations.
   199 bool
   200 Parser::typeAndName(Expression **type, String **namep)
   201 {
   202     if (match(TOK_LABEL)) {
   203         // Old-style declaration:
   204         //   new X:type
   205         Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   206         if (!name)
   207             return false;
   208 
   209         *type = new (pool_) NameProxy(scanner_.begin(), name);
   210         *namep = expectName();
   211         return !!*namep;
   212     }
   213     
   214     *type = NULL;
   215     *namep = expectName();
   216 
   217     return !!*namep;
   218 }
   219 
   220 // Parses both old and new style declarations.
   221 bool
   222 Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
   223 {
   224     // Declaration:
   225     //   NewDecl ::= Type Ident
   226     //   OldDecl ::= Label? (Ident | "...")
   227     //   Type    ::= Ident
   228     //   Label   ::= Ident ":"
   229     //
   230     if (match(TOK_LABEL)) {
   231         // We something of the form:
   232         //     Label Ident
   233         // or: Label "..."
   234         Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   235         if (!name)
   236             return false;
   237 
   238         *type = new (pool_) NameProxy(scanner_.begin(), name);
   239         if (kind == DeclArg && match(TOK_ELLIPSES)) {
   240             *namep = NULL;
   241         } else {
   242             if ((*namep = expectName()) == NULL)
   243                 return false;
   244         }
   245         return true;
   246     }
   247 
   248     Local<String> name(zone_, expectName());
   249     if (!name)
   250         return false;
   251 
   252     if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
   253         // We got something of the form:
   254         //    Ident Ident
   255         *type = new (pool_) NameProxy(scanner_.begin(), name);
   256         if (peek(TOK_NAME)) {
   257             if ((*namep = expectName()) == NULL)
   258                 return false;
   259         } else {
   260             *namep = NULL;
   261         }
   262         return true;
   263     }
   264 
   265     // We got something of the form:
   266     //    Ident
   267     *type = NULL;
   268     *namep = name;
   269     return true;
   270 }
   271 
   272 Expression *
   273 Parser::call(Expression *callee)
   274 {
   275     ExpressionList *arguments = new (pool_) ExpressionList();
   276 
   277     SourcePosition pos = scanner_.begin();
   278     expect(TOK_LPAREN);
   279     
   280     if (!match(TOK_RPAREN)) {
   281         while (true) {
   282             Expression *expr = expression();
   283             if (!expr)
   284                 return NULL;
   285 
   286             if (!arguments->append(expr))
   287                 return NULL;
   288 
   289             if (!match(TOK_COMMA))
   290                 break;
   291         }
   292 
   293         if (!expect(TOK_RPAREN))
   294             return NULL;
   295     }
   296 
   297     return new (pool_) CallExpression(pos, callee, arguments);
   298 }
   299 
   300 Expression *
   301 Parser::index(Expression *left)
   302 {
   303     expect(TOK_LBRACKET);
   304     
   305     SourcePosition pos = scanner_.begin();
   306     Expression *expr = expression();
   307     if (!expr)
   308         return NULL;
   309 
   310     if (!expect(TOK_RBRACKET))
   311         return NULL;
   312 
   313     return new (pool_) IndexExpression(pos, left, expr);
   314 }
   315 
   316 Expression *
   317 Parser::field(Expression *left)
   318 {
   319     expect(TOK_DOT);
   320 
   321     SourcePosition pos = scanner_.begin();
   322     Local<String> name(zone_, expectName());
   323     if (!name)
   324         return NULL;
   325 
   326     return new (pool_) FieldExpression(pos, left, name);
   327 }
   328 
   329 Expression *
   330 Parser::primary()
   331 {
   332     Expression *expr = prefix();
   333     if (!expr)
   334         return NULL;
   335 
   336     for (;;) {
   337         switch (scanner_.peek()) {
   338           case TOK_LPAREN:
   339             if ((expr = call(expr)) == NULL)
   340                 return NULL;
   341             break;
   342 
   343           case TOK_LBRACKET:
   344             if ((expr = index(expr)) == NULL)
   345                 return NULL;
   346             break;
   347 
   348           case TOK_DOT:
   349             if ((expr = field(expr)) == NULL)
   350                 return NULL;
   351             break;
   352 
   353           default:
   354             return expr;
   355         }
   356     }
   357 }
   358 
   359 Expression *
   360 Parser::unary()
   361 {
   362     TokenKind token = scanner_.peek();
   363 
   364     SourcePosition pos = scanner_.begin();
   365     switch (token) {
   366       case TOK_INCREMENT:
   367       case TOK_DECREMENT:
   368       {
   369         scanner_.scan();
   370         Expression *expr = unary();
   371         if (!expr)
   372             return NULL;
   373         return new (pool_) IncDecExpression(pos, token, expr, false);
   374       }
   375 
   376       case TOK_MINUS:
   377       case TOK_NOT:
   378       case TOK_TILDE:
   379       {
   380         scanner_.scan();
   381         Expression *expr = unary();
   382         if (!expr)
   383             return NULL;
   384         return new (pool_) UnaryExpression(pos, token, expr);
   385       }
   386 
   387       case TOK_SIZEOF:
   388       {
   389         scanner_.scan();
   390         if (!expect(TOK_LPAREN))
   391             return NULL;
   392         Expression *expr = unary();
   393         if (!expr)
   394             return NULL;
   395         if (!expect(TOK_RPAREN))
   396             return NULL;
   397         return new (pool_) UnaryExpression(pos, token, expr);
   398       }
   399 
   400       case TOK_LABEL:
   401       {
   402         scanner_.scan();
   403         Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   404         if (!tag)
   405             return NULL;
   406 
   407         NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
   408 
   409         Expression *expr = unary();
   410         if (!expr)
   411             return NULL;
   412 
   413         return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
   414       }
   415 
   416       default:
   417         break;
   418     }
   419 
   420     Expression *expr = primary();
   421 
   422     token = scanner_.peek();
   423     if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
   424         scanner_.scan();
   425         return new (pool_) IncDecExpression(pos, token, expr, true);
   426     }
   427 
   428     return expr;
   429 }
   430 
   431 Expression *
   432 Parser::multiplication()
   433 {
   434     Expression *left = unary();
   435     do {
   436         if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
   437             break;
   438         SourcePosition pos = scanner_.begin();
   439         TokenKind kind = scanner_.last();
   440         Expression *right = unary();
   441         if (!right)
   442             return NULL;
   443         left = new (pool_) BinaryExpression(pos, kind, left, right);
   444     } while (left);
   445     return left;
   446 }
   447 
   448 Expression *
   449 Parser::addition()
   450 {
   451     Expression *left = multiplication();
   452     while (left) {
   453         if (!match(TOK_PLUS) && !match(TOK_MINUS))
   454             break;
   455         SourcePosition pos = scanner_.begin();
   456         TokenKind kind = scanner_.last();
   457         Expression *right = multiplication();
   458         if (!right)
   459             return NULL;
   460         left = new (pool_) BinaryExpression(pos, kind, left, right);
   461     }
   462     return left;
   463 }
   464 
   465 Expression *
   466 Parser::shift()
   467 {
   468     Expression *left = addition();
   469     while (left) {
   470         if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
   471             break;
   472         SourcePosition pos = scanner_.begin();
   473         TokenKind kind = scanner_.last();
   474         Expression *right = addition();
   475         if (!right)
   476             return NULL;
   477         left = new (pool_) BinaryExpression(pos, kind, left, right);
   478     }
   479     return left;
   480 }
   481 
   482 Expression *
   483 Parser::bitand_()
   484 {
   485     Expression *left = shift();
   486     while (left) {
   487         if (!match(TOK_BITAND))
   488             break;
   489         SourcePosition pos = scanner_.begin();
   490         Expression *right = shift();
   491         if (!right)
   492             return NULL;
   493         left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
   494     }
   495     return left;
   496 }
   497 
   498 Expression *
   499 Parser::bitxor()
   500 {
   501     Expression *left = bitand_();
   502     while (left) {
   503         if (!match(TOK_BITXOR))
   504             break;
   505         SourcePosition pos = scanner_.begin();
   506         Expression *right = shift();
   507         if (!right)
   508             return NULL;
   509         left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
   510     }
   511     return left;
   512 }
   513 
   514 Expression *
   515 Parser::bitor_()
   516 {
   517     Expression *left = bitxor();
   518     while (left) {
   519         if (!match(TOK_BITOR))
   520             break;
   521         SourcePosition pos = scanner_.begin();
   522         Expression *right = bitxor();
   523         if (!right)
   524             return NULL;
   525         left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
   526     }
   527     return left;
   528 }
   529 
   530 Expression *
   531 Parser::relational()
   532 {
   533     Expression *left = bitor_();
   534     while (left) {
   535         TokenKind kind = scanner_.peek();
   536         if (kind < TOK_LT || kind > TOK_GE)
   537             break;
   538         scanner_.scan();
   539         SourcePosition pos = scanner_.begin();
   540         Expression *right = shift();
   541         if (!right)
   542             return NULL;
   543         left = new (pool_) BinaryExpression(pos, kind, left, right);
   544     }
   545     return left;
   546 }
   547 
   548 Expression *
   549 Parser::equals()
   550 {
   551     Expression *left = relational();
   552     while (left) {
   553         if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   554             break;
   555         TokenKind kind = scanner_.last();
   556         SourcePosition pos = scanner_.begin();
   557         Expression *right = relational();
   558         if (!right)
   559             return NULL;
   560         left = new (pool_) BinaryExpression(pos, kind, left, right);
   561     }
   562     return left;
   563 }
   564 
   565 Expression *
   566 Parser::and_()
   567 {
   568     Expression *left = equals();
   569     while (left) {
   570         if (!match(TOK_AND))
   571             break;
   572         SourcePosition pos = scanner_.begin();
   573         Expression *right = equals();
   574         if (!right)
   575             return NULL;
   576         left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
   577     }
   578     return left;
   579 }
   580 
   581 Expression *
   582 Parser::or_()
   583 {
   584     Expression *left = and_();
   585     while (left) {
   586         if (!match(TOK_OR))
   587             break;
   588         SourcePosition pos = scanner_.begin();
   589         Expression *right = and_();
   590         if (!right)
   591             return NULL;
   592         left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
   593     }
   594     return left;
   595 }
   596 
   597 Expression *
   598 Parser::ternary()
   599 {
   600     Expression *cond = or_();
   601     if (!cond)
   602         return NULL;
   603     
   604     if (!match(TOK_QMARK))
   605         return cond;
   606 
   607     Expression *left;
   608     SourcePosition pos = scanner_.begin();
   609     AutoAllowTags<false> disableTags(scanner_);
   610     {
   611         if ((left = expression()) == NULL)
   612             return NULL;
   613     }
   614 
   615     if (!expect(TOK_COLON))
   616         return NULL;
   617 
   618     Expression *right = expression();
   619     if (!right)
   620         return NULL;
   621 
   622     return new (pool_) TernaryExpression(pos, cond, left, right);
   623 }
   624 
   625 Expression *
   626 Parser::assignment()
   627 {
   628     Expression *left = ternary();
   629     while (left) {
   630         TokenKind token = scanner_.peek();
   631         if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
   632             break;
   633         scanner_.scan();
   634         SourcePosition pos = scanner_.begin();
   635         Expression *expr = ternary();
   636         if (!expr)
   637             return NULL;
   638 
   639         left = new (pool_) Assignment(pos, token, left, expr);
   640     }
   641     return left;
   642 }
   643 
   644 Expression *
   645 Parser::expression()
   646 {
   647     return assignment();
   648 }
   649 
   650 Statement *
   651 Parser::while_()
   652 {
   653     SourcePosition pos = scanner_.begin();
   654     scanner_.scan();
   655 
   656     if (!expect(TOK_LPAREN))
   657         return NULL;
   658 
   659     Expression *condition = expression();
   660     if (!condition)
   661         return NULL;
   662 
   663     if (!expect(TOK_RPAREN))
   664         return NULL;
   665 
   666     Statement *body;
   667     if (scanner_.peek() == TOK_LBRACE)
   668         body = block();
   669     else
   670         body = localStatement();
   671     if (!body)
   672         return NULL;
   673 
   674     return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
   675 }
   676 
   677 Statement *
   678 Parser::do_()
   679 {
   680     SourcePosition pos = scanner_.begin();
   681     scanner_.scan();
   682 
   683     Statement *body;
   684     if (scanner_.peek() == TOK_LBRACE)
   685         body = block();
   686     else
   687         body = localStatement();
   688     if (!body)
   689         return NULL;
   690 
   691     if (!expect(TOK_WHILE))
   692         return NULL;
   693 
   694     if (!expect(TOK_LPAREN))
   695         return NULL;
   696     Expression *condition = expression();
   697     if (!condition)
   698         return NULL;
   699     if (!expect(TOK_RPAREN))
   700         return NULL;
   701 
   702     return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
   703 }
   704 
   705 Statement *
   706 Parser::switch_()
   707 {
   708     expect(TOK_SWITCH);
   709 
   710     SourcePosition pos = scanner_.begin();
   711 
   712     if (!expect(TOK_LPAREN))
   713         return NULL;
   714     Expression *expr = expression();
   715     if (!expr)
   716         return NULL;
   717     if (!expect(TOK_RPAREN))
   718         return NULL;
   719 
   720     if (!expect(TOK_LBRACE))
   721         return NULL;
   722 
   723     SourcePosition defaultPos;
   724     PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
   725 
   726     Statement *defaultCase = NULL;
   727 
   728     while (!peek(TOK_RBRACE)) {
   729         Expression *expr = NULL;
   730         ExpressionList *others = NULL;
   731         if (match(TOK_DEFAULT)) {
   732             if (defaultCase) {
   733                 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
   734                 return NULL;
   735             }
   736 
   737             defaultPos = scanner_.begin();
   738         } else {
   739             if (defaultCase) {
   740                 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
   741                 return NULL;
   742             }
   743 
   744             if (!expect(TOK_CASE))
   745                 return NULL;
   746 
   747             // A limitation in the grammar is that |case <NAME>:| will be
   748             // detected as a label.
   749             AutoAllowTags<false> disableTags(scanner_);
   750 
   751             if ((expr = expression()) == NULL)
   752                 return NULL;
   753 
   754             if (peek(TOK_COMMA)) {
   755                 others = new (pool_) ExpressionList();
   756                 while (match(TOK_COMMA)) {
   757                     Expression *other = expression();
   758                     if (!other)
   759                         return NULL;
   760                     if (!others->append(other))
   761                         return NULL;
   762                 }
   763             }
   764         }
   765 
   766         if (!expect(TOK_COLON))
   767             return NULL;
   768 
   769         Statement *statement = localStatement();
   770         if (!statement)
   771             return NULL;
   772 
   773         if (!peek(TOK_CASE) &&
   774             !peek(TOK_DEFAULT) &&
   775             !peek(TOK_RBRACE))
   776         {
   777             cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
   778             return NULL;
   779         }
   780 
   781         if (expr) {
   782             Case *caze = new (pool_) Case(expr, others, statement);
   783             if (!cases->append(caze))
   784                 return NULL;
   785         } else {
   786             defaultCase = statement;
   787         }
   788     }
   789 
   790     if (!expect(TOK_RBRACE))
   791         return NULL;
   792 
   793     return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
   794 }
   795 
   796 Statement *
   797 Parser::forStatement()
   798 {
   799     SourcePosition pos = scanner_.begin();
   800     scanner_.scan();
   801     if (!expect(TOK_LPAREN))
   802         return NULL;
   803 
   804     Statement *decl = NULL;
   805     if (!match(TOK_SEMICOLON)) {
   806         if (match(TOK_NEW)) {
   807             if ((decl = vars(Qual_None)) == NULL)
   808                 return NULL;
   809         } else {
   810             if ((decl = expressionStatement()) == NULL)
   811                 return NULL;
   812         }
   813         if (!expect(TOK_SEMICOLON))
   814             return NULL;
   815     }
   816 
   817     Expression *condition = NULL;
   818     if (!match(TOK_SEMICOLON)) {
   819         if ((condition = expression()) == NULL)
   820             return NULL;
   821         if (!expect(TOK_SEMICOLON))
   822             return NULL;
   823     }
   824 
   825     Statement *update = NULL;
   826     if (!match(TOK_RPAREN)) {
   827         if ((update = expressionStatement()) == NULL)
   828             return NULL;
   829         if (!expect(TOK_RPAREN))
   830             return NULL;
   831     }
   832 
   833     Statement *body;
   834     if (scanner_.peek() == TOK_LBRACE)
   835         body = block();
   836     else
   837         body = localStatement();
   838     if (!body)
   839         return NULL;
   840 
   841     return new (pool_) ForStatement(pos, decl, condition, update, body);
   842 }
   843 
   844 ExpressionList *
   845 Parser::dimensions()
   846 {
   847     ExpressionList *postDimensions = new (pool_) ExpressionList();
   848     while (match(TOK_LBRACKET)) {
   849         Expression *dim = NULL;
   850         if (!match(TOK_RBRACKET)) {
   851             if ((dim = expression()) == NULL)
   852                 return NULL;
   853             if (!expect(TOK_RBRACKET))
   854                 return NULL;
   855         }
   856 
   857         if (!postDimensions->append(dim))
   858             return NULL;
   859     }
   860     return postDimensions;
   861 }
   862 
   863 VariableDeclaration *
   864 Parser::var(TypeQualifiers qual)
   865 {
   866     Expression *type;
   867     Local<String> name(zone_);
   868     
   869     if (!typeAndName(&type, name.ref()))
   870         return NULL;
   871 
   872     ExpressionList *dims = NULL;
   873     if (peek(TOK_LBRACKET)) {
   874         if ((dims = dimensions()) == NULL)
   875             return NULL;;
   876     }
   877 
   878     SourcePosition pos = scanner_.begin();
   879     
   880     Expression *expr = NULL;
   881     if (match(TOK_ASSIGN)) {
   882         switch (scanner_.peek()) {
   883           // Note: we don't support [] literals yet.
   884           case TOK_LBRACE:
   885             scanner_.scan();
   886             if ((expr = fixedArrayLiteral()) == NULL)
   887                 return NULL;
   888             break;
   889 
   890           default:
   891             if ((expr = expression()) == NULL)
   892                 return NULL;
   893             break;
   894         }
   895     }
   896 
   897     return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
   898 }
   899 
   900 Statement *
   901 Parser::vars(TypeQualifiers qual)
   902 {
   903     VariableDeclaration *decl = var(qual);
   904     if (!decl)
   905         return NULL;
   906 
   907     if (!peek(TOK_COMMA))
   908         return decl;
   909 
   910     StatementList *statements = new (pool_) StatementList();
   911     if (!statements->append(decl))
   912         return NULL;
   913 
   914     while (match(TOK_COMMA)) {
   915         Statement *decl = var(qual);
   916         if (!decl)
   917             return NULL;
   918         if (!statements->append(decl))
   919             return NULL;
   920     }
   921 
   922     // Create a fake-o block with no scope to create a statement list.
   923     return new (pool_) BlockStatement(decl->pos(), statements);
   924 }
   925 
   926 Statement *
   927 Parser::returnStatement()
   928 {
   929     SourcePosition pos = scanner_.begin();
   930     if (!expect(TOK_RETURN))
   931         return NULL;
   932 
   933     Expression *expr = NULL;
   934     if (scanner_.peek() != TOK_SEMICOLON) {
   935         if ((expr = expression()) == NULL)
   936             return NULL;
   937 
   938         // We only care about non-void returns when determining whether a
   939         // tagless function is non-void.
   940         encounteredReturn_ = true;
   941     }
   942 
   943     return new (pool_) ReturnStatement(pos, expr);
   944 }
   945 
   946 Statement *
   947 Parser::expressionStatement()
   948 {
   949     Expression *left = assignment();
   950     if (!left)
   951         return NULL;
   952 
   953     return new (pool_) ExpressionStatement(left);
   954 }
   955 
   956 Statement *
   957 Parser::block()
   958 {
   959     if (!expect(TOK_LBRACE))
   960         return NULL;
   961 
   962     SourcePosition pos = scanner_.begin();
   963 
   964     StatementList *statements = new (pool_) StatementList();
   965     while (!match(TOK_RBRACE)) {
   966         Statement *statement = localStatement();
   967         if (statement == NULL)
   968             return NULL;
   969         if (!statements->append(statement))
   970             return NULL;
   971     }
   972 
   973     BlockStatement *block = new (pool_) BlockStatement(pos, statements);
   974     return block;
   975 }
   976 
   977 Statement *
   978 Parser::if_()
   979 {
   980     expect(TOK_IF);
   981     
   982     SourcePosition pos = scanner_.begin();
   983     if (!expect(TOK_LPAREN))
   984         return NULL;
   985 
   986     Expression *cond = expression();
   987     if (!cond)
   988         return NULL;
   989 
   990     if (!expect(TOK_RPAREN))
   991         return NULL;
   992 
   993     Statement *ifTrue = localStatement();
   994     if (!ifTrue)
   995         return NULL;
   996 
   997     IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
   998 
   999     IfStatement *last = outer;
  1000     while (match(TOK_ELSE)) {
  1001         if (!match(TOK_IF)) {
  1002             Statement *ifFalse = localStatement();
  1003             if (!ifFalse)
  1004                 return NULL;
  1005 
  1006             last->setIfFalse(ifFalse);
  1007             break;
  1008         }
  1009 
  1010         SourcePosition pos = scanner_.begin();
  1011         if (!expect(TOK_LPAREN))
  1012             return NULL;
  1013 
  1014         Expression *otherCond = expression();
  1015         if (!otherCond)
  1016             return NULL;
  1017 
  1018         if (!expect(TOK_RPAREN))
  1019             return NULL;
  1020 
  1021         Statement *otherIfTrue = localStatement();
  1022         if (!otherIfTrue)
  1023             return NULL;
  1024 
  1025         IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
  1026         last->setIfFalse(inner);
  1027         last = inner;
  1028     }
  1029 
  1030     return outer;
  1031 }
  1032 
  1033 Statement *
  1034 Parser::localStatement()
  1035 {
  1036     Statement *statement = NULL;
  1037 
  1038     // Statements which must be followed by a semicolon will break out of the
  1039     // switch. If they may end in BlockStatements, they'll immediately return.
  1040 
  1041     TokenKind kind = scanner_.peek();
  1042     switch (kind) {
  1043       case TOK_CONST:
  1044       case TOK_NEW:
  1045       {
  1046         TypeQualifiers quals = (kind == TOK_CONST)
  1047                               ? Qual_Const
  1048                               : Qual_None;
  1049         scanner_.scan();
  1050         if ((statement = vars(quals)) == NULL)
  1051           return NULL;
  1052         break;
  1053       }
  1054 
  1055       case TOK_FOR:
  1056         return forStatement();
  1057 
  1058       case TOK_WHILE:
  1059         return while_();
  1060 
  1061       case TOK_BREAK:
  1062         scanner_.scan();
  1063         statement = new (pool_) BreakStatement(scanner_.begin());
  1064         break;
  1065 
  1066       case TOK_CONTINUE:
  1067         scanner_.scan();
  1068         statement = new (pool_) ContinueStatement(scanner_.begin());
  1069         break;
  1070 
  1071       case TOK_DO:
  1072         if ((statement = do_()) == NULL)
  1073             return NULL;
  1074         break;
  1075 
  1076       case TOK_RETURN:
  1077         if ((statement = returnStatement()) == NULL)
  1078           return NULL;
  1079         break;
  1080 
  1081       case TOK_ENUM:
  1082         if ((statement = enum_()) == NULL)
  1083           return NULL;
  1084         break;
  1085 
  1086       case TOK_STRUCT:
  1087         if ((statement = struct_()) == NULL)
  1088           return NULL;
  1089         break;
  1090 
  1091       case TOK_SWITCH:
  1092         return switch_();
  1093 
  1094       case TOK_IF:
  1095         return if_();
  1096 
  1097       case TOK_LBRACE:
  1098         return block();
  1099 
  1100       default:
  1101         break;
  1102     }
  1103 
  1104     if (!statement) {
  1105         if ((statement = expressionStatement()) == NULL)
  1106             return NULL;
  1107     }
  1108 
  1109     if (!expect(TOK_SEMICOLON))
  1110         return NULL;
  1111 
  1112     return statement;
  1113 }
  1114 
  1115 Statement *
  1116 Parser::struct_()
  1117 {
  1118     expect(TOK_STRUCT);
  1119 
  1120     Local<String> name(zone_, expectName());
  1121     if (!name)
  1122         return NULL;
  1123 
  1124     SourcePosition pos = scanner_.begin();
  1125 
  1126     if (!expect(TOK_LBRACE))
  1127         return NULL;
  1128 
  1129     FieldList *fields = new (pool_) FieldList();
  1130 
  1131     while (!peek(TOK_RBRACE)) {
  1132         Expression *type;
  1133         Local<String> fieldName(zone_);
  1134 
  1135         if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
  1136             return NULL;
  1137 
  1138         SourcePosition pos = scanner_.begin();
  1139 
  1140         if (!matchSemicolon())
  1141             return NULL;
  1142 
  1143         StructureStatement::Field *field =
  1144             new (pool_) StructureStatement::Field(pos, type, fieldName);
  1145         if (!field || !fields->append(field))
  1146             return NULL;
  1147     }
  1148 
  1149     if (!expect(TOK_RBRACE))
  1150         return NULL;
  1151 
  1152     if (fields->empty()) {
  1153         cc_.reportError(pos, Message_StructCantBeEmpty);
  1154         return NULL;
  1155     }
  1156 
  1157     return new (pool_) StructureStatement(pos, name, fields);
  1158 }
  1159 
  1160 Statement *
  1161 Parser::enum_()
  1162 {
  1163     expect(TOK_ENUM);
  1164 
  1165     SourcePosition pos = scanner_.begin();
  1166 
  1167     Local<String> name(zone_);
  1168     if (matchName(name.ref()) && !name)
  1169         return NULL;
  1170 
  1171     EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
  1172 
  1173     if (!expect(TOK_LBRACE))
  1174         return NULL;
  1175 
  1176     do {
  1177         if (scanner_.peek() == TOK_RBRACE)
  1178             break;
  1179 
  1180         SourcePosition &pos = scanner_.begin();
  1181         Local<String> name(zone_, expectName());
  1182         if (!name)
  1183             return NULL;
  1184 
  1185         Expression *expr = NULL;
  1186         if (match(TOK_ASSIGN)) {
  1187             if ((expr = expression()) == NULL)
  1188                 return NULL;
  1189         }
  1190 
  1191         if (!entries->append(EnumStatement::Entry(name, expr, pos)))
  1192             return NULL;
  1193     } while (match(TOK_COMMA));
  1194     if (!expect(TOK_RBRACE))
  1195         return NULL;
  1196 
  1197     return new (pool_) EnumStatement(pos, name, entries);
  1198 }
  1199 
  1200 template <class T>
  1201 static inline ScopedRoot<T> *
  1202 NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
  1203 {
  1204     ScopedRoot<T> *root = pool.alloc<ScopedRoot<T> >();
  1205     new (root) ScopedRoot<T>(obj);
  1206     return root;
  1207 }
  1208 
  1209 ImportStatement *
  1210 Parser::import()
  1211 {
  1212     NameList *names = new (pool_) NameList();
  1213 
  1214     SourcePosition pos = scanner_.begin();
  1215 
  1216     Local<String> name(zone_, expectName());
  1217     if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
  1218         return NULL;
  1219 
  1220     TokenKind suffix = TOK_NONE;
  1221     while (match(TOK_DOT)) {
  1222         if (match(TOK_STAR)) {
  1223             suffix = TOK_STAR;
  1224             break;
  1225         }
  1226 
  1227         if ((name = expectName()) == NULL)
  1228             return NULL;
  1229 
  1230         if (!names->append(NewScopedRoot<String>(pool_, name)))
  1231             return NULL;
  1232     }
  1233 
  1234     return new (pool_) ImportStatement(pos, names, suffix);
  1235 }
  1236 
  1237 Statement *
  1238 Parser::function(TokenKind token)
  1239 {
  1240     Expression *returnType;
  1241     Local<String> name(zone_);
  1242 
  1243     if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
  1244         return NULL;
  1245 
  1246     SourcePosition pos = scanner_.begin();
  1247     ParameterList *parameters = new (pool_) ParameterList();
  1248 
  1249     if (!expect(TOK_LPAREN))
  1250         return NULL;
  1251 
  1252     bool variadic = false;
  1253 
  1254     if (!match(TOK_RPAREN)) {
  1255         while (true) {
  1256             bool isConst = match(TOK_CONST);
  1257             bool ref = match(TOK_AMPERSAND);
  1258 
  1259             SourcePosition begin = scanner_.begin();
  1260             Expression *type;
  1261             Local<String> name(zone_);
  1262             if (!fullTypeAndName(&type, name.ref(), DeclArg))
  1263                 return NULL;
  1264 
  1265             if (!name) {
  1266                 if (isConst || ref) {
  1267                     cc_.reportError(begin, Message_InvalidVarArgs);
  1268                     return NULL;
  1269                 }
  1270 
  1271                 if (token != TOK_NATIVE) {
  1272                     cc_.reportError(begin, Message_VarArgsOutsideNative);
  1273                     return NULL;
  1274                 }
  1275 
  1276                 variadic = true;
  1277                 break;
  1278             }
  1279 
  1280             ExpressionList *dims = NULL;
  1281             if (peek(TOK_LBRACKET)) {
  1282                 if ((dims = dimensions()) == NULL)
  1283                     return NULL;
  1284             }
  1285 
  1286             Expression *expr = NULL;
  1287             if (match(TOK_ASSIGN)) {
  1288                 if ((expr = expression()) == NULL)
  1289                     return NULL;
  1290             }
  1291 
  1292             Parameter *parameter = new (pool_) Parameter(name, type, ref, isConst, dims, expr, begin);
  1293             if (!parameters->append(parameter))
  1294                 return NULL;
  1295 
  1296             if (!match(TOK_COMMA))
  1297                 break;
  1298         }
  1299         if (!expect(TOK_RPAREN))
  1300             return NULL;
  1301     }
  1302 
  1303     encounteredReturn_ = false;
  1304 
  1305     Statement *body = NULL;
  1306     if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
  1307         body = block();
  1308         if (!body)
  1309             return NULL;
  1310     }
  1311 
  1312     FunctionSignature signature(returnType, parameters, variadic);
  1313     if (token == TOK_TYPEDEF)
  1314         return new (pool_) FunctionTypeStatement(pos, name, signature);
  1315 
  1316     return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
  1317 }
  1318 
  1319 static inline bool
  1320 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
  1321 {
  1322     Local<String> tag(zone, zone->makeSymbol(name));
  1323     if (!tag)
  1324         return false;
  1325 
  1326     assert(false);
  1327     return false; //return !!scope->declareType(tag, type);
  1328 }
  1329 
  1330 static inline bool
  1331 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
  1332 {
  1333     Local<Type> primitive(zone, zone->types()->getPrimitive(type));
  1334     assert(primitive);
  1335     return DeclareIntrinsicType(zone, scope, name, primitive);
  1336 }
  1337 
  1338 bool
  1339 Parser::setupIntrinsics()
  1340 {
  1341 #if 0
  1342     if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
  1343         return false;
  1344     if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
  1345         return false;
  1346     if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
  1347         return false;
  1348     if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
  1349         return false;
  1350 
  1351     Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
  1352     if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
  1353         return false;
  1354 
  1355     Local<Type> voidType(zone_, zone_->types()->getVoid());
  1356     if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
  1357         return false;
  1358 
  1359     Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
  1360     if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
  1361         return false;
  1362 #endif
  1363     return true;
  1364 }
  1365 
  1366 ParseTree *
  1367 Parser::parse()
  1368 {
  1369     StatementList *statements = new (pool_) StatementList();
  1370 
  1371     if (!setupIntrinsics())
  1372         return NULL;
  1373 
  1374     for (;;) {
  1375         Statement *statement = NULL;
  1376 
  1377         TokenKind kind = scanner_.peek();
  1378         switch (kind) {
  1379           case TOK_ERROR:
  1380             return NULL;
  1381 
  1382           case TOK_EOF:
  1383             break;
  1384 
  1385           case TOK_NAME:
  1386             if ((statement = function(TOK_NAME)) == NULL)
  1387                 return NULL;
  1388             break;
  1389 
  1390           case TOK_IMPORT:
  1391           {
  1392             scanner_.scan();
  1393             if (statements->length())
  1394                 cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
  1395             ImportStatement *stmt = import();
  1396             if (!stmt)
  1397                 return NULL;
  1398             if (!imports_->append(stmt))
  1399                 return NULL;
  1400             if (!matchSemicolon())
  1401                 return NULL;
  1402             continue;
  1403           }
  1404 
  1405           case TOK_FORWARD:
  1406           case TOK_PUBLIC:
  1407           case TOK_NATIVE:
  1408           case TOK_STOCK:
  1409           case TOK_LABEL:
  1410           case TOK_TYPEDEF:
  1411           {
  1412             if (kind != TOK_LABEL)
  1413                 scanner_.scan();
  1414             if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
  1415                 TypeQualifiers quals = TypeQualifiers(Qual_Public | Qual_Const);
  1416                 if ((statement = var(quals)) == NULL)
  1417                     return NULL;
  1418                 if (!matchSemicolon())
  1419                     return NULL;
  1420             } else {
  1421                 if ((statement = function(kind)) == NULL)
  1422                     return NULL;
  1423                 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
  1424                     return NULL;
  1425             }
  1426             break;
  1427           }
  1428 
  1429           case TOK_CONST:
  1430           case TOK_NEW:
  1431           {
  1432             TypeQualifiers quals = (kind == TOK_NEW) ? Qual_Const : Qual_None;
  1433             // Note: at global scope, we don't accept comma-delimited
  1434             // declarations yet, to see if we can get away with forcing
  1435             // a nicer top-level style.
  1436             scanner_.scan();
  1437             if ((statement = var(quals)) == NULL)
  1438                 return NULL;
  1439             if (!matchSemicolon())
  1440                 return NULL;
  1441             break;
  1442           }
  1443 
  1444           case TOK_ENUM:
  1445             if ((statement = enum_()) == NULL)
  1446                 return NULL;
  1447             if (!matchSemicolon())
  1448                 return NULL;
  1449             break;
  1450 
  1451           case TOK_STRUCT:
  1452             if ((statement = struct_()) == NULL)
  1453                 return NULL;
  1454             if (!matchSemicolon())
  1455                 return NULL;
  1456             break;
  1457 
  1458           default:
  1459             cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
  1460             return NULL;
  1461         }
  1462 
  1463         if (!statement)
  1464             break;
  1465 
  1466         if (!statements->append(statement))
  1467             return NULL;
  1468     }
  1469 
  1470     return new (pool_) ParseTree(statements, unbound_, imports_);
  1471 }
  1472 
  1473 class AstPrinter : public AstVisitor
  1474 {
  1475     FILE *fp_;
  1476     size_t level_;
  1477 
  1478   private:
  1479     void prefix() {
  1480         for (size_t i = 0; i < level_; i++)
  1481             fprintf(fp_, "  ");
  1482     }
  1483     void indent() {
  1484         level_++;
  1485     }
  1486     void unindent() {
  1487         level_--;
  1488     }
  1489 
  1490   public:
  1491     AstPrinter(FILE *fp)
  1492       : fp_(fp),
  1493         level_(0)
  1494     {
  1495     }
  1496 
  1497     void dump(const FunctionSignature &sig) {
  1498         prefix();
  1499         fprintf(fp_, "()\n");
  1500     }
  1501     void visitNameProxy(NameProxy *name) {
  1502         prefix();
  1503         fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
  1504     }
  1505     void visitCallExpression(CallExpression *node) {
  1506         prefix();
  1507         fprintf(fp_, "[ CallExpression\n");
  1508         indent();
  1509         node->callee()->accept(this);
  1510         for (size_t i = 0; i < node->arguments()->length(); i++)
  1511             node->arguments()->at(i)->accept(this);
  1512         unindent();
  1513     }
  1514     void visitFunctionTypeStatement(FunctionTypeStatement *node) {
  1515         prefix();
  1516         fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
  1517         indent();
  1518         dump(node->signature());
  1519         unindent();
  1520     }
  1521     void visitFunctionStatement(FunctionStatement *node) {
  1522         prefix();
  1523         fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
  1524         indent();
  1525         dump(node->signature());
  1526         if (node->body())
  1527             node->body()->accept(this);
  1528         unindent();
  1529     }
  1530     void visitExpressionStatement(ExpressionStatement *node) {
  1531         prefix();
  1532         fprintf(fp_, "[ ExpressionStatement\n");
  1533         indent();
  1534         node->expression()->accept(this);
  1535         unindent();
  1536     }
  1537     void visitAssignment(Assignment *node) {
  1538         prefix();
  1539         fprintf(fp_, "[ Assignment\n");
  1540         indent();
  1541         node->lvalue()->accept(this);
  1542         node->expression()->accept(this);
  1543         unindent();
  1544     }
  1545     void visitTernaryExpression(TernaryExpression *node) {
  1546         prefix();
  1547         fprintf(fp_, "[ TernaryExpression\n");
  1548         indent();
  1549         node->condition()->accept(this);
  1550         node->left()->accept(this);
  1551         node->right()->accept(this);
  1552         unindent();
  1553     }
  1554     void visitBinaryExpression(BinaryExpression *node) {
  1555         prefix();
  1556         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
  1557         indent();
  1558         node->left()->accept(this);
  1559         node->right()->accept(this);
  1560         unindent();
  1561     }
  1562     void visitUnaryExpression(UnaryExpression *node) {
  1563         prefix();
  1564         fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
  1565         indent();
  1566         node->expression()->accept(this);
  1567         unindent();
  1568     }
  1569     void visitReturnStatement(ReturnStatement *node) {
  1570         prefix();
  1571         fprintf(fp_, "[ ReturnStatement\n");
  1572         indent();
  1573         if (node->expression())
  1574             node->expression()->accept(this);
  1575         unindent();
  1576     }
  1577     void visitForStatement(ForStatement *node) {
  1578         prefix();
  1579         fprintf(fp_, "[ ForStatement\n");
  1580         indent();
  1581         if (node->initialization())
  1582             node->initialization()->accept(this);
  1583         if (node->condition())
  1584             node->condition()->accept(this);
  1585         if (node->update())
  1586             node->update()->accept(this);
  1587         node->body()->accept(this);
  1588         unindent();
  1589     }
  1590     void visitBlockStatement(BlockStatement *node) {
  1591         prefix();
  1592         fprintf(fp_, "[ BlockStatement\n");
  1593         indent();
  1594         for (size_t i = 0; i < node->statements()->length(); i++)
  1595             node->statements()->at(i)->accept(this);
  1596         unindent();
  1597     }
  1598     void visitVariableDeclaration(VariableDeclaration *node) {
  1599         prefix();
  1600         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
  1601         indent();
  1602         if (node->initialization())
  1603             node->initialization()->accept(this);
  1604         unindent();
  1605     }
  1606     void visitIntegerLiteral(IntegerLiteral *node) {
  1607         prefix();
  1608         fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
  1609     }
  1610     void visitBooleanLiteral(BooleanLiteral *node) {
  1611         prefix();
  1612         fprintf(fp_, "[ BooleanLiteral (%s)\n",
  1613                 (node->token() == TOK_TRUE) ? "true" : "false");
  1614     }
  1615     void visitFloatLiteral(FloatLiteral *node) {
  1616         prefix();
  1617         fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
  1618     }
  1619     void visitIfStatement(IfStatement *node) {
  1620         prefix();
  1621         fprintf(fp_, "[ IfStatement\n");
  1622         indent();
  1623         node->ifTrue()->accept(this);
  1624         if (node->ifFalse())
  1625             node->ifFalse()->accept(this);
  1626         unindent();
  1627     }
  1628     void visitIndexExpression(IndexExpression *node) {
  1629         prefix();
  1630         fprintf(fp_, "[ IndexExpression\n");
  1631         indent();
  1632         node->left()->accept(this);
  1633         node->right()->accept(this);
  1634         unindent();
  1635     }
  1636     void visitEnumStatement(EnumStatement *node) {
  1637         prefix();
  1638         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
  1639         indent();
  1640         for (size_t i = 0; i < node->entries()->length(); i++) {
  1641             prefix();
  1642             fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
  1643             if (node->entries()->at(i).expr) {
  1644                 indent();
  1645                 node->entries()->at(i).expr->accept(this);
  1646                 unindent();
  1647             }
  1648         }
  1649         unindent();
  1650     }
  1651     void visitWhileStatement(WhileStatement *node) {
  1652         prefix();
  1653         fprintf(fp_, "[ WhileStatement (%s)\n",
  1654                 (node->token() == TOK_DO) ? "do" : "while");
  1655         indent();
  1656         if (node->token() == TOK_DO) {
  1657             node->condition()->accept(this);
  1658             node->body()->accept(this);
  1659         } else {
  1660             node->condition()->accept(this);
  1661             node->body()->accept(this);
  1662         }
  1663         unindent();
  1664     }
  1665     void visitBreakStatement(BreakStatement *node) {
  1666         prefix();
  1667         fprintf(fp_, "[ BreakStatement\n");
  1668     }
  1669     void visitContinueStatement(ContinueStatement *node) {
  1670         prefix();
  1671         fprintf(fp_, "[ ContinueStatement\n");
  1672     }
  1673     void visitStringLiteral(StringLiteral *node) {
  1674         prefix();
  1675         fprintf(fp_, "[ StringLiteral\n");
  1676     }
  1677     void visitIncDecExpression(IncDecExpression *node) {
  1678         prefix();
  1679         fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
  1680         indent();
  1681         node->expression()->accept(this);
  1682         unindent();
  1683     }
  1684     void visitStructureStatement(StructureStatement *node) {
  1685         prefix();
  1686         fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
  1687     }
  1688     void visitFieldExpression(FieldExpression *node) {
  1689         prefix();
  1690         fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
  1691         indent();
  1692         node->left()->accept(this);
  1693         unindent();
  1694     }
  1695     void visitSwitchStatement(SwitchStatement *node) {
  1696         prefix();
  1697         fprintf(fp_, "[ SwitchStatement\n");
  1698         indent();
  1699         node->expression()->accept(this);
  1700         for (size_t i = 0; i < node->cases()->length(); i++) {
  1701             Case *c = node->cases()->at(i);
  1702             c->expression()->accept(this);
  1703             if (c->others()) {
  1704                 for (size_t j = 0; j < c->others()->length(); j++)
  1705                     c->others()->at(j)->accept(this);
  1706             }
  1707             indent();
  1708             c->statement()->accept(this);
  1709             unindent();
  1710         }
  1711         if (node->defaultCase())
  1712             node->defaultCase()->accept(this);
  1713         unindent();
  1714     }
  1715     void visitArrayLiteral(ArrayLiteral *node) {
  1716         prefix();
  1717         fprintf(fp_, "[ ArrayLiteral\n");
  1718         indent();
  1719         for (size_t i = 0; i < node->expressions()->length(); i++) {
  1720             Expression *expr = node->expressions()->at(i);
  1721             indent();
  1722             expr->accept(this);
  1723             unindent();
  1724         }
  1725     }
  1726     void visitImportStatement(ImportStatement *node) {
  1727         prefix();
  1728         fprintf(fp_, "[ ImportStatement\n");
  1729     }
  1730 };
  1731 
  1732 void
  1733 ParseTree::dump(FILE *fp)
  1734 {
  1735     AstPrinter printer(fp);
  1736 
  1737     for (size_t i = 0; i < statements_->length(); i++)
  1738         statements_->at(i)->accept(&printer);
  1739 }