jitcraft/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Sat Jul 07 21:30:23 2012 -0700 (2012-07-07)
changeset 59 b7d61ddb3c8d
parent 57 8f1e74d35718
child 63 dd57743d220e
permissions -rw-r--r--
Rename jc:: to ke::
     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::expect(TokenKind kind)
    50 {
    51     TokenKind got = scanner_.scan();
    52     if (got == kind)
    53         return true;
    54     cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
    55     return false;
    56 }
    57 
    58 Scope *
    59 Parser::enterScope(Scope::Kind kind)
    60 {
    61     scope_ = new (pool_) Scope(pool_, kind, scope_);
    62     if (!scope_->initialize())
    63         return NULL;
    64     return scope_;
    65 }
    66 
    67 NameProxy *
    68 Parser::bind(Handle<String> name)
    69 {
    70     BoundName *bound = scope_->lookup(name);
    71     NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
    72     if (!bound && !unbound_->append(proxy))
    73         return NULL;
    74     return proxy;
    75 }
    76 
    77 bool
    78 Parser::matchName(String **name, TokenKind kind)
    79 {
    80     assert(kind == TOK_NAME || kind == TOK_LABEL);
    81     *name = NULL;
    82     if (!match(kind))
    83         return false;
    84     *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
    85     return true;
    86 }
    87 
    88 String *
    89 Parser::expectName()
    90 {
    91     if (!expect(TOK_NAME))
    92         return NULL;
    93     return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
    94 }
    95 
    96 void
    97 Parser::redeclarationError(BoundName *other)
    98 {
    99     cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->pos().line, other->pos().col);
   100 }
   101 
   102 Expression *
   103 Parser::primitive()
   104 {
   105     TokenKind kind = scanner_.peek();
   106     switch (kind) {
   107       case TOK_NAME:
   108       {
   109         Local<String> name(zone_, expectName());
   110         if (!name)
   111             return NULL;
   112         return bind(name);
   113       }
   114 
   115       case TOK_FLOAT_LITERAL:
   116       {
   117         scanner_.scan();
   118         double value = Scanner::ParseDouble(scanner_.literal());
   119         return new (pool_) FloatLiteral(scanner_.begin(), value);
   120       }
   121 
   122       case TOK_INTEGER_LITERAL:
   123       {
   124         scanner_.scan();
   125         int value = atoi(scanner_.literal());
   126         return new (pool_) IntegerLiteral(scanner_.begin(), value);
   127       }
   128 
   129       case TOK_STRING_LITERAL:
   130       {
   131         scanner_.scan();
   132         Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
   133         if (!array)
   134             return NULL;
   135         memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
   136         return new (pool_) StringLiteral(scanner_.begin(), array);
   137       }
   138 
   139       default:
   140       {
   141         if (kind != TOK_ERROR)
   142             cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
   143         return NULL;
   144       }
   145     }
   146 }
   147 
   148 Expression *
   149 Parser::prefix()
   150 {
   151     switch (scanner_.peek()) {
   152       case TOK_LPAREN:
   153       {
   154         scanner_.scan();
   155         Expression *expr = expression();
   156         if (!expr)
   157             return NULL;
   158         if (!expect(TOK_RPAREN))
   159             return NULL;
   160         return expr;
   161       }
   162 
   163       default:
   164         return primitive();
   165     }
   166 }
   167 
   168 Expression *
   169 Parser::call(Expression *callee)
   170 {
   171     ExpressionList *arguments = new (pool_) ExpressionList();
   172 
   173     SourcePosition pos = scanner_.begin();
   174     expect(TOK_LPAREN);
   175     
   176     if (!match(TOK_RPAREN)) {
   177         while (true) {
   178             Expression *expr = expression();
   179             if (!expr)
   180                 return NULL;
   181 
   182             if (!arguments->append(expr))
   183                 return NULL;
   184 
   185             if (!match(TOK_COMMA))
   186                 break;
   187         }
   188 
   189         if (!expect(TOK_RPAREN))
   190             return NULL;
   191     }
   192 
   193     return new (pool_) CallExpression(pos, callee, arguments);
   194 }
   195 
   196 Expression *
   197 Parser::index(Expression *left)
   198 {
   199     expect(TOK_LBRACKET);
   200     
   201     SourcePosition pos = scanner_.begin();
   202     Expression *expr = expression();
   203     if (!expr)
   204         return NULL;
   205 
   206     if (!expect(TOK_RBRACKET))
   207         return NULL;
   208 
   209     return new (pool_) IndexExpression(pos, left, expr);
   210 }
   211 
   212 Expression *
   213 Parser::primary()
   214 {
   215     Expression *expr = prefix();
   216     if (!expr)
   217         return NULL;
   218 
   219     for (;;) {
   220         switch (scanner_.peek()) {
   221           case TOK_LPAREN:
   222             expr = call(expr);
   223             if (!expr)
   224                 return NULL;
   225             break;
   226 
   227           case TOK_LBRACKET:
   228             expr = index(expr);
   229             if (!expr)
   230                 return NULL;
   231             break;
   232 
   233           default:
   234             return expr;
   235         }
   236     }
   237 }
   238 
   239 Expression *
   240 Parser::unary()
   241 {
   242     TokenKind token = scanner_.peek();
   243 
   244     SourcePosition pos = scanner_.begin();
   245     switch (token) {
   246       case TOK_INCREMENT:
   247       case TOK_DECREMENT:
   248       {
   249         scanner_.scan();
   250         Expression *expr = expression();
   251         if (!expr)
   252             return NULL;
   253 
   254         return new (pool_) IncDecExpression(pos, token, expr, false);
   255       }
   256       default:
   257         break;
   258     }
   259 
   260 
   261     Expression *expr = primary();
   262 
   263     token = scanner_.peek();
   264     if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
   265         scanner_.scan();
   266         return new (pool_) IncDecExpression(pos, token, expr, true);
   267     }
   268 
   269     return expr;
   270 }
   271 
   272 Expression *
   273 Parser::multiplication()
   274 {
   275     Expression *left = unary();
   276     do {
   277         if (!match(TOK_SLASH) && !match(TOK_STAR))
   278             break;
   279         SourcePosition pos = scanner_.begin();
   280         TokenKind kind = scanner_.last();
   281         Expression *right = unary();
   282         if (!right)
   283             return NULL;
   284         left = new (pool_) BinaryExpression(pos, kind, left, right);
   285     } while (left);
   286     return left;
   287 }
   288 
   289 Expression *
   290 Parser::addition()
   291 {
   292     Expression *left = multiplication();
   293     while (left) {
   294         if (!match(TOK_PLUS) && !match(TOK_MINUS))
   295             break;
   296         SourcePosition pos = scanner_.begin();
   297         TokenKind kind = scanner_.last();
   298         Expression *right = multiplication();
   299         if (!right)
   300             return NULL;
   301         left = new (pool_) BinaryExpression(pos, kind, left, right);
   302     }
   303     return left;
   304 }
   305 
   306 Expression *
   307 Parser::shift()
   308 {
   309     Expression *left = addition();
   310     while (left) {
   311         if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
   312             break;
   313         SourcePosition pos = scanner_.begin();
   314         TokenKind kind = scanner_.last();
   315         Expression *right = addition();
   316         if (!right)
   317             return NULL;
   318         left = new (pool_) BinaryExpression(pos, kind, left, right);
   319     }
   320     return left;
   321 }
   322 
   323 Expression *
   324 Parser::bitand_()
   325 {
   326     Expression *left = shift();
   327     while (left) {
   328         if (!match(TOK_BITAND))
   329             break;
   330         SourcePosition pos = scanner_.begin();
   331         Expression *right = shift();
   332         if (!right)
   333             return NULL;
   334         left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
   335     }
   336     return left;
   337 }
   338 
   339 Expression *
   340 Parser::bitxor()
   341 {
   342     Expression *left = bitand_();
   343     while (left) {
   344         if (!match(TOK_BITXOR))
   345             break;
   346         SourcePosition pos = scanner_.begin();
   347         Expression *right = shift();
   348         if (!right)
   349             return NULL;
   350         left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
   351     }
   352     return left;
   353 }
   354 
   355 Expression *
   356 Parser::bitor_()
   357 {
   358     Expression *left = bitxor();
   359     while (left) {
   360         if (!match(TOK_BITOR))
   361             break;
   362         SourcePosition pos = scanner_.begin();
   363         Expression *right = shift();
   364         if (!right)
   365             return NULL;
   366         left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
   367     }
   368     return left;
   369 }
   370 
   371 Expression *
   372 Parser::relational()
   373 {
   374     Expression *left = bitor_();
   375     while (left) {
   376         TokenKind kind = scanner_.peek();
   377         if (kind < TOK_LT || kind > TOK_GE)
   378             break;
   379         scanner_.scan();
   380         SourcePosition pos = scanner_.begin();
   381         Expression *right = shift();
   382         if (!right)
   383             return NULL;
   384         left = new (pool_) BinaryExpression(pos, kind, left, right);
   385     }
   386     return left;
   387 }
   388 
   389 Expression *
   390 Parser::equals()
   391 {
   392     Expression *left = relational();
   393     while (left) {
   394         if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   395             break;
   396         TokenKind kind = scanner_.last();
   397         SourcePosition pos = scanner_.begin();
   398         Expression *right = relational();
   399         if (!right)
   400             return NULL;
   401         left = new (pool_) BinaryExpression(pos, kind, left, right);
   402     }
   403     return left;
   404 }
   405 
   406 Expression *
   407 Parser::assignment()
   408 {
   409     Expression *left = equals();
   410     while (left) {
   411         TokenKind token = scanner_.peek();
   412         if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
   413             break;
   414         scanner_.scan();
   415         SourcePosition pos = scanner_.begin();
   416         Expression *expr = equals();
   417         if (!expr)
   418             return NULL;
   419 
   420         left = new (pool_) Assignment(pos, token, left, expr);
   421     }
   422     return left;
   423 }
   424 
   425 Expression *
   426 Parser::expression()
   427 {
   428     return assignment();
   429 }
   430 
   431 Statement *
   432 Parser::while_()
   433 {
   434     SourcePosition pos = scanner_.begin();
   435     scanner_.scan();
   436 
   437     if (!expect(TOK_LPAREN))
   438         return NULL;
   439 
   440     Expression *condition = expression();
   441     if (!condition)
   442         return NULL;
   443 
   444     if (!expect(TOK_RPAREN))
   445         return NULL;
   446 
   447     // Inside a loop, we force the creation of a scope object. Normally, we
   448     // will cull scopes if they have no variables. However inside a loop,
   449     // function calls that take references may compute a LIFO object, and to
   450     // avoid temporarily leaking many such objects, we ensure that a scope
   451     // is present so a LIFO slot can be allocated.
   452     if (!enterScope(Scope::BLOCK))
   453         return NULL;
   454 
   455     Statement *body;
   456     if (scanner_.peek() == TOK_LBRACE)
   457         body = block(scope_);
   458     else
   459         body = localStatement();
   460     if (!body)
   461         return NULL;
   462 
   463     scope_ = scope_->enclosing();
   464     return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
   465 }
   466 
   467 Statement *
   468 Parser::do_()
   469 {
   470     SourcePosition pos = scanner_.begin();
   471     scanner_.scan();
   472 
   473     // See the comment in ::while_() as to why we force a scope.
   474     if (!enterScope(Scope::BLOCK))
   475         return NULL;
   476 
   477     Statement *body;
   478     if (scanner_.peek() == TOK_LBRACE)
   479         body = block(scope_);
   480     else
   481         body = localStatement();
   482     if (!body)
   483         return NULL;
   484 
   485     scope_ = scope_->enclosing();
   486 
   487     if (!expect(TOK_WHILE))
   488         return NULL;
   489 
   490     if (!expect(TOK_LPAREN))
   491         return NULL;
   492     Expression *condition = expression();
   493     if (!condition)
   494         return NULL;
   495     if (!expect(TOK_RPAREN))
   496         return NULL;
   497 
   498     return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
   499 }
   500 
   501 Statement *
   502 Parser::forStatement()
   503 {
   504     SourcePosition pos = scanner_.begin();
   505     scanner_.scan();
   506     if (!expect(TOK_LPAREN))
   507         return NULL;
   508 
   509     Statement *decl = NULL;
   510     if (!match(TOK_SEMICOLON)) {
   511         if (scanner_.peek() == TOK_NEW) {
   512             if (!enterScope(Scope::BLOCK))
   513                 return NULL;
   514             if ((decl = variableDeclaration()) == NULL)
   515                 return NULL;
   516         } else {
   517             if ((decl = expressionStatement()) == NULL)
   518                 return NULL;
   519         }
   520         if (!expect(TOK_SEMICOLON))
   521             return NULL;
   522     }
   523 
   524     Expression *condition = NULL;
   525     if (!match(TOK_SEMICOLON)) {
   526         if ((condition = expression()) == NULL)
   527             return NULL;
   528         if (!expect(TOK_SEMICOLON))
   529             return NULL;
   530     }
   531 
   532     Statement *update = NULL;
   533     if (!match(TOK_RPAREN)) {
   534         if ((update = expressionStatement()) == NULL)
   535             return NULL;
   536         if (!expect(TOK_RPAREN))
   537             return NULL;
   538     }
   539 
   540     // See the comment in ::while_() as to why we force a scope.
   541     if (!enterScope(Scope::BLOCK))
   542         return NULL;
   543 
   544     Statement *body;
   545     if (scanner_.peek() == TOK_LBRACE)
   546         body = block(scope_);
   547     else
   548         body = localStatement();
   549     if (!body)
   550         return NULL;
   551 
   552     scope_ = scope_->enclosing();
   553 
   554     Scope *declScope = NULL;
   555     if (decl && decl->isVariableDeclaration()) {
   556         declScope = scope_->unlinkIfEmpty();
   557         scope_ = scope_->enclosing();
   558     }
   559     return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
   560 }
   561 
   562 VariableDeclaration *
   563 Parser::variableDeclaration()
   564 {
   565     if (!expect(TOK_NEW))
   566         return NULL;
   567 
   568     Local<String> tag(zone_);
   569     if (matchName(tag.ref(), TOK_LABEL) && !tag)
   570         return NULL;
   571 
   572     Local<String> name(zone_, expectName());
   573     if (!name)
   574         return NULL;
   575 
   576     if (BoundName *other = scope_->localLookup(name)) {
   577         redeclarationError(other);
   578         return NULL;
   579     }
   580 
   581     Variable *var = scope_->declareVariable(name, scanner_.begin());
   582     if (!var)
   583         return NULL;
   584 
   585     ExpressionList *postDimensions = NULL;
   586     if (scanner_.peek() == TOK_LBRACKET) {
   587         postDimensions = new (pool_) ExpressionList();
   588         while (match(TOK_LBRACKET)) {
   589             Expression *dim = expression();
   590             if (!dim)
   591                 return NULL;
   592 
   593             if (!expect(TOK_RBRACKET))
   594                 return NULL;
   595 
   596             if (!postDimensions->append(dim))
   597                 return NULL;
   598         }
   599     }
   600     
   601     Expression *expr = NULL;
   602     if (match(TOK_ASSIGN)) {
   603         if ((expr = expression()) == NULL)
   604             return NULL;
   605     }
   606 
   607     return new (pool_) VariableDeclaration(var->pos(), var, tag, postDimensions, expr);
   608 }
   609 
   610 Statement *
   611 Parser::returnStatement()
   612 {
   613     SourcePosition pos = scanner_.begin();
   614     if (!expect(TOK_RETURN))
   615         return NULL;
   616 
   617     Expression *expr = expression();
   618     if (!expr)
   619         return NULL;
   620 
   621     return new (pool_) ReturnStatement(pos, expr);
   622 }
   623 
   624 Statement *
   625 Parser::expressionStatement()
   626 {
   627     Expression *left = assignment();
   628     if (!left)
   629         return NULL;
   630 
   631     return new (pool_) ExpressionStatement(left);
   632 }
   633 
   634 Statement *
   635 Parser::block(Scope *scope)
   636 {
   637     if (!expect(TOK_LBRACE))
   638         return NULL;
   639 
   640     SourcePosition pos = scanner_.begin();
   641     if (!scope && !enterScope(Scope::BLOCK))
   642         return NULL;
   643 
   644     StatementList *statements = new (pool_) StatementList();
   645     while (!match(TOK_RBRACE)) {
   646         Statement *statement = localStatement();
   647         if (statement == NULL)
   648             return NULL;
   649         if (!statements->append(statement))
   650             return NULL;
   651     }
   652 
   653     if (!scope) {
   654     	scope = scope_->unlinkIfEmpty();
   655         scope_ = scope_->enclosing();
   656     }
   657     BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
   658     return block;
   659 }
   660 
   661 Statement *
   662 Parser::if_()
   663 {
   664     expect(TOK_IF);
   665     
   666     SourcePosition pos = scanner_.begin();
   667     if (!expect(TOK_LPAREN))
   668         return NULL;
   669 
   670     Expression *cond = expression();
   671     if (!cond)
   672         return NULL;
   673 
   674     if (!expect(TOK_RPAREN))
   675         return NULL;
   676 
   677     Statement *ifTrue = localStatement();
   678     if (!ifTrue)
   679         return NULL;
   680 
   681     IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
   682 
   683     IfStatement *last = outer;
   684     while (match(TOK_ELSE)) {
   685         if (!match(TOK_IF)) {
   686             Statement *ifFalse = localStatement();
   687             if (!ifFalse)
   688                 return NULL;
   689 
   690             last->setIfFalse(ifFalse);
   691             break;
   692         }
   693 
   694         if (!expect(TOK_IF))
   695             return NULL;
   696 
   697         SourcePosition pos = scanner_.begin();
   698         if (!expect(TOK_LPAREN))
   699             return NULL;
   700 
   701         Expression *otherCond = expression();
   702         if (!otherCond)
   703             return NULL;
   704 
   705         if (!expect(TOK_RPAREN))
   706             return NULL;
   707 
   708         Statement *otherIfTrue = localStatement();
   709         if (!otherIfTrue)
   710             return NULL;
   711 
   712         IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
   713         last->setIfFalse(inner);
   714         last = inner;
   715     }
   716 
   717     return outer;
   718 }
   719 
   720 Statement *
   721 Parser::localStatement()
   722 {
   723     Statement *statement = NULL;
   724 
   725     // Statements which must be followed by a semicolon will break out of the
   726     // switch. If they may end in BlockStatements, they'll immediately return.
   727 
   728     switch (scanner_.peek()) {
   729         case TOK_NEW:
   730           if ((statement = variableDeclaration()) == NULL)
   731               return NULL;
   732           break;
   733 
   734         case TOK_FOR:
   735           return forStatement();
   736 
   737         case TOK_WHILE:
   738           return while_();
   739 
   740         case TOK_BREAK:
   741           scanner_.scan();
   742           statement = new (pool_) BreakStatement(scanner_.begin());
   743           break;
   744 
   745         case TOK_CONTINUE:
   746           scanner_.scan();
   747           statement = new (pool_) ContinueStatement(scanner_.begin());
   748           break;
   749 
   750         case TOK_DO:
   751           if ((statement = do_()) == NULL)
   752               return NULL;
   753           break;
   754 
   755         case TOK_RETURN:
   756           if ((statement = returnStatement()) == NULL)
   757               return NULL;
   758           break;
   759 
   760         case TOK_ENUM:
   761           if ((statement = enum_()) == NULL)
   762               return NULL;
   763           break;
   764 
   765         case TOK_IF:
   766           return if_();
   767 
   768         case TOK_LBRACE:
   769           return block();
   770 
   771 	default:
   772 	  break;
   773     }
   774 
   775     if (!statement) {
   776         if ((statement = expressionStatement()) == NULL)
   777             return NULL;
   778     }
   779 
   780     if (!expect(TOK_SEMICOLON))
   781         return NULL;
   782 
   783     return statement;
   784 }
   785 
   786 Statement *
   787 Parser::enum_()
   788 {
   789     expect(TOK_ENUM);
   790 
   791     SourcePosition pos = scanner_.begin();
   792 
   793     Local<String> name(zone_);
   794     if (matchName(name.ref())) {
   795         if (!name)
   796             return NULL;
   797 
   798         if (BoundName *other = scope_->localLookup(name)) {
   799             redeclarationError(other);
   800             return NULL;
   801         }
   802 
   803         if (!scope_->declareEnum(name, scanner_.begin()))
   804             return NULL;
   805     }
   806 
   807     EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
   808 
   809     if (!expect(TOK_LBRACE))
   810         return NULL;
   811 
   812     do {
   813         if (scanner_.peek() == TOK_RBRACE)
   814             break;
   815 
   816         Local<String> name(zone_, expectName());
   817         if (!name)
   818             return NULL;
   819 
   820         if (BoundName *other = scope_->localLookup(name)) {
   821             redeclarationError(other);
   822             return NULL;
   823         }
   824 
   825         NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
   826         if (!constant)
   827             return NULL;
   828 
   829         Expression *expr = NULL;
   830         if (match(TOK_ASSIGN)) {
   831             if ((expr = expression()) == NULL)
   832                 return NULL;
   833         }
   834 
   835         if (!entries->append(EnumStatement::Entry(constant, expr)))
   836             return NULL;
   837     } while (match(TOK_COMMA));
   838     if (!expect(TOK_RBRACE))
   839         return NULL;
   840 
   841     return new (pool_) EnumStatement(pos, name, entries);
   842 }
   843 
   844 Statement *
   845 Parser::function()
   846 {
   847     Local<String> name(zone_, expectName());
   848     if (!name)
   849         return NULL;
   850 
   851     SourcePosition pos = scanner_.begin();
   852 
   853     // The function name goes into the outer (global) scope.
   854     assert(!scope_->enclosing());
   855 
   856     if (BoundName *other = scope_->localLookup(name)) {
   857         redeclarationError(other);
   858         return NULL;
   859     }
   860     NamedFunction *fun = scope_->declareFunction(name, scanner_.begin());
   861     if (!fun)
   862         return NULL;
   863 
   864     Scope *scope = enterScope(Scope::FUNCTION);
   865     if (!scope)
   866         return NULL;
   867 
   868     ParameterList *parameters = new (pool_) ParameterList();
   869 
   870     if (!expect(TOK_LPAREN))
   871         return NULL;
   872     if (!match(TOK_RPAREN)) {
   873         while (true) {
   874             bool ref = match(TOK_AMPERSAND);
   875 
   876             Local<String> name(zone_, expectName());
   877             if (!name)
   878                 return NULL;
   879 
   880             if (BoundName *other = scope_->localLookup(name)) {
   881                 redeclarationError(other);
   882                 return NULL;
   883             }
   884             Variable *arg = scope_->declareArgument(name, scanner_.begin());
   885             if (!arg)
   886                 return NULL;
   887 
   888             Local<String> tag(zone_);
   889             Parameter *parameter = new (pool_) Parameter(arg, tag, ref);
   890             if (!parameters->append(parameter))
   891                 return NULL;
   892 
   893             if (!match(TOK_COMMA))
   894                 break;
   895         }
   896         if (!expect(TOK_RPAREN))
   897             return NULL;
   898     }
   899 
   900     Statement *body = block();
   901     if (!body)
   902         return NULL;
   903 
   904     scope_ = scope_->enclosing();
   905     return new (pool_) FunctionStatement(pos, scope, fun, body, parameters);
   906 }
   907 
   908 ParseTree *
   909 Parser::parse()
   910 {
   911     StatementList *statements = new (pool_) StatementList();
   912 
   913     if (!enterScope(Scope::GLOBAL))
   914         return NULL;
   915 
   916     for (;;) {
   917         Statement *statement = NULL;
   918 
   919         switch (scanner_.peek()) {
   920           case TOK_ERROR:
   921             return NULL;
   922 
   923           case TOK_EOF:
   924             break;
   925 
   926           case TOK_NAME:
   927             if ((statement = function()) == NULL)
   928                 return NULL;
   929             break;
   930 
   931           case TOK_ENUM:
   932             if ((statement = enum_()) == NULL)
   933                 return NULL;
   934             // :TODO: require semicolon
   935             break;
   936 
   937           default:
   938             fprintf(stderr, "expected function or global variable\n");
   939             return NULL;
   940         }
   941 
   942         if (!statement)
   943             break;
   944 
   945         if (!statements->append(statement))
   946             return NULL;
   947     }
   948 
   949     return new (pool_) ParseTree(scope_, statements, unbound_);
   950 }
   951 
   952 class AstPrinter : public AstVisitor
   953 {
   954     FILE *fp_;
   955     size_t level_;
   956 
   957   private:
   958     void prefix() {
   959         for (size_t i = 0; i < level_; i++)
   960             fprintf(fp_, "  ");
   961     }
   962     void indent() {
   963         level_++;
   964     }
   965     void unindent() {
   966         level_--;
   967     }
   968 
   969   public:
   970     AstPrinter(FILE *fp)
   971       : fp_(fp),
   972         level_(0)
   973     {
   974     }
   975 
   976     void visit(NameProxy *name) {
   977         prefix();
   978         fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
   979                 (name->binding() ? "" : " unbound"));
   980     }
   981     void visit(CallExpression *node) {
   982         prefix();
   983         fprintf(fp_, "[ CallExpression\n");
   984         indent();
   985         node->callee()->accept(this);
   986         for (size_t i = 0; i < node->arguments()->length(); i++)
   987             node->arguments()->at(i)->accept(this);
   988         unindent();
   989     }
   990     void visit(FunctionStatement *node) {
   991         prefix();
   992         fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
   993         indent();
   994         node->body()->accept(this);
   995         unindent();
   996     }
   997     void visit(ExpressionStatement *node) {
   998         prefix();
   999         fprintf(fp_, "[ ExpressionStatement\n");
  1000         indent();
  1001         node->expression()->accept(this);
  1002         unindent();
  1003     }
  1004     void visit(Assignment *node) {
  1005         prefix();
  1006         fprintf(fp_, "[ Assignment\n");
  1007         indent();
  1008         node->lvalue()->accept(this);
  1009         node->expression()->accept(this);
  1010         unindent();
  1011     }
  1012     void visit(BinaryExpression *node) {
  1013         prefix();
  1014         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
  1015         indent();
  1016         node->left()->accept(this);
  1017         node->right()->accept(this);
  1018         unindent();
  1019     }
  1020     void visit(ReturnStatement *node) {
  1021         prefix();
  1022         fprintf(fp_, "[ ReturnStatement\n");
  1023         indent();
  1024         node->expression()->accept(this);
  1025         unindent();
  1026     }
  1027     void visit(ForStatement *node) {
  1028         prefix();
  1029         fprintf(fp_, "[ ForStatement\n");
  1030         indent();
  1031         if (node->initialization())
  1032             node->initialization()->accept(this);
  1033         if (node->condition())
  1034             node->condition()->accept(this);
  1035         if (node->update())
  1036             node->update()->accept(this);
  1037         node->body()->accept(this);
  1038         unindent();
  1039     }
  1040     void visit(BlockStatement *node) {
  1041         prefix();
  1042         fprintf(fp_, "[ BlockStatement\n");
  1043         indent();
  1044         for (size_t i = 0; i < node->statements()->length(); i++)
  1045             node->statements()->at(i)->accept(this);
  1046         unindent();
  1047     }
  1048     void visit(VariableDeclaration *node) {
  1049         prefix();
  1050         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
  1051         indent();
  1052         if (node->initialization())
  1053             node->initialization()->accept(this);
  1054         unindent();
  1055     }
  1056     void visit(IntegerLiteral *node) {
  1057         prefix();
  1058         fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
  1059     }
  1060     void visit(FloatLiteral *node) {
  1061         prefix();
  1062         fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
  1063     }
  1064     void visit(IfStatement *node) {
  1065         prefix();
  1066         fprintf(fp_, "[ IfStatement\n");
  1067         indent();
  1068         node->ifTrue()->accept(this);
  1069         if (node->ifFalse())
  1070             node->ifFalse()->accept(this);
  1071         unindent();
  1072     }
  1073     void visit(IndexExpression *node) {
  1074         prefix();
  1075         fprintf(fp_, "[ IndexExpression\n");
  1076         indent();
  1077         node->left()->accept(this);
  1078         node->right()->accept(this);
  1079         unindent();
  1080     }
  1081     void visit(EnumStatement *node) {
  1082         prefix();
  1083         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
  1084         indent();
  1085         for (size_t i = 0; i < node->entries()->length(); i++) {
  1086             prefix();
  1087             fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
  1088             if (node->entries()->at(i).expr) {
  1089                 indent();
  1090                 node->entries()->at(i).expr->accept(this);
  1091                 unindent();
  1092             }
  1093         }
  1094         unindent();
  1095     }
  1096     void visit(WhileStatement *node) {
  1097         prefix();
  1098         fprintf(fp_, "[ WhileStatement (%s)\n",
  1099                 (node->token() == TOK_DO) ? "do" : "while");
  1100         indent();
  1101         if (node->token() == TOK_DO) {
  1102             node->condition()->accept(this);
  1103             node->body()->accept(this);
  1104         } else {
  1105             node->condition()->accept(this);
  1106             node->body()->accept(this);
  1107         }
  1108         unindent();
  1109     }
  1110     void visit(BreakStatement *node) {
  1111         prefix();
  1112         fprintf(fp_, "[ BreakStatement\n");
  1113     }
  1114     void visit(ContinueStatement *node) {
  1115         prefix();
  1116         fprintf(fp_, "[ ContinueStatement\n");
  1117     }
  1118     void visit(StringLiteral *node) {
  1119         prefix();
  1120         fprintf(fp_, "[ StringLiteral\n");
  1121     }
  1122     void visit(IncDecExpression *node) {
  1123         prefix();
  1124         fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
  1125         indent();
  1126         node->expression()->accept(this);
  1127         unindent();
  1128     }
  1129 };
  1130 
  1131 void
  1132 ParseTree::dump(FILE *fp)
  1133 {
  1134     AstPrinter printer(fp);
  1135 
  1136     for (size_t i = 0; i < statements_->length(); i++)
  1137         statements_->at(i)->accept(&printer);
  1138 }