src/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Sun Jul 29 19:37:47 2012 -0700 (2012-07-29)
changeset 135 72912cf0dd18
parent 134 76dec1323d1f
child 137 be919b22085b
permissions -rw-r--r--
Support TOK_CONST as a declarator in the parser.
     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 "Heap-inl.h"
    26 
    27 using namespace ke;
    28 
    29 Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
    30   : zone_(zone),
    31     cc_(cc),
    32     pool_(zone_->pool()),
    33     scanner_(cc, stream, length),
    34     scope_(NULL),
    35     unbound_(NULL)
    36 {
    37     unbound_ = new (pool_) PoolList<NameProxy *>();
    38 }
    39 
    40 bool
    41 Parser::match(TokenKind kind)
    42 {
    43     if (scanner_.peek() != kind)
    44         return false;
    45     scanner_.scan();
    46     return true;
    47 }
    48 
    49 bool
    50 Parser::matchSemicolon()
    51 {
    52     return expect(TOK_SEMICOLON);
    53 }
    54 
    55 bool
    56 Parser::expect(TokenKind kind)
    57 {
    58     TokenKind got = scanner_.scan();
    59     if (got == kind)
    60         return true;
    61     cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
    62     return false;
    63 }
    64 
    65 Scope *
    66 Parser::enterScope(Scope::Kind kind)
    67 {
    68     scope_ = new (pool_) Scope(pool_, kind, scope_);
    69     if (!scope_->initialize())
    70         return NULL;
    71     return scope_;
    72 }
    73 
    74 NameProxy *
    75 Parser::bind(Handle<String> name)
    76 {
    77     BoundName *bound = scope_->lookup(name);
    78     NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
    79     if (!bound && !unbound_->append(proxy))
    80         return NULL;
    81     return proxy;
    82 }
    83 
    84 bool
    85 Parser::matchName(String **name, TokenKind kind)
    86 {
    87     assert(kind == TOK_NAME || kind == TOK_LABEL);
    88     *name = NULL;
    89     if (!match(kind))
    90         return false;
    91     *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
    92     return true;
    93 }
    94 
    95 String *
    96 Parser::expectName()
    97 {
    98     if (!expect(TOK_NAME))
    99         return NULL;
   100     return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
   101 }
   102 
   103 void
   104 Parser::redeclarationError(BoundName *other)
   105 {
   106     cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->name()->chars(),
   107                     other->pos().line, other->pos().col);
   108 }
   109 
   110 Expression *
   111 Parser::primitive()
   112 {
   113     TokenKind kind = scanner_.peek();
   114     switch (kind) {
   115       case TOK_NAME:
   116       {
   117         Local<String> name(zone_, expectName());
   118         if (!name)
   119             return NULL;
   120         return bind(name);
   121       }
   122 
   123       case TOK_FLOAT_LITERAL:
   124       {
   125         scanner_.scan();
   126         double value = Scanner::ParseDouble(scanner_.literal());
   127         return new (pool_) FloatLiteral(scanner_.begin(), value);
   128       }
   129 
   130       case TOK_INTEGER_LITERAL:
   131       {
   132         scanner_.scan();
   133         int value = atoi(scanner_.literal());
   134         return new (pool_) IntegerLiteral(scanner_.begin(), value);
   135       }
   136 
   137       case TOK_STRING_LITERAL:
   138       {
   139         scanner_.scan();
   140         Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
   141         if (!array)
   142             return NULL;
   143         memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
   144         return new (pool_) StringLiteral(scanner_.begin(), array);
   145       }
   146 
   147       default:
   148       {
   149         if (kind != TOK_ERROR)
   150             cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
   151         return NULL;
   152       }
   153     }
   154 }
   155 
   156 Expression *
   157 Parser::prefix()
   158 {
   159     switch (scanner_.peek()) {
   160       case TOK_LPAREN:
   161       {
   162         scanner_.scan();
   163         Expression *expr = expression();
   164         if (!expr)
   165             return NULL;
   166         if (!expect(TOK_RPAREN))
   167             return NULL;
   168         return expr;
   169       }
   170 
   171       default:
   172         return primitive();
   173     }
   174 }
   175 
   176 Expression *
   177 Parser::call(Expression *callee)
   178 {
   179     ExpressionList *arguments = new (pool_) ExpressionList();
   180 
   181     SourcePosition pos = scanner_.begin();
   182     expect(TOK_LPAREN);
   183     
   184     if (!match(TOK_RPAREN)) {
   185         while (true) {
   186             Expression *expr = expression();
   187             if (!expr)
   188                 return NULL;
   189 
   190             if (!arguments->append(expr))
   191                 return NULL;
   192 
   193             if (!match(TOK_COMMA))
   194                 break;
   195         }
   196 
   197         if (!expect(TOK_RPAREN))
   198             return NULL;
   199     }
   200 
   201     return new (pool_) CallExpression(pos, callee, arguments);
   202 }
   203 
   204 Expression *
   205 Parser::index(Expression *left)
   206 {
   207     expect(TOK_LBRACKET);
   208     
   209     SourcePosition pos = scanner_.begin();
   210     Expression *expr = expression();
   211     if (!expr)
   212         return NULL;
   213 
   214     if (!expect(TOK_RBRACKET))
   215         return NULL;
   216 
   217     return new (pool_) IndexExpression(pos, left, expr);
   218 }
   219 
   220 Expression *
   221 Parser::primary()
   222 {
   223     Expression *expr = prefix();
   224     if (!expr)
   225         return NULL;
   226 
   227     for (;;) {
   228         switch (scanner_.peek()) {
   229           case TOK_LPAREN:
   230             expr = call(expr);
   231             if (!expr)
   232                 return NULL;
   233             break;
   234 
   235           case TOK_LBRACKET:
   236             expr = index(expr);
   237             if (!expr)
   238                 return NULL;
   239             break;
   240 
   241           default:
   242             return expr;
   243         }
   244     }
   245 }
   246 
   247 Expression *
   248 Parser::unary()
   249 {
   250     TokenKind token = scanner_.peek();
   251 
   252     SourcePosition pos = scanner_.begin();
   253     switch (token) {
   254       case TOK_INCREMENT:
   255       case TOK_DECREMENT:
   256       {
   257         scanner_.scan();
   258         Expression *expr = expression();
   259         if (!expr)
   260             return NULL;
   261         return new (pool_) IncDecExpression(pos, token, expr, false);
   262       }
   263 
   264       case TOK_MINUS:
   265       case TOK_NOT:
   266       case TOK_TILDE:
   267       {
   268         scanner_.scan();
   269         Expression *expr = expression();
   270         if (!expr)
   271             return NULL;
   272         return new (pool_) UnaryExpression(pos, token, expr);
   273       }
   274 
   275       default:
   276         break;
   277     }
   278 
   279     Expression *expr = primary();
   280 
   281     token = scanner_.peek();
   282     if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
   283         scanner_.scan();
   284         return new (pool_) IncDecExpression(pos, token, expr, true);
   285     }
   286 
   287     return expr;
   288 }
   289 
   290 Expression *
   291 Parser::multiplication()
   292 {
   293     Expression *left = unary();
   294     do {
   295         if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
   296             break;
   297         SourcePosition pos = scanner_.begin();
   298         TokenKind kind = scanner_.last();
   299         Expression *right = unary();
   300         if (!right)
   301             return NULL;
   302         left = new (pool_) BinaryExpression(pos, kind, left, right);
   303     } while (left);
   304     return left;
   305 }
   306 
   307 Expression *
   308 Parser::addition()
   309 {
   310     Expression *left = multiplication();
   311     while (left) {
   312         if (!match(TOK_PLUS) && !match(TOK_MINUS))
   313             break;
   314         SourcePosition pos = scanner_.begin();
   315         TokenKind kind = scanner_.last();
   316         Expression *right = multiplication();
   317         if (!right)
   318             return NULL;
   319         left = new (pool_) BinaryExpression(pos, kind, left, right);
   320     }
   321     return left;
   322 }
   323 
   324 Expression *
   325 Parser::shift()
   326 {
   327     Expression *left = addition();
   328     while (left) {
   329         if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
   330             break;
   331         SourcePosition pos = scanner_.begin();
   332         TokenKind kind = scanner_.last();
   333         Expression *right = addition();
   334         if (!right)
   335             return NULL;
   336         left = new (pool_) BinaryExpression(pos, kind, left, right);
   337     }
   338     return left;
   339 }
   340 
   341 Expression *
   342 Parser::bitand_()
   343 {
   344     Expression *left = shift();
   345     while (left) {
   346         if (!match(TOK_BITAND))
   347             break;
   348         SourcePosition pos = scanner_.begin();
   349         Expression *right = shift();
   350         if (!right)
   351             return NULL;
   352         left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
   353     }
   354     return left;
   355 }
   356 
   357 Expression *
   358 Parser::bitxor()
   359 {
   360     Expression *left = bitand_();
   361     while (left) {
   362         if (!match(TOK_BITXOR))
   363             break;
   364         SourcePosition pos = scanner_.begin();
   365         Expression *right = shift();
   366         if (!right)
   367             return NULL;
   368         left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
   369     }
   370     return left;
   371 }
   372 
   373 Expression *
   374 Parser::bitor_()
   375 {
   376     Expression *left = bitxor();
   377     while (left) {
   378         if (!match(TOK_BITOR))
   379             break;
   380         SourcePosition pos = scanner_.begin();
   381         Expression *right = bitxor();
   382         if (!right)
   383             return NULL;
   384         left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
   385     }
   386     return left;
   387 }
   388 
   389 Expression *
   390 Parser::relational()
   391 {
   392     Expression *left = bitor_();
   393     while (left) {
   394         TokenKind kind = scanner_.peek();
   395         if (kind < TOK_LT || kind > TOK_GE)
   396             break;
   397         scanner_.scan();
   398         SourcePosition pos = scanner_.begin();
   399         Expression *right = shift();
   400         if (!right)
   401             return NULL;
   402         left = new (pool_) BinaryExpression(pos, kind, left, right);
   403     }
   404     return left;
   405 }
   406 
   407 Expression *
   408 Parser::equals()
   409 {
   410     Expression *left = relational();
   411     while (left) {
   412         if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   413             break;
   414         TokenKind kind = scanner_.last();
   415         SourcePosition pos = scanner_.begin();
   416         Expression *right = relational();
   417         if (!right)
   418             return NULL;
   419         left = new (pool_) BinaryExpression(pos, kind, left, right);
   420     }
   421     return left;
   422 }
   423 
   424 Expression *
   425 Parser::and_()
   426 {
   427     Expression *left = equals();
   428     while (left) {
   429         if (!match(TOK_AND))
   430             break;
   431         SourcePosition pos = scanner_.begin();
   432         Expression *right = equals();
   433         if (!right)
   434             return NULL;
   435         left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
   436     }
   437     return left;
   438 }
   439 
   440 Expression *
   441 Parser::or_()
   442 {
   443     Expression *left = and_();
   444     while (left) {
   445         if (!match(TOK_OR))
   446             break;
   447         SourcePosition pos = scanner_.begin();
   448         Expression *right = and_();
   449         if (!right)
   450             return NULL;
   451         left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
   452     }
   453     return left;
   454 }
   455 
   456 Expression *
   457 Parser::ternary()
   458 {
   459     Expression *cond = or_();
   460     if (!cond)
   461         return NULL;
   462     
   463     if (!match(TOK_QMARK))
   464         return cond;
   465 
   466     SourcePosition pos = scanner_.begin();
   467     Expression *left = expression();
   468     if (!left)
   469         return NULL;
   470 
   471     if (!expect(TOK_COLON))
   472         return NULL;
   473 
   474     Expression *right = expression();
   475     if (!right)
   476         return NULL;
   477 
   478     return new (pool_) TernaryExpression(pos, cond, left, right);
   479 }
   480 
   481 Expression *
   482 Parser::assignment()
   483 {
   484     Expression *left = ternary();
   485     while (left) {
   486         TokenKind token = scanner_.peek();
   487         if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
   488             break;
   489         scanner_.scan();
   490         SourcePosition pos = scanner_.begin();
   491         Expression *expr = ternary();
   492         if (!expr)
   493             return NULL;
   494 
   495         left = new (pool_) Assignment(pos, token, left, expr);
   496     }
   497     return left;
   498 }
   499 
   500 Expression *
   501 Parser::expression()
   502 {
   503     return assignment();
   504 }
   505 
   506 Statement *
   507 Parser::while_()
   508 {
   509     SourcePosition pos = scanner_.begin();
   510     scanner_.scan();
   511 
   512     if (!expect(TOK_LPAREN))
   513         return NULL;
   514 
   515     Expression *condition = expression();
   516     if (!condition)
   517         return NULL;
   518 
   519     if (!expect(TOK_RPAREN))
   520         return NULL;
   521 
   522     // Inside a loop, we force the creation of a scope object. Normally, we
   523     // will cull scopes if they have no variables. However inside a loop,
   524     // function calls that take references may compute a LIFO object, and to
   525     // avoid temporarily leaking many such objects, we ensure that a scope
   526     // is present so a LIFO slot can be allocated.
   527     if (!enterScope(Scope::BLOCK))
   528         return NULL;
   529 
   530     Statement *body;
   531     if (scanner_.peek() == TOK_LBRACE)
   532         body = block(scope_);
   533     else
   534         body = localStatement();
   535     if (!body)
   536         return NULL;
   537 
   538     scope_ = scope_->enclosing();
   539     return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
   540 }
   541 
   542 Statement *
   543 Parser::do_()
   544 {
   545     SourcePosition pos = scanner_.begin();
   546     scanner_.scan();
   547 
   548     // See the comment in ::while_() as to why we force a scope.
   549     if (!enterScope(Scope::BLOCK))
   550         return NULL;
   551 
   552     Statement *body;
   553     if (scanner_.peek() == TOK_LBRACE)
   554         body = block(scope_);
   555     else
   556         body = localStatement();
   557     if (!body)
   558         return NULL;
   559 
   560     scope_ = scope_->enclosing();
   561 
   562     if (!expect(TOK_WHILE))
   563         return NULL;
   564 
   565     if (!expect(TOK_LPAREN))
   566         return NULL;
   567     Expression *condition = expression();
   568     if (!condition)
   569         return NULL;
   570     if (!expect(TOK_RPAREN))
   571         return NULL;
   572 
   573     return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
   574 }
   575 
   576 Statement *
   577 Parser::forStatement()
   578 {
   579     SourcePosition pos = scanner_.begin();
   580     scanner_.scan();
   581     if (!expect(TOK_LPAREN))
   582         return NULL;
   583 
   584     Statement *decl = NULL;
   585     if (!match(TOK_SEMICOLON)) {
   586         if (match(TOK_NEW)) {
   587             if (!enterScope(Scope::BLOCK))
   588                 return NULL;
   589             if ((decl = variableDeclaration(TOK_NEW)) == NULL)
   590                 return NULL;
   591         } else {
   592             if ((decl = expressionStatement()) == NULL)
   593                 return NULL;
   594         }
   595         if (!expect(TOK_SEMICOLON))
   596             return NULL;
   597     }
   598 
   599     Expression *condition = NULL;
   600     if (!match(TOK_SEMICOLON)) {
   601         if ((condition = expression()) == NULL)
   602             return NULL;
   603         if (!expect(TOK_SEMICOLON))
   604             return NULL;
   605     }
   606 
   607     Statement *update = NULL;
   608     if (!match(TOK_RPAREN)) {
   609         if ((update = expressionStatement()) == NULL)
   610             return NULL;
   611         if (!expect(TOK_RPAREN))
   612             return NULL;
   613     }
   614 
   615     // See the comment in ::while_() as to why we force a scope.
   616     if (!enterScope(Scope::BLOCK))
   617         return NULL;
   618 
   619     Statement *body;
   620     if (scanner_.peek() == TOK_LBRACE)
   621         body = block(scope_);
   622     else
   623         body = localStatement();
   624     if (!body)
   625         return NULL;
   626 
   627     scope_ = scope_->enclosing();
   628 
   629     Scope *declScope = NULL;
   630     if (decl && decl->isVariableDeclaration()) {
   631         declScope = scope_->unlinkIfEmpty();
   632         scope_ = scope_->enclosing();
   633     }
   634     return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
   635 }
   636 
   637 VariableDeclaration *
   638 Parser::variableDeclaration(TokenKind kind)
   639 {
   640     Local<String> tag(zone_);
   641     if (matchName(tag.ref(), TOK_LABEL) && !tag)
   642         return NULL;
   643 
   644     Local<String> name(zone_, expectName());
   645     if (!name)
   646         return NULL;
   647 
   648     if (BoundName *other = scope_->localLookup(name)) {
   649         redeclarationError(other);
   650         return NULL;
   651     }
   652 
   653     Variable *var = scope_->declareVariable(name, scanner_.begin());
   654     if (!var)
   655         return NULL;
   656 
   657     ExpressionList *postDimensions = NULL;
   658     if (scanner_.peek() == TOK_LBRACKET) {
   659         postDimensions = new (pool_) ExpressionList();
   660         while (match(TOK_LBRACKET)) {
   661             Expression *dim = expression();
   662             if (!dim)
   663                 return NULL;
   664 
   665             if (!expect(TOK_RBRACKET))
   666                 return NULL;
   667 
   668             if (!postDimensions->append(dim))
   669                 return NULL;
   670         }
   671     }
   672     
   673     Expression *expr = NULL;
   674     if (match(TOK_ASSIGN)) {
   675         if ((expr = expression()) == NULL)
   676             return NULL;
   677     }
   678 
   679     return new (pool_) VariableDeclaration(var->pos(), kind, var, tag, postDimensions, expr);
   680 }
   681 
   682 Statement *
   683 Parser::returnStatement()
   684 {
   685     SourcePosition pos = scanner_.begin();
   686     if (!expect(TOK_RETURN))
   687         return NULL;
   688 
   689     Expression *expr = NULL;
   690     if (scanner_.peek() != TOK_SEMICOLON) {
   691         if ((expr = expression()) == NULL)
   692             return NULL;
   693 
   694         // We only care about non-void returns when determining whether a
   695         // tagless function is non-void.
   696         encounteredReturn_ = true;
   697     }
   698 
   699     return new (pool_) ReturnStatement(pos, expr);
   700 }
   701 
   702 Statement *
   703 Parser::expressionStatement()
   704 {
   705     Expression *left = assignment();
   706     if (!left)
   707         return NULL;
   708 
   709     return new (pool_) ExpressionStatement(left);
   710 }
   711 
   712 Statement *
   713 Parser::block(Scope *scope)
   714 {
   715     if (!expect(TOK_LBRACE))
   716         return NULL;
   717 
   718     SourcePosition pos = scanner_.begin();
   719     if (!scope && !enterScope(Scope::BLOCK))
   720         return NULL;
   721 
   722     StatementList *statements = new (pool_) StatementList();
   723     while (!match(TOK_RBRACE)) {
   724         Statement *statement = localStatement();
   725         if (statement == NULL)
   726             return NULL;
   727         if (!statements->append(statement))
   728             return NULL;
   729     }
   730 
   731     if (!scope) {
   732     	scope = scope_->unlinkIfEmpty();
   733         scope_ = scope_->enclosing();
   734     }
   735     BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
   736     return block;
   737 }
   738 
   739 Statement *
   740 Parser::if_()
   741 {
   742     expect(TOK_IF);
   743     
   744     SourcePosition pos = scanner_.begin();
   745     if (!expect(TOK_LPAREN))
   746         return NULL;
   747 
   748     Expression *cond = expression();
   749     if (!cond)
   750         return NULL;
   751 
   752     if (!expect(TOK_RPAREN))
   753         return NULL;
   754 
   755     Statement *ifTrue = localStatement();
   756     if (!ifTrue)
   757         return NULL;
   758 
   759     IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
   760 
   761     IfStatement *last = outer;
   762     while (match(TOK_ELSE)) {
   763         if (!match(TOK_IF)) {
   764             Statement *ifFalse = localStatement();
   765             if (!ifFalse)
   766                 return NULL;
   767 
   768             last->setIfFalse(ifFalse);
   769             break;
   770         }
   771 
   772         SourcePosition pos = scanner_.begin();
   773         if (!expect(TOK_LPAREN))
   774             return NULL;
   775 
   776         Expression *otherCond = expression();
   777         if (!otherCond)
   778             return NULL;
   779 
   780         if (!expect(TOK_RPAREN))
   781             return NULL;
   782 
   783         Statement *otherIfTrue = localStatement();
   784         if (!otherIfTrue)
   785             return NULL;
   786 
   787         IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
   788         last->setIfFalse(inner);
   789         last = inner;
   790     }
   791 
   792     return outer;
   793 }
   794 
   795 Statement *
   796 Parser::localStatement()
   797 {
   798     Statement *statement = NULL;
   799 
   800     // Statements which must be followed by a semicolon will break out of the
   801     // switch. If they may end in BlockStatements, they'll immediately return.
   802 
   803     TokenKind kind = scanner_.peek();
   804     switch (kind) {
   805       case TOK_CONST:
   806       case TOK_NEW:
   807         scanner_.scan();
   808         if ((statement = variableDeclaration(kind)) == NULL)
   809             return NULL;
   810         break;
   811 
   812       case TOK_FOR:
   813         return forStatement();
   814 
   815       case TOK_WHILE:
   816         return while_();
   817 
   818       case TOK_BREAK:
   819         scanner_.scan();
   820         statement = new (pool_) BreakStatement(scanner_.begin());
   821         break;
   822 
   823       case TOK_CONTINUE:
   824         scanner_.scan();
   825         statement = new (pool_) ContinueStatement(scanner_.begin());
   826         break;
   827 
   828       case TOK_DO:
   829         if ((statement = do_()) == NULL)
   830             return NULL;
   831         break;
   832 
   833       case TOK_RETURN:
   834         if ((statement = returnStatement()) == NULL)
   835             return NULL;
   836         break;
   837 
   838       case TOK_ENUM:
   839         if ((statement = enum_()) == NULL)
   840             return NULL;
   841         break;
   842 
   843       case TOK_IF:
   844         return if_();
   845 
   846       case TOK_LBRACE:
   847         return block();
   848 
   849       default:
   850         break;
   851     }
   852 
   853     if (!statement) {
   854         if ((statement = expressionStatement()) == NULL)
   855             return NULL;
   856     }
   857 
   858     if (!expect(TOK_SEMICOLON))
   859         return NULL;
   860 
   861     return statement;
   862 }
   863 
   864 Statement *
   865 Parser::enum_()
   866 {
   867     expect(TOK_ENUM);
   868 
   869     SourcePosition pos = scanner_.begin();
   870 
   871     Local<String> name(zone_);
   872     if (matchName(name.ref())) {
   873         if (!name)
   874             return NULL;
   875 
   876         if (BoundName *other = scope_->localLookup(name)) {
   877             redeclarationError(other);
   878             return NULL;
   879         }
   880 
   881         if (!scope_->declareEnum(name, scanner_.begin()))
   882             return NULL;
   883     }
   884 
   885     EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
   886 
   887     if (!expect(TOK_LBRACE))
   888         return NULL;
   889 
   890     do {
   891         if (scanner_.peek() == TOK_RBRACE)
   892             break;
   893 
   894         Local<String> name(zone_, expectName());
   895         if (!name)
   896             return NULL;
   897 
   898         if (BoundName *other = scope_->localLookup(name)) {
   899             redeclarationError(other);
   900             return NULL;
   901         }
   902 
   903         NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
   904         if (!constant)
   905             return NULL;
   906 
   907         Expression *expr = NULL;
   908         if (match(TOK_ASSIGN)) {
   909             if ((expr = expression()) == NULL)
   910                 return NULL;
   911         }
   912 
   913         if (!entries->append(EnumStatement::Entry(constant, expr)))
   914             return NULL;
   915     } while (match(TOK_COMMA));
   916     if (!expect(TOK_RBRACE))
   917         return NULL;
   918 
   919     return new (pool_) EnumStatement(pos, name, entries);
   920 }
   921 
   922 Statement *
   923 Parser::function(TokenKind token)
   924 {
   925     Local<String> returnTag(zone_);
   926     if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
   927         return NULL;
   928 
   929     Local<String> name(zone_, expectName());
   930     if (!name)
   931         return NULL;
   932 
   933     SourcePosition pos = scanner_.begin();
   934 
   935     // The function name goes into the outer (global) scope.
   936     assert(!scope_->enclosing());
   937 
   938     NamedFunction *fun;
   939     if (BoundName *other = scope_->localLookup(name)) {
   940         // We allow a redeclaration if the new type is a public, and the old
   941         // type was a forward. However, the forward must come first.
   942         if (other->kind() != BoundName::FUNCTION) {
   943             redeclarationError(other);
   944             return NULL;
   945         }
   946 
   947         fun = other->toNamedFunction();
   948         if (!fun->isForward() || token != TOK_PUBLIC) {
   949             redeclarationError(other);
   950             return NULL;
   951         }
   952         
   953         // We've got the same name, but the original is a forward, so let it
   954         // slide and re-use the original declaration.
   955         fun->setImplemented(scanner_.begin());
   956     } else {
   957         fun = scope_->declareFunction(name, scanner_.begin(), token);
   958         if (!fun)
   959             return NULL;
   960     }
   961 
   962     Scope *scope = enterScope(Scope::FUNCTION);
   963     if (!scope)
   964         return NULL;
   965 
   966     ParameterList *parameters = new (pool_) ParameterList();
   967 
   968     if (!expect(TOK_LPAREN))
   969         return NULL;
   970 
   971     if (!match(TOK_RPAREN)) {
   972         while (true) {
   973             bool isConst = match(TOK_CONST);
   974             bool ref = match(TOK_AMPERSAND);
   975 
   976             SourcePosition begin = scanner_.begin();
   977             Local<String> tag(zone_);
   978             if (matchName(tag.ref(), TOK_LABEL) && !tag)
   979                 return NULL;
   980 
   981             if (match(TOK_ELLIPSES)) {
   982                 if (isConst || ref) {
   983                     cc_.reportError(begin, Message_InvalidVarArgs);
   984                     return NULL;
   985                 }
   986 
   987                 if (token != TOK_NATIVE) {
   988                     cc_.reportError(begin, Message_VarArgsOutsideNative);
   989                     return NULL;
   990                 }
   991 
   992                 fun->markNativeVariadic();
   993                 break;
   994             }
   995 
   996             Local<String> name(zone_, expectName());
   997             if (!name)
   998                 return NULL;
   999 
  1000             if (BoundName *other = scope_->localLookup(name)) {
  1001                 redeclarationError(other);
  1002                 return NULL;
  1003             }
  1004             Variable *arg = scope_->declareArgument(name, scanner_.begin());
  1005             if (!arg)
  1006                 return NULL;
  1007 
  1008             // Look for dimensions.
  1009             ExpressionList *postDimensions = NULL;
  1010             while (match(TOK_LBRACKET)) {
  1011                 if (!postDimensions)
  1012                     postDimensions = new (pool_) ExpressionList();
  1013 
  1014                 Expression *dim = NULL;
  1015                 if (!match(TOK_RBRACKET)) {
  1016                     if ((dim = expression()) == NULL)
  1017                         return NULL;
  1018                     if (!expect(TOK_RBRACKET))
  1019                         return NULL;
  1020                 }
  1021 
  1022                 if (!postDimensions->append(dim))
  1023                     return NULL;
  1024             }
  1025 
  1026             Expression *expr = NULL;
  1027             if (match(TOK_ASSIGN)) {
  1028                 if ((expr = expression()) == NULL)
  1029                     return NULL;
  1030             }
  1031 
  1032             Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions,
  1033                                                          expr);
  1034             if (!parameters->append(parameter))
  1035                 return NULL;
  1036 
  1037             if (!match(TOK_COMMA))
  1038                 break;
  1039         }
  1040         if (!expect(TOK_RPAREN))
  1041             return NULL;
  1042     }
  1043 
  1044     encounteredReturn_ = false;
  1045 
  1046     Statement *body = NULL;
  1047     if (token != TOK_FORWARD && token != TOK_NATIVE) {
  1048         body = block();
  1049         if (!body)
  1050             return NULL;
  1051     }
  1052 
  1053     scope_ = scope_->enclosing();
  1054     return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, returnTag,
  1055                                          encounteredReturn_);
  1056 }
  1057 
  1058 ParseTree *
  1059 Parser::parse()
  1060 {
  1061     StatementList *statements = new (pool_) StatementList();
  1062 
  1063     if (!enterScope(Scope::GLOBAL))
  1064         return NULL;
  1065 
  1066     for (;;) {
  1067         Statement *statement = NULL;
  1068 
  1069         TokenKind kind = scanner_.peek();
  1070         switch (kind) {
  1071           case TOK_ERROR:
  1072             return NULL;
  1073 
  1074           case TOK_EOF:
  1075             break;
  1076 
  1077           case TOK_NAME:
  1078             if ((statement = function(TOK_NAME)) == NULL)
  1079                 return NULL;
  1080             break;
  1081 
  1082           case TOK_FORWARD:
  1083           case TOK_PUBLIC:
  1084           case TOK_NATIVE:
  1085           case TOK_STOCK:
  1086           {
  1087             scanner_.scan();
  1088             if ((statement = function(kind)) == NULL)
  1089                 return NULL;
  1090             if ((kind == TOK_FORWARD || kind == TOK_NATIVE) && !matchSemicolon())
  1091                 return NULL;
  1092             break;
  1093           }
  1094 
  1095           case TOK_CONST:
  1096           case TOK_NEW:
  1097           {
  1098             scanner_.scan();
  1099             if ((statement = variableDeclaration(kind)) == NULL)
  1100                return NULL;
  1101             if (!matchSemicolon())
  1102                 return NULL;
  1103             break;
  1104           }
  1105 
  1106           case TOK_ENUM:
  1107             if ((statement = enum_()) == NULL)
  1108                 return NULL;
  1109             if (!matchSemicolon())
  1110                 return NULL;
  1111             break;
  1112 
  1113           default:
  1114             cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
  1115             return NULL;
  1116         }
  1117 
  1118         if (!statement)
  1119             break;
  1120 
  1121         if (!statements->append(statement))
  1122             return NULL;
  1123     }
  1124 
  1125     return new (pool_) ParseTree(scope_, statements, unbound_);
  1126 }
  1127 
  1128 class AstPrinter : public AstVisitor
  1129 {
  1130     FILE *fp_;
  1131     size_t level_;
  1132 
  1133   private:
  1134     void prefix() {
  1135         for (size_t i = 0; i < level_; i++)
  1136             fprintf(fp_, "  ");
  1137     }
  1138     void indent() {
  1139         level_++;
  1140     }
  1141     void unindent() {
  1142         level_--;
  1143     }
  1144 
  1145   public:
  1146     AstPrinter(FILE *fp)
  1147       : fp_(fp),
  1148         level_(0)
  1149     {
  1150     }
  1151 
  1152     void visit(NameProxy *name) {
  1153         prefix();
  1154         fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
  1155                 (name->binding() ? "" : " unbound"));
  1156     }
  1157     void visit(CallExpression *node) {
  1158         prefix();
  1159         fprintf(fp_, "[ CallExpression\n");
  1160         indent();
  1161         node->callee()->accept(this);
  1162         for (size_t i = 0; i < node->arguments()->length(); i++)
  1163             node->arguments()->at(i)->accept(this);
  1164         unindent();
  1165     }
  1166     void visit(FunctionStatement *node) {
  1167         prefix();
  1168         fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
  1169         indent();
  1170         if (node->body())
  1171             node->body()->accept(this);
  1172         unindent();
  1173     }
  1174     void visit(ExpressionStatement *node) {
  1175         prefix();
  1176         fprintf(fp_, "[ ExpressionStatement\n");
  1177         indent();
  1178         node->expression()->accept(this);
  1179         unindent();
  1180     }
  1181     void visit(Assignment *node) {
  1182         prefix();
  1183         fprintf(fp_, "[ Assignment\n");
  1184         indent();
  1185         node->lvalue()->accept(this);
  1186         node->expression()->accept(this);
  1187         unindent();
  1188     }
  1189     void visit(TernaryExpression *node) {
  1190         prefix();
  1191         fprintf(fp_, "[ TernaryExpression\n");
  1192         indent();
  1193         node->condition()->accept(this);
  1194         node->left()->accept(this);
  1195         node->right()->accept(this);
  1196         unindent();
  1197     }
  1198     void visit(BinaryExpression *node) {
  1199         prefix();
  1200         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
  1201         indent();
  1202         node->left()->accept(this);
  1203         node->right()->accept(this);
  1204         unindent();
  1205     }
  1206     void visit(UnaryExpression *node) {
  1207         prefix();
  1208         fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
  1209         indent();
  1210         node->expression()->accept(this);
  1211         unindent();
  1212     }
  1213     void visit(ReturnStatement *node) {
  1214         prefix();
  1215         fprintf(fp_, "[ ReturnStatement\n");
  1216         indent();
  1217         if (node->expression())
  1218             node->expression()->accept(this);
  1219         unindent();
  1220     }
  1221     void visit(ForStatement *node) {
  1222         prefix();
  1223         fprintf(fp_, "[ ForStatement\n");
  1224         indent();
  1225         if (node->initialization())
  1226             node->initialization()->accept(this);
  1227         if (node->condition())
  1228             node->condition()->accept(this);
  1229         if (node->update())
  1230             node->update()->accept(this);
  1231         node->body()->accept(this);
  1232         unindent();
  1233     }
  1234     void visit(BlockStatement *node) {
  1235         prefix();
  1236         fprintf(fp_, "[ BlockStatement\n");
  1237         indent();
  1238         for (size_t i = 0; i < node->statements()->length(); i++)
  1239             node->statements()->at(i)->accept(this);
  1240         unindent();
  1241     }
  1242     void visit(VariableDeclaration *node) {
  1243         prefix();
  1244         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
  1245         indent();
  1246         if (node->initialization())
  1247             node->initialization()->accept(this);
  1248         unindent();
  1249     }
  1250     void visit(IntegerLiteral *node) {
  1251         prefix();
  1252         fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
  1253     }
  1254     void visit(FloatLiteral *node) {
  1255         prefix();
  1256         fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
  1257     }
  1258     void visit(IfStatement *node) {
  1259         prefix();
  1260         fprintf(fp_, "[ IfStatement\n");
  1261         indent();
  1262         node->ifTrue()->accept(this);
  1263         if (node->ifFalse())
  1264             node->ifFalse()->accept(this);
  1265         unindent();
  1266     }
  1267     void visit(IndexExpression *node) {
  1268         prefix();
  1269         fprintf(fp_, "[ IndexExpression\n");
  1270         indent();
  1271         node->left()->accept(this);
  1272         node->right()->accept(this);
  1273         unindent();
  1274     }
  1275     void visit(EnumStatement *node) {
  1276         prefix();
  1277         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
  1278         indent();
  1279         for (size_t i = 0; i < node->entries()->length(); i++) {
  1280             prefix();
  1281             fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
  1282             if (node->entries()->at(i).expr) {
  1283                 indent();
  1284                 node->entries()->at(i).expr->accept(this);
  1285                 unindent();
  1286             }
  1287         }
  1288         unindent();
  1289     }
  1290     void visit(WhileStatement *node) {
  1291         prefix();
  1292         fprintf(fp_, "[ WhileStatement (%s)\n",
  1293                 (node->token() == TOK_DO) ? "do" : "while");
  1294         indent();
  1295         if (node->token() == TOK_DO) {
  1296             node->condition()->accept(this);
  1297             node->body()->accept(this);
  1298         } else {
  1299             node->condition()->accept(this);
  1300             node->body()->accept(this);
  1301         }
  1302         unindent();
  1303     }
  1304     void visit(BreakStatement *node) {
  1305         prefix();
  1306         fprintf(fp_, "[ BreakStatement\n");
  1307     }
  1308     void visit(ContinueStatement *node) {
  1309         prefix();
  1310         fprintf(fp_, "[ ContinueStatement\n");
  1311     }
  1312     void visit(StringLiteral *node) {
  1313         prefix();
  1314         fprintf(fp_, "[ StringLiteral\n");
  1315     }
  1316     void visit(IncDecExpression *node) {
  1317         prefix();
  1318         fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
  1319         indent();
  1320         node->expression()->accept(this);
  1321         unindent();
  1322     }
  1323 };
  1324 
  1325 void
  1326 ParseTree::dump(FILE *fp)
  1327 {
  1328     AstPrinter printer(fp);
  1329 
  1330     for (size_t i = 0; i < statements_->length(); i++)
  1331         statements_->at(i)->accept(&printer);
  1332 }