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