jitcraft/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Mon Jun 25 02:57:28 2012 -0700 (2012-06-25)
changeset 0 c455ebb9a5dc
child 2 46fc53b8fd2f
permissions -rw-r--r--
Initial import of prototype.
     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 
    21 using namespace jc;
    22 
    23 Parser::Parser(const char *stream, size_t length)
    24   : pool_(ZONE()->pool()),
    25     strings_(pool_),
    26     scanner_(stream, length),
    27     scope_(NULL),
    28     unbound_(NULL)
    29 {
    30     unbound_ = new std::vector<NameProxy *>();
    31 }
    32 
    33 bool
    34 Parser::match(TokenKind kind)
    35 {
    36     if (scanner_.peek() != kind)
    37         return false;
    38     scanner_.scan();
    39     return true;
    40 }
    41 
    42 bool
    43 Parser::expect(TokenKind kind)
    44 {
    45     TokenKind got = scanner_.scan();
    46     if (got == kind)
    47         return true;
    48     fprintf(stderr, "error: expected %s, got %s\n", TokenNames[kind], TokenNames[got]);
    49     return false;
    50 }
    51 
    52 Scope *
    53 Parser::enterScope(Scope::Kind kind)
    54 {
    55     scope_ = new (pool_) Scope(pool_, kind, scope_);
    56     if (!scope_->initialize())
    57         return NULL;
    58     return scope_;
    59 }
    60 
    61 NameProxy *
    62 Parser::bind(Name *name)
    63 {
    64     BoundName *bound = scope_->lookup(name);
    65     NameProxy *proxy = new (pool_) NameProxy(name, bound);
    66     if (!bound)
    67         unbound_->push_back(proxy);
    68     return proxy;
    69 }
    70 
    71 Expression *
    72 Parser::primitive()
    73 {
    74     switch (scanner_.peek()) {
    75       case TOK_NAME:
    76       {
    77         scanner_.scan();
    78         Name *name = strings_.add(scanner_.literal());
    79         return bind(name);
    80       }
    81 
    82       case TOK_INTEGER_LITERAL:
    83       {
    84         scanner_.scan();
    85         int value = atoi(scanner_.literal());
    86         return new (pool_) IntegerLiteralExpression(value);
    87       }
    88 
    89       default:
    90       {
    91         fprintf(stderr, "error: expected expression!\n");
    92         return NULL;
    93       }
    94     }
    95 }
    96 
    97 Expression *
    98 Parser::prefix()
    99 {
   100     switch (scanner_.peek()) {
   101       case TOK_LPAREN:
   102       {
   103         scanner_.scan();
   104         Expression *expr = expression();
   105         if (!expr)
   106             return NULL;
   107         if (!expect(TOK_RPAREN))
   108             return NULL;
   109         return expr;
   110       }
   111 
   112       default:
   113         return primitive();
   114     }
   115 }
   116 
   117 Expression *
   118 Parser::call(Expression *callee)
   119 {
   120     ExpressionList *arguments = new ExpressionList();
   121 
   122     expect(TOK_LPAREN);
   123     
   124     if (!match(TOK_RPAREN)) {
   125         while (true) {
   126             Expression *expr = expression();
   127             if (!expr)
   128                 return NULL;
   129 
   130             arguments->push_back(expr);
   131 
   132             if (!match(TOK_COMMA))
   133                 break;
   134         }
   135 
   136         if (!expect(TOK_RPAREN))
   137             return NULL;
   138     }
   139 
   140     return new (pool_) CallExpression(callee, arguments);
   141 }
   142 
   143 Expression *
   144 Parser::index(Expression *left)
   145 {
   146     expect(TOK_LBRACKET);
   147     
   148     Expression *expr = expression();
   149     if (!expr)
   150         return NULL;
   151 
   152     if (!expect(TOK_RBRACKET))
   153         return NULL;
   154 
   155     return new (pool_) IndexExpression(left, expr);
   156 }
   157 
   158 Expression *
   159 Parser::primary()
   160 {
   161     Expression *expr = prefix();
   162     if (!expr)
   163         return NULL;
   164 
   165     for (;;) {
   166         switch (scanner_.peek()) {
   167           case TOK_LPAREN:
   168             expr = call(expr);
   169             if (!expr)
   170                 return NULL;
   171             break;
   172 
   173           case TOK_LBRACKET:
   174             expr = index(expr);
   175             if (!expr)
   176                 return NULL;
   177             break;
   178 
   179           default:
   180             return expr;
   181         }
   182     }
   183 }
   184 
   185 Expression *
   186 Parser::unary()
   187 {
   188     return primary();
   189 }
   190 
   191 Expression *
   192 Parser::multiplication()
   193 {
   194     Expression *left = unary();
   195     do {
   196         if (!match(TOK_SLASH) && !match(TOK_STAR))
   197             break;
   198         TokenKind kind = scanner_.last();
   199         Expression *right = unary();
   200         if (!right)
   201             return NULL;
   202         left = new (pool_) BinaryExpression(kind, left, right);
   203     } while (left);
   204     return left;
   205 }
   206 
   207 Expression *
   208 Parser::addition()
   209 {
   210     Expression *left = multiplication();
   211     while (left) {
   212         if (!match(TOK_PLUS) && !match(TOK_MINUS))
   213             break;
   214         TokenKind kind = scanner_.last();
   215         Expression *right = multiplication();
   216         if (!right)
   217             return NULL;
   218         left = new (pool_) BinaryExpression(kind, left, right);
   219     }
   220     return left;
   221 }
   222 
   223 Expression *
   224 Parser::relational()
   225 {
   226     Expression *left = addition();
   227     while (left) {
   228         TokenKind kind = scanner_.peek();
   229         if (kind < TOK_LT || kind > TOK_GE)
   230             break;
   231         scanner_.scan();
   232         Expression *right = addition();
   233         if (!right)
   234             return NULL;
   235         left = new (pool_) BinaryExpression(kind, left, right);
   236     }
   237     return left;
   238 }
   239 
   240 Expression *
   241 Parser::equals()
   242 {
   243     Expression *left = relational();
   244     while (left) {
   245         if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   246             break;
   247         TokenKind kind = scanner_.last();
   248         Expression *right = relational();
   249         if (!right)
   250             return NULL;
   251         left = new (pool_) BinaryExpression(kind, left, right);
   252     }
   253     return left;
   254 }
   255 
   256 Expression *
   257 Parser::expression()
   258 {
   259     return equals();
   260 }
   261 
   262 Statement *
   263 Parser::forStatement()
   264 {
   265     scanner_.scan();
   266     if (!expect(TOK_LPAREN))
   267         return NULL;
   268 
   269     VariableDeclaration *decl = NULL;
   270     if (!match(TOK_SEMICOLON)) {
   271         if (!enterScope(Scope::BLOCK))
   272             return NULL;
   273         if ((decl = variableDeclaration()) == NULL)
   274             return NULL;
   275         if (!expect(TOK_SEMICOLON))
   276             return NULL;
   277     }
   278 
   279     Expression *condition = NULL;
   280     if (!match(TOK_SEMICOLON)) {
   281         if ((condition = expression()) == NULL)
   282             return NULL;
   283         if (!expect(TOK_SEMICOLON))
   284             return NULL;
   285     }
   286 
   287     Statement *update = NULL;
   288     if (!match(TOK_RPAREN)) {
   289         if ((update = expressionStatement()) == NULL)
   290             return NULL;
   291         if (!expect(TOK_RPAREN))
   292             return NULL;
   293     }
   294 
   295     Statement *body = localStatement();
   296     if (!body)
   297         return NULL;
   298 
   299     Scope *blockScope = NULL;
   300     if (decl) {
   301         blockScope = scope_->unlinkIfEmpty();
   302         scope_ = scope_->enclosing();
   303     }
   304     return new (pool_) ForStatement(blockScope, decl, condition, update, body);
   305 }
   306 
   307 VariableDeclaration *
   308 Parser::variableDeclaration()
   309 {
   310     if (!expect(TOK_NEW))
   311         return NULL;
   312 
   313     // Get the name.
   314     if (!expect(TOK_NAME))
   315         return NULL;
   316     
   317     Name *name = strings_.add(scanner_.literal());
   318 
   319     ExpressionList *postDimensions = NULL;
   320     if (scanner_.peek() == TOK_LBRACKET) {
   321         postDimensions = new ExpressionList();
   322         while (match(TOK_LBRACKET)) {
   323             Expression *dim = expression();
   324             if (!dim)
   325                 return NULL;
   326 
   327             if (!expect(TOK_RBRACKET))
   328                 return NULL;
   329 
   330             postDimensions->push_back(dim);
   331         }
   332     }
   333     
   334     Expression *expr = NULL;
   335     if (match(TOK_ASSIGN)) {
   336         if ((expr = expression()) == NULL)
   337             return NULL;
   338     }
   339     
   340     if (scope_->localLookup(name)) {
   341         redeclarationError();
   342         return NULL;
   343     }
   344 
   345     Variable *var = scope_->declareVariable(name);
   346     VariableDeclaration *decl = new (pool_) VariableDeclaration(var, postDimensions, expr);
   347 
   348     return decl;
   349 }
   350 
   351 Statement *
   352 Parser::returnStatement()
   353 {
   354     if (!expect(TOK_RETURN))
   355         return NULL;
   356 
   357     Expression *expr = expression();
   358     if (!expr)
   359         return NULL;
   360 
   361     return new (pool_) ReturnStatement(expr);
   362 }
   363 
   364 Statement *
   365 Parser::expressionStatement()
   366 {
   367     Expression *left = primary();
   368     if (!left) {
   369         fprintf(stderr, "expected expression or statement\n");
   370         return NULL;
   371     }
   372 
   373     if (match(TOK_ASSIGN)) {
   374         Expression *expr = expression();
   375         if (!expr)
   376             return NULL;
   377 
   378         left = new (pool_) Assignment(left, expr);
   379     }
   380 
   381     return new (pool_) ExpressionStatement(left);
   382 }
   383 
   384 Statement *
   385 Parser::block()
   386 {
   387     if (!expect(TOK_LBRACE))
   388         return NULL;
   389 
   390     if (!enterScope(Scope::BLOCK))
   391         return NULL;
   392 
   393     StatementList *statements = new (pool_) StatementList();
   394     while (!match(TOK_RBRACE)) {
   395         Statement *statement = localStatement();
   396         if (statement == NULL)
   397             return NULL;
   398         statements->append(pool_, statement);
   399     }
   400 
   401     Scope *blockScope = scope_->unlinkIfEmpty();
   402     BlockStatement *block = new (pool_) BlockStatement(blockScope, statements);
   403 
   404     scope_ = scope_->enclosing();
   405     return block;
   406 }
   407 
   408 Statement *
   409 Parser::if_()
   410 {
   411     expect(TOK_IF);
   412 
   413     if (!expect(TOK_LPAREN))
   414         return NULL;
   415 
   416     Expression *cond = expression();
   417     if (!cond)
   418         return NULL;
   419 
   420     if (!expect(TOK_RPAREN))
   421         return NULL;
   422 
   423     Statement *ifTrue = localStatement();
   424     if (!ifTrue)
   425         return NULL;
   426 
   427     IfStatement *outer = new (pool_) IfStatement(cond, ifTrue);
   428 
   429     IfStatement *last = outer;
   430     while (match(TOK_ELSE)) {
   431         if (!match(TOK_IF)) {
   432             Statement *ifFalse = localStatement();
   433             if (!ifFalse)
   434                 return NULL;
   435 
   436             last->setIfFalse(ifFalse);
   437             break;
   438         }
   439 
   440         if (!expect(TOK_IF))
   441             return false;
   442 
   443         if (!expect(TOK_LPAREN))
   444             return NULL;
   445 
   446         Expression *otherCond = expression();
   447         if (!otherCond)
   448             return NULL;
   449 
   450         if (!expect(TOK_RPAREN))
   451             return NULL;
   452 
   453         Statement *otherIfTrue = localStatement();
   454         if (!otherIfTrue)
   455             return NULL;
   456 
   457         IfStatement *inner = new (pool_) IfStatement(otherCond, otherIfTrue);
   458         last->setIfFalse(inner);
   459         last = inner;
   460     }
   461 
   462     return outer;
   463 }
   464 
   465 Statement *
   466 Parser::localStatement()
   467 {
   468     Statement *statement = NULL;
   469 
   470     // Statements which must be followed by a semicolon will break out of the
   471     // switch. If they may end in BlockStatements, they'll immediately return.
   472 
   473     switch (scanner_.peek()) {
   474         case TOK_NEW:
   475           statement = variableDeclaration();
   476           break;
   477 
   478         case TOK_FOR:
   479           return forStatement();
   480 
   481         case TOK_RETURN:
   482           statement = returnStatement();
   483           break;
   484 
   485         case TOK_IF:
   486           return if_();
   487 
   488         case TOK_LBRACE:
   489           return block();
   490     }
   491 
   492     if (!statement) {
   493         if ((statement = expressionStatement()) == NULL)
   494             return NULL;
   495     }
   496 
   497     if (!expect(TOK_SEMICOLON))
   498         return NULL;
   499 
   500     return statement;
   501 }
   502 
   503 Statement *
   504 Parser::function()
   505 {
   506     expect(TOK_NAME);
   507 
   508     Name *name = strings_.add(scanner_.literal());
   509     if (!name)
   510         return NULL;
   511 
   512     // The function name goes into the outer (global) scope.
   513     assert(!scope_->enclosing());
   514 
   515     if (scope_->localLookup(name)) {
   516         redeclarationError();
   517         return NULL;
   518     }
   519     NamedFunction *fun = scope_->declareFunction(name);
   520     if (!fun)
   521         return NULL;
   522 
   523     Scope *scope = enterScope(Scope::FUNCTION);
   524     if (!scope)
   525         return NULL;
   526 
   527     if (!expect(TOK_LPAREN))
   528         return NULL;
   529     if (!match(TOK_RPAREN)) {
   530         while (true) {
   531             if (!expect(TOK_NAME))
   532                 return NULL;
   533 
   534             Name *name = strings_.add(scanner_.literal());
   535             if (!name)
   536                 return NULL;
   537 
   538             if (scope_->localLookup(name)) {
   539                 redeclarationError();
   540                 return NULL;
   541             }
   542             if (!scope_->declareArgument(name))
   543                 return NULL;
   544 
   545             if (!match(TOK_COMMA))
   546                 break;
   547         }
   548         if (!expect(TOK_RPAREN))
   549             return NULL;
   550     }
   551 
   552     Statement *body = block();
   553     if (!body)
   554         return NULL;
   555 
   556     scope_ = scope_->enclosing();
   557     return new (pool_) FunctionStatement(scope, fun, body);
   558 }
   559 
   560 ParseTree *
   561 Parser::parse()
   562 {
   563     StatementList *statements = new (pool_) StatementList();
   564 
   565     if (!enterScope(Scope::GLOBAL))
   566         return NULL;
   567 
   568     for (;;) {
   569         Statement *statement = NULL;
   570 
   571         switch (scanner_.peek()) {
   572           case TOK_ERROR:
   573             return NULL;
   574 
   575           case TOK_EOF:
   576             break;
   577 
   578           case TOK_NAME:
   579             if ((statement = function()) == NULL)
   580                 return NULL;
   581             break;
   582 
   583           default:
   584             fprintf(stderr, "expected function or global variable\n");
   585             return NULL;
   586         }
   587 
   588         if (!statement)
   589             break;
   590 
   591         statements->append(pool_, statement);
   592     }
   593 
   594     return new (pool_) ParseTree(scope_, statements, unbound_);
   595 }
   596 
   597 class AstPrinter : public AstVisitor
   598 {
   599     FILE *fp_;
   600     size_t level_;
   601 
   602   private:
   603     void prefix() {
   604         for (size_t i = 0; i < level_; i++)
   605             fprintf(fp_, "  ");
   606     }
   607     void indent() {
   608         level_++;
   609     }
   610     void unindent() {
   611         level_--;
   612     }
   613 
   614   public:
   615     AstPrinter(FILE *fp)
   616       : fp_(fp),
   617         level_(0)
   618     {
   619     }
   620 
   621     void visit(NameProxy *name) {
   622         prefix();
   623         fprintf(fp_, "[ NameProxy (%s)%s\n", name->name(),
   624                 (name->binding() ? "" : " unbound"));
   625     }
   626     void visit(CallExpression *node) {
   627         prefix();
   628         fprintf(fp_, "[ CallExpression\n");
   629         indent();
   630         node->callee()->accept(this);
   631         for (size_t i = 0; i < node->arguments()->size(); i++)
   632             node->arguments()->at(i)->accept(this);
   633         unindent();
   634     }
   635     void visit(FunctionStatement *node) {
   636         prefix();
   637         fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name());
   638         indent();
   639         node->body()->accept(this);
   640         unindent();
   641     }
   642     void visit(ExpressionStatement *node) {
   643         prefix();
   644         fprintf(fp_, "[ ExpressionStatement\n");
   645         indent();
   646         node->expression()->accept(this);
   647         unindent();
   648     }
   649     void visit(Assignment *node) {
   650         prefix();
   651         fprintf(fp_, "[ Assignment\n");
   652         indent();
   653         node->lvalue()->accept(this);
   654         node->expression()->accept(this);
   655         unindent();
   656     }
   657     void visit(BinaryExpression *node) {
   658         prefix();
   659         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
   660         indent();
   661         node->left()->accept(this);
   662         node->right()->accept(this);
   663         unindent();
   664     }
   665     void visit(ReturnStatement *node) {
   666         prefix();
   667         fprintf(fp_, "[ ReturnStatement\n");
   668         indent();
   669         node->expression()->accept(this);
   670         unindent();
   671     }
   672     void visit(ForStatement *node) {
   673         prefix();
   674         fprintf(fp_, "[ ForStatement\n");
   675         indent();
   676         if (node->declaration())
   677             node->declaration()->accept(this);
   678         if (node->condition())
   679             node->condition()->accept(this);
   680         if (node->update())
   681             node->update()->accept(this);
   682         node->body()->accept(this);
   683         unindent();
   684     }
   685     void visit(BlockStatement *node) {
   686         prefix();
   687         fprintf(fp_, "[ BlockStatement\n");
   688         indent();
   689         for (size_t i = 0; i < node->statements()->length(); i++)
   690             node->statements()->at(i)->accept(this);
   691         unindent();
   692     }
   693     void visit(VariableDeclaration *node) {
   694         prefix();
   695         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name());
   696         indent();
   697         if (node->initialization())
   698             node->initialization()->accept(this);
   699         unindent();
   700     }
   701     void visit(IntegerLiteralExpression *node) {
   702         prefix();
   703         fprintf(fp_, "[ LiteralExpression (%d)\n", node->value());
   704     }
   705     void visit(IfStatement *node) {
   706         prefix();
   707         fprintf(fp_, "[ IfStatement\n");
   708         indent();
   709         node->ifTrue()->accept(this);
   710         if (node->ifFalse())
   711             node->ifFalse()->accept(this);
   712         unindent();
   713     }
   714     void visit(IndexExpression *node) {
   715         prefix();
   716         fprintf(fp_, "[ IndexExpression\n");
   717         indent();
   718         node->left()->accept(this);
   719         node->right()->accept(this);
   720         unindent();
   721     }
   722 };
   723 
   724 void
   725 ParseTree::dump(FILE *fp)
   726 {
   727     AstPrinter printer(fp);
   728 
   729     for (size_t i = 0; i < statements_->length(); i++)
   730         statements_->at(i)->accept(&printer);
   731 }