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