Add support for float variables and basic math.
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();
256 TokenKind kind = scanner_.last();
257 Expression *right = addition();
260 left = new (pool_) BinaryExpression(kind, left, right);
268 Expression *left = shift();
270 TokenKind kind = scanner_.peek();
271 if (kind < TOK_LT || kind > TOK_GE)
274 Expression *right = shift();
277 left = new (pool_) BinaryExpression(kind, left, right);
285 Expression *left = relational();
287 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
289 TokenKind kind = scanner_.last();
290 Expression *right = relational();
293 left = new (pool_) BinaryExpression(kind, left, right);
305 Parser::forStatement()
308 if (!expect(TOK_LPAREN))
311 VariableDeclaration *decl = NULL;
312 if (!match(TOK_SEMICOLON)) {
313 if (!enterScope(Scope::BLOCK))
315 if ((decl = variableDeclaration()) == NULL)
317 if (!expect(TOK_SEMICOLON))
321 Expression *condition = NULL;
322 if (!match(TOK_SEMICOLON)) {
323 if ((condition = expression()) == NULL)
325 if (!expect(TOK_SEMICOLON))
329 Statement *update = NULL;
330 if (!match(TOK_RPAREN)) {
331 if ((update = expressionStatement()) == NULL)
333 if (!expect(TOK_RPAREN))
337 Statement *body = localStatement();
341 Scope *blockScope = NULL;
343 blockScope = scope_->unlinkIfEmpty();
344 scope_ = scope_->enclosing();
346 return new (pool_) ForStatement(blockScope, decl, condition, update, body);
349 VariableDeclaration *
350 Parser::variableDeclaration()
352 if (!expect(TOK_NEW))
356 if (matchName(&tag, TOK_LABEL) && !tag)
359 Name *name = expectName();
363 ExpressionList *postDimensions = NULL;
364 if (scanner_.peek() == TOK_LBRACKET) {
365 postDimensions = new ExpressionList();
366 while (match(TOK_LBRACKET)) {
367 Expression *dim = expression();
371 if (!expect(TOK_RBRACKET))
374 postDimensions->push_back(dim);
378 Expression *expr = NULL;
379 if (match(TOK_ASSIGN)) {
380 if ((expr = expression()) == NULL)
384 if (scope_->localLookup(name)) {
385 redeclarationError();
389 Variable *var = scope_->declareVariable(name);
390 VariableDeclaration *decl = new (pool_) VariableDeclaration(var, tag, postDimensions, expr);
396 Parser::returnStatement()
398 if (!expect(TOK_RETURN))
401 Expression *expr = expression();
405 return new (pool_) ReturnStatement(expr);
409 Parser::expressionStatement()
411 Expression *left = primary();
413 fprintf(stderr, "expected expression or statement\n");
417 if (match(TOK_ASSIGN)) {
418 Expression *expr = expression();
422 left = new (pool_) Assignment(left, expr);
425 return new (pool_) ExpressionStatement(left);
431 if (!expect(TOK_LBRACE))
434 if (!enterScope(Scope::BLOCK))
437 StatementList *statements = new (pool_) StatementList();
438 while (!match(TOK_RBRACE)) {
439 Statement *statement = localStatement();
440 if (statement == NULL)
442 statements->append(pool_, statement);
445 Scope *blockScope = scope_->unlinkIfEmpty();
446 BlockStatement *block = new (pool_) BlockStatement(blockScope, statements);
448 scope_ = scope_->enclosing();
457 if (!expect(TOK_LPAREN))
460 Expression *cond = expression();
464 if (!expect(TOK_RPAREN))
467 Statement *ifTrue = localStatement();
471 IfStatement *outer = new (pool_) IfStatement(cond, ifTrue);
473 IfStatement *last = outer;
474 while (match(TOK_ELSE)) {
475 if (!match(TOK_IF)) {
476 Statement *ifFalse = localStatement();
480 last->setIfFalse(ifFalse);
487 if (!expect(TOK_LPAREN))
490 Expression *otherCond = expression();
494 if (!expect(TOK_RPAREN))
497 Statement *otherIfTrue = localStatement();
501 IfStatement *inner = new (pool_) IfStatement(otherCond, otherIfTrue);
502 last->setIfFalse(inner);
510 Parser::localStatement()
512 Statement *statement = NULL;
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.
517 switch (scanner_.peek()) {
519 statement = variableDeclaration();
523 return forStatement();
526 statement = returnStatement();
541 if ((statement = expressionStatement()) == NULL)
545 if (!expect(TOK_SEMICOLON))
557 if (match(TOK_NAME)) {
558 if ((name = strings_.add(scanner_.literal())) == NULL)
561 if (scope_->localLookup(name)) {
562 redeclarationError();
566 NamedEnum *e = scope_->declareEnum(name);
571 EnumStatement::EntryList *entries = new EnumStatement::EntryList();
573 if (!expect(TOK_LBRACE))
577 if (scanner_.peek() == TOK_RBRACE)
580 Name *name = expectName();
584 if (scope_->localLookup(name)) {
585 redeclarationError();
589 NamedConstant *constant = scope_->declareConstant(name);
593 Expression *expr = NULL;
594 if (match(TOK_ASSIGN)) {
595 if ((expr = expression()) == NULL)
599 entries->push_back(EnumStatement::Entry(constant, expr));
600 } while (match(TOK_COMMA));
601 if (!expect(TOK_RBRACE))
604 return new (pool_) EnumStatement(name, entries);
610 Name *name = expectName();
614 // The function name goes into the outer (global) scope.
615 assert(!scope_->enclosing());
617 if (scope_->localLookup(name)) {
618 redeclarationError();
621 NamedFunction *fun = scope_->declareFunction(name);
625 Scope *scope = enterScope(Scope::FUNCTION);
629 if (!expect(TOK_LPAREN))
631 if (!match(TOK_RPAREN)) {
633 Name *name = expectName();
637 if (scope_->localLookup(name)) {
638 redeclarationError();
641 if (!scope_->declareArgument(name))
644 if (!match(TOK_COMMA))
647 if (!expect(TOK_RPAREN))
651 Statement *body = block();
655 scope_ = scope_->enclosing();
656 return new (pool_) FunctionStatement(scope, fun, body);
662 StatementList *statements = new (pool_) StatementList();
664 if (!enterScope(Scope::GLOBAL))
668 Statement *statement = NULL;
670 switch (scanner_.peek()) {
678 if ((statement = function()) == NULL)
683 if ((statement = enum_()) == NULL)
685 // :TODO: require semicolon
689 fprintf(stderr, "expected function or global variable\n");
696 statements->append(pool_, statement);
699 return new (pool_) ParseTree(scope_, statements, unbound_);
702 class AstPrinter : public AstVisitor
709 for (size_t i = 0; i < level_; i++)
726 void visit(NameProxy *name) {
728 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name(),
729 (name->binding() ? "" : " unbound"));
731 void visit(CallExpression *node) {
733 fprintf(fp_, "[ CallExpression\n");
735 node->callee()->accept(this);
736 for (size_t i = 0; i < node->arguments()->size(); i++)
737 node->arguments()->at(i)->accept(this);
740 void visit(FunctionStatement *node) {
742 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name());
744 node->body()->accept(this);
747 void visit(ExpressionStatement *node) {
749 fprintf(fp_, "[ ExpressionStatement\n");
751 node->expression()->accept(this);
754 void visit(Assignment *node) {
756 fprintf(fp_, "[ Assignment\n");
758 node->lvalue()->accept(this);
759 node->expression()->accept(this);
762 void visit(BinaryExpression *node) {
764 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
766 node->left()->accept(this);
767 node->right()->accept(this);
770 void visit(ReturnStatement *node) {
772 fprintf(fp_, "[ ReturnStatement\n");
774 node->expression()->accept(this);
777 void visit(ForStatement *node) {
779 fprintf(fp_, "[ ForStatement\n");
781 if (node->declaration())
782 node->declaration()->accept(this);
783 if (node->condition())
784 node->condition()->accept(this);
786 node->update()->accept(this);
787 node->body()->accept(this);
790 void visit(BlockStatement *node) {
792 fprintf(fp_, "[ BlockStatement\n");
794 for (size_t i = 0; i < node->statements()->length(); i++)
795 node->statements()->at(i)->accept(this);
798 void visit(VariableDeclaration *node) {
800 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name());
802 if (node->initialization())
803 node->initialization()->accept(this);
806 void visit(IntegerLiteral *node) {
808 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
810 void visit(FloatLiteral *node) {
812 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
814 void visit(IfStatement *node) {
816 fprintf(fp_, "[ IfStatement\n");
818 node->ifTrue()->accept(this);
820 node->ifFalse()->accept(this);
823 void visit(IndexExpression *node) {
825 fprintf(fp_, "[ IndexExpression\n");
827 node->left()->accept(this);
828 node->right()->accept(this);
831 void visit(EnumStatement *node) {
833 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name() : "<anonymous>");
835 for (size_t i = 0; i < node->entries()->size(); i++) {
837 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name());
838 if (node->entries()->at(i).expr) {
840 node->entries()->at(i).expr->accept(this);
849 ParseTree::dump(FILE *fp)
851 AstPrinter printer(fp);
853 for (size_t i = 0; i < statements_->length(); i++)
854 statements_->at(i)->accept(&printer);