jitcraft/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Mon Jul 09 22:25:52 2012 -0700 (2012-07-09)
changeset 67 b765a6383849
parent 66 cbba1997dc71
child 68 b40b0e18a918
permissions -rw-r--r--
Implemented const for references and arrays.
     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 = expression();
   625     if (!expr)
   626         return NULL;
   627 
   628     return new (pool_) ReturnStatement(pos, expr);
   629 }
   630 
   631 Statement *
   632 Parser::expressionStatement()
   633 {
   634     Expression *left = assignment();
   635     if (!left)
   636         return NULL;
   637 
   638     return new (pool_) ExpressionStatement(left);
   639 }
   640 
   641 Statement *
   642 Parser::block(Scope *scope)
   643 {
   644     if (!expect(TOK_LBRACE))
   645         return NULL;
   646 
   647     SourcePosition pos = scanner_.begin();
   648     if (!scope && !enterScope(Scope::BLOCK))
   649         return NULL;
   650 
   651     StatementList *statements = new (pool_) StatementList();
   652     while (!match(TOK_RBRACE)) {
   653         Statement *statement = localStatement();
   654         if (statement == NULL)
   655             return NULL;
   656         if (!statements->append(statement))
   657             return NULL;
   658     }
   659 
   660     if (!scope) {
   661     	scope = scope_->unlinkIfEmpty();
   662         scope_ = scope_->enclosing();
   663     }
   664     BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
   665     return block;
   666 }
   667 
   668 Statement *
   669 Parser::if_()
   670 {
   671     expect(TOK_IF);
   672     
   673     SourcePosition pos = scanner_.begin();
   674     if (!expect(TOK_LPAREN))
   675         return NULL;
   676 
   677     Expression *cond = expression();
   678     if (!cond)
   679         return NULL;
   680 
   681     if (!expect(TOK_RPAREN))
   682         return NULL;
   683 
   684     Statement *ifTrue = localStatement();
   685     if (!ifTrue)
   686         return NULL;
   687 
   688     IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
   689 
   690     IfStatement *last = outer;
   691     while (match(TOK_ELSE)) {
   692         if (!match(TOK_IF)) {
   693             Statement *ifFalse = localStatement();
   694             if (!ifFalse)
   695                 return NULL;
   696 
   697             last->setIfFalse(ifFalse);
   698             break;
   699         }
   700 
   701         if (!expect(TOK_IF))
   702             return NULL;
   703 
   704         SourcePosition pos = scanner_.begin();
   705         if (!expect(TOK_LPAREN))
   706             return NULL;
   707 
   708         Expression *otherCond = expression();
   709         if (!otherCond)
   710             return NULL;
   711 
   712         if (!expect(TOK_RPAREN))
   713             return NULL;
   714 
   715         Statement *otherIfTrue = localStatement();
   716         if (!otherIfTrue)
   717             return NULL;
   718 
   719         IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
   720         last->setIfFalse(inner);
   721         last = inner;
   722     }
   723 
   724     return outer;
   725 }
   726 
   727 Statement *
   728 Parser::localStatement()
   729 {
   730     Statement *statement = NULL;
   731 
   732     // Statements which must be followed by a semicolon will break out of the
   733     // switch. If they may end in BlockStatements, they'll immediately return.
   734 
   735     switch (scanner_.peek()) {
   736         case TOK_NEW:
   737           if ((statement = variableDeclaration()) == NULL)
   738               return NULL;
   739           break;
   740 
   741         case TOK_FOR:
   742           return forStatement();
   743 
   744         case TOK_WHILE:
   745           return while_();
   746 
   747         case TOK_BREAK:
   748           scanner_.scan();
   749           statement = new (pool_) BreakStatement(scanner_.begin());
   750           break;
   751 
   752         case TOK_CONTINUE:
   753           scanner_.scan();
   754           statement = new (pool_) ContinueStatement(scanner_.begin());
   755           break;
   756 
   757         case TOK_DO:
   758           if ((statement = do_()) == NULL)
   759               return NULL;
   760           break;
   761 
   762         case TOK_RETURN:
   763           if ((statement = returnStatement()) == NULL)
   764               return NULL;
   765           break;
   766 
   767         case TOK_ENUM:
   768           if ((statement = enum_()) == NULL)
   769               return NULL;
   770           break;
   771 
   772         case TOK_IF:
   773           return if_();
   774 
   775         case TOK_LBRACE:
   776           return block();
   777 
   778 	default:
   779 	  break;
   780     }
   781 
   782     if (!statement) {
   783         if ((statement = expressionStatement()) == NULL)
   784             return NULL;
   785     }
   786 
   787     if (!expect(TOK_SEMICOLON))
   788         return NULL;
   789 
   790     return statement;
   791 }
   792 
   793 Statement *
   794 Parser::enum_()
   795 {
   796     expect(TOK_ENUM);
   797 
   798     SourcePosition pos = scanner_.begin();
   799 
   800     Local<String> name(zone_);
   801     if (matchName(name.ref())) {
   802         if (!name)
   803             return NULL;
   804 
   805         if (BoundName *other = scope_->localLookup(name)) {
   806             redeclarationError(other);
   807             return NULL;
   808         }
   809 
   810         if (!scope_->declareEnum(name, scanner_.begin()))
   811             return NULL;
   812     }
   813 
   814     EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
   815 
   816     if (!expect(TOK_LBRACE))
   817         return NULL;
   818 
   819     do {
   820         if (scanner_.peek() == TOK_RBRACE)
   821             break;
   822 
   823         Local<String> name(zone_, expectName());
   824         if (!name)
   825             return NULL;
   826 
   827         if (BoundName *other = scope_->localLookup(name)) {
   828             redeclarationError(other);
   829             return NULL;
   830         }
   831 
   832         NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
   833         if (!constant)
   834             return NULL;
   835 
   836         Expression *expr = NULL;
   837         if (match(TOK_ASSIGN)) {
   838             if ((expr = expression()) == NULL)
   839                 return NULL;
   840         }
   841 
   842         if (!entries->append(EnumStatement::Entry(constant, expr)))
   843             return NULL;
   844     } while (match(TOK_COMMA));
   845     if (!expect(TOK_RBRACE))
   846         return NULL;
   847 
   848     return new (pool_) EnumStatement(pos, name, entries);
   849 }
   850 
   851 Statement *
   852 Parser::function(TokenKind token)
   853 {
   854     Local<String> name(zone_, expectName());
   855     if (!name)
   856         return NULL;
   857 
   858     SourcePosition pos = scanner_.begin();
   859 
   860     // The function name goes into the outer (global) scope.
   861     assert(!scope_->enclosing());
   862 
   863     NamedFunction *fun;
   864     if (BoundName *other = scope_->localLookup(name)) {
   865         // We allow a redeclaration if the new type is a public, and the old
   866         // type was a forward. However, the forward must come first.
   867         if (other->kind() != BoundName::FUNCTION) {
   868             redeclarationError(other);
   869             return NULL;
   870         }
   871 
   872         fun = other->toNamedFunction();
   873         if (!fun->isForward() || token != TOK_PUBLIC) {
   874             redeclarationError(other);
   875             return NULL;
   876         }
   877         
   878         // We've got the same name, but the original is a forward, so let it
   879         // slide and re-use the original declaration.
   880         fun->setImplemented(scanner_.begin());
   881     } else {
   882         fun = scope_->declareFunction(name, scanner_.begin(), token);
   883         if (!fun)
   884             return NULL;
   885     }
   886 
   887     Scope *scope = enterScope(Scope::FUNCTION);
   888     if (!scope)
   889         return NULL;
   890 
   891     ParameterList *parameters = new (pool_) ParameterList();
   892 
   893     if (!expect(TOK_LPAREN))
   894         return NULL;
   895     if (!match(TOK_RPAREN)) {
   896         while (true) {
   897             bool isConst = match(TOK_CONST);
   898             bool ref = match(TOK_AMPERSAND);
   899 
   900             SourcePosition begin = scanner_.begin();
   901             Local<String> tag(zone_);
   902             if (matchName(tag.ref(), TOK_LABEL) && !tag)
   903                 return NULL;
   904 
   905             Local<String> name(zone_, expectName());
   906             if (!name)
   907                 return NULL;
   908 
   909             if (BoundName *other = scope_->localLookup(name)) {
   910                 redeclarationError(other);
   911                 return NULL;
   912             }
   913             Variable *arg = scope_->declareArgument(name, scanner_.begin());
   914             if (!arg)
   915                 return NULL;
   916 
   917             // Look for dimensions.
   918             ExpressionList *postDimensions = NULL;
   919             while (match(TOK_LBRACKET)) {
   920                 if (!postDimensions)
   921                     postDimensions = new (pool_) ExpressionList();
   922 
   923                 Expression *dim = NULL;
   924                 if (!match(TOK_RBRACKET)) {
   925                     if ((dim = expression()) == NULL)
   926                         return NULL;
   927                     if (!expect(TOK_RBRACKET))
   928                         return NULL;
   929                 }
   930 
   931                 if (!postDimensions->append(dim))
   932                     return NULL;
   933             }
   934 
   935             Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions);
   936             if (!parameters->append(parameter))
   937                 return NULL;
   938 
   939             if (!match(TOK_COMMA))
   940                 break;
   941         }
   942         if (!expect(TOK_RPAREN))
   943             return NULL;
   944     }
   945 
   946     Statement *body = NULL;
   947     if (token != TOK_FORWARD) {
   948         body = block();
   949         if (!body)
   950             return NULL;
   951     }
   952 
   953     scope_ = scope_->enclosing();
   954     return new (pool_) FunctionStatement(pos, scope, fun, body, parameters);
   955 }
   956 
   957 ParseTree *
   958 Parser::parse()
   959 {
   960     StatementList *statements = new (pool_) StatementList();
   961 
   962     if (!enterScope(Scope::GLOBAL))
   963         return NULL;
   964 
   965     for (;;) {
   966         Statement *statement = NULL;
   967 
   968         switch (scanner_.peek()) {
   969           case TOK_ERROR:
   970             return NULL;
   971 
   972           case TOK_EOF:
   973             break;
   974 
   975           case TOK_NAME:
   976             if ((statement = function(TOK_NAME)) == NULL)
   977                 return NULL;
   978             break;
   979 
   980           case TOK_FORWARD:
   981           case TOK_PUBLIC:
   982           {
   983             TokenKind kind = scanner_.scan();
   984             if ((statement = function(kind)) == NULL)
   985                 return NULL;
   986             if (kind == TOK_FORWARD && !matchSemicolon())
   987                 return NULL;
   988             break;
   989           }
   990 
   991           case TOK_ENUM:
   992             if ((statement = enum_()) == NULL)
   993                 return NULL;
   994             if (!matchSemicolon())
   995                 return NULL;
   996             break;
   997 
   998           default:
   999             cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
  1000             return NULL;
  1001         }
  1002 
  1003         if (!statement)
  1004             break;
  1005 
  1006         if (!statements->append(statement))
  1007             return NULL;
  1008     }
  1009 
  1010     return new (pool_) ParseTree(scope_, statements, unbound_);
  1011 }
  1012 
  1013 class AstPrinter : public AstVisitor
  1014 {
  1015     FILE *fp_;
  1016     size_t level_;
  1017 
  1018   private:
  1019     void prefix() {
  1020         for (size_t i = 0; i < level_; i++)
  1021             fprintf(fp_, "  ");
  1022     }
  1023     void indent() {
  1024         level_++;
  1025     }
  1026     void unindent() {
  1027         level_--;
  1028     }
  1029 
  1030   public:
  1031     AstPrinter(FILE *fp)
  1032       : fp_(fp),
  1033         level_(0)
  1034     {
  1035     }
  1036 
  1037     void visit(NameProxy *name) {
  1038         prefix();
  1039         fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
  1040                 (name->binding() ? "" : " unbound"));
  1041     }
  1042     void visit(CallExpression *node) {
  1043         prefix();
  1044         fprintf(fp_, "[ CallExpression\n");
  1045         indent();
  1046         node->callee()->accept(this);
  1047         for (size_t i = 0; i < node->arguments()->length(); i++)
  1048             node->arguments()->at(i)->accept(this);
  1049         unindent();
  1050     }
  1051     void visit(FunctionStatement *node) {
  1052         prefix();
  1053         fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
  1054         indent();
  1055         if (node->body())
  1056             node->body()->accept(this);
  1057         unindent();
  1058     }
  1059     void visit(ExpressionStatement *node) {
  1060         prefix();
  1061         fprintf(fp_, "[ ExpressionStatement\n");
  1062         indent();
  1063         node->expression()->accept(this);
  1064         unindent();
  1065     }
  1066     void visit(Assignment *node) {
  1067         prefix();
  1068         fprintf(fp_, "[ Assignment\n");
  1069         indent();
  1070         node->lvalue()->accept(this);
  1071         node->expression()->accept(this);
  1072         unindent();
  1073     }
  1074     void visit(BinaryExpression *node) {
  1075         prefix();
  1076         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
  1077         indent();
  1078         node->left()->accept(this);
  1079         node->right()->accept(this);
  1080         unindent();
  1081     }
  1082     void visit(ReturnStatement *node) {
  1083         prefix();
  1084         fprintf(fp_, "[ ReturnStatement\n");
  1085         indent();
  1086         node->expression()->accept(this);
  1087         unindent();
  1088     }
  1089     void visit(ForStatement *node) {
  1090         prefix();
  1091         fprintf(fp_, "[ ForStatement\n");
  1092         indent();
  1093         if (node->initialization())
  1094             node->initialization()->accept(this);
  1095         if (node->condition())
  1096             node->condition()->accept(this);
  1097         if (node->update())
  1098             node->update()->accept(this);
  1099         node->body()->accept(this);
  1100         unindent();
  1101     }
  1102     void visit(BlockStatement *node) {
  1103         prefix();
  1104         fprintf(fp_, "[ BlockStatement\n");
  1105         indent();
  1106         for (size_t i = 0; i < node->statements()->length(); i++)
  1107             node->statements()->at(i)->accept(this);
  1108         unindent();
  1109     }
  1110     void visit(VariableDeclaration *node) {
  1111         prefix();
  1112         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
  1113         indent();
  1114         if (node->initialization())
  1115             node->initialization()->accept(this);
  1116         unindent();
  1117     }
  1118     void visit(IntegerLiteral *node) {
  1119         prefix();
  1120         fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
  1121     }
  1122     void visit(FloatLiteral *node) {
  1123         prefix();
  1124         fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
  1125     }
  1126     void visit(IfStatement *node) {
  1127         prefix();
  1128         fprintf(fp_, "[ IfStatement\n");
  1129         indent();
  1130         node->ifTrue()->accept(this);
  1131         if (node->ifFalse())
  1132             node->ifFalse()->accept(this);
  1133         unindent();
  1134     }
  1135     void visit(IndexExpression *node) {
  1136         prefix();
  1137         fprintf(fp_, "[ IndexExpression\n");
  1138         indent();
  1139         node->left()->accept(this);
  1140         node->right()->accept(this);
  1141         unindent();
  1142     }
  1143     void visit(EnumStatement *node) {
  1144         prefix();
  1145         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
  1146         indent();
  1147         for (size_t i = 0; i < node->entries()->length(); i++) {
  1148             prefix();
  1149             fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
  1150             if (node->entries()->at(i).expr) {
  1151                 indent();
  1152                 node->entries()->at(i).expr->accept(this);
  1153                 unindent();
  1154             }
  1155         }
  1156         unindent();
  1157     }
  1158     void visit(WhileStatement *node) {
  1159         prefix();
  1160         fprintf(fp_, "[ WhileStatement (%s)\n",
  1161                 (node->token() == TOK_DO) ? "do" : "while");
  1162         indent();
  1163         if (node->token() == TOK_DO) {
  1164             node->condition()->accept(this);
  1165             node->body()->accept(this);
  1166         } else {
  1167             node->condition()->accept(this);
  1168             node->body()->accept(this);
  1169         }
  1170         unindent();
  1171     }
  1172     void visit(BreakStatement *node) {
  1173         prefix();
  1174         fprintf(fp_, "[ BreakStatement\n");
  1175     }
  1176     void visit(ContinueStatement *node) {
  1177         prefix();
  1178         fprintf(fp_, "[ ContinueStatement\n");
  1179     }
  1180     void visit(StringLiteral *node) {
  1181         prefix();
  1182         fprintf(fp_, "[ StringLiteral\n");
  1183     }
  1184     void visit(IncDecExpression *node) {
  1185         prefix();
  1186         fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
  1187         indent();
  1188         node->expression()->accept(this);
  1189         unindent();
  1190     }
  1191 };
  1192 
  1193 void
  1194 ParseTree::dump(FILE *fp)
  1195 {
  1196     AstPrinter printer(fp);
  1197 
  1198     for (size_t i = 0; i < statements_->length(); i++)
  1199         statements_->at(i)->accept(&printer);
  1200 }