Added support for enums.
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);
74 switch (scanner_.peek()) {
78 Name *name = strings_.add(scanner_.literal());
82 case TOK_INTEGER_LITERAL:
85 int value = atoi(scanner_.literal());
86 return new (pool_) IntegerLiteralExpression(value);
91 fprintf(stderr, "error: expected expression!\n");
100 switch (scanner_.peek()) {
104 Expression *expr = expression();
107 if (!expect(TOK_RPAREN))
118 Parser::call(Expression *callee)
120 ExpressionList *arguments = new ExpressionList();
124 if (!match(TOK_RPAREN)) {
126 Expression *expr = expression();
130 arguments->push_back(expr);
132 if (!match(TOK_COMMA))
136 if (!expect(TOK_RPAREN))
140 return new (pool_) CallExpression(callee, arguments);
144 Parser::index(Expression *left)
146 expect(TOK_LBRACKET);
148 Expression *expr = expression();
152 if (!expect(TOK_RBRACKET))
155 return new (pool_) IndexExpression(left, expr);
161 Expression *expr = prefix();
166 switch (scanner_.peek()) {
192 Parser::multiplication()
194 Expression *left = unary();
196 if (!match(TOK_SLASH) && !match(TOK_STAR))
198 TokenKind kind = scanner_.last();
199 Expression *right = unary();
202 left = new (pool_) BinaryExpression(kind, left, right);
210 Expression *left = multiplication();
212 if (!match(TOK_PLUS) && !match(TOK_MINUS))
214 TokenKind kind = scanner_.last();
215 Expression *right = multiplication();
218 left = new (pool_) BinaryExpression(kind, left, right);
226 Expression *left = addition();
230 TokenKind kind = scanner_.last();
231 Expression *right = addition();
234 left = new (pool_) BinaryExpression(kind, left, right);
242 Expression *left = shift();
244 TokenKind kind = scanner_.peek();
245 if (kind < TOK_LT || kind > TOK_GE)
248 Expression *right = shift();
251 left = new (pool_) BinaryExpression(kind, left, right);
259 Expression *left = relational();
261 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
263 TokenKind kind = scanner_.last();
264 Expression *right = relational();
267 left = new (pool_) BinaryExpression(kind, left, right);
279 Parser::forStatement()
282 if (!expect(TOK_LPAREN))
285 VariableDeclaration *decl = NULL;
286 if (!match(TOK_SEMICOLON)) {
287 if (!enterScope(Scope::BLOCK))
289 if ((decl = variableDeclaration()) == NULL)
291 if (!expect(TOK_SEMICOLON))
295 Expression *condition = NULL;
296 if (!match(TOK_SEMICOLON)) {
297 if ((condition = expression()) == NULL)
299 if (!expect(TOK_SEMICOLON))
303 Statement *update = NULL;
304 if (!match(TOK_RPAREN)) {
305 if ((update = expressionStatement()) == NULL)
307 if (!expect(TOK_RPAREN))
311 Statement *body = localStatement();
315 Scope *blockScope = NULL;
317 blockScope = scope_->unlinkIfEmpty();
318 scope_ = scope_->enclosing();
320 return new (pool_) ForStatement(blockScope, decl, condition, update, body);
323 VariableDeclaration *
324 Parser::variableDeclaration()
326 if (!expect(TOK_NEW))
330 if (!expect(TOK_NAME))
333 Name *name = strings_.add(scanner_.literal());
335 ExpressionList *postDimensions = NULL;
336 if (scanner_.peek() == TOK_LBRACKET) {
337 postDimensions = new ExpressionList();
338 while (match(TOK_LBRACKET)) {
339 Expression *dim = expression();
343 if (!expect(TOK_RBRACKET))
346 postDimensions->push_back(dim);
350 Expression *expr = NULL;
351 if (match(TOK_ASSIGN)) {
352 if ((expr = expression()) == NULL)
356 if (scope_->localLookup(name)) {
357 redeclarationError();
361 Variable *var = scope_->declareVariable(name);
362 VariableDeclaration *decl = new (pool_) VariableDeclaration(var, postDimensions, expr);
368 Parser::returnStatement()
370 if (!expect(TOK_RETURN))
373 Expression *expr = expression();
377 return new (pool_) ReturnStatement(expr);
381 Parser::expressionStatement()
383 Expression *left = primary();
385 fprintf(stderr, "expected expression or statement\n");
389 if (match(TOK_ASSIGN)) {
390 Expression *expr = expression();
394 left = new (pool_) Assignment(left, expr);
397 return new (pool_) ExpressionStatement(left);
403 if (!expect(TOK_LBRACE))
406 if (!enterScope(Scope::BLOCK))
409 StatementList *statements = new (pool_) StatementList();
410 while (!match(TOK_RBRACE)) {
411 Statement *statement = localStatement();
412 if (statement == NULL)
414 statements->append(pool_, statement);
417 Scope *blockScope = scope_->unlinkIfEmpty();
418 BlockStatement *block = new (pool_) BlockStatement(blockScope, statements);
420 scope_ = scope_->enclosing();
429 if (!expect(TOK_LPAREN))
432 Expression *cond = expression();
436 if (!expect(TOK_RPAREN))
439 Statement *ifTrue = localStatement();
443 IfStatement *outer = new (pool_) IfStatement(cond, ifTrue);
445 IfStatement *last = outer;
446 while (match(TOK_ELSE)) {
447 if (!match(TOK_IF)) {
448 Statement *ifFalse = localStatement();
452 last->setIfFalse(ifFalse);
459 if (!expect(TOK_LPAREN))
462 Expression *otherCond = expression();
466 if (!expect(TOK_RPAREN))
469 Statement *otherIfTrue = localStatement();
473 IfStatement *inner = new (pool_) IfStatement(otherCond, otherIfTrue);
474 last->setIfFalse(inner);
482 Parser::localStatement()
484 Statement *statement = NULL;
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.
489 switch (scanner_.peek()) {
491 statement = variableDeclaration();
495 return forStatement();
498 statement = returnStatement();
513 if ((statement = expressionStatement()) == NULL)
517 if (!expect(TOK_SEMICOLON))
529 if (match(TOK_NAME)) {
530 if ((name = strings_.add(scanner_.literal())) == NULL)
533 if (scope_->localLookup(name)) {
534 redeclarationError();
538 NamedEnum *e = scope_->declareEnum(name);
543 EnumStatement::EntryList *entries = new EnumStatement::EntryList();
545 if (!expect(TOK_LBRACE))
549 if (scanner_.peek() == TOK_RBRACE)
552 if (!expect(TOK_NAME))
555 Name *name = strings_.add(scanner_.literal());
559 if (scope_->localLookup(name)) {
560 redeclarationError();
564 NamedConstant *constant = scope_->declareConstant(name);
568 Expression *expr = NULL;
569 if (match(TOK_ASSIGN)) {
570 if ((expr = expression()) == NULL)
574 entries->push_back(EnumStatement::Entry(constant, expr));
575 } while (match(TOK_COMMA));
576 if (!expect(TOK_RBRACE))
579 return new (pool_) EnumStatement(name, entries);
587 Name *name = strings_.add(scanner_.literal());
591 // The function name goes into the outer (global) scope.
592 assert(!scope_->enclosing());
594 if (scope_->localLookup(name)) {
595 redeclarationError();
598 NamedFunction *fun = scope_->declareFunction(name);
602 Scope *scope = enterScope(Scope::FUNCTION);
606 if (!expect(TOK_LPAREN))
608 if (!match(TOK_RPAREN)) {
610 if (!expect(TOK_NAME))
613 Name *name = strings_.add(scanner_.literal());
617 if (scope_->localLookup(name)) {
618 redeclarationError();
621 if (!scope_->declareArgument(name))
624 if (!match(TOK_COMMA))
627 if (!expect(TOK_RPAREN))
631 Statement *body = block();
635 scope_ = scope_->enclosing();
636 return new (pool_) FunctionStatement(scope, fun, body);
642 StatementList *statements = new (pool_) StatementList();
644 if (!enterScope(Scope::GLOBAL))
648 Statement *statement = NULL;
650 switch (scanner_.peek()) {
658 if ((statement = function()) == NULL)
663 if ((statement = enum_()) == NULL)
665 // :TODO: require semicolon
669 fprintf(stderr, "expected function or global variable\n");
676 statements->append(pool_, statement);
679 return new (pool_) ParseTree(scope_, statements, unbound_);
682 class AstPrinter : public AstVisitor
689 for (size_t i = 0; i < level_; i++)
706 void visit(NameProxy *name) {
708 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name(),
709 (name->binding() ? "" : " unbound"));
711 void visit(CallExpression *node) {
713 fprintf(fp_, "[ CallExpression\n");
715 node->callee()->accept(this);
716 for (size_t i = 0; i < node->arguments()->size(); i++)
717 node->arguments()->at(i)->accept(this);
720 void visit(FunctionStatement *node) {
722 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name());
724 node->body()->accept(this);
727 void visit(ExpressionStatement *node) {
729 fprintf(fp_, "[ ExpressionStatement\n");
731 node->expression()->accept(this);
734 void visit(Assignment *node) {
736 fprintf(fp_, "[ Assignment\n");
738 node->lvalue()->accept(this);
739 node->expression()->accept(this);
742 void visit(BinaryExpression *node) {
744 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
746 node->left()->accept(this);
747 node->right()->accept(this);
750 void visit(ReturnStatement *node) {
752 fprintf(fp_, "[ ReturnStatement\n");
754 node->expression()->accept(this);
757 void visit(ForStatement *node) {
759 fprintf(fp_, "[ ForStatement\n");
761 if (node->declaration())
762 node->declaration()->accept(this);
763 if (node->condition())
764 node->condition()->accept(this);
766 node->update()->accept(this);
767 node->body()->accept(this);
770 void visit(BlockStatement *node) {
772 fprintf(fp_, "[ BlockStatement\n");
774 for (size_t i = 0; i < node->statements()->length(); i++)
775 node->statements()->at(i)->accept(this);
778 void visit(VariableDeclaration *node) {
780 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name());
782 if (node->initialization())
783 node->initialization()->accept(this);
786 void visit(IntegerLiteralExpression *node) {
788 fprintf(fp_, "[ LiteralExpression (%d)\n", node->value());
790 void visit(IfStatement *node) {
792 fprintf(fp_, "[ IfStatement\n");
794 node->ifTrue()->accept(this);
796 node->ifFalse()->accept(this);
799 void visit(IndexExpression *node) {
801 fprintf(fp_, "[ IndexExpression\n");
803 node->left()->accept(this);
804 node->right()->accept(this);
807 void visit(EnumStatement *node) {
809 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name() : "<anonymous>");
811 for (size_t i = 0; i < node->entries()->size(); i++) {
813 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name());
814 if (node->entries()->at(i).expr) {
816 node->entries()->at(i).expr->accept(this);
825 ParseTree::dump(FILE *fp)
827 AstPrinter printer(fp);
829 for (size_t i = 0; i < statements_->length(); i++)
830 statements_->at(i)->accept(&printer);