src/compiler/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Sat Jan 12 16:26:09 2013 -0800 (2013-01-12)
changeset 259 99ab8b19f0b9
parent 258 241d082d6d89
child 261 219b49bf4a03
permissions -rw-r--r--
Add |from x import names| support.
     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(TokenKind kind)
  1244 {
  1245     SourcePosition pos = scanner_.begin();
  1246 
  1247     // import       ::= "from" import_path "import" import_names
  1248     //                | "import" import_path
  1249     //                | "import" import_path ".*"
  1250     // import_path  ::= name
  1251     //                | name "." import_path
  1252     // import_names ::= "*"
  1253     //                | import_name_list
  1254     // import_name_list ::= name
  1255     //                    | name "," import_name_list
  1256 
  1257     Local<String> name(zone_, expectName());
  1258     if (!name)
  1259         return NULL;
  1260 
  1261     PathComponent *root = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
  1262     PathComponent *current = root;
  1263 
  1264     // NULL namelist means that we do not import any names. An empty namelist
  1265     // means we import all names.
  1266     NameList *names = NULL;
  1267 
  1268     while (match(TOK_DOT)) {
  1269         if (kind == TOK_IMPORT && match(TOK_STAR)) {
  1270             names = new (pool_) NameList();
  1271             break;
  1272         }
  1273 
  1274         if ((name = expectName()) == NULL)
  1275             return NULL;
  1276 
  1277         current->next = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
  1278         current = current->next;
  1279     }
  1280 
  1281     if (kind == TOK_FROM) {
  1282         if (!expect(TOK_IMPORT))
  1283             return NULL;
  1284 
  1285         names = new (pool_) NameList();
  1286 
  1287         if (!match(TOK_STAR)) {
  1288             if (!matchName(name.address())) {
  1289                 cc_.reportError(scanner_.begin(), Message_BadImportFrom);
  1290                 return NULL;
  1291             }
  1292 
  1293             if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
  1294                 return NULL;
  1295 
  1296             while (match(TOK_COMMA)) {
  1297                 if ((name = expectName()) == NULL)
  1298                     return NULL;
  1299                 if (!names->append(NewScopedRoot<String>(pool_, name)))
  1300                     return NULL;
  1301             }
  1302         }
  1303     }
  1304 
  1305     return new (pool_) ImportStatement(pos, root, names);
  1306 }
  1307 
  1308 Statement *
  1309 Parser::function(TokenKind token)
  1310 {
  1311     Expression *returnType;
  1312     Local<String> name(zone_);
  1313 
  1314     if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
  1315         return NULL;
  1316 
  1317     SourcePosition pos = scanner_.begin();
  1318     ParameterList *parameters = new (pool_) ParameterList();
  1319 
  1320     if (!expect(TOK_LPAREN))
  1321         return NULL;
  1322 
  1323     bool variadic = false;
  1324 
  1325     if (!match(TOK_RPAREN)) {
  1326         while (true) {
  1327             TypeQualifiers quals = TypeQual_None;
  1328             if (match(TOK_CONST))
  1329                 quals = TypeQualifiers(quals | TypeQual_Const);
  1330 
  1331             bool ref = match(TOK_AMPERSAND);
  1332 
  1333             SourcePosition begin = scanner_.begin();
  1334             Expression *type;
  1335             Local<String> name(zone_);
  1336             if (!fullTypeAndName(&type, name.ref(), DeclArg))
  1337                 return NULL;
  1338 
  1339             if (!name) {
  1340                 if ((quals & TypeQual_Const) || ref) {
  1341                     cc_.reportError(begin, Message_InvalidVarArgs);
  1342                     return NULL;
  1343                 }
  1344 
  1345                 if (token != TOK_NATIVE) {
  1346                     cc_.reportError(begin, Message_VarArgsOutsideNative);
  1347                     return NULL;
  1348                 }
  1349 
  1350                 variadic = true;
  1351                 break;
  1352             }
  1353 
  1354             ExpressionList *dims = NULL;
  1355             if (peek(TOK_LBRACKET)) {
  1356                 if ((dims = dimensions()) == NULL)
  1357                     return NULL;
  1358             }
  1359 
  1360             Expression *expr = NULL;
  1361             if (match(TOK_ASSIGN)) {
  1362                 if ((expr = expression()) == NULL)
  1363                     return NULL;
  1364             }
  1365 
  1366             Parameter *parameter = new (pool_) Parameter(name, type, ref, quals, dims, expr, begin);
  1367             if (!parameters->append(parameter))
  1368                 return NULL;
  1369 
  1370             if (!match(TOK_COMMA))
  1371                 break;
  1372         }
  1373         if (!expect(TOK_RPAREN))
  1374             return NULL;
  1375     }
  1376 
  1377     encounteredReturn_ = false;
  1378 
  1379     Statement *body = NULL;
  1380     if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
  1381         body = block();
  1382         if (!body)
  1383             return NULL;
  1384     }
  1385 
  1386     FunctionSignature signature(returnType, parameters, variadic);
  1387     if (token == TOK_TYPEDEF)
  1388         return new (pool_) FunctionTypeStatement(pos, name, signature);
  1389 
  1390     return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
  1391 }
  1392 
  1393 static inline bool
  1394 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
  1395 {
  1396     Local<String> tag(zone, zone->makeSymbol(name));
  1397     if (!tag)
  1398         return false;
  1399 
  1400     assert(false);
  1401     return false; //return !!scope->declareType(tag, type);
  1402 }
  1403 
  1404 static inline bool
  1405 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
  1406 {
  1407     Local<Type> primitive(zone, zone->types()->getPrimitive(type));
  1408     assert(primitive);
  1409     return DeclareIntrinsicType(zone, scope, name, primitive);
  1410 }
  1411 
  1412 ParseTree *
  1413 Parser::parse()
  1414 {
  1415     StatementList *statements = new (pool_) StatementList();
  1416 
  1417     for (;;) {
  1418         Statement *statement = NULL;
  1419 
  1420         TokenKind kind = scanner_.peek();
  1421         switch (kind) {
  1422           case TOK_ERROR:
  1423             return NULL;
  1424 
  1425           case TOK_EOF:
  1426             break;
  1427 
  1428           case TOK_NAME:
  1429             if ((statement = function(TOK_NAME)) == NULL)
  1430                 return NULL;
  1431             break;
  1432 
  1433           case TOK_FROM:
  1434           case TOK_IMPORT:
  1435           {
  1436             scanner_.scan();
  1437             if (statements->length())
  1438                 cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
  1439             ImportStatement *stmt = import(kind);
  1440             if (!stmt)
  1441                 return NULL;
  1442             if (!imports_->append(stmt))
  1443                 return NULL;
  1444             if (!matchSemicolon())
  1445                 return NULL;
  1446             continue;
  1447           }
  1448 
  1449           case TOK_FORWARD:
  1450           case TOK_PUBLIC:
  1451           case TOK_NATIVE:
  1452           case TOK_STOCK:
  1453           case TOK_LABEL:
  1454           case TOK_TYPEDEF:
  1455           {
  1456             if (kind != TOK_LABEL)
  1457                 scanner_.scan();
  1458             if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
  1459                 if ((statement = var(TypeQual_Const)) == NULL)
  1460                     return NULL;
  1461                 if (!matchSemicolon())
  1462                     return NULL;
  1463             } else {
  1464                 if ((statement = function(kind)) == NULL)
  1465                     return NULL;
  1466                 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
  1467                     return NULL;
  1468             }
  1469             break;
  1470           }
  1471 
  1472           case TOK_CONST:
  1473           case TOK_NEW:
  1474           {
  1475             TypeQualifiers quals = (kind == TOK_CONST) ? TypeQual_Const : TypeQual_None;
  1476             // Note: at global scope, we don't accept comma-delimited
  1477             // declarations yet, to see if we can get away with forcing
  1478             // a nicer top-level style.
  1479             scanner_.scan();
  1480             if ((statement = var(quals)) == NULL)
  1481                 return NULL;
  1482             if (!matchSemicolon())
  1483                 return NULL;
  1484             break;
  1485           }
  1486 
  1487           case TOK_ENUM:
  1488             if ((statement = enum_()) == NULL)
  1489                 return NULL;
  1490             if (!matchSemicolon())
  1491                 return NULL;
  1492             break;
  1493 
  1494           case TOK_STRUCT:
  1495             if ((statement = struct_()) == NULL)
  1496                 return NULL;
  1497             if (!matchSemicolon())
  1498                 return NULL;
  1499             break;
  1500 
  1501           default:
  1502             cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
  1503             return NULL;
  1504         }
  1505 
  1506         if (!statement)
  1507             break;
  1508 
  1509         if (!statements->append(statement))
  1510             return NULL;
  1511     }
  1512 
  1513     return new (pool_) ParseTree(statements, unbound_, imports_);
  1514 }
  1515 
  1516 class AstPrinter : public AstVisitor
  1517 {
  1518     FILE *fp_;
  1519     size_t level_;
  1520 
  1521   private:
  1522     void prefix() {
  1523         for (size_t i = 0; i < level_; i++)
  1524             fprintf(fp_, "  ");
  1525     }
  1526     void indent() {
  1527         level_++;
  1528     }
  1529     void unindent() {
  1530         level_--;
  1531     }
  1532 
  1533   public:
  1534     AstPrinter(FILE *fp)
  1535       : fp_(fp),
  1536         level_(0)
  1537     {
  1538     }
  1539 
  1540     void dump(const FunctionSignature &sig) {
  1541         prefix();
  1542         fprintf(fp_, "()\n");
  1543     }
  1544     void visitNameProxy(NameProxy *name) {
  1545         prefix();
  1546         fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
  1547     }
  1548     void visitCallExpression(CallExpression *node) {
  1549         prefix();
  1550         fprintf(fp_, "[ CallExpression\n");
  1551         indent();
  1552         node->callee()->accept(this);
  1553         for (size_t i = 0; i < node->arguments()->length(); i++)
  1554             node->arguments()->at(i)->accept(this);
  1555         unindent();
  1556     }
  1557     void visitFunctionTypeStatement(FunctionTypeStatement *node) {
  1558         prefix();
  1559         fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
  1560         indent();
  1561         dump(node->signature());
  1562         unindent();
  1563     }
  1564     void visitFunctionStatement(FunctionStatement *node) {
  1565         prefix();
  1566         fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
  1567         indent();
  1568         dump(node->signature());
  1569         if (node->body())
  1570             node->body()->accept(this);
  1571         unindent();
  1572     }
  1573     void visitExpressionStatement(ExpressionStatement *node) {
  1574         prefix();
  1575         fprintf(fp_, "[ ExpressionStatement\n");
  1576         indent();
  1577         node->expression()->accept(this);
  1578         unindent();
  1579     }
  1580     void visitAssignment(Assignment *node) {
  1581         prefix();
  1582         fprintf(fp_, "[ Assignment\n");
  1583         indent();
  1584         node->lvalue()->accept(this);
  1585         node->expression()->accept(this);
  1586         unindent();
  1587     }
  1588     void visitTernaryExpression(TernaryExpression *node) {
  1589         prefix();
  1590         fprintf(fp_, "[ TernaryExpression\n");
  1591         indent();
  1592         node->condition()->accept(this);
  1593         node->left()->accept(this);
  1594         node->right()->accept(this);
  1595         unindent();
  1596     }
  1597     void visitBinaryExpression(BinaryExpression *node) {
  1598         prefix();
  1599         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
  1600         indent();
  1601         node->left()->accept(this);
  1602         node->right()->accept(this);
  1603         unindent();
  1604     }
  1605     void visitUnaryExpression(UnaryExpression *node) {
  1606         prefix();
  1607         fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
  1608         indent();
  1609         node->expression()->accept(this);
  1610         unindent();
  1611     }
  1612     void visitReturnStatement(ReturnStatement *node) {
  1613         prefix();
  1614         fprintf(fp_, "[ ReturnStatement\n");
  1615         indent();
  1616         if (node->expression())
  1617             node->expression()->accept(this);
  1618         unindent();
  1619     }
  1620     void visitForStatement(ForStatement *node) {
  1621         prefix();
  1622         fprintf(fp_, "[ ForStatement\n");
  1623         indent();
  1624         if (node->initialization())
  1625             node->initialization()->accept(this);
  1626         if (node->condition())
  1627             node->condition()->accept(this);
  1628         if (node->update())
  1629             node->update()->accept(this);
  1630         node->body()->accept(this);
  1631         unindent();
  1632     }
  1633     void visitBlockStatement(BlockStatement *node) {
  1634         prefix();
  1635         fprintf(fp_, "[ BlockStatement\n");
  1636         indent();
  1637         for (size_t i = 0; i < node->statements()->length(); i++)
  1638             node->statements()->at(i)->accept(this);
  1639         unindent();
  1640     }
  1641     void visitVariableDeclaration(VariableDeclaration *node) {
  1642         prefix();
  1643         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
  1644         indent();
  1645         if (node->initialization())
  1646             node->initialization()->accept(this);
  1647         unindent();
  1648     }
  1649     void visitIntegerLiteral(IntegerLiteral *node) {
  1650         prefix();
  1651         fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
  1652     }
  1653     void visitBooleanLiteral(BooleanLiteral *node) {
  1654         prefix();
  1655         fprintf(fp_, "[ BooleanLiteral (%s)\n",
  1656                 (node->token() == TOK_TRUE) ? "true" : "false");
  1657     }
  1658     void visitFloatLiteral(FloatLiteral *node) {
  1659         prefix();
  1660         fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
  1661     }
  1662     void visitIfStatement(IfStatement *node) {
  1663         prefix();
  1664         fprintf(fp_, "[ IfStatement\n");
  1665         indent();
  1666         node->ifTrue()->accept(this);
  1667         if (node->ifFalse())
  1668             node->ifFalse()->accept(this);
  1669         unindent();
  1670     }
  1671     void visitIndexExpression(IndexExpression *node) {
  1672         prefix();
  1673         fprintf(fp_, "[ IndexExpression\n");
  1674         indent();
  1675         node->left()->accept(this);
  1676         node->right()->accept(this);
  1677         unindent();
  1678     }
  1679     void visitEnumStatement(EnumStatement *node) {
  1680         prefix();
  1681         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
  1682         indent();
  1683         for (size_t i = 0; i < node->entries()->length(); i++) {
  1684             prefix();
  1685             fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
  1686             if (node->entries()->at(i).expr) {
  1687                 indent();
  1688                 node->entries()->at(i).expr->accept(this);
  1689                 unindent();
  1690             }
  1691         }
  1692         unindent();
  1693     }
  1694     void visitWhileStatement(WhileStatement *node) {
  1695         prefix();
  1696         fprintf(fp_, "[ WhileStatement (%s)\n",
  1697                 (node->token() == TOK_DO) ? "do" : "while");
  1698         indent();
  1699         if (node->token() == TOK_DO) {
  1700             node->condition()->accept(this);
  1701             node->body()->accept(this);
  1702         } else {
  1703             node->condition()->accept(this);
  1704             node->body()->accept(this);
  1705         }
  1706         unindent();
  1707     }
  1708     void visitBreakStatement(BreakStatement *node) {
  1709         prefix();
  1710         fprintf(fp_, "[ BreakStatement\n");
  1711     }
  1712     void visitContinueStatement(ContinueStatement *node) {
  1713         prefix();
  1714         fprintf(fp_, "[ ContinueStatement\n");
  1715     }
  1716     void visitStringLiteral(StringLiteral *node) {
  1717         prefix();
  1718         fprintf(fp_, "[ StringLiteral\n");
  1719     }
  1720     void visitIncDecExpression(IncDecExpression *node) {
  1721         prefix();
  1722         fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
  1723         indent();
  1724         node->expression()->accept(this);
  1725         unindent();
  1726     }
  1727     void visitStructureStatement(StructureStatement *node) {
  1728         prefix();
  1729         fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
  1730     }
  1731     void visitFieldExpression(FieldExpression *node) {
  1732         prefix();
  1733         fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
  1734         indent();
  1735         node->left()->accept(this);
  1736         unindent();
  1737     }
  1738     void visitSwitchStatement(SwitchStatement *node) {
  1739         prefix();
  1740         fprintf(fp_, "[ SwitchStatement\n");
  1741         indent();
  1742         node->expression()->accept(this);
  1743         for (size_t i = 0; i < node->cases()->length(); i++) {
  1744             Case *c = node->cases()->at(i);
  1745             c->expression()->accept(this);
  1746             if (c->others()) {
  1747                 for (size_t j = 0; j < c->others()->length(); j++)
  1748                     c->others()->at(j)->accept(this);
  1749             }
  1750             indent();
  1751             c->statement()->accept(this);
  1752             unindent();
  1753         }
  1754         if (node->defaultCase())
  1755             node->defaultCase()->accept(this);
  1756         unindent();
  1757     }
  1758     void visitArrayLiteral(ArrayLiteral *node) {
  1759         prefix();
  1760         fprintf(fp_, "[ ArrayLiteral\n");
  1761         indent();
  1762         for (size_t i = 0; i < node->expressions()->length(); i++) {
  1763             Expression *expr = node->expressions()->at(i);
  1764             indent();
  1765             expr->accept(this);
  1766             unindent();
  1767         }
  1768     }
  1769     void visitImportStatement(ImportStatement *node) {
  1770         prefix();
  1771         fprintf(fp_, "[ ImportStatement\n");
  1772     }
  1773 };
  1774 
  1775 void
  1776 ParseTree::dump(FILE *fp)
  1777 {
  1778     AstPrinter printer(fp);
  1779 
  1780     for (size_t i = 0; i < statements_->length(); i++)
  1781         statements_->at(i)->accept(&printer);
  1782 }