Convert Name and StringPool to a GC-safe symbol table.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
21 #include "FixedArray.h"
28 Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
32 scanner_(cc, stream, length),
36 unbound_ = new std::vector<NameProxy *>();
40 Parser::match(TokenKind kind)
42 if (scanner_.peek() != kind)
49 Parser::expect(TokenKind kind)
51 TokenKind got = scanner_.scan();
54 cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
59 Parser::enterScope(Scope::Kind kind)
61 scope_ = new (pool_) Scope(pool_, kind, scope_);
62 if (!scope_->initialize())
68 Parser::bind(Handle<String> name)
70 BoundName *bound = scope_->lookup(name);
71 NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
73 unbound_->push_back(proxy);
78 Parser::matchName(String **name, TokenKind kind)
80 assert(kind == TOK_NAME || kind == TOK_LABEL);
84 *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
91 if (!expect(TOK_NAME))
93 return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
97 Parser::redeclarationError(BoundName *other)
99 cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->pos().line, other->pos().col);
105 TokenKind kind = scanner_.peek();
109 Local<String> name(zone_, expectName());
115 case TOK_FLOAT_LITERAL:
118 double value = Scanner::ParseDouble(scanner_.literal());
119 return new (pool_) FloatLiteral(scanner_.begin(), value);
122 case TOK_INTEGER_LITERAL:
125 int value = atoi(scanner_.literal());
126 return new (pool_) IntegerLiteral(scanner_.begin(), value);
129 case TOK_STRING_LITERAL:
132 Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
135 memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
136 return new (pool_) StringLiteral(scanner_.begin(), array);
141 if (kind != TOK_ERROR)
142 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
151 switch (scanner_.peek()) {
155 Expression *expr = expression();
158 if (!expect(TOK_RPAREN))
169 Parser::call(Expression *callee)
171 ExpressionList *arguments = new ExpressionList();
173 SourcePosition pos = scanner_.begin();
176 if (!match(TOK_RPAREN)) {
178 Expression *expr = expression();
182 arguments->push_back(expr);
184 if (!match(TOK_COMMA))
188 if (!expect(TOK_RPAREN))
192 return new (pool_) CallExpression(pos, callee, arguments);
196 Parser::index(Expression *left)
198 expect(TOK_LBRACKET);
200 SourcePosition pos = scanner_.begin();
201 Expression *expr = expression();
205 if (!expect(TOK_RBRACKET))
208 return new (pool_) IndexExpression(pos, left, expr);
214 Expression *expr = prefix();
219 switch (scanner_.peek()) {
241 TokenKind token = scanner_.peek();
243 SourcePosition pos = scanner_.begin();
249 Expression *expr = expression();
253 return new (pool_) IncDecExpression(pos, token, expr, false);
260 Expression *expr = primary();
262 token = scanner_.peek();
263 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
265 return new (pool_) IncDecExpression(pos, token, expr, true);
272 Parser::multiplication()
274 Expression *left = unary();
276 if (!match(TOK_SLASH) && !match(TOK_STAR))
278 SourcePosition pos = scanner_.begin();
279 TokenKind kind = scanner_.last();
280 Expression *right = unary();
283 left = new (pool_) BinaryExpression(pos, kind, left, right);
291 Expression *left = multiplication();
293 if (!match(TOK_PLUS) && !match(TOK_MINUS))
295 SourcePosition pos = scanner_.begin();
296 TokenKind kind = scanner_.last();
297 Expression *right = multiplication();
300 left = new (pool_) BinaryExpression(pos, kind, left, right);
308 Expression *left = addition();
310 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
312 SourcePosition pos = scanner_.begin();
313 TokenKind kind = scanner_.last();
314 Expression *right = addition();
317 left = new (pool_) BinaryExpression(pos, kind, left, right);
325 Expression *left = shift();
327 if (!match(TOK_BITAND))
329 SourcePosition pos = scanner_.begin();
330 Expression *right = shift();
333 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
341 Expression *left = bitand_();
343 if (!match(TOK_BITXOR))
345 SourcePosition pos = scanner_.begin();
346 Expression *right = shift();
349 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
357 Expression *left = bitxor();
359 if (!match(TOK_BITOR))
361 SourcePosition pos = scanner_.begin();
362 Expression *right = shift();
365 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
373 Expression *left = bitor_();
375 TokenKind kind = scanner_.peek();
376 if (kind < TOK_LT || kind > TOK_GE)
379 SourcePosition pos = scanner_.begin();
380 Expression *right = shift();
383 left = new (pool_) BinaryExpression(pos, kind, left, right);
391 Expression *left = relational();
393 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
395 TokenKind kind = scanner_.last();
396 SourcePosition pos = scanner_.begin();
397 Expression *right = relational();
400 left = new (pool_) BinaryExpression(pos, kind, left, right);
408 Expression *left = equals();
410 TokenKind token = scanner_.peek();
411 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
414 SourcePosition pos = scanner_.begin();
415 Expression *expr = equals();
419 left = new (pool_) Assignment(pos, token, left, expr);
433 SourcePosition pos = scanner_.begin();
436 if (!expect(TOK_LPAREN))
439 Expression *condition = expression();
443 if (!expect(TOK_RPAREN))
446 // Inside a loop, we force the creation of a scope object. Normally, we
447 // will cull scopes if they have no variables. However inside a loop,
448 // function calls that take references may compute a LIFO object, and to
449 // avoid temporarily leaking many such objects, we ensure that a scope
450 // is present so a LIFO slot can be allocated.
451 if (!enterScope(Scope::BLOCK))
455 if (scanner_.peek() == TOK_LBRACE)
456 body = block(scope_);
458 body = localStatement();
462 scope_ = scope_->enclosing();
463 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
469 SourcePosition pos = scanner_.begin();
472 // See the comment in ::while_() as to why we force a scope.
473 if (!enterScope(Scope::BLOCK))
477 if (scanner_.peek() == TOK_LBRACE)
478 body = block(scope_);
480 body = localStatement();
484 scope_ = scope_->enclosing();
486 if (!expect(TOK_WHILE))
489 if (!expect(TOK_LPAREN))
491 Expression *condition = expression();
494 if (!expect(TOK_RPAREN))
497 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
501 Parser::forStatement()
503 SourcePosition pos = scanner_.begin();
505 if (!expect(TOK_LPAREN))
508 Statement *decl = NULL;
509 if (!match(TOK_SEMICOLON)) {
510 if (scanner_.peek() == TOK_NEW) {
511 if (!enterScope(Scope::BLOCK))
513 if ((decl = variableDeclaration()) == NULL)
516 if ((decl = expressionStatement()) == NULL)
519 if (!expect(TOK_SEMICOLON))
523 Expression *condition = NULL;
524 if (!match(TOK_SEMICOLON)) {
525 if ((condition = expression()) == NULL)
527 if (!expect(TOK_SEMICOLON))
531 Statement *update = NULL;
532 if (!match(TOK_RPAREN)) {
533 if ((update = expressionStatement()) == NULL)
535 if (!expect(TOK_RPAREN))
539 // See the comment in ::while_() as to why we force a scope.
540 if (!enterScope(Scope::BLOCK))
544 if (scanner_.peek() == TOK_LBRACE)
545 body = block(scope_);
547 body = localStatement();
551 scope_ = scope_->enclosing();
553 Scope *declScope = NULL;
554 if (decl && decl->isVariableDeclaration()) {
555 declScope = scope_->unlinkIfEmpty();
556 scope_ = scope_->enclosing();
558 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
561 VariableDeclaration *
562 Parser::variableDeclaration()
564 if (!expect(TOK_NEW))
567 Local<String> tag(zone_);
568 if (matchName(tag.ref(), TOK_LABEL) && !tag)
571 Local<String> name(zone_, expectName());
575 if (BoundName *other = scope_->localLookup(name)) {
576 redeclarationError(other);
580 Variable *var = scope_->declareVariable(name, scanner_.begin());
584 ExpressionList *postDimensions = NULL;
585 if (scanner_.peek() == TOK_LBRACKET) {
586 postDimensions = new ExpressionList();
587 while (match(TOK_LBRACKET)) {
588 Expression *dim = expression();
592 if (!expect(TOK_RBRACKET))
595 postDimensions->push_back(dim);
599 Expression *expr = NULL;
600 if (match(TOK_ASSIGN)) {
601 if ((expr = expression()) == NULL)
605 return new (pool_) VariableDeclaration(var->pos(), var, tag, postDimensions, expr);
609 Parser::returnStatement()
611 SourcePosition pos = scanner_.begin();
612 if (!expect(TOK_RETURN))
615 Expression *expr = expression();
619 return new (pool_) ReturnStatement(pos, expr);
623 Parser::expressionStatement()
625 Expression *left = assignment();
629 return new (pool_) ExpressionStatement(left);
633 Parser::block(Scope *scope)
635 if (!expect(TOK_LBRACE))
638 SourcePosition pos = scanner_.begin();
639 if (!scope && !enterScope(Scope::BLOCK))
642 StatementList *statements = new (pool_) StatementList();
643 while (!match(TOK_RBRACE)) {
644 Statement *statement = localStatement();
645 if (statement == NULL)
647 statements->append(pool_, statement);
651 scope = scope_->unlinkIfEmpty();
652 scope_ = scope_->enclosing();
654 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
663 SourcePosition pos = scanner_.begin();
664 if (!expect(TOK_LPAREN))
667 Expression *cond = expression();
671 if (!expect(TOK_RPAREN))
674 Statement *ifTrue = localStatement();
678 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
680 IfStatement *last = outer;
681 while (match(TOK_ELSE)) {
682 if (!match(TOK_IF)) {
683 Statement *ifFalse = localStatement();
687 last->setIfFalse(ifFalse);
694 SourcePosition pos = scanner_.begin();
695 if (!expect(TOK_LPAREN))
698 Expression *otherCond = expression();
702 if (!expect(TOK_RPAREN))
705 Statement *otherIfTrue = localStatement();
709 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
710 last->setIfFalse(inner);
718 Parser::localStatement()
720 Statement *statement = NULL;
722 // Statements which must be followed by a semicolon will break out of the
723 // switch. If they may end in BlockStatements, they'll immediately return.
725 switch (scanner_.peek()) {
727 if ((statement = variableDeclaration()) == NULL)
732 return forStatement();
739 statement = new (pool_) BreakStatement(scanner_.begin());
744 statement = new (pool_) ContinueStatement(scanner_.begin());
748 if ((statement = do_()) == NULL)
753 if ((statement = returnStatement()) == NULL)
758 if ((statement = enum_()) == NULL)
773 if ((statement = expressionStatement()) == NULL)
777 if (!expect(TOK_SEMICOLON))
788 SourcePosition pos = scanner_.begin();
790 Local<String> name(zone_);
791 if (matchName(name.ref())) {
795 if (BoundName *other = scope_->localLookup(name)) {
796 redeclarationError(other);
800 if (!scope_->declareEnum(name, scanner_.begin()))
804 EnumStatement::EntryList *entries = new EnumStatement::EntryList();
806 if (!expect(TOK_LBRACE))
810 if (scanner_.peek() == TOK_RBRACE)
813 Local<String> name(zone_, expectName());
817 if (BoundName *other = scope_->localLookup(name)) {
818 redeclarationError(other);
822 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
826 Expression *expr = NULL;
827 if (match(TOK_ASSIGN)) {
828 if ((expr = expression()) == NULL)
832 entries->push_back(EnumStatement::Entry(constant, expr));
833 } while (match(TOK_COMMA));
834 if (!expect(TOK_RBRACE))
837 return new (pool_) EnumStatement(pos, name, entries);
843 Local<String> name(zone_, expectName());
847 SourcePosition pos = scanner_.begin();
849 // The function name goes into the outer (global) scope.
850 assert(!scope_->enclosing());
852 if (BoundName *other = scope_->localLookup(name)) {
853 redeclarationError(other);
856 NamedFunction *fun = scope_->declareFunction(name, scanner_.begin());
860 Scope *scope = enterScope(Scope::FUNCTION);
864 ParameterList *parameters = new ParameterList();
866 if (!expect(TOK_LPAREN))
868 if (!match(TOK_RPAREN)) {
870 bool ref = match(TOK_AMPERSAND);
872 Local<String> name(zone_, expectName());
876 if (BoundName *other = scope_->localLookup(name)) {
877 redeclarationError(other);
880 Variable *arg = scope_->declareArgument(name, scanner_.begin());
884 Local<String> tag(zone_);
885 Parameter *parameter = new (pool_) Parameter(arg, tag, ref);
886 parameters->push_back(parameter);
888 if (!match(TOK_COMMA))
891 if (!expect(TOK_RPAREN))
895 Statement *body = block();
899 scope_ = scope_->enclosing();
900 return new (pool_) FunctionStatement(pos, scope, fun, body, parameters);
906 StatementList *statements = new (pool_) StatementList();
908 if (!enterScope(Scope::GLOBAL))
912 Statement *statement = NULL;
914 switch (scanner_.peek()) {
922 if ((statement = function()) == NULL)
927 if ((statement = enum_()) == NULL)
929 // :TODO: require semicolon
933 fprintf(stderr, "expected function or global variable\n");
940 statements->append(pool_, statement);
943 return new (pool_) ParseTree(scope_, statements, unbound_);
946 class AstPrinter : public AstVisitor
953 for (size_t i = 0; i < level_; i++)
970 void visit(NameProxy *name) {
972 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
973 (name->binding() ? "" : " unbound"));
975 void visit(CallExpression *node) {
977 fprintf(fp_, "[ CallExpression\n");
979 node->callee()->accept(this);
980 for (size_t i = 0; i < node->arguments()->size(); i++)
981 node->arguments()->at(i)->accept(this);
984 void visit(FunctionStatement *node) {
986 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
988 node->body()->accept(this);
991 void visit(ExpressionStatement *node) {
993 fprintf(fp_, "[ ExpressionStatement\n");
995 node->expression()->accept(this);
998 void visit(Assignment *node) {
1000 fprintf(fp_, "[ Assignment\n");
1002 node->lvalue()->accept(this);
1003 node->expression()->accept(this);
1006 void visit(BinaryExpression *node) {
1008 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1010 node->left()->accept(this);
1011 node->right()->accept(this);
1014 void visit(ReturnStatement *node) {
1016 fprintf(fp_, "[ ReturnStatement\n");
1018 node->expression()->accept(this);
1021 void visit(ForStatement *node) {
1023 fprintf(fp_, "[ ForStatement\n");
1025 if (node->initialization())
1026 node->initialization()->accept(this);
1027 if (node->condition())
1028 node->condition()->accept(this);
1030 node->update()->accept(this);
1031 node->body()->accept(this);
1034 void visit(BlockStatement *node) {
1036 fprintf(fp_, "[ BlockStatement\n");
1038 for (size_t i = 0; i < node->statements()->length(); i++)
1039 node->statements()->at(i)->accept(this);
1042 void visit(VariableDeclaration *node) {
1044 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1046 if (node->initialization())
1047 node->initialization()->accept(this);
1050 void visit(IntegerLiteral *node) {
1052 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1054 void visit(FloatLiteral *node) {
1056 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1058 void visit(IfStatement *node) {
1060 fprintf(fp_, "[ IfStatement\n");
1062 node->ifTrue()->accept(this);
1063 if (node->ifFalse())
1064 node->ifFalse()->accept(this);
1067 void visit(IndexExpression *node) {
1069 fprintf(fp_, "[ IndexExpression\n");
1071 node->left()->accept(this);
1072 node->right()->accept(this);
1075 void visit(EnumStatement *node) {
1077 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1079 for (size_t i = 0; i < node->entries()->size(); i++) {
1081 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1082 if (node->entries()->at(i).expr) {
1084 node->entries()->at(i).expr->accept(this);
1090 void visit(WhileStatement *node) {
1092 fprintf(fp_, "[ WhileStatement (%s)\n",
1093 (node->token() == TOK_DO) ? "do" : "while");
1095 if (node->token() == TOK_DO) {
1096 node->condition()->accept(this);
1097 node->body()->accept(this);
1099 node->condition()->accept(this);
1100 node->body()->accept(this);
1104 void visit(BreakStatement *node) {
1106 fprintf(fp_, "[ BreakStatement\n");
1108 void visit(ContinueStatement *node) {
1110 fprintf(fp_, "[ ContinueStatement\n");
1112 void visit(StringLiteral *node) {
1114 fprintf(fp_, "[ StringLiteral\n");
1116 void visit(IncDecExpression *node) {
1118 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1120 node->expression()->accept(this);
1126 ParseTree::dump(FILE *fp)
1128 AstPrinter printer(fp);
1130 for (size_t i = 0; i < statements_->length(); i++)
1131 statements_->at(i)->accept(&printer);