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