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