src/compiler/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Sun Jan 06 13:52:21 2013 -0800 (2013-01-06)
changeset 256 3c184218462d
parent 252 1dee2330aa78
child 257 9db4cc815ebc
permissions -rw-r--r--
Initial implementation of module imports.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include <string.h>
    20 #include "../Zone.h"
    21 #include "../FixedArray.h"
    22 #include "../Heap.h"
    23 #include "../Strings.h"
    24 #include "../TypeManager.h"
    25 #include "Parser.h"
    26 #include "../Heap-inl.h"
    27 
    28 using namespace ke;
    29 
    30 Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
    31   : zone_(zone),
    32     cc_(cc),
    33     pool_(zone_->pool()),
    34     scanner_(cc, stream, length),
    35     unbound_(NULL)
    36 {
    37     unbound_ = new (pool_) PoolList<NameProxy *>();
    38     imports_ = new (pool_) PoolList<ImportStatement *>();
    39 }
    40 
    41 bool
    42 Parser::peek(TokenKind kind)
    43 {
    44     return scanner_.peek() == kind;
    45 }
    46 
    47 bool
    48 Parser::match(TokenKind kind)
    49 {
    50     if (!peek(kind))
    51         return false;
    52     scanner_.scan();
    53     return true;
    54 }
    55 
    56 bool
    57 Parser::matchSemicolon()
    58 {
    59     return expect(TOK_SEMICOLON);
    60 }
    61 
    62 bool
    63 Parser::expect(TokenKind kind)
    64 {
    65     TokenKind got = scanner_.scan();
    66     if (got == kind)
    67         return true;
    68     cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
    69     return false;
    70 }
    71 
    72 bool
    73 Parser::matchName(String **name, TokenKind kind)
    74 {
    75     assert(kind == TOK_NAME || kind == TOK_LABEL);
    76     *name = NULL;
    77     if (!match(kind))
    78         return false;
    79     *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
    80     return true;
    81 }
    82 
    83 String *
    84 Parser::expectName()
    85 {
    86     if (!expect(TOK_NAME))
    87         return NULL;
    88     return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
    89 }
    90 
    91 Expression *
    92 Parser::primitive()
    93 {
    94     TokenKind kind = scanner_.peek();
    95     switch (kind) {
    96       case TOK_FLOAT_LITERAL:
    97       {
    98         scanner_.scan();
    99         double value = Scanner::ParseDouble(scanner_.literal());
   100         return new (pool_) FloatLiteral(scanner_.begin(), value);
   101       }
   102 
   103       case TOK_HEX_LITERAL:
   104       {
   105         scanner_.scan();
   106         int value = strtol(scanner_.literal(), NULL, 16);
   107         return new (pool_) IntegerLiteral(scanner_.begin(), value);
   108       }
   109 
   110       case TOK_INTEGER_LITERAL:
   111       {
   112         scanner_.scan();
   113         int value = atoi(scanner_.literal());
   114         return new (pool_) IntegerLiteral(scanner_.begin(), value);
   115       }
   116 
   117       case TOK_TRUE:
   118       case TOK_FALSE:
   119         scanner_.scan();
   120         return new (pool_) BooleanLiteral(scanner_.begin(), kind);
   121 
   122       case TOK_STRING_LITERAL:
   123       {
   124         scanner_.scan();
   125         Local<String> string(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   126         return new (pool_) StringLiteral(scanner_.begin(), string);
   127       }
   128 
   129       default:
   130       {
   131         if (kind != TOK_ERROR)
   132             cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
   133         return NULL;
   134       }
   135     }
   136 }
   137 
   138 Expression *
   139 Parser::fixedArrayLiteral()
   140 {
   141     SourcePosition pos = scanner_.begin();
   142 
   143     ExpressionList *list = new (pool_) ExpressionList();
   144     do {
   145         // { } is an illegal array literal.
   146         if (list->length() > 0 && match(TOK_LBRACE))
   147             break;
   148 
   149         Expression *expr = NULL;
   150         if (peek(TOK_LBRACE))
   151             expr = fixedArrayLiteral();
   152         else
   153             expr = primitive();
   154         if (!expr)
   155             return NULL;
   156 
   157         if (!list->append(expr))
   158             return NULL;
   159 
   160         if (!match(TOK_COMMA)) {
   161             if (!expect(TOK_RBRACE))
   162                 return NULL;
   163             break;
   164         }
   165     } while (true);
   166 
   167     return new (pool_) ArrayLiteral(pos, TOK_LBRACE, list);
   168 }
   169 
   170 Expression *
   171 Parser::prefix()
   172 {
   173     switch (scanner_.peek()) {
   174       case TOK_LPAREN:
   175       {
   176         scanner_.scan();
   177         Expression *expr = expression();
   178         if (!expr)
   179             return NULL;
   180         if (!expect(TOK_RPAREN))
   181             return NULL;
   182         return expr;
   183       }
   184 
   185       case TOK_NAME:
   186       {
   187         Local<String> name(zone_, expectName());
   188         if (!name)
   189             return NULL;
   190         return new (pool_) NameProxy(scanner_.begin(), name);
   191       }
   192 
   193       default:
   194         return primitive();
   195     }
   196 }
   197 
   198 // Parses only old-style declarations.
   199 bool
   200 Parser::typeAndName(Expression **type, String **namep)
   201 {
   202     if (match(TOK_LABEL)) {
   203         // Old-style declaration:
   204         //   new X:type
   205         Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   206         if (!name)
   207             return false;
   208 
   209         *type = new (pool_) NameProxy(scanner_.begin(), name);
   210         *namep = expectName();
   211         return !!*namep;
   212     }
   213     
   214     *type = NULL;
   215     *namep = expectName();
   216 
   217     return !!*namep;
   218 }
   219 
   220 // Parses both old and new style declarations.
   221 bool
   222 Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
   223 {
   224     //   decl    ::= newdecl | olddecl
   225     //   newdecl ::= Type Ident
   226     //   olddecl ::= Label? (Ident | "...")
   227     //   type    ::= Ident
   228     //   label   ::= Ident ":"
   229     //
   230     if (match(TOK_LABEL)) {
   231         // We something of the form:
   232         //     Label Ident
   233         // or: Label "..."
   234         Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   235         if (!name)
   236             return false;
   237 
   238         *type = new (pool_) NameProxy(scanner_.begin(), name);
   239         if (kind == DeclArg && match(TOK_ELLIPSES)) {
   240             *namep = NULL;
   241         } else {
   242             if ((*namep = expectName()) == NULL)
   243                 return false;
   244         }
   245         return true;
   246     }
   247 
   248     Local<String> name(zone_, expectName());
   249     if (!name)
   250         return false;
   251 
   252     if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
   253         // We got something of the form:
   254         //    Ident Ident
   255         *type = new (pool_) NameProxy(scanner_.begin(), name);
   256         if (peek(TOK_NAME)) {
   257             if ((*namep = expectName()) == NULL)
   258                 return false;
   259         } else {
   260             *namep = NULL;
   261         }
   262         return true;
   263     }
   264 
   265     // We got something of the form:
   266     //    Ident
   267     *type = NULL;
   268     *namep = name;
   269     return true;
   270 }
   271 
   272 Expression *
   273 Parser::call(Expression *callee)
   274 {
   275     ExpressionList *arguments = new (pool_) ExpressionList();
   276 
   277     SourcePosition pos = scanner_.begin();
   278     expect(TOK_LPAREN);
   279     
   280     if (!match(TOK_RPAREN)) {
   281         while (true) {
   282             Expression *expr = expression();
   283             if (!expr)
   284                 return NULL;
   285 
   286             if (!arguments->append(expr))
   287                 return NULL;
   288 
   289             if (!match(TOK_COMMA))
   290                 break;
   291         }
   292 
   293         if (!expect(TOK_RPAREN))
   294             return NULL;
   295     }
   296 
   297     return new (pool_) CallExpression(pos, callee, arguments);
   298 }
   299 
   300 Expression *
   301 Parser::index(Expression *left)
   302 {
   303     expect(TOK_LBRACKET);
   304     
   305     SourcePosition pos = scanner_.begin();
   306     Expression *expr = expression();
   307     if (!expr)
   308         return NULL;
   309 
   310     if (!expect(TOK_RBRACKET))
   311         return NULL;
   312 
   313     return new (pool_) IndexExpression(pos, left, expr);
   314 }
   315 
   316 Expression *
   317 Parser::field(Expression *left)
   318 {
   319     expect(TOK_DOT);
   320 
   321     SourcePosition pos = scanner_.begin();
   322     Local<String> name(zone_, expectName());
   323     if (!name)
   324         return NULL;
   325 
   326     return new (pool_) FieldExpression(pos, left, name);
   327 }
   328 
   329 Expression *
   330 Parser::primary()
   331 {
   332     Expression *expr = prefix();
   333     if (!expr)
   334         return NULL;
   335 
   336     for (;;) {
   337         switch (scanner_.peek()) {
   338           case TOK_LPAREN:
   339             if ((expr = call(expr)) == NULL)
   340                 return NULL;
   341             break;
   342 
   343           case TOK_LBRACKET:
   344             if ((expr = index(expr)) == NULL)
   345                 return NULL;
   346             break;
   347 
   348           case TOK_DOT:
   349             if ((expr = field(expr)) == NULL)
   350                 return NULL;
   351             break;
   352 
   353           default:
   354             return expr;
   355         }
   356     }
   357 }
   358 
   359 Expression *
   360 Parser::unary()
   361 {
   362     TokenKind token = scanner_.peek();
   363 
   364     SourcePosition pos = scanner_.begin();
   365     switch (token) {
   366       case TOK_INCREMENT:
   367       case TOK_DECREMENT:
   368       {
   369         scanner_.scan();
   370         Expression *expr = unary();
   371         if (!expr)
   372             return NULL;
   373         return new (pool_) IncDecExpression(pos, token, expr, false);
   374       }
   375 
   376       case TOK_MINUS:
   377       case TOK_NOT:
   378       case TOK_TILDE:
   379       {
   380         scanner_.scan();
   381         Expression *expr = unary();
   382         if (!expr)
   383             return NULL;
   384         return new (pool_) UnaryExpression(pos, token, expr);
   385       }
   386 
   387       case TOK_SIZEOF:
   388       {
   389         scanner_.scan();
   390         if (!expect(TOK_LPAREN))
   391             return NULL;
   392         Expression *expr = unary();
   393         if (!expr)
   394             return NULL;
   395         if (!expect(TOK_RPAREN))
   396             return NULL;
   397         return new (pool_) UnaryExpression(pos, token, expr);
   398       }
   399 
   400       case TOK_LABEL:
   401       {
   402         scanner_.scan();
   403         Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   404         if (!tag)
   405             return NULL;
   406 
   407         NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
   408 
   409         Expression *expr = unary();
   410         if (!expr)
   411             return NULL;
   412 
   413         return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
   414       }
   415 
   416       default:
   417         break;
   418     }
   419 
   420     Expression *expr = primary();
   421 
   422     token = scanner_.peek();
   423     if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
   424         scanner_.scan();
   425         return new (pool_) IncDecExpression(pos, token, expr, true);
   426     }
   427 
   428     return expr;
   429 }
   430 
   431 Expression *
   432 Parser::multiplication()
   433 {
   434     Expression *left = unary();
   435     do {
   436         if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
   437             break;
   438         SourcePosition pos = scanner_.begin();
   439         TokenKind kind = scanner_.last();
   440         Expression *right = unary();
   441         if (!right)
   442             return NULL;
   443         left = new (pool_) BinaryExpression(pos, kind, left, right);
   444     } while (left);
   445     return left;
   446 }
   447 
   448 Expression *
   449 Parser::addition()
   450 {
   451     Expression *left = multiplication();
   452     while (left) {
   453         if (!match(TOK_PLUS) && !match(TOK_MINUS))
   454             break;
   455         SourcePosition pos = scanner_.begin();
   456         TokenKind kind = scanner_.last();
   457         Expression *right = multiplication();
   458         if (!right)
   459             return NULL;
   460         left = new (pool_) BinaryExpression(pos, kind, left, right);
   461     }
   462     return left;
   463 }
   464 
   465 Expression *
   466 Parser::shift()
   467 {
   468     Expression *left = addition();
   469     while (left) {
   470         if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
   471             break;
   472         SourcePosition pos = scanner_.begin();
   473         TokenKind kind = scanner_.last();
   474         Expression *right = addition();
   475         if (!right)
   476             return NULL;
   477         left = new (pool_) BinaryExpression(pos, kind, left, right);
   478     }
   479     return left;
   480 }
   481 
   482 Expression *
   483 Parser::bitand_()
   484 {
   485     Expression *left = shift();
   486     while (left) {
   487         if (!match(TOK_BITAND))
   488             break;
   489         SourcePosition pos = scanner_.begin();
   490         Expression *right = shift();
   491         if (!right)
   492             return NULL;
   493         left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
   494     }
   495     return left;
   496 }
   497 
   498 Expression *
   499 Parser::bitxor()
   500 {
   501     Expression *left = bitand_();
   502     while (left) {
   503         if (!match(TOK_BITXOR))
   504             break;
   505         SourcePosition pos = scanner_.begin();
   506         Expression *right = shift();
   507         if (!right)
   508             return NULL;
   509         left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
   510     }
   511     return left;
   512 }
   513 
   514 Expression *
   515 Parser::bitor_()
   516 {
   517     Expression *left = bitxor();
   518     while (left) {
   519         if (!match(TOK_BITOR))
   520             break;
   521         SourcePosition pos = scanner_.begin();
   522         Expression *right = bitxor();
   523         if (!right)
   524             return NULL;
   525         left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
   526     }
   527     return left;
   528 }
   529 
   530 Expression *
   531 Parser::relational()
   532 {
   533     Expression *left = bitor_();
   534     while (left) {
   535         TokenKind kind = scanner_.peek();
   536         if (kind < TOK_LT || kind > TOK_GE)
   537             break;
   538         scanner_.scan();
   539         SourcePosition pos = scanner_.begin();
   540         Expression *right = shift();
   541         if (!right)
   542             return NULL;
   543         left = new (pool_) BinaryExpression(pos, kind, left, right);
   544     }
   545     return left;
   546 }
   547 
   548 Expression *
   549 Parser::equals()
   550 {
   551     Expression *left = relational();
   552     while (left) {
   553         if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   554             break;
   555         TokenKind kind = scanner_.last();
   556         SourcePosition pos = scanner_.begin();
   557         Expression *right = relational();
   558         if (!right)
   559             return NULL;
   560         left = new (pool_) BinaryExpression(pos, kind, left, right);
   561     }
   562     return left;
   563 }
   564 
   565 Expression *
   566 Parser::and_()
   567 {
   568     Expression *left = equals();
   569     while (left) {
   570         if (!match(TOK_AND))
   571             break;
   572         SourcePosition pos = scanner_.begin();
   573         Expression *right = equals();
   574         if (!right)
   575             return NULL;
   576         left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
   577     }
   578     return left;
   579 }
   580 
   581 Expression *
   582 Parser::or_()
   583 {
   584     Expression *left = and_();
   585     while (left) {
   586         if (!match(TOK_OR))
   587             break;
   588         SourcePosition pos = scanner_.begin();
   589         Expression *right = and_();
   590         if (!right)
   591             return NULL;
   592         left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
   593     }
   594     return left;
   595 }
   596 
   597 Expression *
   598 Parser::ternary()
   599 {
   600     Expression *cond = or_();
   601     if (!cond)
   602         return NULL;
   603     
   604     if (!match(TOK_QMARK))
   605         return cond;
   606 
   607     Expression *left;
   608     SourcePosition pos = scanner_.begin();
   609     AutoAllowTags<false> disableTags(scanner_);
   610     {
   611         if ((left = expression()) == NULL)
   612             return NULL;
   613     }
   614 
   615     if (!expect(TOK_COLON))
   616         return NULL;
   617 
   618     Expression *right = expression();
   619     if (!right)
   620         return NULL;
   621 
   622     return new (pool_) TernaryExpression(pos, cond, left, right);
   623 }
   624 
   625 Expression *
   626 Parser::assignment()
   627 {
   628     Expression *left = ternary();
   629     while (left) {
   630         TokenKind token = scanner_.peek();
   631         if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
   632             break;
   633         scanner_.scan();
   634         SourcePosition pos = scanner_.begin();
   635         Expression *expr = ternary();
   636         if (!expr)
   637             return NULL;
   638 
   639         left = new (pool_) Assignment(pos, token, left, expr);
   640     }
   641     return left;
   642 }
   643 
   644 Expression *
   645 Parser::expression()
   646 {
   647     return assignment();
   648 }
   649 
   650 Statement *
   651 Parser::while_()
   652 {
   653     // while ::= "while" "(" expr ")" statement
   654     SourcePosition pos = scanner_.begin();
   655     scanner_.scan();
   656 
   657     if (!expect(TOK_LPAREN))
   658         return NULL;
   659 
   660     Expression *condition = expression();
   661     if (!condition)
   662         return NULL;
   663 
   664     if (!expect(TOK_RPAREN))
   665         return NULL;
   666 
   667     Statement *body;
   668     if (scanner_.peek() == TOK_LBRACE)
   669         body = block();
   670     else
   671         body = localStatement();
   672     if (!body)
   673         return NULL;
   674 
   675     return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
   676 }
   677 
   678 Statement *
   679 Parser::do_()
   680 {
   681     // do ::= "do" block "while" "(" expr ")"
   682     SourcePosition pos = scanner_.begin();
   683     scanner_.scan();
   684 
   685     Statement *body = block();
   686     if (!body)
   687         return NULL;
   688 
   689     if (!expect(TOK_WHILE))
   690         return NULL;
   691 
   692     if (!expect(TOK_LPAREN))
   693         return NULL;
   694     Expression *condition = expression();
   695     if (!condition)
   696         return NULL;
   697     if (!expect(TOK_RPAREN))
   698         return NULL;
   699 
   700     return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
   701 }
   702 
   703 Statement *
   704 Parser::switch_()
   705 {
   706     // switch ::= "switch" "(" expr ")" "{" case* defaultcase? "}"
   707     // case ::= "case" casevals ":" statement
   708     // defaultcase ::= "default" ":" statement
   709     //
   710     expect(TOK_SWITCH);
   711 
   712     SourcePosition pos = scanner_.begin();
   713 
   714     if (!expect(TOK_LPAREN))
   715         return NULL;
   716     Expression *expr = expression();
   717     if (!expr)
   718         return NULL;
   719     if (!expect(TOK_RPAREN))
   720         return NULL;
   721 
   722     if (!expect(TOK_LBRACE))
   723         return NULL;
   724 
   725     SourcePosition defaultPos;
   726     PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
   727 
   728     Statement *defaultCase = NULL;
   729 
   730     while (!peek(TOK_RBRACE)) {
   731         Expression *expr = NULL;
   732         ExpressionList *others = NULL;
   733         if (match(TOK_DEFAULT)) {
   734             if (defaultCase) {
   735                 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
   736                 return NULL;
   737             }
   738 
   739             defaultPos = scanner_.begin();
   740         } else {
   741             if (defaultCase) {
   742                 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
   743                 return NULL;
   744             }
   745 
   746             if (!expect(TOK_CASE))
   747                 return NULL;
   748 
   749             // A limitation in the grammar is that |case <NAME>:| will be
   750             // detected as a label.
   751             AutoAllowTags<false> disableTags(scanner_);
   752 
   753             if ((expr = expression()) == NULL)
   754                 return NULL;
   755 
   756             if (peek(TOK_COMMA)) {
   757                 others = new (pool_) ExpressionList();
   758                 while (match(TOK_COMMA)) {
   759                     Expression *other = expression();
   760                     if (!other)
   761                         return NULL;
   762                     if (!others->append(other))
   763                         return NULL;
   764                 }
   765             }
   766         }
   767 
   768         if (!expect(TOK_COLON))
   769             return NULL;
   770 
   771         Statement *statement = localStatement();
   772         if (!statement)
   773             return NULL;
   774 
   775         if (!peek(TOK_CASE) &&
   776             !peek(TOK_DEFAULT) &&
   777             !peek(TOK_RBRACE))
   778         {
   779             cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
   780             return NULL;
   781         }
   782 
   783         if (expr) {
   784             Case *caze = new (pool_) Case(expr, others, statement);
   785             if (!cases->append(caze))
   786                 return NULL;
   787         } else {
   788             defaultCase = statement;
   789         }
   790     }
   791 
   792     if (!expect(TOK_RBRACE))
   793         return NULL;
   794 
   795     return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
   796 }
   797 
   798 Statement *
   799 Parser::forStatement()
   800 {
   801     // for ::= "for" "(" forinit? ";" forcond? ";" forstep ")" statement
   802     // forint ::= "new" vardecl |
   803     //            exprstmt
   804     // forcond ::= expr
   805     // forstep ::= exprstmt
   806     //
   807     SourcePosition pos = scanner_.begin();
   808     scanner_.scan();
   809     if (!expect(TOK_LPAREN))
   810         return NULL;
   811 
   812     Statement *decl = NULL;
   813     if (!match(TOK_SEMICOLON)) {
   814         if (match(TOK_NEW)) {
   815             if ((decl = vars(TypeQual_None)) == NULL)
   816                 return NULL;
   817         } else {
   818             if ((decl = expressionStatement()) == NULL)
   819                 return NULL;
   820         }
   821         if (!expect(TOK_SEMICOLON))
   822             return NULL;
   823     }
   824 
   825     Expression *condition = NULL;
   826     if (!match(TOK_SEMICOLON)) {
   827         if ((condition = expression()) == NULL)
   828             return NULL;
   829         if (!expect(TOK_SEMICOLON))
   830             return NULL;
   831     }
   832 
   833     Statement *update = NULL;
   834     if (!match(TOK_RPAREN)) {
   835         if ((update = expressionStatement()) == NULL)
   836             return NULL;
   837         if (!expect(TOK_RPAREN))
   838             return NULL;
   839     }
   840 
   841     Statement *body;
   842     if (scanner_.peek() == TOK_LBRACE)
   843         body = block();
   844     else
   845         body = localStatement();
   846     if (!body)
   847         return NULL;
   848 
   849     return new (pool_) ForStatement(pos, decl, condition, update, body);
   850 }
   851 
   852 ExpressionList *
   853 Parser::dimensions()
   854 {
   855     // dimensions ::= ("[" expr? "]")*
   856 
   857     ExpressionList *postDimensions = new (pool_) ExpressionList();
   858     while (match(TOK_LBRACKET)) {
   859         Expression *dim = NULL;
   860         if (!match(TOK_RBRACKET)) {
   861             if ((dim = expression()) == NULL)
   862                 return NULL;
   863             if (!expect(TOK_RBRACKET))
   864                 return NULL;
   865         }
   866 
   867         if (!postDimensions->append(dim))
   868             return NULL;
   869     }
   870     return postDimensions;
   871 }
   872 
   873 VariableDeclaration *
   874 Parser::var(TypeQualifiers qual)
   875 {
   876     // vardecl ::= decl ("=" expr)?
   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 (peek(TOK_LBRACKET)) {
   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             scanner_.scan();
   898             if ((expr = fixedArrayLiteral()) == NULL)
   899                 return NULL;
   900             break;
   901 
   902           default:
   903             if ((expr = expression()) == NULL)
   904                 return NULL;
   905             break;
   906         }
   907     }
   908 
   909     return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
   910 }
   911 
   912 Statement *
   913 Parser::vars(TypeQualifiers qual)
   914 {
   915     // localvars ::= ("new" | "const" | "decl") vardecl ("," vardecl)*
   916     // globalvars ::= ("public" | "const" | "new" | "public" "const") vardecl
   917     VariableDeclaration *decl = var(qual);
   918     if (!decl)
   919         return NULL;
   920 
   921     if (!peek(TOK_COMMA))
   922         return decl;
   923 
   924     StatementList *statements = new (pool_) StatementList();
   925     if (!statements->append(decl))
   926         return NULL;
   927 
   928     while (match(TOK_COMMA)) {
   929         Statement *decl = var(qual);
   930         if (!decl)
   931             return NULL;
   932         if (!statements->append(decl))
   933             return NULL;
   934     }
   935 
   936     // Create a fake-o block with no scope to create a statement list.
   937     return new (pool_) BlockStatement(decl->pos(), statements, TOK_NEW);
   938 }
   939 
   940 Statement *
   941 Parser::returnStatement()
   942 {
   943     // return ::= "return" term |
   944     //            "return" "expr"
   945 
   946     SourcePosition pos = scanner_.begin();
   947     if (!expect(TOK_RETURN))
   948         return NULL;
   949 
   950     Expression *expr = NULL;
   951     if (scanner_.peek() != TOK_SEMICOLON) {
   952         if ((expr = expression()) == NULL)
   953             return NULL;
   954 
   955         // We only care about non-void returns when determining whether a
   956         // tagless function is non-void.
   957         encounteredReturn_ = true;
   958     }
   959 
   960     return new (pool_) ReturnStatement(pos, expr);
   961 }
   962 
   963 Statement *
   964 Parser::expressionStatement()
   965 {
   966     // exprstmt ::= expr
   967     Expression *left = assignment();
   968     if (!left)
   969         return NULL;
   970 
   971     return new (pool_) ExpressionStatement(left);
   972 }
   973 
   974 Statement *
   975 Parser::block()
   976 {
   977     // block ::= "{" statement* "}"
   978 
   979     if (!expect(TOK_LBRACE))
   980         return NULL;
   981 
   982     SourcePosition pos = scanner_.begin();
   983 
   984     StatementList *statements = new (pool_) StatementList();
   985     while (!match(TOK_RBRACE)) {
   986         Statement *statement = localStatement();
   987         if (statement == NULL)
   988             return NULL;
   989         if (!statements->append(statement))
   990             return NULL;
   991     }
   992 
   993     BlockStatement *block = new (pool_) BlockStatement(pos, statements, TOK_LBRACE);
   994     return block;
   995 }
   996 
   997 Statement *
   998 Parser::if_()
   999 {
  1000     // if ::= "if" "(" expr ")" statement elseif* else?
  1001     // elseif ::= "elseif" "(" expr ")" statement
  1002     // else ::= "else" statement
  1003     expect(TOK_IF);
  1004   
  1005     SourcePosition pos = scanner_.begin();
  1006     if (!expect(TOK_LPAREN))
  1007         return NULL;
  1008 
  1009     Expression *cond = expression();
  1010     if (!cond)
  1011         return NULL;
  1012 
  1013     if (!expect(TOK_RPAREN))
  1014         return NULL;
  1015 
  1016     Statement *ifTrue = localStatement();
  1017     if (!ifTrue)
  1018         return NULL;
  1019 
  1020     IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
  1021 
  1022     IfStatement *last = outer;
  1023     while (match(TOK_ELSE)) {
  1024         if (!match(TOK_IF)) {
  1025             Statement *ifFalse = localStatement();
  1026             if (!ifFalse)
  1027                 return NULL;
  1028 
  1029             last->setIfFalse(ifFalse);
  1030             break;
  1031         }
  1032 
  1033         SourcePosition pos = scanner_.begin();
  1034         if (!expect(TOK_LPAREN))
  1035             return NULL;
  1036 
  1037         Expression *otherCond = expression();
  1038         if (!otherCond)
  1039             return NULL;
  1040 
  1041         if (!expect(TOK_RPAREN))
  1042             return NULL;
  1043 
  1044         Statement *otherIfTrue = localStatement();
  1045         if (!otherIfTrue)
  1046             return NULL;
  1047 
  1048         IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
  1049         last->setIfFalse(inner);
  1050         last = inner;
  1051     }
  1052 
  1053     return outer;
  1054 }
  1055 
  1056 Statement *
  1057 Parser::localStatement()
  1058 {
  1059     // statement ::= stmt term
  1060     // stmt ::= do | for | if | while | struct | enum |
  1061     //          localvars | return | switch | break | continue
  1062 
  1063     Statement *statement = NULL;
  1064 
  1065     // Statements which must be followed by a semicolon will break out of the
  1066     // switch. If they may end in BlockStatements, they'll immediately return.
  1067 
  1068     TokenKind kind = scanner_.peek();
  1069     switch (kind) {
  1070       case TOK_CONST:
  1071       case TOK_NEW:
  1072       {
  1073         TypeQualifiers quals = (kind == TOK_CONST)
  1074                               ? TypeQual_Const
  1075                               : TypeQual_None;
  1076         scanner_.scan();
  1077         if ((statement = vars(quals)) == NULL)
  1078           return NULL;
  1079         break;
  1080       }
  1081 
  1082       case TOK_FOR:
  1083         return forStatement();
  1084 
  1085       case TOK_WHILE:
  1086         return while_();
  1087 
  1088       case TOK_BREAK:
  1089         scanner_.scan();
  1090         statement = new (pool_) BreakStatement(scanner_.begin());
  1091         break;
  1092 
  1093       case TOK_CONTINUE:
  1094         scanner_.scan();
  1095         statement = new (pool_) ContinueStatement(scanner_.begin());
  1096         break;
  1097 
  1098       case TOK_DO:
  1099         if ((statement = do_()) == NULL)
  1100             return NULL;
  1101         break;
  1102 
  1103       case TOK_RETURN:
  1104         if ((statement = returnStatement()) == NULL)
  1105           return NULL;
  1106         break;
  1107 
  1108       case TOK_ENUM:
  1109         if ((statement = enum_()) == NULL)
  1110           return NULL;
  1111         break;
  1112 
  1113       case TOK_STRUCT:
  1114         if ((statement = struct_()) == NULL)
  1115           return NULL;
  1116         break;
  1117 
  1118       case TOK_SWITCH:
  1119         return switch_();
  1120 
  1121       case TOK_IF:
  1122         return if_();
  1123 
  1124       case TOK_LBRACE:
  1125         return block();
  1126 
  1127       default:
  1128         break;
  1129     }
  1130 
  1131     if (!statement) {
  1132         if ((statement = expressionStatement()) == NULL)
  1133             return NULL;
  1134     }
  1135 
  1136     if (!expect(TOK_SEMICOLON))
  1137         return NULL;
  1138 
  1139     return statement;
  1140 }
  1141 
  1142 Statement *
  1143 Parser::struct_()
  1144 {
  1145     // struct ::= "struct" name { struct_fields }
  1146     // struct_fields ::= struct_field |
  1147     //                   struct_field struct_fields
  1148     // struct_field ::= label? name term
  1149     expect(TOK_STRUCT);
  1150 
  1151     Local<String> name(zone_, expectName());
  1152     if (!name)
  1153         return NULL;
  1154 
  1155     SourcePosition pos = scanner_.begin();
  1156 
  1157     if (!expect(TOK_LBRACE))
  1158         return NULL;
  1159 
  1160     FieldList *fields = new (pool_) FieldList();
  1161 
  1162     while (!peek(TOK_RBRACE)) {
  1163         Expression *type;
  1164         Local<String> fieldName(zone_);
  1165 
  1166         if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
  1167             return NULL;
  1168 
  1169         SourcePosition pos = scanner_.begin();
  1170 
  1171         if (!matchSemicolon())
  1172             return NULL;
  1173 
  1174         StructureStatement::Field *field =
  1175             new (pool_) StructureStatement::Field(pos, type, fieldName);
  1176         if (!field || !fields->append(field))
  1177             return NULL;
  1178     }
  1179 
  1180     if (!expect(TOK_RBRACE))
  1181         return NULL;
  1182 
  1183     if (fields->empty()) {
  1184         cc_.reportError(pos, Message_StructCantBeEmpty);
  1185         return NULL;
  1186     }
  1187 
  1188     return new (pool_) StructureStatement(pos, name, fields);
  1189 }
  1190 
  1191 Statement *
  1192 Parser::enum_()
  1193 {
  1194     // enum ::= "enum" name? { enum_members? }
  1195     // enum_members ::= enum_member ","? |
  1196     //                  enum_member "," enum_members
  1197     // enum_member ::= ident ("=" constexpr)?
  1198     expect(TOK_ENUM);
  1199 
  1200     SourcePosition pos = scanner_.begin();
  1201 
  1202     Local<String> name(zone_);
  1203     if (matchName(name.ref()) && !name)
  1204         return NULL;
  1205 
  1206     EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
  1207 
  1208     if (!expect(TOK_LBRACE))
  1209         return NULL;
  1210 
  1211     do {
  1212         if (scanner_.peek() == TOK_RBRACE)
  1213             break;
  1214 
  1215         SourcePosition pos = scanner_.begin();
  1216         Local<String> name(zone_, expectName());
  1217         if (!name)
  1218             return NULL;
  1219 
  1220         Expression *expr = NULL;
  1221         if (match(TOK_ASSIGN)) {
  1222             if ((expr = expression()) == NULL)
  1223                 return NULL;
  1224         }
  1225 
  1226         if (!entries->append(EnumStatement::Entry(name, expr, pos)))
  1227             return NULL;
  1228     } while (match(TOK_COMMA));
  1229     if (!expect(TOK_RBRACE))
  1230         return NULL;
  1231 
  1232     return new (pool_) EnumStatement(pos, name, entries);
  1233 }
  1234 
  1235 template <class T>
  1236 static inline ScopedRoot<T> *
  1237 NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
  1238 {
  1239     return new (pool) ScopedRoot<T>(obj);
  1240 }
  1241 
  1242 ImportStatement *
  1243 Parser::import()
  1244 {
  1245     SourcePosition pos = scanner_.begin();
  1246 
  1247     // import       ::= import_path
  1248     // import_path  ::= name |
  1249     //                  name "." import_path
  1250 
  1251     Local<String> name(zone_, expectName());
  1252     if (!name)
  1253         return NULL;
  1254 
  1255     PathComponent *root = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
  1256     PathComponent *current = root;
  1257 
  1258     TokenKind suffix = TOK_NONE;
  1259     while (match(TOK_DOT)) {
  1260         if ((name = expectName()) == NULL)
  1261             return NULL;
  1262 
  1263         current->next = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
  1264         current = current->next;
  1265     }
  1266 
  1267     return new (pool_) ImportStatement(pos, root);
  1268 }
  1269 
  1270 Statement *
  1271 Parser::function(TokenKind token)
  1272 {
  1273     Expression *returnType;
  1274     Local<String> name(zone_);
  1275 
  1276     if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
  1277         return NULL;
  1278 
  1279     SourcePosition pos = scanner_.begin();
  1280     ParameterList *parameters = new (pool_) ParameterList();
  1281 
  1282     if (!expect(TOK_LPAREN))
  1283         return NULL;
  1284 
  1285     bool variadic = false;
  1286 
  1287     if (!match(TOK_RPAREN)) {
  1288         while (true) {
  1289             TypeQualifiers quals = TypeQual_None;
  1290             if (match(TOK_CONST))
  1291                 quals = TypeQualifiers(quals | TypeQual_Const);
  1292 
  1293             bool ref = match(TOK_AMPERSAND);
  1294 
  1295             SourcePosition begin = scanner_.begin();
  1296             Expression *type;
  1297             Local<String> name(zone_);
  1298             if (!fullTypeAndName(&type, name.ref(), DeclArg))
  1299                 return NULL;
  1300 
  1301             if (!name) {
  1302                 if ((quals & TypeQual_Const) || ref) {
  1303                     cc_.reportError(begin, Message_InvalidVarArgs);
  1304                     return NULL;
  1305                 }
  1306 
  1307                 if (token != TOK_NATIVE) {
  1308                     cc_.reportError(begin, Message_VarArgsOutsideNative);
  1309                     return NULL;
  1310                 }
  1311 
  1312                 variadic = true;
  1313                 break;
  1314             }
  1315 
  1316             ExpressionList *dims = NULL;
  1317             if (peek(TOK_LBRACKET)) {
  1318                 if ((dims = dimensions()) == NULL)
  1319                     return NULL;
  1320             }
  1321 
  1322             Expression *expr = NULL;
  1323             if (match(TOK_ASSIGN)) {
  1324                 if ((expr = expression()) == NULL)
  1325                     return NULL;
  1326             }
  1327 
  1328             Parameter *parameter = new (pool_) Parameter(name, type, ref, quals, dims, expr, begin);
  1329             if (!parameters->append(parameter))
  1330                 return NULL;
  1331 
  1332             if (!match(TOK_COMMA))
  1333                 break;
  1334         }
  1335         if (!expect(TOK_RPAREN))
  1336             return NULL;
  1337     }
  1338 
  1339     encounteredReturn_ = false;
  1340 
  1341     Statement *body = NULL;
  1342     if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
  1343         body = block();
  1344         if (!body)
  1345             return NULL;
  1346     }
  1347 
  1348     FunctionSignature signature(returnType, parameters, variadic);
  1349     if (token == TOK_TYPEDEF)
  1350         return new (pool_) FunctionTypeStatement(pos, name, signature);
  1351 
  1352     return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
  1353 }
  1354 
  1355 static inline bool
  1356 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
  1357 {
  1358     Local<String> tag(zone, zone->makeSymbol(name));
  1359     if (!tag)
  1360         return false;
  1361 
  1362     assert(false);
  1363     return false; //return !!scope->declareType(tag, type);
  1364 }
  1365 
  1366 static inline bool
  1367 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
  1368 {
  1369     Local<Type> primitive(zone, zone->types()->getPrimitive(type));
  1370     assert(primitive);
  1371     return DeclareIntrinsicType(zone, scope, name, primitive);
  1372 }
  1373 
  1374 ParseTree *
  1375 Parser::parse()
  1376 {
  1377     StatementList *statements = new (pool_) StatementList();
  1378 
  1379     for (;;) {
  1380         Statement *statement = NULL;
  1381 
  1382         TokenKind kind = scanner_.peek();
  1383         switch (kind) {
  1384           case TOK_ERROR:
  1385             return NULL;
  1386 
  1387           case TOK_EOF:
  1388             break;
  1389 
  1390           case TOK_NAME:
  1391             if ((statement = function(TOK_NAME)) == NULL)
  1392                 return NULL;
  1393             break;
  1394 
  1395           case TOK_IMPORT:
  1396           {
  1397             scanner_.scan();
  1398             if (statements->length())
  1399                 cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
  1400             ImportStatement *stmt = import();
  1401             if (!stmt)
  1402                 return NULL;
  1403             if (!imports_->append(stmt))
  1404                 return NULL;
  1405             if (!matchSemicolon())
  1406                 return NULL;
  1407             continue;
  1408           }
  1409 
  1410           case TOK_FORWARD:
  1411           case TOK_PUBLIC:
  1412           case TOK_NATIVE:
  1413           case TOK_STOCK:
  1414           case TOK_LABEL:
  1415           case TOK_TYPEDEF:
  1416           {
  1417             if (kind != TOK_LABEL)
  1418                 scanner_.scan();
  1419             if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
  1420                 if ((statement = var(TypeQual_Const)) == 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_CONST) ? TypeQual_Const : TypeQual_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 }