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