Renamed jitcraft/ to src/, fixed some /Wp64 warnings.
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();
260 return new (pool_) IncDecExpression(pos, token, expr, false);
268 Expression *expr = expression();
271 return new (pool_) UnaryExpression(pos, token, expr);
278 Expression *expr = primary();
280 token = scanner_.peek();
281 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
283 return new (pool_) IncDecExpression(pos, token, expr, true);
290 Parser::multiplication()
292 Expression *left = unary();
294 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
296 SourcePosition pos = scanner_.begin();
297 TokenKind kind = scanner_.last();
298 Expression *right = unary();
301 left = new (pool_) BinaryExpression(pos, kind, left, right);
309 Expression *left = multiplication();
311 if (!match(TOK_PLUS) && !match(TOK_MINUS))
313 SourcePosition pos = scanner_.begin();
314 TokenKind kind = scanner_.last();
315 Expression *right = multiplication();
318 left = new (pool_) BinaryExpression(pos, kind, left, right);
326 Expression *left = addition();
328 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
330 SourcePosition pos = scanner_.begin();
331 TokenKind kind = scanner_.last();
332 Expression *right = addition();
335 left = new (pool_) BinaryExpression(pos, kind, left, right);
343 Expression *left = shift();
345 if (!match(TOK_BITAND))
347 SourcePosition pos = scanner_.begin();
348 Expression *right = shift();
351 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
359 Expression *left = bitand_();
361 if (!match(TOK_BITXOR))
363 SourcePosition pos = scanner_.begin();
364 Expression *right = shift();
367 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
375 Expression *left = bitxor();
377 if (!match(TOK_BITOR))
379 SourcePosition pos = scanner_.begin();
380 Expression *right = bitxor();
383 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
391 Expression *left = bitor_();
393 TokenKind kind = scanner_.peek();
394 if (kind < TOK_LT || kind > TOK_GE)
397 SourcePosition pos = scanner_.begin();
398 Expression *right = shift();
401 left = new (pool_) BinaryExpression(pos, kind, left, right);
409 Expression *left = relational();
411 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
413 TokenKind kind = scanner_.last();
414 SourcePosition pos = scanner_.begin();
415 Expression *right = relational();
418 left = new (pool_) BinaryExpression(pos, kind, left, right);
426 Expression *left = equals();
430 SourcePosition pos = scanner_.begin();
431 Expression *right = equals();
434 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
442 Expression *left = and_();
446 SourcePosition pos = scanner_.begin();
447 Expression *right = and_();
450 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
458 Expression *cond = or_();
462 if (!match(TOK_QMARK))
465 SourcePosition pos = scanner_.begin();
466 Expression *left = expression();
470 if (!expect(TOK_COLON))
473 Expression *right = expression();
477 return new (pool_) TernaryExpression(pos, cond, left, right);
483 Expression *left = ternary();
485 TokenKind token = scanner_.peek();
486 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
489 SourcePosition pos = scanner_.begin();
490 Expression *expr = ternary();
494 left = new (pool_) Assignment(pos, token, left, expr);
508 SourcePosition pos = scanner_.begin();
511 if (!expect(TOK_LPAREN))
514 Expression *condition = expression();
518 if (!expect(TOK_RPAREN))
521 // Inside a loop, we force the creation of a scope object. Normally, we
522 // will cull scopes if they have no variables. However inside a loop,
523 // function calls that take references may compute a LIFO object, and to
524 // avoid temporarily leaking many such objects, we ensure that a scope
525 // is present so a LIFO slot can be allocated.
526 if (!enterScope(Scope::BLOCK))
530 if (scanner_.peek() == TOK_LBRACE)
531 body = block(scope_);
533 body = localStatement();
537 scope_ = scope_->enclosing();
538 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
544 SourcePosition pos = scanner_.begin();
547 // See the comment in ::while_() as to why we force a scope.
548 if (!enterScope(Scope::BLOCK))
552 if (scanner_.peek() == TOK_LBRACE)
553 body = block(scope_);
555 body = localStatement();
559 scope_ = scope_->enclosing();
561 if (!expect(TOK_WHILE))
564 if (!expect(TOK_LPAREN))
566 Expression *condition = expression();
569 if (!expect(TOK_RPAREN))
572 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
576 Parser::forStatement()
578 SourcePosition pos = scanner_.begin();
580 if (!expect(TOK_LPAREN))
583 Statement *decl = NULL;
584 if (!match(TOK_SEMICOLON)) {
585 if (scanner_.peek() == TOK_NEW) {
586 if (!enterScope(Scope::BLOCK))
588 if ((decl = variableDeclaration()) == NULL)
591 if ((decl = expressionStatement()) == NULL)
594 if (!expect(TOK_SEMICOLON))
598 Expression *condition = NULL;
599 if (!match(TOK_SEMICOLON)) {
600 if ((condition = expression()) == NULL)
602 if (!expect(TOK_SEMICOLON))
606 Statement *update = NULL;
607 if (!match(TOK_RPAREN)) {
608 if ((update = expressionStatement()) == NULL)
610 if (!expect(TOK_RPAREN))
614 // See the comment in ::while_() as to why we force a scope.
615 if (!enterScope(Scope::BLOCK))
619 if (scanner_.peek() == TOK_LBRACE)
620 body = block(scope_);
622 body = localStatement();
626 scope_ = scope_->enclosing();
628 Scope *declScope = NULL;
629 if (decl && decl->isVariableDeclaration()) {
630 declScope = scope_->unlinkIfEmpty();
631 scope_ = scope_->enclosing();
633 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
636 VariableDeclaration *
637 Parser::variableDeclaration()
639 if (!expect(TOK_NEW))
642 Local<String> tag(zone_);
643 if (matchName(tag.ref(), TOK_LABEL) && !tag)
646 Local<String> name(zone_, expectName());
650 if (BoundName *other = scope_->localLookup(name)) {
651 redeclarationError(other);
655 Variable *var = scope_->declareVariable(name, scanner_.begin());
659 ExpressionList *postDimensions = NULL;
660 if (scanner_.peek() == TOK_LBRACKET) {
661 postDimensions = new (pool_) ExpressionList();
662 while (match(TOK_LBRACKET)) {
663 Expression *dim = expression();
667 if (!expect(TOK_RBRACKET))
670 if (!postDimensions->append(dim))
675 Expression *expr = NULL;
676 if (match(TOK_ASSIGN)) {
677 if ((expr = expression()) == NULL)
681 return new (pool_) VariableDeclaration(var->pos(), var, tag, postDimensions, expr);
685 Parser::returnStatement()
687 SourcePosition pos = scanner_.begin();
688 if (!expect(TOK_RETURN))
691 Expression *expr = NULL;
692 if (scanner_.peek() != TOK_SEMICOLON) {
693 if ((expr = expression()) == NULL)
696 // We only care about non-void returns when determining whether a
697 // tagless function is non-void.
698 encounteredReturn_ = true;
701 return new (pool_) ReturnStatement(pos, expr);
705 Parser::expressionStatement()
707 Expression *left = assignment();
711 return new (pool_) ExpressionStatement(left);
715 Parser::block(Scope *scope)
717 if (!expect(TOK_LBRACE))
720 SourcePosition pos = scanner_.begin();
721 if (!scope && !enterScope(Scope::BLOCK))
724 StatementList *statements = new (pool_) StatementList();
725 while (!match(TOK_RBRACE)) {
726 Statement *statement = localStatement();
727 if (statement == NULL)
729 if (!statements->append(statement))
734 scope = scope_->unlinkIfEmpty();
735 scope_ = scope_->enclosing();
737 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
746 SourcePosition pos = scanner_.begin();
747 if (!expect(TOK_LPAREN))
750 Expression *cond = expression();
754 if (!expect(TOK_RPAREN))
757 Statement *ifTrue = localStatement();
761 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
763 IfStatement *last = outer;
764 while (match(TOK_ELSE)) {
765 if (!match(TOK_IF)) {
766 Statement *ifFalse = localStatement();
770 last->setIfFalse(ifFalse);
774 SourcePosition pos = scanner_.begin();
775 if (!expect(TOK_LPAREN))
778 Expression *otherCond = expression();
782 if (!expect(TOK_RPAREN))
785 Statement *otherIfTrue = localStatement();
789 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
790 last->setIfFalse(inner);
798 Parser::localStatement()
800 Statement *statement = NULL;
802 // Statements which must be followed by a semicolon will break out of the
803 // switch. If they may end in BlockStatements, they'll immediately return.
805 switch (scanner_.peek()) {
807 if ((statement = variableDeclaration()) == NULL)
812 return forStatement();
819 statement = new (pool_) BreakStatement(scanner_.begin());
824 statement = new (pool_) ContinueStatement(scanner_.begin());
828 if ((statement = do_()) == NULL)
833 if ((statement = returnStatement()) == NULL)
838 if ((statement = enum_()) == NULL)
853 if ((statement = expressionStatement()) == NULL)
857 if (!expect(TOK_SEMICOLON))
868 SourcePosition pos = scanner_.begin();
870 Local<String> name(zone_);
871 if (matchName(name.ref())) {
875 if (BoundName *other = scope_->localLookup(name)) {
876 redeclarationError(other);
880 if (!scope_->declareEnum(name, scanner_.begin()))
884 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
886 if (!expect(TOK_LBRACE))
890 if (scanner_.peek() == TOK_RBRACE)
893 Local<String> name(zone_, expectName());
897 if (BoundName *other = scope_->localLookup(name)) {
898 redeclarationError(other);
902 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
906 Expression *expr = NULL;
907 if (match(TOK_ASSIGN)) {
908 if ((expr = expression()) == NULL)
912 if (!entries->append(EnumStatement::Entry(constant, expr)))
914 } while (match(TOK_COMMA));
915 if (!expect(TOK_RBRACE))
918 return new (pool_) EnumStatement(pos, name, entries);
922 Parser::function(TokenKind token)
924 Local<String> name(zone_, expectName());
928 SourcePosition pos = scanner_.begin();
930 // The function name goes into the outer (global) scope.
931 assert(!scope_->enclosing());
934 if (BoundName *other = scope_->localLookup(name)) {
935 // We allow a redeclaration if the new type is a public, and the old
936 // type was a forward. However, the forward must come first.
937 if (other->kind() != BoundName::FUNCTION) {
938 redeclarationError(other);
942 fun = other->toNamedFunction();
943 if (!fun->isForward() || token != TOK_PUBLIC) {
944 redeclarationError(other);
948 // We've got the same name, but the original is a forward, so let it
949 // slide and re-use the original declaration.
950 fun->setImplemented(scanner_.begin());
952 fun = scope_->declareFunction(name, scanner_.begin(), token);
957 Scope *scope = enterScope(Scope::FUNCTION);
961 ParameterList *parameters = new (pool_) ParameterList();
963 if (!expect(TOK_LPAREN))
965 if (!match(TOK_RPAREN)) {
967 bool isConst = match(TOK_CONST);
968 bool ref = match(TOK_AMPERSAND);
970 SourcePosition begin = scanner_.begin();
971 Local<String> tag(zone_);
972 if (matchName(tag.ref(), TOK_LABEL) && !tag)
975 if (match(TOK_ELLIPSES)) {
976 if (isConst || ref) {
977 cc_.reportError(begin, Message_InvalidVarArgs);
981 if (token != TOK_NATIVE) {
982 cc_.reportError(begin, Message_VarArgsOutsideNative);
986 fun->markNativeVariadic();
990 Local<String> name(zone_, expectName());
994 if (BoundName *other = scope_->localLookup(name)) {
995 redeclarationError(other);
998 Variable *arg = scope_->declareArgument(name, scanner_.begin());
1002 // Look for dimensions.
1003 ExpressionList *postDimensions = NULL;
1004 while (match(TOK_LBRACKET)) {
1005 if (!postDimensions)
1006 postDimensions = new (pool_) ExpressionList();
1008 Expression *dim = NULL;
1009 if (!match(TOK_RBRACKET)) {
1010 if ((dim = expression()) == NULL)
1012 if (!expect(TOK_RBRACKET))
1016 if (!postDimensions->append(dim))
1020 Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions);
1021 if (!parameters->append(parameter))
1024 if (!match(TOK_COMMA))
1027 if (!expect(TOK_RPAREN))
1031 encounteredReturn_ = false;
1033 Statement *body = NULL;
1034 if (token != TOK_FORWARD && token != TOK_NATIVE) {
1040 scope_ = scope_->enclosing();
1041 return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, encounteredReturn_);
1047 StatementList *statements = new (pool_) StatementList();
1049 if (!enterScope(Scope::GLOBAL))
1053 Statement *statement = NULL;
1055 switch (scanner_.peek()) {
1063 if ((statement = function(TOK_NAME)) == NULL)
1071 TokenKind kind = scanner_.scan();
1072 if ((statement = function(kind)) == NULL)
1074 if ((kind == TOK_FORWARD || kind == TOK_NATIVE) && !matchSemicolon())
1081 if ((statement = variableDeclaration()) == NULL)
1083 if (!matchSemicolon())
1089 if ((statement = enum_()) == NULL)
1091 if (!matchSemicolon())
1096 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1103 if (!statements->append(statement))
1107 return new (pool_) ParseTree(scope_, statements, unbound_);
1110 class AstPrinter : public AstVisitor
1117 for (size_t i = 0; i < level_; i++)
1128 AstPrinter(FILE *fp)
1134 void visit(NameProxy *name) {
1136 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1137 (name->binding() ? "" : " unbound"));
1139 void visit(CallExpression *node) {
1141 fprintf(fp_, "[ CallExpression\n");
1143 node->callee()->accept(this);
1144 for (size_t i = 0; i < node->arguments()->length(); i++)
1145 node->arguments()->at(i)->accept(this);
1148 void visit(FunctionStatement *node) {
1150 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1153 node->body()->accept(this);
1156 void visit(ExpressionStatement *node) {
1158 fprintf(fp_, "[ ExpressionStatement\n");
1160 node->expression()->accept(this);
1163 void visit(Assignment *node) {
1165 fprintf(fp_, "[ Assignment\n");
1167 node->lvalue()->accept(this);
1168 node->expression()->accept(this);
1171 void visit(TernaryExpression *node) {
1173 fprintf(fp_, "[ TernaryExpression\n");
1175 node->condition()->accept(this);
1176 node->left()->accept(this);
1177 node->right()->accept(this);
1180 void visit(BinaryExpression *node) {
1182 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1184 node->left()->accept(this);
1185 node->right()->accept(this);
1188 void visit(UnaryExpression *node) {
1190 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1192 node->expression()->accept(this);
1195 void visit(ReturnStatement *node) {
1197 fprintf(fp_, "[ ReturnStatement\n");
1199 if (node->expression())
1200 node->expression()->accept(this);
1203 void visit(ForStatement *node) {
1205 fprintf(fp_, "[ ForStatement\n");
1207 if (node->initialization())
1208 node->initialization()->accept(this);
1209 if (node->condition())
1210 node->condition()->accept(this);
1212 node->update()->accept(this);
1213 node->body()->accept(this);
1216 void visit(BlockStatement *node) {
1218 fprintf(fp_, "[ BlockStatement\n");
1220 for (size_t i = 0; i < node->statements()->length(); i++)
1221 node->statements()->at(i)->accept(this);
1224 void visit(VariableDeclaration *node) {
1226 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1228 if (node->initialization())
1229 node->initialization()->accept(this);
1232 void visit(IntegerLiteral *node) {
1234 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1236 void visit(FloatLiteral *node) {
1238 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1240 void visit(IfStatement *node) {
1242 fprintf(fp_, "[ IfStatement\n");
1244 node->ifTrue()->accept(this);
1245 if (node->ifFalse())
1246 node->ifFalse()->accept(this);
1249 void visit(IndexExpression *node) {
1251 fprintf(fp_, "[ IndexExpression\n");
1253 node->left()->accept(this);
1254 node->right()->accept(this);
1257 void visit(EnumStatement *node) {
1259 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1261 for (size_t i = 0; i < node->entries()->length(); i++) {
1263 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1264 if (node->entries()->at(i).expr) {
1266 node->entries()->at(i).expr->accept(this);
1272 void visit(WhileStatement *node) {
1274 fprintf(fp_, "[ WhileStatement (%s)\n",
1275 (node->token() == TOK_DO) ? "do" : "while");
1277 if (node->token() == TOK_DO) {
1278 node->condition()->accept(this);
1279 node->body()->accept(this);
1281 node->condition()->accept(this);
1282 node->body()->accept(this);
1286 void visit(BreakStatement *node) {
1288 fprintf(fp_, "[ BreakStatement\n");
1290 void visit(ContinueStatement *node) {
1292 fprintf(fp_, "[ ContinueStatement\n");
1294 void visit(StringLiteral *node) {
1296 fprintf(fp_, "[ StringLiteral\n");
1298 void visit(IncDecExpression *node) {
1300 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1302 node->expression()->accept(this);
1308 ParseTree::dump(FILE *fp)
1310 AstPrinter printer(fp);
1312 for (size_t i = 0; i < statements_->length(); i++)
1313 statements_->at(i)->accept(&printer);