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