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