jitcraft/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Wed Jun 27 02:21:56 2012 -0700 (2012-06-27)
changeset 4 633176823669
parent 2 46fc53b8fd2f
child 8 069d207a8f2a
permissions -rw-r--r--
Add support for float variables and basic math.
     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 bool
    72 Parser::matchName(Name **name, TokenKind kind)
    73 {
    74     assert(kind == TOK_NAME || kind == TOK_LABEL);
    75     *name = NULL;
    76     if (!match(kind))
    77         return false;
    78     *name = strings_.add(scanner_.literal());
    79     return true;
    80 }
    81 
    82 Name *
    83 Parser::expectName()
    84 {
    85     if (!expect(TOK_NAME))
    86         return NULL;
    87     return strings_.add(scanner_.literal());
    88 }
    89 
    90 Expression *
    91 Parser::primitive()
    92 {
    93     switch (scanner_.peek()) {
    94       case TOK_NAME:
    95       {
    96         scanner_.scan();
    97         Name *name = strings_.add(scanner_.literal());
    98         return bind(name);
    99       }
   100 
   101       case TOK_FLOAT_LITERAL:
   102       {
   103         scanner_.scan();
   104         double value = Scanner::ParseDouble(scanner_.literal());
   105         return new (pool_) FloatLiteral(value);
   106       }
   107 
   108       case TOK_INTEGER_LITERAL:
   109       {
   110         scanner_.scan();
   111         int value = atoi(scanner_.literal());
   112         return new (pool_) IntegerLiteral(value);
   113       }
   114 
   115       default:
   116       {
   117         fprintf(stderr, "error: expected expression!\n");
   118         return NULL;
   119       }
   120     }
   121 }
   122 
   123 Expression *
   124 Parser::prefix()
   125 {
   126     switch (scanner_.peek()) {
   127       case TOK_LPAREN:
   128       {
   129         scanner_.scan();
   130         Expression *expr = expression();
   131         if (!expr)
   132             return NULL;
   133         if (!expect(TOK_RPAREN))
   134             return NULL;
   135         return expr;
   136       }
   137 
   138       default:
   139         return primitive();
   140     }
   141 }
   142 
   143 Expression *
   144 Parser::call(Expression *callee)
   145 {
   146     ExpressionList *arguments = new ExpressionList();
   147 
   148     expect(TOK_LPAREN);
   149     
   150     if (!match(TOK_RPAREN)) {
   151         while (true) {
   152             Expression *expr = expression();
   153             if (!expr)
   154                 return NULL;
   155 
   156             arguments->push_back(expr);
   157 
   158             if (!match(TOK_COMMA))
   159                 break;
   160         }
   161 
   162         if (!expect(TOK_RPAREN))
   163             return NULL;
   164     }
   165 
   166     return new (pool_) CallExpression(callee, arguments);
   167 }
   168 
   169 Expression *
   170 Parser::index(Expression *left)
   171 {
   172     expect(TOK_LBRACKET);
   173     
   174     Expression *expr = expression();
   175     if (!expr)
   176         return NULL;
   177 
   178     if (!expect(TOK_RBRACKET))
   179         return NULL;
   180 
   181     return new (pool_) IndexExpression(left, expr);
   182 }
   183 
   184 Expression *
   185 Parser::primary()
   186 {
   187     Expression *expr = prefix();
   188     if (!expr)
   189         return NULL;
   190 
   191     for (;;) {
   192         switch (scanner_.peek()) {
   193           case TOK_LPAREN:
   194             expr = call(expr);
   195             if (!expr)
   196                 return NULL;
   197             break;
   198 
   199           case TOK_LBRACKET:
   200             expr = index(expr);
   201             if (!expr)
   202                 return NULL;
   203             break;
   204 
   205           default:
   206             return expr;
   207         }
   208     }
   209 }
   210 
   211 Expression *
   212 Parser::unary()
   213 {
   214     return primary();
   215 }
   216 
   217 Expression *
   218 Parser::multiplication()
   219 {
   220     Expression *left = unary();
   221     do {
   222         if (!match(TOK_SLASH) && !match(TOK_STAR))
   223             break;
   224         TokenKind kind = scanner_.last();
   225         Expression *right = unary();
   226         if (!right)
   227             return NULL;
   228         left = new (pool_) BinaryExpression(kind, left, right);
   229     } while (left);
   230     return left;
   231 }
   232 
   233 Expression *
   234 Parser::addition()
   235 {
   236     Expression *left = multiplication();
   237     while (left) {
   238         if (!match(TOK_PLUS) && !match(TOK_MINUS))
   239             break;
   240         TokenKind kind = scanner_.last();
   241         Expression *right = multiplication();
   242         if (!right)
   243             return NULL;
   244         left = new (pool_) BinaryExpression(kind, left, right);
   245     }
   246     return left;
   247 }
   248 
   249 Expression *
   250 Parser::shift()
   251 {
   252     Expression *left = addition();
   253     while (left) {
   254         if (!match(TOK_SHL))
   255             break;
   256         TokenKind kind = scanner_.last();
   257         Expression *right = addition();
   258         if (!right)
   259             return NULL;
   260         left = new (pool_) BinaryExpression(kind, left, right);
   261     }
   262     return left;
   263 }
   264 
   265 Expression *
   266 Parser::relational()
   267 {
   268     Expression *left = shift();
   269     while (left) {
   270         TokenKind kind = scanner_.peek();
   271         if (kind < TOK_LT || kind > TOK_GE)
   272             break;
   273         scanner_.scan();
   274         Expression *right = shift();
   275         if (!right)
   276             return NULL;
   277         left = new (pool_) BinaryExpression(kind, left, right);
   278     }
   279     return left;
   280 }
   281 
   282 Expression *
   283 Parser::equals()
   284 {
   285     Expression *left = relational();
   286     while (left) {
   287         if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   288             break;
   289         TokenKind kind = scanner_.last();
   290         Expression *right = relational();
   291         if (!right)
   292             return NULL;
   293         left = new (pool_) BinaryExpression(kind, left, right);
   294     }
   295     return left;
   296 }
   297 
   298 Expression *
   299 Parser::expression()
   300 {
   301     return equals();
   302 }
   303 
   304 Statement *
   305 Parser::forStatement()
   306 {
   307     scanner_.scan();
   308     if (!expect(TOK_LPAREN))
   309         return NULL;
   310 
   311     VariableDeclaration *decl = NULL;
   312     if (!match(TOK_SEMICOLON)) {
   313         if (!enterScope(Scope::BLOCK))
   314             return NULL;
   315         if ((decl = variableDeclaration()) == NULL)
   316             return NULL;
   317         if (!expect(TOK_SEMICOLON))
   318             return NULL;
   319     }
   320 
   321     Expression *condition = NULL;
   322     if (!match(TOK_SEMICOLON)) {
   323         if ((condition = expression()) == NULL)
   324             return NULL;
   325         if (!expect(TOK_SEMICOLON))
   326             return NULL;
   327     }
   328 
   329     Statement *update = NULL;
   330     if (!match(TOK_RPAREN)) {
   331         if ((update = expressionStatement()) == NULL)
   332             return NULL;
   333         if (!expect(TOK_RPAREN))
   334             return NULL;
   335     }
   336 
   337     Statement *body = localStatement();
   338     if (!body)
   339         return NULL;
   340 
   341     Scope *blockScope = NULL;
   342     if (decl) {
   343         blockScope = scope_->unlinkIfEmpty();
   344         scope_ = scope_->enclosing();
   345     }
   346     return new (pool_) ForStatement(blockScope, decl, condition, update, body);
   347 }
   348 
   349 VariableDeclaration *
   350 Parser::variableDeclaration()
   351 {
   352     if (!expect(TOK_NEW))
   353         return NULL;
   354 
   355     Name *tag;
   356     if (matchName(&tag, TOK_LABEL) && !tag)
   357         return NULL;
   358 
   359     Name *name = expectName();
   360     if (!name)
   361         return NULL;
   362 
   363     ExpressionList *postDimensions = NULL;
   364     if (scanner_.peek() == TOK_LBRACKET) {
   365         postDimensions = new ExpressionList();
   366         while (match(TOK_LBRACKET)) {
   367             Expression *dim = expression();
   368             if (!dim)
   369                 return NULL;
   370 
   371             if (!expect(TOK_RBRACKET))
   372                 return NULL;
   373 
   374             postDimensions->push_back(dim);
   375         }
   376     }
   377     
   378     Expression *expr = NULL;
   379     if (match(TOK_ASSIGN)) {
   380         if ((expr = expression()) == NULL)
   381             return NULL;
   382     }
   383     
   384     if (scope_->localLookup(name)) {
   385         redeclarationError();
   386         return NULL;
   387     }
   388 
   389     Variable *var = scope_->declareVariable(name);
   390     VariableDeclaration *decl = new (pool_) VariableDeclaration(var, tag, postDimensions, expr);
   391 
   392     return decl;
   393 }
   394 
   395 Statement *
   396 Parser::returnStatement()
   397 {
   398     if (!expect(TOK_RETURN))
   399         return NULL;
   400 
   401     Expression *expr = expression();
   402     if (!expr)
   403         return NULL;
   404 
   405     return new (pool_) ReturnStatement(expr);
   406 }
   407 
   408 Statement *
   409 Parser::expressionStatement()
   410 {
   411     Expression *left = primary();
   412     if (!left) {
   413         fprintf(stderr, "expected expression or statement\n");
   414         return NULL;
   415     }
   416 
   417     if (match(TOK_ASSIGN)) {
   418         Expression *expr = expression();
   419         if (!expr)
   420             return NULL;
   421 
   422         left = new (pool_) Assignment(left, expr);
   423     }
   424 
   425     return new (pool_) ExpressionStatement(left);
   426 }
   427 
   428 Statement *
   429 Parser::block()
   430 {
   431     if (!expect(TOK_LBRACE))
   432         return NULL;
   433 
   434     if (!enterScope(Scope::BLOCK))
   435         return NULL;
   436 
   437     StatementList *statements = new (pool_) StatementList();
   438     while (!match(TOK_RBRACE)) {
   439         Statement *statement = localStatement();
   440         if (statement == NULL)
   441             return NULL;
   442         statements->append(pool_, statement);
   443     }
   444 
   445     Scope *blockScope = scope_->unlinkIfEmpty();
   446     BlockStatement *block = new (pool_) BlockStatement(blockScope, statements);
   447 
   448     scope_ = scope_->enclosing();
   449     return block;
   450 }
   451 
   452 Statement *
   453 Parser::if_()
   454 {
   455     expect(TOK_IF);
   456 
   457     if (!expect(TOK_LPAREN))
   458         return NULL;
   459 
   460     Expression *cond = expression();
   461     if (!cond)
   462         return NULL;
   463 
   464     if (!expect(TOK_RPAREN))
   465         return NULL;
   466 
   467     Statement *ifTrue = localStatement();
   468     if (!ifTrue)
   469         return NULL;
   470 
   471     IfStatement *outer = new (pool_) IfStatement(cond, ifTrue);
   472 
   473     IfStatement *last = outer;
   474     while (match(TOK_ELSE)) {
   475         if (!match(TOK_IF)) {
   476             Statement *ifFalse = localStatement();
   477             if (!ifFalse)
   478                 return NULL;
   479 
   480             last->setIfFalse(ifFalse);
   481             break;
   482         }
   483 
   484         if (!expect(TOK_IF))
   485             return false;
   486 
   487         if (!expect(TOK_LPAREN))
   488             return NULL;
   489 
   490         Expression *otherCond = expression();
   491         if (!otherCond)
   492             return NULL;
   493 
   494         if (!expect(TOK_RPAREN))
   495             return NULL;
   496 
   497         Statement *otherIfTrue = localStatement();
   498         if (!otherIfTrue)
   499             return NULL;
   500 
   501         IfStatement *inner = new (pool_) IfStatement(otherCond, otherIfTrue);
   502         last->setIfFalse(inner);
   503         last = inner;
   504     }
   505 
   506     return outer;
   507 }
   508 
   509 Statement *
   510 Parser::localStatement()
   511 {
   512     Statement *statement = NULL;
   513 
   514     // Statements which must be followed by a semicolon will break out of the
   515     // switch. If they may end in BlockStatements, they'll immediately return.
   516 
   517     switch (scanner_.peek()) {
   518         case TOK_NEW:
   519           statement = variableDeclaration();
   520           break;
   521 
   522         case TOK_FOR:
   523           return forStatement();
   524 
   525         case TOK_RETURN:
   526           statement = returnStatement();
   527           break;
   528 
   529         case TOK_ENUM:
   530           statement = enum_();
   531           break;
   532 
   533         case TOK_IF:
   534           return if_();
   535 
   536         case TOK_LBRACE:
   537           return block();
   538     }
   539 
   540     if (!statement) {
   541         if ((statement = expressionStatement()) == NULL)
   542             return NULL;
   543     }
   544 
   545     if (!expect(TOK_SEMICOLON))
   546         return NULL;
   547 
   548     return statement;
   549 }
   550 
   551 Statement *
   552 Parser::enum_()
   553 {
   554     expect(TOK_ENUM);
   555 
   556     Name *name = NULL;
   557     if (match(TOK_NAME)) {
   558         if ((name = strings_.add(scanner_.literal())) == NULL)
   559             return NULL;
   560 
   561         if (scope_->localLookup(name)) {
   562             redeclarationError();
   563             return NULL;
   564         }
   565 
   566         NamedEnum *e = scope_->declareEnum(name);
   567         if (!e)
   568             return NULL;
   569     }
   570 
   571     EnumStatement::EntryList *entries = new EnumStatement::EntryList();
   572 
   573     if (!expect(TOK_LBRACE))
   574         return NULL;
   575 
   576     do {
   577         if (scanner_.peek() == TOK_RBRACE)
   578             break;
   579 
   580         Name *name = expectName();
   581         if (!name)
   582             return NULL;
   583 
   584         if (scope_->localLookup(name)) {
   585             redeclarationError();
   586             return NULL;
   587         }
   588 
   589         NamedConstant *constant = scope_->declareConstant(name);
   590         if (!constant)
   591             return NULL;
   592 
   593         Expression *expr = NULL;
   594         if (match(TOK_ASSIGN)) {
   595             if ((expr = expression()) == NULL)
   596                 return NULL;
   597         }
   598 
   599         entries->push_back(EnumStatement::Entry(constant, expr));
   600     } while (match(TOK_COMMA));
   601     if (!expect(TOK_RBRACE))
   602         return NULL;
   603 
   604     return new (pool_) EnumStatement(name, entries);
   605 }
   606 
   607 Statement *
   608 Parser::function()
   609 {
   610     Name *name = expectName();
   611     if (!name)
   612         return NULL;
   613 
   614     // The function name goes into the outer (global) scope.
   615     assert(!scope_->enclosing());
   616 
   617     if (scope_->localLookup(name)) {
   618         redeclarationError();
   619         return NULL;
   620     }
   621     NamedFunction *fun = scope_->declareFunction(name);
   622     if (!fun)
   623         return NULL;
   624 
   625     Scope *scope = enterScope(Scope::FUNCTION);
   626     if (!scope)
   627         return NULL;
   628 
   629     if (!expect(TOK_LPAREN))
   630         return NULL;
   631     if (!match(TOK_RPAREN)) {
   632         while (true) {
   633             Name *name = expectName();
   634             if (!name)
   635                 return NULL;
   636 
   637             if (scope_->localLookup(name)) {
   638                 redeclarationError();
   639                 return NULL;
   640             }
   641             if (!scope_->declareArgument(name))
   642                 return NULL;
   643 
   644             if (!match(TOK_COMMA))
   645                 break;
   646         }
   647         if (!expect(TOK_RPAREN))
   648             return NULL;
   649     }
   650 
   651     Statement *body = block();
   652     if (!body)
   653         return NULL;
   654 
   655     scope_ = scope_->enclosing();
   656     return new (pool_) FunctionStatement(scope, fun, body);
   657 }
   658 
   659 ParseTree *
   660 Parser::parse()
   661 {
   662     StatementList *statements = new (pool_) StatementList();
   663 
   664     if (!enterScope(Scope::GLOBAL))
   665         return NULL;
   666 
   667     for (;;) {
   668         Statement *statement = NULL;
   669 
   670         switch (scanner_.peek()) {
   671           case TOK_ERROR:
   672             return NULL;
   673 
   674           case TOK_EOF:
   675             break;
   676 
   677           case TOK_NAME:
   678             if ((statement = function()) == NULL)
   679                 return NULL;
   680             break;
   681 
   682           case TOK_ENUM:
   683             if ((statement = enum_()) == NULL)
   684                 return NULL;
   685             // :TODO: require semicolon
   686             break;
   687 
   688           default:
   689             fprintf(stderr, "expected function or global variable\n");
   690             return NULL;
   691         }
   692 
   693         if (!statement)
   694             break;
   695 
   696         statements->append(pool_, statement);
   697     }
   698 
   699     return new (pool_) ParseTree(scope_, statements, unbound_);
   700 }
   701 
   702 class AstPrinter : public AstVisitor
   703 {
   704     FILE *fp_;
   705     size_t level_;
   706 
   707   private:
   708     void prefix() {
   709         for (size_t i = 0; i < level_; i++)
   710             fprintf(fp_, "  ");
   711     }
   712     void indent() {
   713         level_++;
   714     }
   715     void unindent() {
   716         level_--;
   717     }
   718 
   719   public:
   720     AstPrinter(FILE *fp)
   721       : fp_(fp),
   722         level_(0)
   723     {
   724     }
   725 
   726     void visit(NameProxy *name) {
   727         prefix();
   728         fprintf(fp_, "[ NameProxy (%s)%s\n", name->name(),
   729                 (name->binding() ? "" : " unbound"));
   730     }
   731     void visit(CallExpression *node) {
   732         prefix();
   733         fprintf(fp_, "[ CallExpression\n");
   734         indent();
   735         node->callee()->accept(this);
   736         for (size_t i = 0; i < node->arguments()->size(); i++)
   737             node->arguments()->at(i)->accept(this);
   738         unindent();
   739     }
   740     void visit(FunctionStatement *node) {
   741         prefix();
   742         fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name());
   743         indent();
   744         node->body()->accept(this);
   745         unindent();
   746     }
   747     void visit(ExpressionStatement *node) {
   748         prefix();
   749         fprintf(fp_, "[ ExpressionStatement\n");
   750         indent();
   751         node->expression()->accept(this);
   752         unindent();
   753     }
   754     void visit(Assignment *node) {
   755         prefix();
   756         fprintf(fp_, "[ Assignment\n");
   757         indent();
   758         node->lvalue()->accept(this);
   759         node->expression()->accept(this);
   760         unindent();
   761     }
   762     void visit(BinaryExpression *node) {
   763         prefix();
   764         fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
   765         indent();
   766         node->left()->accept(this);
   767         node->right()->accept(this);
   768         unindent();
   769     }
   770     void visit(ReturnStatement *node) {
   771         prefix();
   772         fprintf(fp_, "[ ReturnStatement\n");
   773         indent();
   774         node->expression()->accept(this);
   775         unindent();
   776     }
   777     void visit(ForStatement *node) {
   778         prefix();
   779         fprintf(fp_, "[ ForStatement\n");
   780         indent();
   781         if (node->declaration())
   782             node->declaration()->accept(this);
   783         if (node->condition())
   784             node->condition()->accept(this);
   785         if (node->update())
   786             node->update()->accept(this);
   787         node->body()->accept(this);
   788         unindent();
   789     }
   790     void visit(BlockStatement *node) {
   791         prefix();
   792         fprintf(fp_, "[ BlockStatement\n");
   793         indent();
   794         for (size_t i = 0; i < node->statements()->length(); i++)
   795             node->statements()->at(i)->accept(this);
   796         unindent();
   797     }
   798     void visit(VariableDeclaration *node) {
   799         prefix();
   800         fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name());
   801         indent();
   802         if (node->initialization())
   803             node->initialization()->accept(this);
   804         unindent();
   805     }
   806     void visit(IntegerLiteral *node) {
   807         prefix();
   808         fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
   809     }
   810     void visit(FloatLiteral *node) {
   811         prefix();
   812         fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
   813     }
   814     void visit(IfStatement *node) {
   815         prefix();
   816         fprintf(fp_, "[ IfStatement\n");
   817         indent();
   818         node->ifTrue()->accept(this);
   819         if (node->ifFalse())
   820             node->ifFalse()->accept(this);
   821         unindent();
   822     }
   823     void visit(IndexExpression *node) {
   824         prefix();
   825         fprintf(fp_, "[ IndexExpression\n");
   826         indent();
   827         node->left()->accept(this);
   828         node->right()->accept(this);
   829         unindent();
   830     }
   831     void visit(EnumStatement *node) {
   832         prefix();
   833         fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name() : "<anonymous>");
   834         indent();
   835         for (size_t i = 0; i < node->entries()->size(); i++) {
   836             prefix();
   837             fprintf(fp_, "%s =\n", node->entries()->at(i).name->name());
   838             if (node->entries()->at(i).expr) {
   839                 indent();
   840                 node->entries()->at(i).expr->accept(this);
   841                 unindent();
   842             }
   843         }
   844         unindent();
   845     }
   846 };
   847 
   848 void
   849 ParseTree::dump(FILE *fp)
   850 {
   851     AstPrinter printer(fp);
   852 
   853     for (size_t i = 0; i < statements_->length(); i++)
   854         statements_->at(i)->accept(&printer);
   855 }