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