Initial import of prototype.
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();
228 TokenKind kind = scanner_.peek();
229 if (kind < TOK_LT || kind > TOK_GE)
232 Expression *right = addition();
235 left = new (pool_) BinaryExpression(kind, left, right);
243 Expression *left = relational();
245 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
247 TokenKind kind = scanner_.last();
248 Expression *right = relational();
251 left = new (pool_) BinaryExpression(kind, left, right);
263 Parser::forStatement()
266 if (!expect(TOK_LPAREN))
269 VariableDeclaration *decl = NULL;
270 if (!match(TOK_SEMICOLON)) {
271 if (!enterScope(Scope::BLOCK))
273 if ((decl = variableDeclaration()) == NULL)
275 if (!expect(TOK_SEMICOLON))
279 Expression *condition = NULL;
280 if (!match(TOK_SEMICOLON)) {
281 if ((condition = expression()) == NULL)
283 if (!expect(TOK_SEMICOLON))
287 Statement *update = NULL;
288 if (!match(TOK_RPAREN)) {
289 if ((update = expressionStatement()) == NULL)
291 if (!expect(TOK_RPAREN))
295 Statement *body = localStatement();
299 Scope *blockScope = NULL;
301 blockScope = scope_->unlinkIfEmpty();
302 scope_ = scope_->enclosing();
304 return new (pool_) ForStatement(blockScope, decl, condition, update, body);
307 VariableDeclaration *
308 Parser::variableDeclaration()
310 if (!expect(TOK_NEW))
314 if (!expect(TOK_NAME))
317 Name *name = strings_.add(scanner_.literal());
319 ExpressionList *postDimensions = NULL;
320 if (scanner_.peek() == TOK_LBRACKET) {
321 postDimensions = new ExpressionList();
322 while (match(TOK_LBRACKET)) {
323 Expression *dim = expression();
327 if (!expect(TOK_RBRACKET))
330 postDimensions->push_back(dim);
334 Expression *expr = NULL;
335 if (match(TOK_ASSIGN)) {
336 if ((expr = expression()) == NULL)
340 if (scope_->localLookup(name)) {
341 redeclarationError();
345 Variable *var = scope_->declareVariable(name);
346 VariableDeclaration *decl = new (pool_) VariableDeclaration(var, postDimensions, expr);
352 Parser::returnStatement()
354 if (!expect(TOK_RETURN))
357 Expression *expr = expression();
361 return new (pool_) ReturnStatement(expr);
365 Parser::expressionStatement()
367 Expression *left = primary();
369 fprintf(stderr, "expected expression or statement\n");
373 if (match(TOK_ASSIGN)) {
374 Expression *expr = expression();
378 left = new (pool_) Assignment(left, expr);
381 return new (pool_) ExpressionStatement(left);
387 if (!expect(TOK_LBRACE))
390 if (!enterScope(Scope::BLOCK))
393 StatementList *statements = new (pool_) StatementList();
394 while (!match(TOK_RBRACE)) {
395 Statement *statement = localStatement();
396 if (statement == NULL)
398 statements->append(pool_, statement);
401 Scope *blockScope = scope_->unlinkIfEmpty();
402 BlockStatement *block = new (pool_) BlockStatement(blockScope, statements);
404 scope_ = scope_->enclosing();
413 if (!expect(TOK_LPAREN))
416 Expression *cond = expression();
420 if (!expect(TOK_RPAREN))
423 Statement *ifTrue = localStatement();
427 IfStatement *outer = new (pool_) IfStatement(cond, ifTrue);
429 IfStatement *last = outer;
430 while (match(TOK_ELSE)) {
431 if (!match(TOK_IF)) {
432 Statement *ifFalse = localStatement();
436 last->setIfFalse(ifFalse);
443 if (!expect(TOK_LPAREN))
446 Expression *otherCond = expression();
450 if (!expect(TOK_RPAREN))
453 Statement *otherIfTrue = localStatement();
457 IfStatement *inner = new (pool_) IfStatement(otherCond, otherIfTrue);
458 last->setIfFalse(inner);
466 Parser::localStatement()
468 Statement *statement = NULL;
470 // Statements which must be followed by a semicolon will break out of the
471 // switch. If they may end in BlockStatements, they'll immediately return.
473 switch (scanner_.peek()) {
475 statement = variableDeclaration();
479 return forStatement();
482 statement = returnStatement();
493 if ((statement = expressionStatement()) == NULL)
497 if (!expect(TOK_SEMICOLON))
508 Name *name = strings_.add(scanner_.literal());
512 // The function name goes into the outer (global) scope.
513 assert(!scope_->enclosing());
515 if (scope_->localLookup(name)) {
516 redeclarationError();
519 NamedFunction *fun = scope_->declareFunction(name);
523 Scope *scope = enterScope(Scope::FUNCTION);
527 if (!expect(TOK_LPAREN))
529 if (!match(TOK_RPAREN)) {
531 if (!expect(TOK_NAME))
534 Name *name = strings_.add(scanner_.literal());
538 if (scope_->localLookup(name)) {
539 redeclarationError();
542 if (!scope_->declareArgument(name))
545 if (!match(TOK_COMMA))
548 if (!expect(TOK_RPAREN))
552 Statement *body = block();
556 scope_ = scope_->enclosing();
557 return new (pool_) FunctionStatement(scope, fun, body);
563 StatementList *statements = new (pool_) StatementList();
565 if (!enterScope(Scope::GLOBAL))
569 Statement *statement = NULL;
571 switch (scanner_.peek()) {
579 if ((statement = function()) == NULL)
584 fprintf(stderr, "expected function or global variable\n");
591 statements->append(pool_, statement);
594 return new (pool_) ParseTree(scope_, statements, unbound_);
597 class AstPrinter : public AstVisitor
604 for (size_t i = 0; i < level_; i++)
621 void visit(NameProxy *name) {
623 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name(),
624 (name->binding() ? "" : " unbound"));
626 void visit(CallExpression *node) {
628 fprintf(fp_, "[ CallExpression\n");
630 node->callee()->accept(this);
631 for (size_t i = 0; i < node->arguments()->size(); i++)
632 node->arguments()->at(i)->accept(this);
635 void visit(FunctionStatement *node) {
637 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name());
639 node->body()->accept(this);
642 void visit(ExpressionStatement *node) {
644 fprintf(fp_, "[ ExpressionStatement\n");
646 node->expression()->accept(this);
649 void visit(Assignment *node) {
651 fprintf(fp_, "[ Assignment\n");
653 node->lvalue()->accept(this);
654 node->expression()->accept(this);
657 void visit(BinaryExpression *node) {
659 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
661 node->left()->accept(this);
662 node->right()->accept(this);
665 void visit(ReturnStatement *node) {
667 fprintf(fp_, "[ ReturnStatement\n");
669 node->expression()->accept(this);
672 void visit(ForStatement *node) {
674 fprintf(fp_, "[ ForStatement\n");
676 if (node->declaration())
677 node->declaration()->accept(this);
678 if (node->condition())
679 node->condition()->accept(this);
681 node->update()->accept(this);
682 node->body()->accept(this);
685 void visit(BlockStatement *node) {
687 fprintf(fp_, "[ BlockStatement\n");
689 for (size_t i = 0; i < node->statements()->length(); i++)
690 node->statements()->at(i)->accept(this);
693 void visit(VariableDeclaration *node) {
695 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name());
697 if (node->initialization())
698 node->initialization()->accept(this);
701 void visit(IntegerLiteralExpression *node) {
703 fprintf(fp_, "[ LiteralExpression (%d)\n", node->value());
705 void visit(IfStatement *node) {
707 fprintf(fp_, "[ IfStatement\n");
709 node->ifTrue()->accept(this);
711 node->ifFalse()->accept(this);
714 void visit(IndexExpression *node) {
716 fprintf(fp_, "[ IndexExpression\n");
718 node->left()->accept(this);
719 node->right()->accept(this);
725 ParseTree::dump(FILE *fp)
727 AstPrinter printer(fp);
729 for (size_t i = 0; i < statements_->length(); i++)
730 statements_->at(i)->accept(&printer);