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