Added support for && and ||.
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 (pool_) PoolList<NameProxy *>();
40 Parser::match(TokenKind kind)
42 if (scanner_.peek() != kind)
49 Parser::matchSemicolon()
51 return expect(TOK_SEMICOLON);
55 Parser::expect(TokenKind kind)
57 TokenKind got = scanner_.scan();
60 cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
65 Parser::enterScope(Scope::Kind kind)
67 scope_ = new (pool_) Scope(pool_, kind, scope_);
68 if (!scope_->initialize())
74 Parser::bind(Handle<String> name)
76 BoundName *bound = scope_->lookup(name);
77 NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
78 if (!bound && !unbound_->append(proxy))
84 Parser::matchName(String **name, TokenKind kind)
86 assert(kind == TOK_NAME || kind == TOK_LABEL);
90 *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
97 if (!expect(TOK_NAME))
99 return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
103 Parser::redeclarationError(BoundName *other)
105 cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->name()->chars(),
106 other->pos().line, other->pos().col);
112 TokenKind kind = scanner_.peek();
116 Local<String> name(zone_, expectName());
122 case TOK_FLOAT_LITERAL:
125 double value = Scanner::ParseDouble(scanner_.literal());
126 return new (pool_) FloatLiteral(scanner_.begin(), value);
129 case TOK_INTEGER_LITERAL:
132 int value = atoi(scanner_.literal());
133 return new (pool_) IntegerLiteral(scanner_.begin(), value);
136 case TOK_STRING_LITERAL:
139 Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
142 memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
143 return new (pool_) StringLiteral(scanner_.begin(), array);
148 if (kind != TOK_ERROR)
149 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
158 switch (scanner_.peek()) {
162 Expression *expr = expression();
165 if (!expect(TOK_RPAREN))
176 Parser::call(Expression *callee)
178 ExpressionList *arguments = new (pool_) ExpressionList();
180 SourcePosition pos = scanner_.begin();
183 if (!match(TOK_RPAREN)) {
185 Expression *expr = expression();
189 if (!arguments->append(expr))
192 if (!match(TOK_COMMA))
196 if (!expect(TOK_RPAREN))
200 return new (pool_) CallExpression(pos, callee, arguments);
204 Parser::index(Expression *left)
206 expect(TOK_LBRACKET);
208 SourcePosition pos = scanner_.begin();
209 Expression *expr = expression();
213 if (!expect(TOK_RBRACKET))
216 return new (pool_) IndexExpression(pos, left, expr);
222 Expression *expr = prefix();
227 switch (scanner_.peek()) {
249 TokenKind token = scanner_.peek();
251 SourcePosition pos = scanner_.begin();
257 Expression *expr = expression();
261 return new (pool_) IncDecExpression(pos, token, expr, false);
268 Expression *expr = primary();
270 token = scanner_.peek();
271 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
273 return new (pool_) IncDecExpression(pos, token, expr, true);
280 Parser::multiplication()
282 Expression *left = unary();
284 if (!match(TOK_SLASH) && !match(TOK_STAR))
286 SourcePosition pos = scanner_.begin();
287 TokenKind kind = scanner_.last();
288 Expression *right = unary();
291 left = new (pool_) BinaryExpression(pos, kind, left, right);
299 Expression *left = multiplication();
301 if (!match(TOK_PLUS) && !match(TOK_MINUS))
303 SourcePosition pos = scanner_.begin();
304 TokenKind kind = scanner_.last();
305 Expression *right = multiplication();
308 left = new (pool_) BinaryExpression(pos, kind, left, right);
316 Expression *left = addition();
318 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
320 SourcePosition pos = scanner_.begin();
321 TokenKind kind = scanner_.last();
322 Expression *right = addition();
325 left = new (pool_) BinaryExpression(pos, kind, left, right);
333 Expression *left = shift();
335 if (!match(TOK_BITAND))
337 SourcePosition pos = scanner_.begin();
338 Expression *right = shift();
341 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
349 Expression *left = bitand_();
351 if (!match(TOK_BITXOR))
353 SourcePosition pos = scanner_.begin();
354 Expression *right = shift();
357 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
365 Expression *left = bitxor();
367 if (!match(TOK_BITOR))
369 SourcePosition pos = scanner_.begin();
370 Expression *right = bitxor();
373 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
381 Expression *left = bitor_();
383 TokenKind kind = scanner_.peek();
384 if (kind < TOK_LT || kind > TOK_GE)
387 SourcePosition pos = scanner_.begin();
388 Expression *right = shift();
391 left = new (pool_) BinaryExpression(pos, kind, left, right);
399 Expression *left = relational();
401 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
403 TokenKind kind = scanner_.last();
404 SourcePosition pos = scanner_.begin();
405 Expression *right = relational();
408 left = new (pool_) BinaryExpression(pos, kind, left, right);
416 Expression *left = equals();
420 SourcePosition pos = scanner_.begin();
421 Expression *right = equals();
424 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
432 Expression *left = and_();
436 SourcePosition pos = scanner_.begin();
437 Expression *right = and_();
440 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
448 Expression *left = or_();
450 TokenKind token = scanner_.peek();
451 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
454 SourcePosition pos = scanner_.begin();
455 Expression *expr = or_();
459 left = new (pool_) Assignment(pos, token, left, expr);
473 SourcePosition pos = scanner_.begin();
476 if (!expect(TOK_LPAREN))
479 Expression *condition = expression();
483 if (!expect(TOK_RPAREN))
486 // Inside a loop, we force the creation of a scope object. Normally, we
487 // will cull scopes if they have no variables. However inside a loop,
488 // function calls that take references may compute a LIFO object, and to
489 // avoid temporarily leaking many such objects, we ensure that a scope
490 // is present so a LIFO slot can be allocated.
491 if (!enterScope(Scope::BLOCK))
495 if (scanner_.peek() == TOK_LBRACE)
496 body = block(scope_);
498 body = localStatement();
502 scope_ = scope_->enclosing();
503 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
509 SourcePosition pos = scanner_.begin();
512 // See the comment in ::while_() as to why we force a scope.
513 if (!enterScope(Scope::BLOCK))
517 if (scanner_.peek() == TOK_LBRACE)
518 body = block(scope_);
520 body = localStatement();
524 scope_ = scope_->enclosing();
526 if (!expect(TOK_WHILE))
529 if (!expect(TOK_LPAREN))
531 Expression *condition = expression();
534 if (!expect(TOK_RPAREN))
537 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
541 Parser::forStatement()
543 SourcePosition pos = scanner_.begin();
545 if (!expect(TOK_LPAREN))
548 Statement *decl = NULL;
549 if (!match(TOK_SEMICOLON)) {
550 if (scanner_.peek() == TOK_NEW) {
551 if (!enterScope(Scope::BLOCK))
553 if ((decl = variableDeclaration()) == NULL)
556 if ((decl = expressionStatement()) == NULL)
559 if (!expect(TOK_SEMICOLON))
563 Expression *condition = NULL;
564 if (!match(TOK_SEMICOLON)) {
565 if ((condition = expression()) == NULL)
567 if (!expect(TOK_SEMICOLON))
571 Statement *update = NULL;
572 if (!match(TOK_RPAREN)) {
573 if ((update = expressionStatement()) == NULL)
575 if (!expect(TOK_RPAREN))
579 // See the comment in ::while_() as to why we force a scope.
580 if (!enterScope(Scope::BLOCK))
584 if (scanner_.peek() == TOK_LBRACE)
585 body = block(scope_);
587 body = localStatement();
591 scope_ = scope_->enclosing();
593 Scope *declScope = NULL;
594 if (decl && decl->isVariableDeclaration()) {
595 declScope = scope_->unlinkIfEmpty();
596 scope_ = scope_->enclosing();
598 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
601 VariableDeclaration *
602 Parser::variableDeclaration()
604 if (!expect(TOK_NEW))
607 Local<String> tag(zone_);
608 if (matchName(tag.ref(), TOK_LABEL) && !tag)
611 Local<String> name(zone_, expectName());
615 if (BoundName *other = scope_->localLookup(name)) {
616 redeclarationError(other);
620 Variable *var = scope_->declareVariable(name, scanner_.begin());
624 ExpressionList *postDimensions = NULL;
625 if (scanner_.peek() == TOK_LBRACKET) {
626 postDimensions = new (pool_) ExpressionList();
627 while (match(TOK_LBRACKET)) {
628 Expression *dim = expression();
632 if (!expect(TOK_RBRACKET))
635 if (!postDimensions->append(dim))
640 Expression *expr = NULL;
641 if (match(TOK_ASSIGN)) {
642 if ((expr = expression()) == NULL)
646 return new (pool_) VariableDeclaration(var->pos(), var, tag, postDimensions, expr);
650 Parser::returnStatement()
652 SourcePosition pos = scanner_.begin();
653 if (!expect(TOK_RETURN))
656 Expression *expr = NULL;
657 if (scanner_.peek() != TOK_SEMICOLON) {
658 if ((expr = expression()) == NULL)
661 // We only care about non-void returns when determining whether a
662 // tagless function is non-void.
663 encounteredReturn_ = true;
666 return new (pool_) ReturnStatement(pos, expr);
670 Parser::expressionStatement()
672 Expression *left = assignment();
676 return new (pool_) ExpressionStatement(left);
680 Parser::block(Scope *scope)
682 if (!expect(TOK_LBRACE))
685 SourcePosition pos = scanner_.begin();
686 if (!scope && !enterScope(Scope::BLOCK))
689 StatementList *statements = new (pool_) StatementList();
690 while (!match(TOK_RBRACE)) {
691 Statement *statement = localStatement();
692 if (statement == NULL)
694 if (!statements->append(statement))
699 scope = scope_->unlinkIfEmpty();
700 scope_ = scope_->enclosing();
702 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
711 SourcePosition pos = scanner_.begin();
712 if (!expect(TOK_LPAREN))
715 Expression *cond = expression();
719 if (!expect(TOK_RPAREN))
722 Statement *ifTrue = localStatement();
726 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
728 IfStatement *last = outer;
729 while (match(TOK_ELSE)) {
730 if (!match(TOK_IF)) {
731 Statement *ifFalse = localStatement();
735 last->setIfFalse(ifFalse);
739 SourcePosition pos = scanner_.begin();
740 if (!expect(TOK_LPAREN))
743 Expression *otherCond = expression();
747 if (!expect(TOK_RPAREN))
750 Statement *otherIfTrue = localStatement();
754 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
755 last->setIfFalse(inner);
763 Parser::localStatement()
765 Statement *statement = NULL;
767 // Statements which must be followed by a semicolon will break out of the
768 // switch. If they may end in BlockStatements, they'll immediately return.
770 switch (scanner_.peek()) {
772 if ((statement = variableDeclaration()) == NULL)
777 return forStatement();
784 statement = new (pool_) BreakStatement(scanner_.begin());
789 statement = new (pool_) ContinueStatement(scanner_.begin());
793 if ((statement = do_()) == NULL)
798 if ((statement = returnStatement()) == NULL)
803 if ((statement = enum_()) == NULL)
818 if ((statement = expressionStatement()) == NULL)
822 if (!expect(TOK_SEMICOLON))
833 SourcePosition pos = scanner_.begin();
835 Local<String> name(zone_);
836 if (matchName(name.ref())) {
840 if (BoundName *other = scope_->localLookup(name)) {
841 redeclarationError(other);
845 if (!scope_->declareEnum(name, scanner_.begin()))
849 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
851 if (!expect(TOK_LBRACE))
855 if (scanner_.peek() == TOK_RBRACE)
858 Local<String> name(zone_, expectName());
862 if (BoundName *other = scope_->localLookup(name)) {
863 redeclarationError(other);
867 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
871 Expression *expr = NULL;
872 if (match(TOK_ASSIGN)) {
873 if ((expr = expression()) == NULL)
877 if (!entries->append(EnumStatement::Entry(constant, expr)))
879 } while (match(TOK_COMMA));
880 if (!expect(TOK_RBRACE))
883 return new (pool_) EnumStatement(pos, name, entries);
887 Parser::function(TokenKind token)
889 Local<String> name(zone_, expectName());
893 SourcePosition pos = scanner_.begin();
895 // The function name goes into the outer (global) scope.
896 assert(!scope_->enclosing());
899 if (BoundName *other = scope_->localLookup(name)) {
900 // We allow a redeclaration if the new type is a public, and the old
901 // type was a forward. However, the forward must come first.
902 if (other->kind() != BoundName::FUNCTION) {
903 redeclarationError(other);
907 fun = other->toNamedFunction();
908 if (!fun->isForward() || token != TOK_PUBLIC) {
909 redeclarationError(other);
913 // We've got the same name, but the original is a forward, so let it
914 // slide and re-use the original declaration.
915 fun->setImplemented(scanner_.begin());
917 fun = scope_->declareFunction(name, scanner_.begin(), token);
922 Scope *scope = enterScope(Scope::FUNCTION);
926 ParameterList *parameters = new (pool_) ParameterList();
928 if (!expect(TOK_LPAREN))
930 if (!match(TOK_RPAREN)) {
932 bool isConst = match(TOK_CONST);
933 bool ref = match(TOK_AMPERSAND);
935 SourcePosition begin = scanner_.begin();
936 Local<String> tag(zone_);
937 if (matchName(tag.ref(), TOK_LABEL) && !tag)
940 if (match(TOK_ELLIPSES)) {
941 if (isConst || ref) {
942 cc_.reportError(begin, Message_InvalidVarArgs);
946 if (token != TOK_NATIVE) {
947 cc_.reportError(begin, Message_VarArgsOutsideNative);
951 fun->markNativeVariadic();
955 Local<String> name(zone_, expectName());
959 if (BoundName *other = scope_->localLookup(name)) {
960 redeclarationError(other);
963 Variable *arg = scope_->declareArgument(name, scanner_.begin());
967 // Look for dimensions.
968 ExpressionList *postDimensions = NULL;
969 while (match(TOK_LBRACKET)) {
971 postDimensions = new (pool_) ExpressionList();
973 Expression *dim = NULL;
974 if (!match(TOK_RBRACKET)) {
975 if ((dim = expression()) == NULL)
977 if (!expect(TOK_RBRACKET))
981 if (!postDimensions->append(dim))
985 Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions);
986 if (!parameters->append(parameter))
989 if (!match(TOK_COMMA))
992 if (!expect(TOK_RPAREN))
996 encounteredReturn_ = false;
998 Statement *body = NULL;
999 if (token != TOK_FORWARD && token != TOK_NATIVE) {
1005 scope_ = scope_->enclosing();
1006 return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, encounteredReturn_);
1012 StatementList *statements = new (pool_) StatementList();
1014 if (!enterScope(Scope::GLOBAL))
1018 Statement *statement = NULL;
1020 switch (scanner_.peek()) {
1028 if ((statement = function(TOK_NAME)) == NULL)
1036 TokenKind kind = scanner_.scan();
1037 if ((statement = function(kind)) == NULL)
1039 if ((kind == TOK_FORWARD || kind == TOK_NATIVE) && !matchSemicolon())
1046 // if ((statement = variableDeclaration()) == NULL)
1052 if ((statement = enum_()) == NULL)
1054 if (!matchSemicolon())
1059 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1066 if (!statements->append(statement))
1070 return new (pool_) ParseTree(scope_, statements, unbound_);
1073 class AstPrinter : public AstVisitor
1080 for (size_t i = 0; i < level_; i++)
1091 AstPrinter(FILE *fp)
1097 void visit(NameProxy *name) {
1099 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1100 (name->binding() ? "" : " unbound"));
1102 void visit(CallExpression *node) {
1104 fprintf(fp_, "[ CallExpression\n");
1106 node->callee()->accept(this);
1107 for (size_t i = 0; i < node->arguments()->length(); i++)
1108 node->arguments()->at(i)->accept(this);
1111 void visit(FunctionStatement *node) {
1113 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1116 node->body()->accept(this);
1119 void visit(ExpressionStatement *node) {
1121 fprintf(fp_, "[ ExpressionStatement\n");
1123 node->expression()->accept(this);
1126 void visit(Assignment *node) {
1128 fprintf(fp_, "[ Assignment\n");
1130 node->lvalue()->accept(this);
1131 node->expression()->accept(this);
1134 void visit(BinaryExpression *node) {
1136 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1138 node->left()->accept(this);
1139 node->right()->accept(this);
1142 void visit(ReturnStatement *node) {
1144 fprintf(fp_, "[ ReturnStatement\n");
1146 if (node->expression())
1147 node->expression()->accept(this);
1150 void visit(ForStatement *node) {
1152 fprintf(fp_, "[ ForStatement\n");
1154 if (node->initialization())
1155 node->initialization()->accept(this);
1156 if (node->condition())
1157 node->condition()->accept(this);
1159 node->update()->accept(this);
1160 node->body()->accept(this);
1163 void visit(BlockStatement *node) {
1165 fprintf(fp_, "[ BlockStatement\n");
1167 for (size_t i = 0; i < node->statements()->length(); i++)
1168 node->statements()->at(i)->accept(this);
1171 void visit(VariableDeclaration *node) {
1173 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1175 if (node->initialization())
1176 node->initialization()->accept(this);
1179 void visit(IntegerLiteral *node) {
1181 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1183 void visit(FloatLiteral *node) {
1185 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1187 void visit(IfStatement *node) {
1189 fprintf(fp_, "[ IfStatement\n");
1191 node->ifTrue()->accept(this);
1192 if (node->ifFalse())
1193 node->ifFalse()->accept(this);
1196 void visit(IndexExpression *node) {
1198 fprintf(fp_, "[ IndexExpression\n");
1200 node->left()->accept(this);
1201 node->right()->accept(this);
1204 void visit(EnumStatement *node) {
1206 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1208 for (size_t i = 0; i < node->entries()->length(); i++) {
1210 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1211 if (node->entries()->at(i).expr) {
1213 node->entries()->at(i).expr->accept(this);
1219 void visit(WhileStatement *node) {
1221 fprintf(fp_, "[ WhileStatement (%s)\n",
1222 (node->token() == TOK_DO) ? "do" : "while");
1224 if (node->token() == TOK_DO) {
1225 node->condition()->accept(this);
1226 node->body()->accept(this);
1228 node->condition()->accept(this);
1229 node->body()->accept(this);
1233 void visit(BreakStatement *node) {
1235 fprintf(fp_, "[ BreakStatement\n");
1237 void visit(ContinueStatement *node) {
1239 fprintf(fp_, "[ ContinueStatement\n");
1241 void visit(StringLiteral *node) {
1243 fprintf(fp_, "[ StringLiteral\n");
1245 void visit(IncDecExpression *node) {
1247 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1249 node->expression()->accept(this);
1255 ParseTree::dump(FILE *fp)
1257 AstPrinter printer(fp);
1259 for (size_t i = 0; i < statements_->length(); i++)
1260 statements_->at(i)->accept(&printer);