Fix bugs where "new x[x]" or "new x = x" would compile.
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"
25 #include "TypeManager.h"
30 Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
34 scanner_(cc, stream, length),
38 unbound_ = new (pool_) PoolList<NameProxy *>();
42 Parser::peek(TokenKind kind)
44 return scanner_.peek() == kind;
48 Parser::match(TokenKind kind)
57 Parser::matchSemicolon()
59 return expect(TOK_SEMICOLON);
63 Parser::expect(TokenKind kind)
65 TokenKind got = scanner_.scan();
68 cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
73 Parser::enterScope(Scope::Kind kind)
75 scope_ = new (pool_) Scope(pool_, kind, scope_);
76 if (!scope_->initialize())
82 Parser::bind(Handle<String> name)
84 BoundName *bound = scope_->lookup(name);
85 NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
86 if (!bound && !unbound_->append(proxy))
92 Parser::bindType(Handle<String> name)
94 if (BoundName *binding = scope_->lookup(name))
97 return new (pool_) UnboundName(scope_, name);
101 Parser::matchName(String **name, TokenKind kind)
103 assert(kind == TOK_NAME || kind == TOK_LABEL);
107 *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
114 if (!expect(TOK_NAME))
116 return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
120 Parser::redeclarationError(BoundName *other)
122 cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->name()->chars(),
123 other->pos().line, other->pos().col);
129 TokenKind kind = scanner_.peek();
131 case TOK_FLOAT_LITERAL:
134 double value = Scanner::ParseDouble(scanner_.literal());
135 return new (pool_) FloatLiteral(scanner_.begin(), value);
138 case TOK_HEX_LITERAL:
141 int value = strtol(scanner_.literal(), NULL, 16);
142 return new (pool_) IntegerLiteral(scanner_.begin(), value);
145 case TOK_INTEGER_LITERAL:
148 int value = atoi(scanner_.literal());
149 return new (pool_) IntegerLiteral(scanner_.begin(), value);
155 return new (pool_) BooleanLiteral(scanner_.begin(), kind);
157 case TOK_STRING_LITERAL:
160 Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
163 memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
164 return new (pool_) StringLiteral(scanner_.begin(), array);
169 if (kind != TOK_ERROR)
170 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
177 Parser::arrayLiteral(TokenKind kind)
179 assert(kind == TOK_LBRACE || kind == TOK_LBRACKET);
181 TokenKind close = (kind == TOK_LBRACE)
185 SourcePosition pos = scanner_.begin();
187 ExpressionList *list = new (pool_) ExpressionList();
192 Expression *expr = NULL;
193 if (kind == TOK_LBRACE) {
194 if (peek(TOK_LBRACE))
195 expr = arrayLiteral(TOK_LBRACE);
204 if (!list->append(expr))
207 if (!match(TOK_COMMA)) {
214 return new (pool_) ArrayLiteral(pos, kind, list);
220 switch (scanner_.peek()) {
224 Expression *expr = expression();
227 if (!expect(TOK_RPAREN))
234 Local<String> name(zone_, expectName());
246 Parser::call(Expression *callee)
248 ExpressionList *arguments = new (pool_) ExpressionList();
250 SourcePosition pos = scanner_.begin();
253 if (!match(TOK_RPAREN)) {
255 Expression *expr = expression();
259 if (!arguments->append(expr))
262 if (!match(TOK_COMMA))
266 if (!expect(TOK_RPAREN))
270 return new (pool_) CallExpression(pos, callee, arguments);
274 Parser::index(Expression *left)
276 expect(TOK_LBRACKET);
278 SourcePosition pos = scanner_.begin();
279 Expression *expr = expression();
283 if (!expect(TOK_RBRACKET))
286 return new (pool_) IndexExpression(pos, left, expr);
290 Parser::field(Expression *left)
294 SourcePosition pos = scanner_.begin();
295 Local<String> name(zone_, expectName());
299 return new (pool_) FieldExpression(pos, left, name);
305 Expression *expr = prefix();
310 switch (scanner_.peek()) {
312 if ((expr = call(expr)) == NULL)
317 if ((expr = index(expr)) == NULL)
322 if ((expr = field(expr)) == NULL)
335 TokenKind token = scanner_.peek();
337 SourcePosition pos = scanner_.begin();
343 Expression *expr = unary();
346 return new (pool_) IncDecExpression(pos, token, expr, false);
354 Expression *expr = unary();
357 return new (pool_) UnaryExpression(pos, token, expr);
363 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
367 BoundName *type = NULL;
369 type = bindType(tag);
371 Expression *expr = unary();
375 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, type);
382 Expression *expr = primary();
384 token = scanner_.peek();
385 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
387 return new (pool_) IncDecExpression(pos, token, expr, true);
394 Parser::multiplication()
396 Expression *left = unary();
398 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
400 SourcePosition pos = scanner_.begin();
401 TokenKind kind = scanner_.last();
402 Expression *right = unary();
405 left = new (pool_) BinaryExpression(pos, kind, left, right);
413 Expression *left = multiplication();
415 if (!match(TOK_PLUS) && !match(TOK_MINUS))
417 SourcePosition pos = scanner_.begin();
418 TokenKind kind = scanner_.last();
419 Expression *right = multiplication();
422 left = new (pool_) BinaryExpression(pos, kind, left, right);
430 Expression *left = addition();
432 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
434 SourcePosition pos = scanner_.begin();
435 TokenKind kind = scanner_.last();
436 Expression *right = addition();
439 left = new (pool_) BinaryExpression(pos, kind, left, right);
447 Expression *left = shift();
449 if (!match(TOK_BITAND))
451 SourcePosition pos = scanner_.begin();
452 Expression *right = shift();
455 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
463 Expression *left = bitand_();
465 if (!match(TOK_BITXOR))
467 SourcePosition pos = scanner_.begin();
468 Expression *right = shift();
471 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
479 Expression *left = bitxor();
481 if (!match(TOK_BITOR))
483 SourcePosition pos = scanner_.begin();
484 Expression *right = bitxor();
487 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
495 Expression *left = bitor_();
497 TokenKind kind = scanner_.peek();
498 if (kind < TOK_LT || kind > TOK_GE)
501 SourcePosition pos = scanner_.begin();
502 Expression *right = shift();
505 left = new (pool_) BinaryExpression(pos, kind, left, right);
513 Expression *left = relational();
515 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
517 TokenKind kind = scanner_.last();
518 SourcePosition pos = scanner_.begin();
519 Expression *right = relational();
522 left = new (pool_) BinaryExpression(pos, kind, left, right);
530 Expression *left = equals();
534 SourcePosition pos = scanner_.begin();
535 Expression *right = equals();
538 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
546 Expression *left = and_();
550 SourcePosition pos = scanner_.begin();
551 Expression *right = and_();
554 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
562 Expression *cond = or_();
566 if (!match(TOK_QMARK))
570 SourcePosition pos = scanner_.begin();
571 AutoAllowTags<false> disableTags(scanner_);
573 if ((left = expression()) == NULL)
577 if (!expect(TOK_COLON))
580 Expression *right = expression();
584 return new (pool_) TernaryExpression(pos, cond, left, right);
590 Expression *left = ternary();
592 TokenKind token = scanner_.peek();
593 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
596 SourcePosition pos = scanner_.begin();
597 Expression *expr = ternary();
601 left = new (pool_) Assignment(pos, token, left, expr);
615 SourcePosition pos = scanner_.begin();
618 if (!expect(TOK_LPAREN))
621 Expression *condition = expression();
625 if (!expect(TOK_RPAREN))
628 // Inside a loop, we force the creation of a scope object. Normally, we
629 // will cull scopes if they have no variables. However inside a loop,
630 // function calls that take references may compute a LIFO object, and to
631 // avoid temporarily leaking many such objects, we ensure that a scope
632 // is present so a LIFO slot can be allocated.
633 if (!enterScope(Scope::BLOCK))
637 if (scanner_.peek() == TOK_LBRACE)
638 body = block(scope_);
640 body = localStatement();
644 scope_ = scope_->enclosing();
645 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
651 SourcePosition pos = scanner_.begin();
654 // See the comment in ::while_() as to why we force a scope.
655 if (!enterScope(Scope::BLOCK))
659 if (scanner_.peek() == TOK_LBRACE)
660 body = block(scope_);
662 body = localStatement();
666 scope_ = scope_->enclosing();
668 if (!expect(TOK_WHILE))
671 if (!expect(TOK_LPAREN))
673 Expression *condition = expression();
676 if (!expect(TOK_RPAREN))
679 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
687 SourcePosition pos = scanner_.begin();
689 if (!expect(TOK_LPAREN))
691 Expression *expr = expression();
694 if (!expect(TOK_RPAREN))
697 if (!expect(TOK_LBRACE))
700 SourcePosition defaultPos;
701 PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
703 Statement *defaultCase = NULL;
705 while (!peek(TOK_RBRACE)) {
706 Expression *expr = NULL;
707 ExpressionList *others = NULL;
708 if (match(TOK_DEFAULT)) {
710 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
714 defaultPos = scanner_.begin();
717 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
721 if (!expect(TOK_CASE))
724 // A limitation in the grammar is that |case <NAME>:| will be
725 // detected as a label.
726 AutoAllowTags<false> disableTags(scanner_);
728 if ((expr = expression()) == NULL)
731 if (peek(TOK_COMMA)) {
732 others = new (pool_) ExpressionList();
733 while (match(TOK_COMMA)) {
734 Expression *other = expression();
737 if (!others->append(other))
743 if (!expect(TOK_COLON))
746 Statement *statement = localStatement();
750 if (!peek(TOK_CASE) &&
751 !peek(TOK_DEFAULT) &&
754 cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
759 Case *caze = new (pool_) Case(expr, others, statement);
760 if (!cases->append(caze))
763 defaultCase = statement;
767 if (!expect(TOK_RBRACE))
770 return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
774 Parser::forStatement()
776 SourcePosition pos = scanner_.begin();
778 if (!expect(TOK_LPAREN))
781 Statement *decl = NULL;
782 if (!match(TOK_SEMICOLON)) {
783 if (match(TOK_NEW)) {
784 if (!enterScope(Scope::BLOCK))
786 if ((decl = vars(TOK_STOCK, TOK_NEW)) == NULL)
789 if ((decl = expressionStatement()) == NULL)
792 if (!expect(TOK_SEMICOLON))
796 Expression *condition = NULL;
797 if (!match(TOK_SEMICOLON)) {
798 if ((condition = expression()) == NULL)
800 if (!expect(TOK_SEMICOLON))
804 Statement *update = NULL;
805 if (!match(TOK_RPAREN)) {
806 if ((update = expressionStatement()) == NULL)
808 if (!expect(TOK_RPAREN))
812 // See the comment in ::while_() as to why we force a scope.
813 if (!enterScope(Scope::BLOCK))
817 if (scanner_.peek() == TOK_LBRACE)
818 body = block(scope_);
820 body = localStatement();
824 scope_ = scope_->enclosing();
826 Scope *declScope = NULL;
827 if (decl && (decl->isVariableDeclaration() || decl->isBlockStatement())) {
828 declScope = scope_->unlinkIfEmpty();
829 scope_ = scope_->enclosing();
831 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
837 ExpressionList *postDimensions = new (pool_) ExpressionList();
838 while (match(TOK_LBRACKET)) {
839 Expression *dim = NULL;
840 if (!match(TOK_RBRACKET)) {
841 if ((dim = expression()) == NULL)
843 if (!expect(TOK_RBRACKET))
847 if (!postDimensions->append(dim))
850 return postDimensions;
853 VariableDeclaration *
854 Parser::var(TokenKind scope, TokenKind kind)
856 Local<String> tag(zone_);
857 if (matchName(tag.ref(), TOK_LABEL) && !tag)
860 BoundName *type = NULL;
862 type = bindType(tag);
864 Local<String> name(zone_, expectName());
868 SourcePosition pos = scanner_.begin();
870 if (BoundName *other = scope_->localLookup(name)) {
871 redeclarationError(other);
875 ExpressionList *postDimensions = NULL;
876 if (peek(TOK_LBRACKET)) {
877 if ((postDimensions = dimensions()) == NULL)
881 Expression *expr = NULL;
882 if (match(TOK_ASSIGN)) {
883 switch (scanner_.peek()) {
884 // Note: we don't support [] literals yet.
886 if ((expr = arrayLiteral(scanner_.scan())) == NULL)
891 if ((expr = expression()) == NULL)
897 Variable *var = scope_->declareVariable(name, pos);
901 if (scope == TOK_PUBLIC)
904 return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr);
908 Parser::vars(TokenKind scope, TokenKind kind)
910 VariableDeclaration *decl = var(scope, kind);
914 if (!peek(TOK_COMMA))
917 StatementList *statements = new (pool_) StatementList();
918 if (!statements->append(decl))
921 while (match(TOK_COMMA)) {
922 Statement *decl = var(scope, kind);
925 if (!statements->append(decl))
929 // Create a fake-o block with no scope to create a statement list.
930 return new (pool_) BlockStatement(decl->pos(), NULL, statements);
934 Parser::returnStatement()
936 SourcePosition pos = scanner_.begin();
937 if (!expect(TOK_RETURN))
940 Expression *expr = NULL;
941 if (scanner_.peek() != TOK_SEMICOLON) {
942 if ((expr = expression()) == NULL)
945 // We only care about non-void returns when determining whether a
946 // tagless function is non-void.
947 encounteredReturn_ = true;
950 return new (pool_) ReturnStatement(pos, expr);
954 Parser::expressionStatement()
956 Expression *left = assignment();
960 return new (pool_) ExpressionStatement(left);
964 Parser::block(Scope *scope)
966 if (!expect(TOK_LBRACE))
969 SourcePosition pos = scanner_.begin();
970 if (!scope && !enterScope(Scope::BLOCK))
973 StatementList *statements = new (pool_) StatementList();
974 while (!match(TOK_RBRACE)) {
975 Statement *statement = localStatement();
976 if (statement == NULL)
978 if (!statements->append(statement))
983 scope = scope_->unlinkIfEmpty();
984 scope_ = scope_->enclosing();
986 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
995 SourcePosition pos = scanner_.begin();
996 if (!expect(TOK_LPAREN))
999 Expression *cond = expression();
1003 if (!expect(TOK_RPAREN))
1006 Statement *ifTrue = localStatement();
1010 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1012 IfStatement *last = outer;
1013 while (match(TOK_ELSE)) {
1014 if (!match(TOK_IF)) {
1015 Statement *ifFalse = localStatement();
1019 last->setIfFalse(ifFalse);
1023 SourcePosition pos = scanner_.begin();
1024 if (!expect(TOK_LPAREN))
1027 Expression *otherCond = expression();
1031 if (!expect(TOK_RPAREN))
1034 Statement *otherIfTrue = localStatement();
1038 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1039 last->setIfFalse(inner);
1047 Parser::localStatement()
1049 Statement *statement = NULL;
1051 // Statements which must be followed by a semicolon will break out of the
1052 // switch. If they may end in BlockStatements, they'll immediately return.
1054 TokenKind kind = scanner_.peek();
1059 if ((statement = vars(TOK_STOCK, kind)) == NULL)
1064 return forStatement();
1071 statement = new (pool_) BreakStatement(scanner_.begin());
1076 statement = new (pool_) ContinueStatement(scanner_.begin());
1080 if ((statement = do_()) == NULL)
1085 if ((statement = returnStatement()) == NULL)
1090 if ((statement = enum_()) == NULL)
1095 if ((statement = struct_()) == NULL)
1113 if ((statement = expressionStatement()) == NULL)
1117 if (!expect(TOK_SEMICOLON))
1128 Local<String> name(zone_, expectName());
1132 SourcePosition pos = scanner_.begin();
1134 if (BoundName *other = scope_->localLookup(name)) {
1135 redeclarationError(other);
1140 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1143 if (!expect(TOK_LBRACE))
1146 FieldList *fields = new (pool_) FieldList();
1148 while (!peek(TOK_RBRACE)) {
1149 if (matchName(name.ref(), TOK_LABEL) && !name)
1152 BoundName *type = NULL;
1154 if ((type = bindType(name)) == NULL)
1158 name = expectName();
1162 SourcePosition pos = scanner_.begin();
1164 ExpressionList *postDimensions = NULL;
1165 //if (peek(TOK_LBRACKET)) {
1166 // if ((postDimensions = dimensions()) == NULL)
1170 if (!matchSemicolon())
1173 StructureStatement::Field *field =
1174 new (pool_) StructureStatement::Field(pos, type, name, postDimensions);
1175 if (!field || !fields->append(field))
1179 if (!expect(TOK_RBRACE))
1182 if (fields->empty()) {
1183 cc_.reportError(pos, Message_StructCantBeEmpty);
1187 return new (pool_) StructureStatement(pos, type, fields);
1195 NamedType *type = NULL;
1196 SourcePosition pos = scanner_.begin();
1198 Local<String> name(zone_);
1199 if (matchName(name.ref())) {
1203 if (BoundName *other = scope_->localLookup(name)) {
1204 redeclarationError(other);
1208 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1212 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1214 if (!expect(TOK_LBRACE))
1218 if (scanner_.peek() == TOK_RBRACE)
1221 Local<String> name(zone_, expectName());
1225 if (BoundName *other = scope_->localLookup(name)) {
1226 redeclarationError(other);
1230 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
1234 Expression *expr = NULL;
1235 if (match(TOK_ASSIGN)) {
1236 if ((expr = expression()) == NULL)
1240 if (!entries->append(EnumStatement::Entry(constant, expr)))
1242 } while (match(TOK_COMMA));
1243 if (!expect(TOK_RBRACE))
1246 return new (pool_) EnumStatement(pos, type, name, entries);
1250 Parser::function(TokenKind token)
1252 Local<String> returnTag(zone_);
1253 if (token == TOK_LABEL) {
1254 returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1260 if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
1264 BoundName *returnType = NULL;
1266 returnType = bindType(returnTag);
1268 Local<String> name(zone_, expectName());
1272 SourcePosition pos = scanner_.begin();
1274 // The function name goes into the outer (global) scope.
1275 assert(!scope_->enclosing());
1277 NamedType *type = NULL;
1278 NamedFunction *fun = NULL;
1279 if (BoundName *other = scope_->localLookup(name)) {
1280 // We allow a redeclaration if the new type is a public, and the old
1281 // type was a forward. However, the forward must come first.
1282 if (token == TOK_TYPEDEF || other->kind() != BoundName::FUNCTION) {
1283 redeclarationError(other);
1287 fun = other->toNamedFunction();
1288 if (!fun->isForward() || token != TOK_PUBLIC) {
1289 redeclarationError(other);
1293 // We've got the same name, but the original is a forward, so let it
1294 // slide and re-use the original declaration.
1295 fun->setImplemented(scanner_.begin());
1296 } else if (token == TOK_TYPEDEF) {
1297 type = scope_->declareType(name, scanner_.begin());
1301 fun = scope_->declareFunction(name, scanner_.begin(), token);
1306 if (fun && fun->isPublic())
1309 Scope *scope = enterScope(Scope::FUNCTION);
1313 ParameterList *parameters = new (pool_) ParameterList();
1315 if (!expect(TOK_LPAREN))
1318 if (!match(TOK_RPAREN)) {
1320 bool isConst = match(TOK_CONST);
1321 bool ref = match(TOK_AMPERSAND);
1323 SourcePosition begin = scanner_.begin();
1324 Local<String> tag(zone_);
1325 if (matchName(tag.ref(), TOK_LABEL) && !tag)
1328 BoundName *type = NULL;
1330 type = bindType(tag);
1332 if (match(TOK_ELLIPSES)) {
1333 if (isConst || ref) {
1334 cc_.reportError(begin, Message_InvalidVarArgs);
1338 if (token != TOK_NATIVE) {
1339 cc_.reportError(begin, Message_VarArgsOutsideNative);
1343 fun->markNativeVariadic();
1347 Local<String> name(zone_, expectName());
1351 if (BoundName *other = scope_->localLookup(name)) {
1352 redeclarationError(other);
1355 Variable *arg = scope_->declareArgument(name, scanner_.begin());
1359 // Look for dimensions.
1360 ExpressionList *postDimensions = NULL;
1361 if (peek(TOK_LBRACKET)) {
1362 if ((postDimensions = dimensions()) == NULL)
1366 Expression *expr = NULL;
1367 if (match(TOK_ASSIGN)) {
1368 if ((expr = expression()) == NULL)
1372 Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
1374 if (!parameters->append(parameter))
1377 if (!match(TOK_COMMA))
1380 if (!expect(TOK_RPAREN))
1384 encounteredReturn_ = false;
1386 Statement *body = NULL;
1387 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1393 scope_ = scope_->enclosing();
1395 FunctionSignature signature(returnType, parameters);
1396 if (token == TOK_TYPEDEF)
1397 return new (pool_) FunctionTypeStatement(pos, type, signature);
1399 return new (pool_) FunctionStatement(pos, scope, fun, body, signature, encounteredReturn_);
1403 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1405 Local<String> tag(zone, zone->makeSymbol(name));
1409 return !!scope->declareType(tag, type);
1413 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1415 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1417 return DeclareIntrinsicType(zone, scope, name, primitive);
1421 Parser::setupIntrinsics()
1423 if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1425 if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1427 if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1429 if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1432 Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1433 if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1436 Local<Type> voidType(zone_, zone_->types()->getVoid());
1437 if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1440 Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1441 if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1450 StatementList *statements = new (pool_) StatementList();
1452 if (!enterScope(Scope::GLOBAL))
1455 if (!setupIntrinsics())
1459 Statement *statement = NULL;
1461 TokenKind kind = scanner_.peek();
1470 if ((statement = function(TOK_NAME)) == NULL)
1482 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1483 if ((statement = var(TOK_PUBLIC, scanner_.scan())) == NULL)
1485 if (!matchSemicolon())
1488 if ((statement = function(kind)) == NULL)
1490 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1499 // Note: at global scope, we don't accept comma-delimited
1500 // declarations yet, to see if we can get away with forcing
1501 // a nicer top-level style.
1503 if ((statement = var(TOK_STOCK, kind)) == NULL)
1505 if (!matchSemicolon())
1511 if ((statement = enum_()) == NULL)
1513 if (!matchSemicolon())
1518 if ((statement = struct_()) == NULL)
1520 if (!matchSemicolon())
1525 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1532 if (!statements->append(statement))
1536 return new (pool_) ParseTree(scope_, statements, unbound_);
1539 class AstPrinter : public AstVisitor
1546 for (size_t i = 0; i < level_; i++)
1557 AstPrinter(FILE *fp)
1563 void visit(NameProxy *name) {
1565 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1566 (name->binding() ? "" : " unbound"));
1568 void visit(CallExpression *node) {
1570 fprintf(fp_, "[ CallExpression\n");
1572 node->callee()->accept(this);
1573 for (size_t i = 0; i < node->arguments()->length(); i++)
1574 node->arguments()->at(i)->accept(this);
1577 void visit(FunctionTypeStatement *node) {
1579 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->decl()->name()->chars());
1581 void visit(FunctionStatement *node) {
1583 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1586 node->body()->accept(this);
1589 void visit(ExpressionStatement *node) {
1591 fprintf(fp_, "[ ExpressionStatement\n");
1593 node->expression()->accept(this);
1596 void visit(Assignment *node) {
1598 fprintf(fp_, "[ Assignment\n");
1600 node->lvalue()->accept(this);
1601 node->expression()->accept(this);
1604 void visit(TernaryExpression *node) {
1606 fprintf(fp_, "[ TernaryExpression\n");
1608 node->condition()->accept(this);
1609 node->left()->accept(this);
1610 node->right()->accept(this);
1613 void visit(BinaryExpression *node) {
1615 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1617 node->left()->accept(this);
1618 node->right()->accept(this);
1621 void visit(UnaryExpression *node) {
1623 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1625 node->expression()->accept(this);
1628 void visit(ReturnStatement *node) {
1630 fprintf(fp_, "[ ReturnStatement\n");
1632 if (node->expression())
1633 node->expression()->accept(this);
1636 void visit(ForStatement *node) {
1638 fprintf(fp_, "[ ForStatement\n");
1640 if (node->initialization())
1641 node->initialization()->accept(this);
1642 if (node->condition())
1643 node->condition()->accept(this);
1645 node->update()->accept(this);
1646 node->body()->accept(this);
1649 void visit(BlockStatement *node) {
1651 fprintf(fp_, "[ BlockStatement\n");
1653 for (size_t i = 0; i < node->statements()->length(); i++)
1654 node->statements()->at(i)->accept(this);
1657 void visit(VariableDeclaration *node) {
1659 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1661 if (node->initialization())
1662 node->initialization()->accept(this);
1665 void visit(IntegerLiteral *node) {
1667 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1669 void visit(BooleanLiteral *node) {
1671 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1672 (node->token() == TOK_TRUE) ? "true" : "false");
1674 void visit(FloatLiteral *node) {
1676 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1678 void visit(IfStatement *node) {
1680 fprintf(fp_, "[ IfStatement\n");
1682 node->ifTrue()->accept(this);
1683 if (node->ifFalse())
1684 node->ifFalse()->accept(this);
1687 void visit(IndexExpression *node) {
1689 fprintf(fp_, "[ IndexExpression\n");
1691 node->left()->accept(this);
1692 node->right()->accept(this);
1695 void visit(EnumStatement *node) {
1697 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1699 for (size_t i = 0; i < node->entries()->length(); i++) {
1701 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1702 if (node->entries()->at(i).expr) {
1704 node->entries()->at(i).expr->accept(this);
1710 void visit(WhileStatement *node) {
1712 fprintf(fp_, "[ WhileStatement (%s)\n",
1713 (node->token() == TOK_DO) ? "do" : "while");
1715 if (node->token() == TOK_DO) {
1716 node->condition()->accept(this);
1717 node->body()->accept(this);
1719 node->condition()->accept(this);
1720 node->body()->accept(this);
1724 void visit(BreakStatement *node) {
1726 fprintf(fp_, "[ BreakStatement\n");
1728 void visit(ContinueStatement *node) {
1730 fprintf(fp_, "[ ContinueStatement\n");
1732 void visit(StringLiteral *node) {
1734 fprintf(fp_, "[ StringLiteral\n");
1736 void visit(IncDecExpression *node) {
1738 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1740 node->expression()->accept(this);
1743 void visit(StructureStatement *node) {
1745 fprintf(fp_, "[ StructureStatement %s\n", node->decl()->name()->chars());
1747 void visit(FieldExpression *node) {
1749 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1751 node->left()->accept(this);
1754 void visit(SwitchStatement *node) {
1756 fprintf(fp_, "[ SwitchStatement\n");
1758 node->expression()->accept(this);
1759 for (size_t i = 0; i < node->cases()->length(); i++) {
1760 Case *c = node->cases()->at(i);
1761 c->expression()->accept(this);
1763 for (size_t j = 0; j < c->others()->length(); j++)
1764 c->others()->at(j)->accept(this);
1767 c->statement()->accept(this);
1770 if (node->defaultCase())
1771 node->defaultCase()->accept(this);
1774 void visit(ArrayLiteral *node) {
1776 fprintf(fp_, "[ ArrayLiteral\n");
1778 for (size_t i = 0; i < node->expressions()->length(); i++) {
1779 Expression *expr = node->expressions()->at(i);
1788 ParseTree::dump(FILE *fp)
1790 AstPrinter printer(fp);
1792 for (size_t i = 0; i < statements_->length(); i++)
1793 statements_->at(i)->accept(&printer);