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