Added support for do/while loops.
2 * Copyright (C) 2012 David Anderson
4 * This file is part of JITCraft.
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)
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.
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/.
23 Parser::Parser(const char *stream, size_t length)
24 : pool_(ZONE()->pool()),
26 scanner_(stream, length),
30 unbound_ = new std::vector<NameProxy *>();
34 Parser::match(TokenKind kind)
36 if (scanner_.peek() != kind)
43 Parser::expect(TokenKind kind)
45 TokenKind got = scanner_.scan();
48 fprintf(stderr, "error: expected %s, got %s\n", TokenNames[kind], TokenNames[got]);
53 Parser::enterScope(Scope::Kind kind)
55 scope_ = new (pool_) Scope(pool_, kind, scope_);
56 if (!scope_->initialize())
62 Parser::bind(Name *name)
64 BoundName *bound = scope_->lookup(name);
65 NameProxy *proxy = new (pool_) NameProxy(name, bound);
67 unbound_->push_back(proxy);
72 Parser::matchName(Name **name, TokenKind kind)
74 assert(kind == TOK_NAME || kind == TOK_LABEL);
78 *name = strings_.add(scanner_.literal());
85 if (!expect(TOK_NAME))
87 return strings_.add(scanner_.literal());
93 switch (scanner_.peek()) {
97 Name *name = strings_.add(scanner_.literal());
101 case TOK_FLOAT_LITERAL:
104 double value = Scanner::ParseDouble(scanner_.literal());
105 return new (pool_) FloatLiteral(value);
108 case TOK_INTEGER_LITERAL:
111 int value = atoi(scanner_.literal());
112 return new (pool_) IntegerLiteral(value);
117 fprintf(stderr, "error: expected expression!\n");
126 switch (scanner_.peek()) {
130 Expression *expr = expression();
133 if (!expect(TOK_RPAREN))
144 Parser::call(Expression *callee)
146 ExpressionList *arguments = new ExpressionList();
150 if (!match(TOK_RPAREN)) {
152 Expression *expr = expression();
156 arguments->push_back(expr);
158 if (!match(TOK_COMMA))
162 if (!expect(TOK_RPAREN))
166 return new (pool_) CallExpression(callee, arguments);
170 Parser::index(Expression *left)
172 expect(TOK_LBRACKET);
174 Expression *expr = expression();
178 if (!expect(TOK_RBRACKET))
181 return new (pool_) IndexExpression(left, expr);
187 Expression *expr = prefix();
192 switch (scanner_.peek()) {
218 Parser::multiplication()
220 Expression *left = unary();
222 if (!match(TOK_SLASH) && !match(TOK_STAR))
224 TokenKind kind = scanner_.last();
225 Expression *right = unary();
228 left = new (pool_) BinaryExpression(kind, left, right);
236 Expression *left = multiplication();
238 if (!match(TOK_PLUS) && !match(TOK_MINUS))
240 TokenKind kind = scanner_.last();
241 Expression *right = multiplication();
244 left = new (pool_) BinaryExpression(kind, left, right);
252 Expression *left = addition();
254 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
256 TokenKind kind = scanner_.last();
257 Expression *right = addition();
260 left = new (pool_) BinaryExpression(kind, left, right);
268 Expression *left = shift();
270 if (!match(TOK_BITAND))
272 Expression *right = shift();
275 left = new (pool_) BinaryExpression(TOK_BITAND, left, right);
283 Expression *left = bitand();
285 if (!match(TOK_BITXOR))
287 Expression *right = shift();
290 left = new (pool_) BinaryExpression(TOK_BITXOR, left, right);
298 Expression *left = bitxor();
300 if (!match(TOK_BITOR))
302 Expression *right = shift();
305 left = new (pool_) BinaryExpression(TOK_BITOR, left, right);
313 Expression *left = bitor();
315 TokenKind kind = scanner_.peek();
316 if (kind < TOK_LT || kind > TOK_GE)
319 Expression *right = shift();
322 left = new (pool_) BinaryExpression(kind, left, right);
330 Expression *left = relational();
332 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
334 TokenKind kind = scanner_.last();
335 Expression *right = relational();
338 left = new (pool_) BinaryExpression(kind, left, right);
354 if (!expect(TOK_LPAREN))
356 Expression *condition = expression();
359 if (!expect(TOK_RPAREN))
362 Statement *body = localStatement();
366 return new (pool_) WhileStatement(TOK_WHILE, condition, body);
374 Statement *body = block();
378 if (!expect(TOK_WHILE))
381 if (!expect(TOK_LPAREN))
383 Expression *condition = expression();
386 if (!expect(TOK_RPAREN))
389 return new (pool_) WhileStatement(TOK_DO, condition, body);
393 Parser::forStatement()
396 if (!expect(TOK_LPAREN))
399 VariableDeclaration *decl = NULL;
400 if (!match(TOK_SEMICOLON)) {
401 if (!enterScope(Scope::BLOCK))
403 if ((decl = variableDeclaration()) == NULL)
405 if (!expect(TOK_SEMICOLON))
409 Expression *condition = NULL;
410 if (!match(TOK_SEMICOLON)) {
411 if ((condition = expression()) == NULL)
413 if (!expect(TOK_SEMICOLON))
417 Statement *update = NULL;
418 if (!match(TOK_RPAREN)) {
419 if ((update = expressionStatement()) == NULL)
421 if (!expect(TOK_RPAREN))
425 Statement *body = localStatement();
429 Scope *blockScope = NULL;
431 blockScope = scope_->unlinkIfEmpty();
432 scope_ = scope_->enclosing();
434 return new (pool_) ForStatement(blockScope, decl, condition, update, body);
437 VariableDeclaration *
438 Parser::variableDeclaration()
440 if (!expect(TOK_NEW))
444 if (matchName(&tag, TOK_LABEL) && !tag)
447 Name *name = expectName();
451 ExpressionList *postDimensions = NULL;
452 if (scanner_.peek() == TOK_LBRACKET) {
453 postDimensions = new ExpressionList();
454 while (match(TOK_LBRACKET)) {
455 Expression *dim = expression();
459 if (!expect(TOK_RBRACKET))
462 postDimensions->push_back(dim);
466 Expression *expr = NULL;
467 if (match(TOK_ASSIGN)) {
468 if ((expr = expression()) == NULL)
472 if (scope_->localLookup(name)) {
473 redeclarationError();
477 Variable *var = scope_->declareVariable(name);
478 VariableDeclaration *decl = new (pool_) VariableDeclaration(var, tag, postDimensions, expr);
484 Parser::returnStatement()
486 if (!expect(TOK_RETURN))
489 Expression *expr = expression();
493 return new (pool_) ReturnStatement(expr);
497 Parser::expressionStatement()
499 Expression *left = primary();
501 fprintf(stderr, "expected expression or statement\n");
505 if (match(TOK_ASSIGN)) {
506 Expression *expr = expression();
510 left = new (pool_) Assignment(left, expr);
513 return new (pool_) ExpressionStatement(left);
519 if (!expect(TOK_LBRACE))
522 if (!enterScope(Scope::BLOCK))
525 StatementList *statements = new (pool_) StatementList();
526 while (!match(TOK_RBRACE)) {
527 Statement *statement = localStatement();
528 if (statement == NULL)
530 statements->append(pool_, statement);
533 Scope *blockScope = scope_->unlinkIfEmpty();
534 BlockStatement *block = new (pool_) BlockStatement(blockScope, statements);
536 scope_ = scope_->enclosing();
545 if (!expect(TOK_LPAREN))
548 Expression *cond = expression();
552 if (!expect(TOK_RPAREN))
555 Statement *ifTrue = localStatement();
559 IfStatement *outer = new (pool_) IfStatement(cond, ifTrue);
561 IfStatement *last = outer;
562 while (match(TOK_ELSE)) {
563 if (!match(TOK_IF)) {
564 Statement *ifFalse = localStatement();
568 last->setIfFalse(ifFalse);
575 if (!expect(TOK_LPAREN))
578 Expression *otherCond = expression();
582 if (!expect(TOK_RPAREN))
585 Statement *otherIfTrue = localStatement();
589 IfStatement *inner = new (pool_) IfStatement(otherCond, otherIfTrue);
590 last->setIfFalse(inner);
598 Parser::localStatement()
600 Statement *statement = NULL;
602 // Statements which must be followed by a semicolon will break out of the
603 // switch. If they may end in BlockStatements, they'll immediately return.
605 switch (scanner_.peek()) {
607 statement = variableDeclaration();
611 return forStatement();
617 if ((statement = do_()) == NULL)
622 statement = returnStatement();
637 if ((statement = expressionStatement()) == NULL)
641 if (!expect(TOK_SEMICOLON))
653 if (match(TOK_NAME)) {
654 if ((name = strings_.add(scanner_.literal())) == NULL)
657 if (scope_->localLookup(name)) {
658 redeclarationError();
662 NamedEnum *e = scope_->declareEnum(name);
667 EnumStatement::EntryList *entries = new EnumStatement::EntryList();
669 if (!expect(TOK_LBRACE))
673 if (scanner_.peek() == TOK_RBRACE)
676 Name *name = expectName();
680 if (scope_->localLookup(name)) {
681 redeclarationError();
685 NamedConstant *constant = scope_->declareConstant(name);
689 Expression *expr = NULL;
690 if (match(TOK_ASSIGN)) {
691 if ((expr = expression()) == NULL)
695 entries->push_back(EnumStatement::Entry(constant, expr));
696 } while (match(TOK_COMMA));
697 if (!expect(TOK_RBRACE))
700 return new (pool_) EnumStatement(name, entries);
706 Name *name = expectName();
710 // The function name goes into the outer (global) scope.
711 assert(!scope_->enclosing());
713 if (scope_->localLookup(name)) {
714 redeclarationError();
717 NamedFunction *fun = scope_->declareFunction(name);
721 Scope *scope = enterScope(Scope::FUNCTION);
725 if (!expect(TOK_LPAREN))
727 if (!match(TOK_RPAREN)) {
729 Name *name = expectName();
733 if (scope_->localLookup(name)) {
734 redeclarationError();
737 if (!scope_->declareArgument(name))
740 if (!match(TOK_COMMA))
743 if (!expect(TOK_RPAREN))
747 Statement *body = block();
751 scope_ = scope_->enclosing();
752 return new (pool_) FunctionStatement(scope, fun, body);
758 StatementList *statements = new (pool_) StatementList();
760 if (!enterScope(Scope::GLOBAL))
764 Statement *statement = NULL;
766 switch (scanner_.peek()) {
774 if ((statement = function()) == NULL)
779 if ((statement = enum_()) == NULL)
781 // :TODO: require semicolon
785 fprintf(stderr, "expected function or global variable\n");
792 statements->append(pool_, statement);
795 return new (pool_) ParseTree(scope_, statements, unbound_);
798 class AstPrinter : public AstVisitor
805 for (size_t i = 0; i < level_; i++)
822 void visit(NameProxy *name) {
824 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name(),
825 (name->binding() ? "" : " unbound"));
827 void visit(CallExpression *node) {
829 fprintf(fp_, "[ CallExpression\n");
831 node->callee()->accept(this);
832 for (size_t i = 0; i < node->arguments()->size(); i++)
833 node->arguments()->at(i)->accept(this);
836 void visit(FunctionStatement *node) {
838 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name());
840 node->body()->accept(this);
843 void visit(ExpressionStatement *node) {
845 fprintf(fp_, "[ ExpressionStatement\n");
847 node->expression()->accept(this);
850 void visit(Assignment *node) {
852 fprintf(fp_, "[ Assignment\n");
854 node->lvalue()->accept(this);
855 node->expression()->accept(this);
858 void visit(BinaryExpression *node) {
860 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
862 node->left()->accept(this);
863 node->right()->accept(this);
866 void visit(ReturnStatement *node) {
868 fprintf(fp_, "[ ReturnStatement\n");
870 node->expression()->accept(this);
873 void visit(ForStatement *node) {
875 fprintf(fp_, "[ ForStatement\n");
877 if (node->declaration())
878 node->declaration()->accept(this);
879 if (node->condition())
880 node->condition()->accept(this);
882 node->update()->accept(this);
883 node->body()->accept(this);
886 void visit(BlockStatement *node) {
888 fprintf(fp_, "[ BlockStatement\n");
890 for (size_t i = 0; i < node->statements()->length(); i++)
891 node->statements()->at(i)->accept(this);
894 void visit(VariableDeclaration *node) {
896 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name());
898 if (node->initialization())
899 node->initialization()->accept(this);
902 void visit(IntegerLiteral *node) {
904 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
906 void visit(FloatLiteral *node) {
908 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
910 void visit(IfStatement *node) {
912 fprintf(fp_, "[ IfStatement\n");
914 node->ifTrue()->accept(this);
916 node->ifFalse()->accept(this);
919 void visit(IndexExpression *node) {
921 fprintf(fp_, "[ IndexExpression\n");
923 node->left()->accept(this);
924 node->right()->accept(this);
927 void visit(EnumStatement *node) {
929 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name() : "<anonymous>");
931 for (size_t i = 0; i < node->entries()->size(); i++) {
933 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name());
934 if (node->entries()->at(i).expr) {
936 node->entries()->at(i).expr->accept(this);
942 void visit(WhileStatement *node) {
944 fprintf(fp_, "[ WhileStatement (%s)\n",
945 (node->token() == TOK_DO) ? "do" : "while");
947 if (node->token() == TOK_DO) {
948 node->condition()->accept(this);
949 node->body()->accept(this);
951 node->condition()->accept(this);
952 node->body()->accept(this);
959 ParseTree::dump(FILE *fp)
961 AstPrinter printer(fp);
963 for (size_t i = 0; i < statements_->length(); i++)
964 statements_->at(i)->accept(&printer);