Initial support for booleans. Coercion does not work yet.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of SourcePawn.
7 * SourcePawn 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 * SourcePawn 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 * SourcePawn. If not, see http://www.gnu.org/licenses/.
22 #include "FixedArray.h"
29 Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
33 scanner_(cc, stream, length),
37 unbound_ = new (pool_) PoolList<NameProxy *>();
41 Parser::match(TokenKind kind)
43 if (scanner_.peek() != kind)
50 Parser::matchSemicolon()
52 return expect(TOK_SEMICOLON);
56 Parser::expect(TokenKind kind)
58 TokenKind got = scanner_.scan();
61 cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
66 Parser::enterScope(Scope::Kind kind)
68 scope_ = new (pool_) Scope(pool_, kind, scope_);
69 if (!scope_->initialize())
75 Parser::bind(Handle<String> name)
77 BoundName *bound = scope_->lookup(name);
78 NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
79 if (!bound && !unbound_->append(proxy))
85 Parser::matchName(String **name, TokenKind kind)
87 assert(kind == TOK_NAME || kind == TOK_LABEL);
91 *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
98 if (!expect(TOK_NAME))
100 return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
104 Parser::redeclarationError(BoundName *other)
106 cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->name()->chars(),
107 other->pos().line, other->pos().col);
113 TokenKind kind = scanner_.peek();
117 Local<String> name(zone_, expectName());
123 case TOK_FLOAT_LITERAL:
126 double value = Scanner::ParseDouble(scanner_.literal());
127 return new (pool_) FloatLiteral(scanner_.begin(), value);
130 case TOK_INTEGER_LITERAL:
133 int value = atoi(scanner_.literal());
134 return new (pool_) IntegerLiteral(scanner_.begin(), value);
140 return new (pool_) BooleanLiteral(scanner_.begin(), kind);
142 case TOK_STRING_LITERAL:
145 Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
148 memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
149 return new (pool_) StringLiteral(scanner_.begin(), array);
154 if (kind != TOK_ERROR)
155 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
164 switch (scanner_.peek()) {
168 Expression *expr = expression();
171 if (!expect(TOK_RPAREN))
182 Parser::call(Expression *callee)
184 ExpressionList *arguments = new (pool_) ExpressionList();
186 SourcePosition pos = scanner_.begin();
189 if (!match(TOK_RPAREN)) {
191 Expression *expr = expression();
195 if (!arguments->append(expr))
198 if (!match(TOK_COMMA))
202 if (!expect(TOK_RPAREN))
206 return new (pool_) CallExpression(pos, callee, arguments);
210 Parser::index(Expression *left)
212 expect(TOK_LBRACKET);
214 SourcePosition pos = scanner_.begin();
215 Expression *expr = expression();
219 if (!expect(TOK_RBRACKET))
222 return new (pool_) IndexExpression(pos, left, expr);
228 Expression *expr = prefix();
233 switch (scanner_.peek()) {
255 TokenKind token = scanner_.peek();
257 SourcePosition pos = scanner_.begin();
263 Expression *expr = unary();
266 return new (pool_) IncDecExpression(pos, token, expr, false);
274 Expression *expr = unary();
277 return new (pool_) UnaryExpression(pos, token, expr);
283 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
287 Expression *expr = unary();
291 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, tag);
298 Expression *expr = primary();
300 token = scanner_.peek();
301 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
303 return new (pool_) IncDecExpression(pos, token, expr, true);
310 Parser::multiplication()
312 Expression *left = unary();
314 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
316 SourcePosition pos = scanner_.begin();
317 TokenKind kind = scanner_.last();
318 Expression *right = unary();
321 left = new (pool_) BinaryExpression(pos, kind, left, right);
329 Expression *left = multiplication();
331 if (!match(TOK_PLUS) && !match(TOK_MINUS))
333 SourcePosition pos = scanner_.begin();
334 TokenKind kind = scanner_.last();
335 Expression *right = multiplication();
338 left = new (pool_) BinaryExpression(pos, kind, left, right);
346 Expression *left = addition();
348 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
350 SourcePosition pos = scanner_.begin();
351 TokenKind kind = scanner_.last();
352 Expression *right = addition();
355 left = new (pool_) BinaryExpression(pos, kind, left, right);
363 Expression *left = shift();
365 if (!match(TOK_BITAND))
367 SourcePosition pos = scanner_.begin();
368 Expression *right = shift();
371 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
379 Expression *left = bitand_();
381 if (!match(TOK_BITXOR))
383 SourcePosition pos = scanner_.begin();
384 Expression *right = shift();
387 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
395 Expression *left = bitxor();
397 if (!match(TOK_BITOR))
399 SourcePosition pos = scanner_.begin();
400 Expression *right = bitxor();
403 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
411 Expression *left = bitor_();
413 TokenKind kind = scanner_.peek();
414 if (kind < TOK_LT || kind > TOK_GE)
417 SourcePosition pos = scanner_.begin();
418 Expression *right = shift();
421 left = new (pool_) BinaryExpression(pos, kind, left, right);
429 Expression *left = relational();
431 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
433 TokenKind kind = scanner_.last();
434 SourcePosition pos = scanner_.begin();
435 Expression *right = relational();
438 left = new (pool_) BinaryExpression(pos, kind, left, right);
446 Expression *left = equals();
450 SourcePosition pos = scanner_.begin();
451 Expression *right = equals();
454 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
462 Expression *left = and_();
466 SourcePosition pos = scanner_.begin();
467 Expression *right = and_();
470 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
478 Expression *cond = or_();
482 if (!match(TOK_QMARK))
485 SourcePosition pos = scanner_.begin();
486 Expression *left = expression();
490 if (!expect(TOK_COLON))
493 Expression *right = expression();
497 return new (pool_) TernaryExpression(pos, cond, left, right);
503 Expression *left = ternary();
505 TokenKind token = scanner_.peek();
506 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
509 SourcePosition pos = scanner_.begin();
510 Expression *expr = ternary();
514 left = new (pool_) Assignment(pos, token, left, expr);
528 SourcePosition pos = scanner_.begin();
531 if (!expect(TOK_LPAREN))
534 Expression *condition = expression();
538 if (!expect(TOK_RPAREN))
541 // Inside a loop, we force the creation of a scope object. Normally, we
542 // will cull scopes if they have no variables. However inside a loop,
543 // function calls that take references may compute a LIFO object, and to
544 // avoid temporarily leaking many such objects, we ensure that a scope
545 // is present so a LIFO slot can be allocated.
546 if (!enterScope(Scope::BLOCK))
550 if (scanner_.peek() == TOK_LBRACE)
551 body = block(scope_);
553 body = localStatement();
557 scope_ = scope_->enclosing();
558 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
564 SourcePosition pos = scanner_.begin();
567 // See the comment in ::while_() as to why we force a scope.
568 if (!enterScope(Scope::BLOCK))
572 if (scanner_.peek() == TOK_LBRACE)
573 body = block(scope_);
575 body = localStatement();
579 scope_ = scope_->enclosing();
581 if (!expect(TOK_WHILE))
584 if (!expect(TOK_LPAREN))
586 Expression *condition = expression();
589 if (!expect(TOK_RPAREN))
592 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
596 Parser::forStatement()
598 SourcePosition pos = scanner_.begin();
600 if (!expect(TOK_LPAREN))
603 Statement *decl = NULL;
604 if (!match(TOK_SEMICOLON)) {
605 if (match(TOK_NEW)) {
606 if (!enterScope(Scope::BLOCK))
608 if ((decl = variableDeclaration(TOK_NEW)) == NULL)
611 if ((decl = expressionStatement()) == NULL)
614 if (!expect(TOK_SEMICOLON))
618 Expression *condition = NULL;
619 if (!match(TOK_SEMICOLON)) {
620 if ((condition = expression()) == NULL)
622 if (!expect(TOK_SEMICOLON))
626 Statement *update = NULL;
627 if (!match(TOK_RPAREN)) {
628 if ((update = expressionStatement()) == NULL)
630 if (!expect(TOK_RPAREN))
634 // See the comment in ::while_() as to why we force a scope.
635 if (!enterScope(Scope::BLOCK))
639 if (scanner_.peek() == TOK_LBRACE)
640 body = block(scope_);
642 body = localStatement();
646 scope_ = scope_->enclosing();
648 Scope *declScope = NULL;
649 if (decl && decl->isVariableDeclaration()) {
650 declScope = scope_->unlinkIfEmpty();
651 scope_ = scope_->enclosing();
653 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
656 VariableDeclaration *
657 Parser::variableDeclaration(TokenKind kind)
659 Local<String> tag(zone_);
660 if (matchName(tag.ref(), TOK_LABEL) && !tag)
663 Local<String> name(zone_, expectName());
667 if (BoundName *other = scope_->localLookup(name)) {
668 redeclarationError(other);
672 Variable *var = scope_->declareVariable(name, scanner_.begin());
676 ExpressionList *postDimensions = NULL;
677 if (scanner_.peek() == TOK_LBRACKET) {
678 postDimensions = new (pool_) ExpressionList();
679 while (match(TOK_LBRACKET)) {
680 Expression *dim = NULL;
681 if (!match(TOK_RBRACKET)) {
682 if ((dim = expression()) == NULL)
684 if (!expect(TOK_RBRACKET))
688 if (!postDimensions->append(dim))
693 Expression *expr = NULL;
694 if (match(TOK_ASSIGN)) {
695 if ((expr = expression()) == NULL)
699 return new (pool_) VariableDeclaration(var->pos(), kind, var, tag, postDimensions, expr);
703 Parser::returnStatement()
705 SourcePosition pos = scanner_.begin();
706 if (!expect(TOK_RETURN))
709 Expression *expr = NULL;
710 if (scanner_.peek() != TOK_SEMICOLON) {
711 if ((expr = expression()) == NULL)
714 // We only care about non-void returns when determining whether a
715 // tagless function is non-void.
716 encounteredReturn_ = true;
719 return new (pool_) ReturnStatement(pos, expr);
723 Parser::expressionStatement()
725 Expression *left = assignment();
729 return new (pool_) ExpressionStatement(left);
733 Parser::block(Scope *scope)
735 if (!expect(TOK_LBRACE))
738 SourcePosition pos = scanner_.begin();
739 if (!scope && !enterScope(Scope::BLOCK))
742 StatementList *statements = new (pool_) StatementList();
743 while (!match(TOK_RBRACE)) {
744 Statement *statement = localStatement();
745 if (statement == NULL)
747 if (!statements->append(statement))
752 scope = scope_->unlinkIfEmpty();
753 scope_ = scope_->enclosing();
755 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
764 SourcePosition pos = scanner_.begin();
765 if (!expect(TOK_LPAREN))
768 Expression *cond = expression();
772 if (!expect(TOK_RPAREN))
775 Statement *ifTrue = localStatement();
779 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
781 IfStatement *last = outer;
782 while (match(TOK_ELSE)) {
783 if (!match(TOK_IF)) {
784 Statement *ifFalse = localStatement();
788 last->setIfFalse(ifFalse);
792 SourcePosition pos = scanner_.begin();
793 if (!expect(TOK_LPAREN))
796 Expression *otherCond = expression();
800 if (!expect(TOK_RPAREN))
803 Statement *otherIfTrue = localStatement();
807 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
808 last->setIfFalse(inner);
816 Parser::localStatement()
818 Statement *statement = NULL;
820 // Statements which must be followed by a semicolon will break out of the
821 // switch. If they may end in BlockStatements, they'll immediately return.
823 TokenKind kind = scanner_.peek();
828 if ((statement = variableDeclaration(kind)) == NULL)
833 return forStatement();
840 statement = new (pool_) BreakStatement(scanner_.begin());
845 statement = new (pool_) ContinueStatement(scanner_.begin());
849 if ((statement = do_()) == NULL)
854 if ((statement = returnStatement()) == NULL)
859 if ((statement = enum_()) == NULL)
874 if ((statement = expressionStatement()) == NULL)
878 if (!expect(TOK_SEMICOLON))
889 SourcePosition pos = scanner_.begin();
891 Local<String> name(zone_);
892 if (matchName(name.ref())) {
896 if (BoundName *other = scope_->localLookup(name)) {
897 redeclarationError(other);
901 if (!scope_->declareEnum(name, scanner_.begin()))
905 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
907 if (!expect(TOK_LBRACE))
911 if (scanner_.peek() == TOK_RBRACE)
914 Local<String> name(zone_, expectName());
918 if (BoundName *other = scope_->localLookup(name)) {
919 redeclarationError(other);
923 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
927 Expression *expr = NULL;
928 if (match(TOK_ASSIGN)) {
929 if ((expr = expression()) == NULL)
933 if (!entries->append(EnumStatement::Entry(constant, expr)))
935 } while (match(TOK_COMMA));
936 if (!expect(TOK_RBRACE))
939 return new (pool_) EnumStatement(pos, name, entries);
943 Parser::function(TokenKind token)
945 Local<String> returnTag(zone_);
946 if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
949 Local<String> name(zone_, expectName());
953 SourcePosition pos = scanner_.begin();
955 // The function name goes into the outer (global) scope.
956 assert(!scope_->enclosing());
959 if (BoundName *other = scope_->localLookup(name)) {
960 // We allow a redeclaration if the new type is a public, and the old
961 // type was a forward. However, the forward must come first.
962 if (other->kind() != BoundName::FUNCTION) {
963 redeclarationError(other);
967 fun = other->toNamedFunction();
968 if (!fun->isForward() || token != TOK_PUBLIC) {
969 redeclarationError(other);
973 // We've got the same name, but the original is a forward, so let it
974 // slide and re-use the original declaration.
975 fun->setImplemented(scanner_.begin());
977 fun = scope_->declareFunction(name, scanner_.begin(), token);
985 Scope *scope = enterScope(Scope::FUNCTION);
989 ParameterList *parameters = new (pool_) ParameterList();
991 if (!expect(TOK_LPAREN))
994 if (!match(TOK_RPAREN)) {
996 bool isConst = match(TOK_CONST);
997 bool ref = match(TOK_AMPERSAND);
999 SourcePosition begin = scanner_.begin();
1000 Local<String> tag(zone_);
1001 if (matchName(tag.ref(), TOK_LABEL) && !tag)
1004 if (match(TOK_ELLIPSES)) {
1005 if (isConst || ref) {
1006 cc_.reportError(begin, Message_InvalidVarArgs);
1010 if (token != TOK_NATIVE) {
1011 cc_.reportError(begin, Message_VarArgsOutsideNative);
1015 fun->markNativeVariadic();
1019 Local<String> name(zone_, expectName());
1023 if (BoundName *other = scope_->localLookup(name)) {
1024 redeclarationError(other);
1027 Variable *arg = scope_->declareArgument(name, scanner_.begin());
1031 // Look for dimensions.
1032 ExpressionList *postDimensions = NULL;
1033 while (match(TOK_LBRACKET)) {
1034 if (!postDimensions)
1035 postDimensions = new (pool_) ExpressionList();
1037 Expression *dim = NULL;
1038 if (!match(TOK_RBRACKET)) {
1039 if ((dim = expression()) == NULL)
1041 if (!expect(TOK_RBRACKET))
1045 if (!postDimensions->append(dim))
1049 Expression *expr = NULL;
1050 if (match(TOK_ASSIGN)) {
1051 if ((expr = expression()) == NULL)
1055 Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions,
1057 if (!parameters->append(parameter))
1060 if (!match(TOK_COMMA))
1063 if (!expect(TOK_RPAREN))
1067 encounteredReturn_ = false;
1069 Statement *body = NULL;
1070 if (token != TOK_FORWARD && token != TOK_NATIVE) {
1076 scope_ = scope_->enclosing();
1077 return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, returnTag,
1078 encounteredReturn_);
1084 StatementList *statements = new (pool_) StatementList();
1086 if (!enterScope(Scope::GLOBAL))
1090 Statement *statement = NULL;
1092 TokenKind kind = scanner_.peek();
1101 if ((statement = function(TOK_NAME)) == NULL)
1111 if ((statement = function(kind)) == NULL)
1113 if ((kind == TOK_FORWARD || kind == TOK_NATIVE) && !matchSemicolon())
1122 if ((statement = variableDeclaration(kind)) == NULL)
1124 if (!matchSemicolon())
1130 if ((statement = enum_()) == NULL)
1132 if (!matchSemicolon())
1137 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1144 if (!statements->append(statement))
1148 return new (pool_) ParseTree(scope_, statements, unbound_);
1151 class AstPrinter : public AstVisitor
1158 for (size_t i = 0; i < level_; i++)
1169 AstPrinter(FILE *fp)
1175 void visit(NameProxy *name) {
1177 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1178 (name->binding() ? "" : " unbound"));
1180 void visit(CallExpression *node) {
1182 fprintf(fp_, "[ CallExpression\n");
1184 node->callee()->accept(this);
1185 for (size_t i = 0; i < node->arguments()->length(); i++)
1186 node->arguments()->at(i)->accept(this);
1189 void visit(FunctionStatement *node) {
1191 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1194 node->body()->accept(this);
1197 void visit(ExpressionStatement *node) {
1199 fprintf(fp_, "[ ExpressionStatement\n");
1201 node->expression()->accept(this);
1204 void visit(Assignment *node) {
1206 fprintf(fp_, "[ Assignment\n");
1208 node->lvalue()->accept(this);
1209 node->expression()->accept(this);
1212 void visit(TernaryExpression *node) {
1214 fprintf(fp_, "[ TernaryExpression\n");
1216 node->condition()->accept(this);
1217 node->left()->accept(this);
1218 node->right()->accept(this);
1221 void visit(BinaryExpression *node) {
1223 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1225 node->left()->accept(this);
1226 node->right()->accept(this);
1229 void visit(UnaryExpression *node) {
1231 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1233 node->expression()->accept(this);
1236 void visit(ReturnStatement *node) {
1238 fprintf(fp_, "[ ReturnStatement\n");
1240 if (node->expression())
1241 node->expression()->accept(this);
1244 void visit(ForStatement *node) {
1246 fprintf(fp_, "[ ForStatement\n");
1248 if (node->initialization())
1249 node->initialization()->accept(this);
1250 if (node->condition())
1251 node->condition()->accept(this);
1253 node->update()->accept(this);
1254 node->body()->accept(this);
1257 void visit(BlockStatement *node) {
1259 fprintf(fp_, "[ BlockStatement\n");
1261 for (size_t i = 0; i < node->statements()->length(); i++)
1262 node->statements()->at(i)->accept(this);
1265 void visit(VariableDeclaration *node) {
1267 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1269 if (node->initialization())
1270 node->initialization()->accept(this);
1273 void visit(IntegerLiteral *node) {
1275 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1277 void visit(BooleanLiteral *node) {
1279 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1280 (node->token() == TOK_TRUE) ? "true" : "false");
1282 void visit(FloatLiteral *node) {
1284 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1286 void visit(IfStatement *node) {
1288 fprintf(fp_, "[ IfStatement\n");
1290 node->ifTrue()->accept(this);
1291 if (node->ifFalse())
1292 node->ifFalse()->accept(this);
1295 void visit(IndexExpression *node) {
1297 fprintf(fp_, "[ IndexExpression\n");
1299 node->left()->accept(this);
1300 node->right()->accept(this);
1303 void visit(EnumStatement *node) {
1305 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1307 for (size_t i = 0; i < node->entries()->length(); i++) {
1309 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1310 if (node->entries()->at(i).expr) {
1312 node->entries()->at(i).expr->accept(this);
1318 void visit(WhileStatement *node) {
1320 fprintf(fp_, "[ WhileStatement (%s)\n",
1321 (node->token() == TOK_DO) ? "do" : "while");
1323 if (node->token() == TOK_DO) {
1324 node->condition()->accept(this);
1325 node->body()->accept(this);
1327 node->condition()->accept(this);
1328 node->body()->accept(this);
1332 void visit(BreakStatement *node) {
1334 fprintf(fp_, "[ BreakStatement\n");
1336 void visit(ContinueStatement *node) {
1338 fprintf(fp_, "[ ContinueStatement\n");
1340 void visit(StringLiteral *node) {
1342 fprintf(fp_, "[ StringLiteral\n");
1344 void visit(IncDecExpression *node) {
1346 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1348 node->expression()->accept(this);
1354 ParseTree::dump(FILE *fp)
1356 AstPrinter printer(fp);
1358 for (size_t i = 0; i < statements_->length(); i++)
1359 statements_->at(i)->accept(&printer);