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