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