src/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Sun Sep 16 21:59:26 2012 -0700 (2012-09-16)
changeset 190 dd04fce774cd
parent 189 eee18bf13c9b
child 191 9d17f29fe16a
permissions -rw-r--r--
Enable dynamic array declarations.
     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 (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
  1261             return NULL;
  1262     }
  1263 
  1264     BoundName *returnType = NULL;
  1265     if (returnTag)
  1266         returnType = bindType(returnTag);
  1267 
  1268     Local<String> name(zone_, expectName());
  1269     if (!name)
  1270         return NULL;
  1271 
  1272     SourcePosition pos = scanner_.begin();
  1273 
  1274     // The function name goes into the outer (global) scope.
  1275     assert(!scope_->enclosing());
  1276 
  1277     NamedType *type = NULL;
  1278     NamedFunction *fun = NULL;
  1279     if (BoundName *other = scope_->localLookup(name)) {
  1280         // We allow a redeclaration if the new type is a public, and the old
  1281         // type was a forward. However, the forward must come first.
  1282         if (token == TOK_TYPEDEF || other->kind() != BoundName::FUNCTION) {
  1283             redeclarationError(other);
  1284             return NULL;
  1285         }
  1286 
  1287         fun = other->toNamedFunction();
  1288         if (!fun->isForward() || token != TOK_PUBLIC) {
  1289             redeclarationError(other);
  1290             return NULL;
  1291         }
  1292         
  1293         // We've got the same name, but the original is a forward, so let it
  1294         // slide and re-use the original declaration.
  1295         fun->setImplemented(scanner_.begin());
  1296     } else if (token == TOK_TYPEDEF) {
  1297         type = scope_->declareType(name, scanner_.begin());
  1298         if (!type)
  1299             return NULL;
  1300     } else {
  1301         fun = scope_->declareFunction(name, scanner_.begin(), token);
  1302         if (!fun)
  1303             return NULL;
  1304     }
  1305 
  1306     if (fun && fun->isPublic())
  1307         fun->setUsed();
  1308 
  1309     Scope *scope = enterScope(Scope::FUNCTION);
  1310     if (!scope)
  1311         return NULL;
  1312 
  1313     ParameterList *parameters = new (pool_) ParameterList();
  1314 
  1315     if (!expect(TOK_LPAREN))
  1316         return NULL;
  1317 
  1318     if (!match(TOK_RPAREN)) {
  1319         while (true) {
  1320             bool isConst = match(TOK_CONST);
  1321             bool ref = match(TOK_AMPERSAND);
  1322 
  1323             SourcePosition begin = scanner_.begin();
  1324             Local<String> tag(zone_);
  1325             if (matchName(tag.ref(), TOK_LABEL) && !tag)
  1326                 return NULL;
  1327 
  1328             BoundName *type = NULL;
  1329             if (tag)
  1330                 type = bindType(tag);
  1331 
  1332             if (match(TOK_ELLIPSES)) {
  1333                 if (isConst || ref) {
  1334                     cc_.reportError(begin, Message_InvalidVarArgs);
  1335                     return NULL;
  1336                 }
  1337 
  1338                 if (token != TOK_NATIVE) {
  1339                     cc_.reportError(begin, Message_VarArgsOutsideNative);
  1340                     return NULL;
  1341                 }
  1342 
  1343                 fun->markNativeVariadic();
  1344                 break;
  1345             }
  1346 
  1347             Local<String> name(zone_, expectName());
  1348             if (!name)
  1349                 return NULL;
  1350 
  1351             if (BoundName *other = scope_->localLookup(name)) {
  1352                 redeclarationError(other);
  1353                 return NULL;
  1354             }
  1355             Variable *arg = scope_->declareArgument(name, scanner_.begin());
  1356             if (!arg)
  1357                 return NULL;
  1358 
  1359             // Look for dimensions.
  1360             ExpressionList *postDimensions = NULL;
  1361             if (peek(TOK_LBRACKET)) {
  1362                 if ((postDimensions = dimensions()) == NULL)
  1363                     return NULL;
  1364             }
  1365 
  1366             Expression *expr = NULL;
  1367             if (match(TOK_ASSIGN)) {
  1368                 if ((expr = expression()) == NULL)
  1369                     return NULL;
  1370             }
  1371 
  1372             Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
  1373                                                          expr);
  1374             if (!parameters->append(parameter))
  1375                 return NULL;
  1376 
  1377             if (!match(TOK_COMMA))
  1378                 break;
  1379         }
  1380         if (!expect(TOK_RPAREN))
  1381             return NULL;
  1382     }
  1383 
  1384     encounteredReturn_ = false;
  1385 
  1386     Statement *body = NULL;
  1387     if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
  1388         body = block();
  1389         if (!body)
  1390             return NULL;
  1391     }
  1392 
  1393     scope_ = scope_->enclosing();
  1394 
  1395     FunctionSignature signature(returnType, parameters);
  1396     if (token == TOK_TYPEDEF)
  1397         return new (pool_) FunctionTypeStatement(pos, type, signature);
  1398 
  1399     return new (pool_) FunctionStatement(pos, scope, fun, body, signature, encounteredReturn_);
  1400 }
  1401 
  1402 static inline bool
  1403 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
  1404 {
  1405     Local<String> tag(zone, zone->makeSymbol(name));
  1406     if (!tag)
  1407         return false;
  1408 
  1409     return !!scope->declareType(tag, type);
  1410 }
  1411 
  1412 static inline bool
  1413 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
  1414 {
  1415     Local<Type> primitive(zone, zone->types()->getPrimitive(type));
  1416     assert(primitive);
  1417     return DeclareIntrinsicType(zone, scope, name, primitive);
  1418 }
  1419 
  1420 bool
  1421 Parser::setupIntrinsics()
  1422 {
  1423     if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
  1424         return false;
  1425     if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
  1426         return false;
  1427     if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
  1428         return false;
  1429     if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
  1430         return false;
  1431 
  1432     Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
  1433     if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
  1434         return false;
  1435 
  1436     Local<Type> voidType(zone_, zone_->types()->getVoid());
  1437     if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
  1438         return false;
  1439 
  1440     Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
  1441     if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
  1442         return false;
  1443 
  1444     return true;
  1445 }
  1446 
  1447 ParseTree *
  1448 Parser::parse()
  1449 {
  1450     StatementList *statements = new (pool_) StatementList();
  1451 
  1452     if (!enterScope(Scope::GLOBAL))
  1453         return NULL;
  1454 
  1455     if (!setupIntrinsics())
  1456         return NULL;
  1457 
  1458     for (;;) {
  1459         Statement *statement = NULL;
  1460 
  1461         TokenKind kind = scanner_.peek();
  1462         switch (kind) {
  1463           case TOK_ERROR:
  1464             return NULL;
  1465 
  1466           case TOK_EOF:
  1467             break;
  1468 
  1469           case TOK_NAME:
  1470             if ((statement = function(TOK_NAME)) == NULL)
  1471                 return NULL;
  1472             break;
  1473 
  1474           case TOK_FORWARD:
  1475           case TOK_PUBLIC:
  1476           case TOK_NATIVE:
  1477           case TOK_STOCK:
  1478           case TOK_LABEL:
  1479           case TOK_TYPEDEF:
  1480           {
  1481             scanner_.scan();
  1482             if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
  1483                 if ((statement = var(TOK_PUBLIC, scanner_.scan())) == NULL)
  1484                     return NULL;
  1485                 if (!matchSemicolon())
  1486                     return NULL;
  1487             } else {
  1488                 if ((statement = function(kind)) == NULL)
  1489                     return NULL;
  1490                 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
  1491                     return NULL;
  1492             }
  1493             break;
  1494           }
  1495 
  1496           case TOK_CONST:
  1497           case TOK_NEW:
  1498           {
  1499             // Note: at global scope, we don't accept comma-delimited
  1500             // declarations yet, to see if we can get away with forcing
  1501             // a nicer top-level style.
  1502             scanner_.scan();
  1503             if ((statement = var(TOK_STOCK, kind)) == NULL)
  1504                 return NULL;
  1505             if (!matchSemicolon())
  1506                 return NULL;
  1507             break;
  1508           }
  1509 
  1510           case TOK_ENUM:
  1511             if ((statement = enum_()) == NULL)
  1512                 return NULL;
  1513             if (!matchSemicolon())
  1514                 return NULL;
  1515             break;
  1516 
  1517           case TOK_STRUCT:
  1518             if ((statement = struct_()) == NULL)
  1519                 return NULL;
  1520             if (!matchSemicolon())
  1521                 return NULL;
  1522             break;
  1523 
  1524           default:
  1525             cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
  1526             return NULL;
  1527         }
  1528 
  1529         if (!statement)
  1530             break;
  1531 
  1532         if (!statements->append(statement))
  1533             return NULL;
  1534     }
  1535 
  1536     return new (pool_) ParseTree(scope_, statements, unbound_);
  1537 }
  1538 
  1539 class AstPrinter : public AstVisitor
  1540 {
  1541     FILE *fp_;
  1542     size_t level_;
  1543 
  1544   private:
  1545     void prefix() {
  1546         for (size_t i = 0; i < level_; i++)
  1547             fprintf(fp_, "  ");
  1548     }
  1549     void indent() {
  1550         level_++;
  1551     }
  1552     void unindent() {
  1553         level_--;
  1554     }
  1555 
  1556   public:
  1557     AstPrinter(FILE *fp)
  1558       : fp_(fp),
  1559         level_(0)
  1560     {
  1561     }
  1562 
  1563     void visit(NameProxy *name) {
  1564         prefix();
  1565         fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
  1566                 (name->binding() ? "" : " unbound"));
  1567     }
  1568     void visit(CallExpression *node) {
  1569         prefix();
  1570         fprintf(fp_, "[ CallExpression\n");
  1571         indent();
  1572         node->callee()->accept(this);
  1573         for (size_t i = 0; i < node->arguments()->length(); i++)
  1574             node->arguments()->at(i)->accept(this);
  1575         unindent();
  1576     }
  1577     void visit(FunctionTypeStatement *node) {
  1578         prefix();
  1579         fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->decl()->name()->chars());
  1580     }
  1581     void visit(FunctionStatement *node) {
  1582         prefix();
  1583         fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
  1584         indent();
  1585         if (node->body())
  1586             node->body()->accept(this);
  1587         unindent();
  1588     }
  1589     void visit(ExpressionStatement *node) {
  1590         prefix();
  1591         fprintf(fp_, "[ ExpressionStatement\n");
  1592         indent();
  1593         node->expression()->accept(this);
  1594         unindent();
  1595     }
  1596     void visit(Assignment *node) {
  1597         prefix();
  1598         fprintf(fp_, "[ Assignment\n");
  1599         indent();
  1600         node->lvalue()->accept(this);
  1601         node->expression()->accept(this);
  1602         unindent();
  1603     }
  1604     void visit(TernaryExpression *node) {
  1605         prefix();
  1606         fprintf(fp_, "[ TernaryExpression\n");
  1607         indent();
  1608         node->condition()->accept(this);
  1609         node->left()->accept(this);
  1610         node->right()->accept(this);
  1611         unindent();
  1612     }
  1613     void visit(BinaryExpression *node) {
  1614         prefix();
  1615         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
  1616         indent();
  1617         node->left()->accept(this);
  1618         node->right()->accept(this);
  1619         unindent();
  1620     }
  1621     void visit(UnaryExpression *node) {
  1622         prefix();
  1623         fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
  1624         indent();
  1625         node->expression()->accept(this);
  1626         unindent();
  1627     }
  1628     void visit(ReturnStatement *node) {
  1629         prefix();
  1630         fprintf(fp_, "[ ReturnStatement\n");
  1631         indent();
  1632         if (node->expression())
  1633             node->expression()->accept(this);
  1634         unindent();
  1635     }
  1636     void visit(ForStatement *node) {
  1637         prefix();
  1638         fprintf(fp_, "[ ForStatement\n");
  1639         indent();
  1640         if (node->initialization())
  1641             node->initialization()->accept(this);
  1642         if (node->condition())
  1643             node->condition()->accept(this);
  1644         if (node->update())
  1645             node->update()->accept(this);
  1646         node->body()->accept(this);
  1647         unindent();
  1648     }
  1649     void visit(BlockStatement *node) {
  1650         prefix();
  1651         fprintf(fp_, "[ BlockStatement\n");
  1652         indent();
  1653         for (size_t i = 0; i < node->statements()->length(); i++)
  1654             node->statements()->at(i)->accept(this);
  1655         unindent();
  1656     }
  1657     void visit(VariableDeclaration *node) {
  1658         prefix();
  1659         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
  1660         indent();
  1661         if (node->initialization())
  1662             node->initialization()->accept(this);
  1663         unindent();
  1664     }
  1665     void visit(IntegerLiteral *node) {
  1666         prefix();
  1667         fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
  1668     }
  1669     void visit(BooleanLiteral *node) {
  1670         prefix();
  1671         fprintf(fp_, "[ BooleanLiteral (%s)\n",
  1672                 (node->token() == TOK_TRUE) ? "true" : "false");
  1673     }
  1674     void visit(FloatLiteral *node) {
  1675         prefix();
  1676         fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
  1677     }
  1678     void visit(IfStatement *node) {
  1679         prefix();
  1680         fprintf(fp_, "[ IfStatement\n");
  1681         indent();
  1682         node->ifTrue()->accept(this);
  1683         if (node->ifFalse())
  1684             node->ifFalse()->accept(this);
  1685         unindent();
  1686     }
  1687     void visit(IndexExpression *node) {
  1688         prefix();
  1689         fprintf(fp_, "[ IndexExpression\n");
  1690         indent();
  1691         node->left()->accept(this);
  1692         node->right()->accept(this);
  1693         unindent();
  1694     }
  1695     void visit(EnumStatement *node) {
  1696         prefix();
  1697         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
  1698         indent();
  1699         for (size_t i = 0; i < node->entries()->length(); i++) {
  1700             prefix();
  1701             fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
  1702             if (node->entries()->at(i).expr) {
  1703                 indent();
  1704                 node->entries()->at(i).expr->accept(this);
  1705                 unindent();
  1706             }
  1707         }
  1708         unindent();
  1709     }
  1710     void visit(WhileStatement *node) {
  1711         prefix();
  1712         fprintf(fp_, "[ WhileStatement (%s)\n",
  1713                 (node->token() == TOK_DO) ? "do" : "while");
  1714         indent();
  1715         if (node->token() == TOK_DO) {
  1716             node->condition()->accept(this);
  1717             node->body()->accept(this);
  1718         } else {
  1719             node->condition()->accept(this);
  1720             node->body()->accept(this);
  1721         }
  1722         unindent();
  1723     }
  1724     void visit(BreakStatement *node) {
  1725         prefix();
  1726         fprintf(fp_, "[ BreakStatement\n");
  1727     }
  1728     void visit(ContinueStatement *node) {
  1729         prefix();
  1730         fprintf(fp_, "[ ContinueStatement\n");
  1731     }
  1732     void visit(StringLiteral *node) {
  1733         prefix();
  1734         fprintf(fp_, "[ StringLiteral\n");
  1735     }
  1736     void visit(IncDecExpression *node) {
  1737         prefix();
  1738         fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
  1739         indent();
  1740         node->expression()->accept(this);
  1741         unindent();
  1742     }
  1743     void visit(StructureStatement *node) {
  1744         prefix();
  1745         fprintf(fp_, "[ StructureStatement %s\n", node->decl()->name()->chars());
  1746     }
  1747     void visit(FieldExpression *node) {
  1748         prefix();
  1749         fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
  1750         indent();
  1751         node->left()->accept(this);
  1752         unindent();
  1753     }
  1754     void visit(SwitchStatement *node) {
  1755         prefix();
  1756         fprintf(fp_, "[ SwitchStatement\n");
  1757         indent();
  1758         node->expression()->accept(this);
  1759         for (size_t i = 0; i < node->cases()->length(); i++) {
  1760             Case *c = node->cases()->at(i);
  1761             c->expression()->accept(this);
  1762             if (c->others()) {
  1763                 for (size_t j = 0; j < c->others()->length(); j++)
  1764                     c->others()->at(j)->accept(this);
  1765             }
  1766             indent();
  1767             c->statement()->accept(this);
  1768             unindent();
  1769         }
  1770         if (node->defaultCase())
  1771             node->defaultCase()->accept(this);
  1772         unindent();
  1773     }
  1774     void visit(ArrayLiteral *node) {
  1775         prefix();
  1776         fprintf(fp_, "[ ArrayLiteral\n");
  1777         indent();
  1778         for (size_t i = 0; i < node->expressions()->length(); i++) {
  1779             Expression *expr = node->expressions()->at(i);
  1780             indent();
  1781             expr->accept(this);
  1782             unindent();
  1783         }
  1784     }
  1785 };
  1786 
  1787 void
  1788 ParseTree::dump(FILE *fp)
  1789 {
  1790     AstPrinter printer(fp);
  1791 
  1792     for (size_t i = 0; i < statements_->length(); i++)
  1793         statements_->at(i)->accept(&printer);
  1794 }