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