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