jitcraft/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jun 26 00:35:15 2012 -0700 (2012-06-26)
changeset 2 46fc53b8fd2f
parent 0 c455ebb9a5dc
child 4 633176823669
permissions -rw-r--r--
Added support for enums.
     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::shift()
   225 {
   226     Expression *left = addition();
   227     while (left) {
   228         if (!match(TOK_SHL))
   229             break;
   230         TokenKind kind = scanner_.last();
   231         Expression *right = addition();
   232         if (!right)
   233             return NULL;
   234         left = new (pool_) BinaryExpression(kind, left, right);
   235     }
   236     return left;
   237 }
   238 
   239 Expression *
   240 Parser::relational()
   241 {
   242     Expression *left = shift();
   243     while (left) {
   244         TokenKind kind = scanner_.peek();
   245         if (kind < TOK_LT || kind > TOK_GE)
   246             break;
   247         scanner_.scan();
   248         Expression *right = shift();
   249         if (!right)
   250             return NULL;
   251         left = new (pool_) BinaryExpression(kind, left, right);
   252     }
   253     return left;
   254 }
   255 
   256 Expression *
   257 Parser::equals()
   258 {
   259     Expression *left = relational();
   260     while (left) {
   261         if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   262             break;
   263         TokenKind kind = scanner_.last();
   264         Expression *right = relational();
   265         if (!right)
   266             return NULL;
   267         left = new (pool_) BinaryExpression(kind, left, right);
   268     }
   269     return left;
   270 }
   271 
   272 Expression *
   273 Parser::expression()
   274 {
   275     return equals();
   276 }
   277 
   278 Statement *
   279 Parser::forStatement()
   280 {
   281     scanner_.scan();
   282     if (!expect(TOK_LPAREN))
   283         return NULL;
   284 
   285     VariableDeclaration *decl = NULL;
   286     if (!match(TOK_SEMICOLON)) {
   287         if (!enterScope(Scope::BLOCK))
   288             return NULL;
   289         if ((decl = variableDeclaration()) == NULL)
   290             return NULL;
   291         if (!expect(TOK_SEMICOLON))
   292             return NULL;
   293     }
   294 
   295     Expression *condition = NULL;
   296     if (!match(TOK_SEMICOLON)) {
   297         if ((condition = expression()) == NULL)
   298             return NULL;
   299         if (!expect(TOK_SEMICOLON))
   300             return NULL;
   301     }
   302 
   303     Statement *update = NULL;
   304     if (!match(TOK_RPAREN)) {
   305         if ((update = expressionStatement()) == NULL)
   306             return NULL;
   307         if (!expect(TOK_RPAREN))
   308             return NULL;
   309     }
   310 
   311     Statement *body = localStatement();
   312     if (!body)
   313         return NULL;
   314 
   315     Scope *blockScope = NULL;
   316     if (decl) {
   317         blockScope = scope_->unlinkIfEmpty();
   318         scope_ = scope_->enclosing();
   319     }
   320     return new (pool_) ForStatement(blockScope, decl, condition, update, body);
   321 }
   322 
   323 VariableDeclaration *
   324 Parser::variableDeclaration()
   325 {
   326     if (!expect(TOK_NEW))
   327         return NULL;
   328 
   329     // Get the name.
   330     if (!expect(TOK_NAME))
   331         return NULL;
   332     
   333     Name *name = strings_.add(scanner_.literal());
   334 
   335     ExpressionList *postDimensions = NULL;
   336     if (scanner_.peek() == TOK_LBRACKET) {
   337         postDimensions = new ExpressionList();
   338         while (match(TOK_LBRACKET)) {
   339             Expression *dim = expression();
   340             if (!dim)
   341                 return NULL;
   342 
   343             if (!expect(TOK_RBRACKET))
   344                 return NULL;
   345 
   346             postDimensions->push_back(dim);
   347         }
   348     }
   349     
   350     Expression *expr = NULL;
   351     if (match(TOK_ASSIGN)) {
   352         if ((expr = expression()) == NULL)
   353             return NULL;
   354     }
   355     
   356     if (scope_->localLookup(name)) {
   357         redeclarationError();
   358         return NULL;
   359     }
   360 
   361     Variable *var = scope_->declareVariable(name);
   362     VariableDeclaration *decl = new (pool_) VariableDeclaration(var, postDimensions, expr);
   363 
   364     return decl;
   365 }
   366 
   367 Statement *
   368 Parser::returnStatement()
   369 {
   370     if (!expect(TOK_RETURN))
   371         return NULL;
   372 
   373     Expression *expr = expression();
   374     if (!expr)
   375         return NULL;
   376 
   377     return new (pool_) ReturnStatement(expr);
   378 }
   379 
   380 Statement *
   381 Parser::expressionStatement()
   382 {
   383     Expression *left = primary();
   384     if (!left) {
   385         fprintf(stderr, "expected expression or statement\n");
   386         return NULL;
   387     }
   388 
   389     if (match(TOK_ASSIGN)) {
   390         Expression *expr = expression();
   391         if (!expr)
   392             return NULL;
   393 
   394         left = new (pool_) Assignment(left, expr);
   395     }
   396 
   397     return new (pool_) ExpressionStatement(left);
   398 }
   399 
   400 Statement *
   401 Parser::block()
   402 {
   403     if (!expect(TOK_LBRACE))
   404         return NULL;
   405 
   406     if (!enterScope(Scope::BLOCK))
   407         return NULL;
   408 
   409     StatementList *statements = new (pool_) StatementList();
   410     while (!match(TOK_RBRACE)) {
   411         Statement *statement = localStatement();
   412         if (statement == NULL)
   413             return NULL;
   414         statements->append(pool_, statement);
   415     }
   416 
   417     Scope *blockScope = scope_->unlinkIfEmpty();
   418     BlockStatement *block = new (pool_) BlockStatement(blockScope, statements);
   419 
   420     scope_ = scope_->enclosing();
   421     return block;
   422 }
   423 
   424 Statement *
   425 Parser::if_()
   426 {
   427     expect(TOK_IF);
   428 
   429     if (!expect(TOK_LPAREN))
   430         return NULL;
   431 
   432     Expression *cond = expression();
   433     if (!cond)
   434         return NULL;
   435 
   436     if (!expect(TOK_RPAREN))
   437         return NULL;
   438 
   439     Statement *ifTrue = localStatement();
   440     if (!ifTrue)
   441         return NULL;
   442 
   443     IfStatement *outer = new (pool_) IfStatement(cond, ifTrue);
   444 
   445     IfStatement *last = outer;
   446     while (match(TOK_ELSE)) {
   447         if (!match(TOK_IF)) {
   448             Statement *ifFalse = localStatement();
   449             if (!ifFalse)
   450                 return NULL;
   451 
   452             last->setIfFalse(ifFalse);
   453             break;
   454         }
   455 
   456         if (!expect(TOK_IF))
   457             return false;
   458 
   459         if (!expect(TOK_LPAREN))
   460             return NULL;
   461 
   462         Expression *otherCond = expression();
   463         if (!otherCond)
   464             return NULL;
   465 
   466         if (!expect(TOK_RPAREN))
   467             return NULL;
   468 
   469         Statement *otherIfTrue = localStatement();
   470         if (!otherIfTrue)
   471             return NULL;
   472 
   473         IfStatement *inner = new (pool_) IfStatement(otherCond, otherIfTrue);
   474         last->setIfFalse(inner);
   475         last = inner;
   476     }
   477 
   478     return outer;
   479 }
   480 
   481 Statement *
   482 Parser::localStatement()
   483 {
   484     Statement *statement = NULL;
   485 
   486     // Statements which must be followed by a semicolon will break out of the
   487     // switch. If they may end in BlockStatements, they'll immediately return.
   488 
   489     switch (scanner_.peek()) {
   490         case TOK_NEW:
   491           statement = variableDeclaration();
   492           break;
   493 
   494         case TOK_FOR:
   495           return forStatement();
   496 
   497         case TOK_RETURN:
   498           statement = returnStatement();
   499           break;
   500 
   501         case TOK_ENUM:
   502           statement = enum_();
   503           break;
   504 
   505         case TOK_IF:
   506           return if_();
   507 
   508         case TOK_LBRACE:
   509           return block();
   510     }
   511 
   512     if (!statement) {
   513         if ((statement = expressionStatement()) == NULL)
   514             return NULL;
   515     }
   516 
   517     if (!expect(TOK_SEMICOLON))
   518         return NULL;
   519 
   520     return statement;
   521 }
   522 
   523 Statement *
   524 Parser::enum_()
   525 {
   526     expect(TOK_ENUM);
   527 
   528     Name *name = NULL;
   529     if (match(TOK_NAME)) {
   530         if ((name = strings_.add(scanner_.literal())) == NULL)
   531             return NULL;
   532 
   533         if (scope_->localLookup(name)) {
   534             redeclarationError();
   535             return NULL;
   536         }
   537 
   538         NamedEnum *e = scope_->declareEnum(name);
   539         if (!e)
   540             return NULL;
   541     }
   542 
   543     EnumStatement::EntryList *entries = new EnumStatement::EntryList();
   544 
   545     if (!expect(TOK_LBRACE))
   546         return NULL;
   547 
   548     do {
   549         if (scanner_.peek() == TOK_RBRACE)
   550             break;
   551 
   552         if (!expect(TOK_NAME))
   553             return NULL;
   554 
   555         Name *name = strings_.add(scanner_.literal());
   556         if (!name)
   557             return NULL;
   558 
   559         if (scope_->localLookup(name)) {
   560             redeclarationError();
   561             return NULL;
   562         }
   563 
   564         NamedConstant *constant = scope_->declareConstant(name);
   565         if (!constant)
   566             return NULL;
   567 
   568         Expression *expr = NULL;
   569         if (match(TOK_ASSIGN)) {
   570             if ((expr = expression()) == NULL)
   571                 return NULL;
   572         }
   573 
   574         entries->push_back(EnumStatement::Entry(constant, expr));
   575     } while (match(TOK_COMMA));
   576     if (!expect(TOK_RBRACE))
   577         return NULL;
   578 
   579     return new (pool_) EnumStatement(name, entries);
   580 }
   581 
   582 Statement *
   583 Parser::function()
   584 {
   585     expect(TOK_NAME);
   586 
   587     Name *name = strings_.add(scanner_.literal());
   588     if (!name)
   589         return NULL;
   590 
   591     // The function name goes into the outer (global) scope.
   592     assert(!scope_->enclosing());
   593 
   594     if (scope_->localLookup(name)) {
   595         redeclarationError();
   596         return NULL;
   597     }
   598     NamedFunction *fun = scope_->declareFunction(name);
   599     if (!fun)
   600         return NULL;
   601 
   602     Scope *scope = enterScope(Scope::FUNCTION);
   603     if (!scope)
   604         return NULL;
   605 
   606     if (!expect(TOK_LPAREN))
   607         return NULL;
   608     if (!match(TOK_RPAREN)) {
   609         while (true) {
   610             if (!expect(TOK_NAME))
   611                 return NULL;
   612 
   613             Name *name = strings_.add(scanner_.literal());
   614             if (!name)
   615                 return NULL;
   616 
   617             if (scope_->localLookup(name)) {
   618                 redeclarationError();
   619                 return NULL;
   620             }
   621             if (!scope_->declareArgument(name))
   622                 return NULL;
   623 
   624             if (!match(TOK_COMMA))
   625                 break;
   626         }
   627         if (!expect(TOK_RPAREN))
   628             return NULL;
   629     }
   630 
   631     Statement *body = block();
   632     if (!body)
   633         return NULL;
   634 
   635     scope_ = scope_->enclosing();
   636     return new (pool_) FunctionStatement(scope, fun, body);
   637 }
   638 
   639 ParseTree *
   640 Parser::parse()
   641 {
   642     StatementList *statements = new (pool_) StatementList();
   643 
   644     if (!enterScope(Scope::GLOBAL))
   645         return NULL;
   646 
   647     for (;;) {
   648         Statement *statement = NULL;
   649 
   650         switch (scanner_.peek()) {
   651           case TOK_ERROR:
   652             return NULL;
   653 
   654           case TOK_EOF:
   655             break;
   656 
   657           case TOK_NAME:
   658             if ((statement = function()) == NULL)
   659                 return NULL;
   660             break;
   661 
   662           case TOK_ENUM:
   663             if ((statement = enum_()) == NULL)
   664                 return NULL;
   665             // :TODO: require semicolon
   666             break;
   667 
   668           default:
   669             fprintf(stderr, "expected function or global variable\n");
   670             return NULL;
   671         }
   672 
   673         if (!statement)
   674             break;
   675 
   676         statements->append(pool_, statement);
   677     }
   678 
   679     return new (pool_) ParseTree(scope_, statements, unbound_);
   680 }
   681 
   682 class AstPrinter : public AstVisitor
   683 {
   684     FILE *fp_;
   685     size_t level_;
   686 
   687   private:
   688     void prefix() {
   689         for (size_t i = 0; i < level_; i++)
   690             fprintf(fp_, "  ");
   691     }
   692     void indent() {
   693         level_++;
   694     }
   695     void unindent() {
   696         level_--;
   697     }
   698 
   699   public:
   700     AstPrinter(FILE *fp)
   701       : fp_(fp),
   702         level_(0)
   703     {
   704     }
   705 
   706     void visit(NameProxy *name) {
   707         prefix();
   708         fprintf(fp_, "[ NameProxy (%s)%s\n", name->name(),
   709                 (name->binding() ? "" : " unbound"));
   710     }
   711     void visit(CallExpression *node) {
   712         prefix();
   713         fprintf(fp_, "[ CallExpression\n");
   714         indent();
   715         node->callee()->accept(this);
   716         for (size_t i = 0; i < node->arguments()->size(); i++)
   717             node->arguments()->at(i)->accept(this);
   718         unindent();
   719     }
   720     void visit(FunctionStatement *node) {
   721         prefix();
   722         fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name());
   723         indent();
   724         node->body()->accept(this);
   725         unindent();
   726     }
   727     void visit(ExpressionStatement *node) {
   728         prefix();
   729         fprintf(fp_, "[ ExpressionStatement\n");
   730         indent();
   731         node->expression()->accept(this);
   732         unindent();
   733     }
   734     void visit(Assignment *node) {
   735         prefix();
   736         fprintf(fp_, "[ Assignment\n");
   737         indent();
   738         node->lvalue()->accept(this);
   739         node->expression()->accept(this);
   740         unindent();
   741     }
   742     void visit(BinaryExpression *node) {
   743         prefix();
   744         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
   745         indent();
   746         node->left()->accept(this);
   747         node->right()->accept(this);
   748         unindent();
   749     }
   750     void visit(ReturnStatement *node) {
   751         prefix();
   752         fprintf(fp_, "[ ReturnStatement\n");
   753         indent();
   754         node->expression()->accept(this);
   755         unindent();
   756     }
   757     void visit(ForStatement *node) {
   758         prefix();
   759         fprintf(fp_, "[ ForStatement\n");
   760         indent();
   761         if (node->declaration())
   762             node->declaration()->accept(this);
   763         if (node->condition())
   764             node->condition()->accept(this);
   765         if (node->update())
   766             node->update()->accept(this);
   767         node->body()->accept(this);
   768         unindent();
   769     }
   770     void visit(BlockStatement *node) {
   771         prefix();
   772         fprintf(fp_, "[ BlockStatement\n");
   773         indent();
   774         for (size_t i = 0; i < node->statements()->length(); i++)
   775             node->statements()->at(i)->accept(this);
   776         unindent();
   777     }
   778     void visit(VariableDeclaration *node) {
   779         prefix();
   780         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name());
   781         indent();
   782         if (node->initialization())
   783             node->initialization()->accept(this);
   784         unindent();
   785     }
   786     void visit(IntegerLiteralExpression *node) {
   787         prefix();
   788         fprintf(fp_, "[ LiteralExpression (%d)\n", node->value());
   789     }
   790     void visit(IfStatement *node) {
   791         prefix();
   792         fprintf(fp_, "[ IfStatement\n");
   793         indent();
   794         node->ifTrue()->accept(this);
   795         if (node->ifFalse())
   796             node->ifFalse()->accept(this);
   797         unindent();
   798     }
   799     void visit(IndexExpression *node) {
   800         prefix();
   801         fprintf(fp_, "[ IndexExpression\n");
   802         indent();
   803         node->left()->accept(this);
   804         node->right()->accept(this);
   805         unindent();
   806     }
   807     void visit(EnumStatement *node) {
   808         prefix();
   809         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name() : "<anonymous>");
   810         indent();
   811         for (size_t i = 0; i < node->entries()->size(); i++) {
   812             prefix();
   813             fprintf(fp_, "%s =\n", node->entries()->at(i).name->name());
   814             if (node->entries()->at(i).expr) {
   815                 indent();
   816                 node->entries()->at(i).expr->accept(this);
   817                 unindent();
   818             }
   819         }
   820         unindent();
   821     }
   822 };
   823 
   824 void
   825 ParseTree::dump(FILE *fp)
   826 {
   827     AstPrinter printer(fp);
   828 
   829     for (size_t i = 0; i < statements_->length(); i++)
   830         statements_->at(i)->accept(&printer);
   831 }