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