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