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