Re-added parameter support.
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/.
21 #include "../FixedArray.h"
23 #include "../Strings.h"
24 #include "../TypeManager.h"
26 #include "../Heap-inl.h"
30 Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
34 scanner_(cc, stream, length),
37 unbound_ = new (pool_) PoolList<NameProxy *>();
38 imports_ = new (pool_) PoolList<ImportStatement *>();
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::matchName(String **name, TokenKind kind)
75 assert(kind == TOK_NAME || kind == TOK_LABEL);
79 *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
86 if (!expect(TOK_NAME))
88 return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
94 TokenKind kind = scanner_.peek();
96 case TOK_FLOAT_LITERAL:
99 double value = Scanner::ParseDouble(scanner_.literal());
100 return new (pool_) FloatLiteral(scanner_.begin(), value);
103 case TOK_HEX_LITERAL:
106 int value = strtol(scanner_.literal(), NULL, 16);
107 return new (pool_) IntegerLiteral(scanner_.begin(), value);
110 case TOK_INTEGER_LITERAL:
113 int value = atoi(scanner_.literal());
114 return new (pool_) IntegerLiteral(scanner_.begin(), value);
120 return new (pool_) BooleanLiteral(scanner_.begin(), kind);
122 case TOK_STRING_LITERAL:
125 Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
128 memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
129 return new (pool_) StringLiteral(scanner_.begin(), array);
134 if (kind != TOK_ERROR)
135 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
142 Parser::fixedArrayLiteral()
144 SourcePosition pos = scanner_.begin();
146 ExpressionList *list = new (pool_) ExpressionList();
148 // { } is an illegal array literal.
149 if (list->length() > 0 && match(TOK_LBRACE))
152 Expression *expr = NULL;
153 if (peek(TOK_LBRACE))
154 expr = fixedArrayLiteral();
160 if (!list->append(expr))
163 if (!match(TOK_COMMA)) {
164 if (!expect(TOK_RBRACE))
170 return new (pool_) ArrayLiteral(pos, TOK_LBRACE, list);
176 switch (scanner_.peek()) {
180 Expression *expr = expression();
183 if (!expect(TOK_RPAREN))
190 Local<String> name(zone_, expectName());
193 return new (pool_) NameProxy(scanner_.begin(), name);
201 // Parses only old-style declarations.
203 Parser::typeAndName(Expression **type, String **namep)
205 if (match(TOK_LABEL)) {
206 // Old-style declaration:
208 Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
212 *type = new (pool_) NameProxy(scanner_.begin(), name);
213 *namep = expectName();
218 *namep = expectName();
223 // Parses both old and new style declarations.
225 Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
228 // NewDecl ::= Type Ident
229 // OldDecl ::= Label? (Ident | "...")
231 // Label ::= Ident ":"
233 if (match(TOK_LABEL)) {
234 // We something of the form:
237 Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
241 *type = new (pool_) NameProxy(scanner_.begin(), name);
242 if (kind == DeclArg && match(TOK_ELLIPSES)) {
245 if ((*namep = expectName()) == NULL)
251 Local<String> name(zone_, expectName());
255 if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
256 // We got something of the form:
258 *type = new (pool_) NameProxy(scanner_.begin(), name);
259 if (peek(TOK_NAME)) {
260 if ((*namep = expectName()) == NULL)
268 // We got something of the form:
276 Parser::call(Expression *callee)
278 ExpressionList *arguments = new (pool_) ExpressionList();
280 SourcePosition pos = scanner_.begin();
283 if (!match(TOK_RPAREN)) {
285 Expression *expr = expression();
289 if (!arguments->append(expr))
292 if (!match(TOK_COMMA))
296 if (!expect(TOK_RPAREN))
300 return new (pool_) CallExpression(pos, callee, arguments);
304 Parser::index(Expression *left)
306 expect(TOK_LBRACKET);
308 SourcePosition pos = scanner_.begin();
309 Expression *expr = expression();
313 if (!expect(TOK_RBRACKET))
316 return new (pool_) IndexExpression(pos, left, expr);
320 Parser::field(Expression *left)
324 SourcePosition pos = scanner_.begin();
325 Local<String> name(zone_, expectName());
329 return new (pool_) FieldExpression(pos, left, name);
335 Expression *expr = prefix();
340 switch (scanner_.peek()) {
342 if ((expr = call(expr)) == NULL)
347 if ((expr = index(expr)) == NULL)
352 if ((expr = field(expr)) == NULL)
365 TokenKind token = scanner_.peek();
367 SourcePosition pos = scanner_.begin();
373 Expression *expr = unary();
376 return new (pool_) IncDecExpression(pos, token, expr, false);
384 Expression *expr = unary();
387 return new (pool_) UnaryExpression(pos, token, expr);
393 if (!expect(TOK_LPAREN))
395 Expression *expr = unary();
398 if (!expect(TOK_RPAREN))
400 return new (pool_) UnaryExpression(pos, token, expr);
406 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
410 NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
412 Expression *expr = unary();
416 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
423 Expression *expr = primary();
425 token = scanner_.peek();
426 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
428 return new (pool_) IncDecExpression(pos, token, expr, true);
435 Parser::multiplication()
437 Expression *left = unary();
439 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
441 SourcePosition pos = scanner_.begin();
442 TokenKind kind = scanner_.last();
443 Expression *right = unary();
446 left = new (pool_) BinaryExpression(pos, kind, left, right);
454 Expression *left = multiplication();
456 if (!match(TOK_PLUS) && !match(TOK_MINUS))
458 SourcePosition pos = scanner_.begin();
459 TokenKind kind = scanner_.last();
460 Expression *right = multiplication();
463 left = new (pool_) BinaryExpression(pos, kind, left, right);
471 Expression *left = addition();
473 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
475 SourcePosition pos = scanner_.begin();
476 TokenKind kind = scanner_.last();
477 Expression *right = addition();
480 left = new (pool_) BinaryExpression(pos, kind, left, right);
488 Expression *left = shift();
490 if (!match(TOK_BITAND))
492 SourcePosition pos = scanner_.begin();
493 Expression *right = shift();
496 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
504 Expression *left = bitand_();
506 if (!match(TOK_BITXOR))
508 SourcePosition pos = scanner_.begin();
509 Expression *right = shift();
512 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
520 Expression *left = bitxor();
522 if (!match(TOK_BITOR))
524 SourcePosition pos = scanner_.begin();
525 Expression *right = bitxor();
528 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
536 Expression *left = bitor_();
538 TokenKind kind = scanner_.peek();
539 if (kind < TOK_LT || kind > TOK_GE)
542 SourcePosition pos = scanner_.begin();
543 Expression *right = shift();
546 left = new (pool_) BinaryExpression(pos, kind, left, right);
554 Expression *left = relational();
556 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
558 TokenKind kind = scanner_.last();
559 SourcePosition pos = scanner_.begin();
560 Expression *right = relational();
563 left = new (pool_) BinaryExpression(pos, kind, left, right);
571 Expression *left = equals();
575 SourcePosition pos = scanner_.begin();
576 Expression *right = equals();
579 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
587 Expression *left = and_();
591 SourcePosition pos = scanner_.begin();
592 Expression *right = and_();
595 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
603 Expression *cond = or_();
607 if (!match(TOK_QMARK))
611 SourcePosition pos = scanner_.begin();
612 AutoAllowTags<false> disableTags(scanner_);
614 if ((left = expression()) == NULL)
618 if (!expect(TOK_COLON))
621 Expression *right = expression();
625 return new (pool_) TernaryExpression(pos, cond, left, right);
631 Expression *left = ternary();
633 TokenKind token = scanner_.peek();
634 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
637 SourcePosition pos = scanner_.begin();
638 Expression *expr = ternary();
642 left = new (pool_) Assignment(pos, token, left, expr);
656 SourcePosition pos = scanner_.begin();
659 if (!expect(TOK_LPAREN))
662 Expression *condition = expression();
666 if (!expect(TOK_RPAREN))
670 if (scanner_.peek() == TOK_LBRACE)
673 body = localStatement();
677 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
683 SourcePosition pos = scanner_.begin();
687 if (scanner_.peek() == TOK_LBRACE)
690 body = localStatement();
694 if (!expect(TOK_WHILE))
697 if (!expect(TOK_LPAREN))
699 Expression *condition = expression();
702 if (!expect(TOK_RPAREN))
705 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
713 SourcePosition pos = scanner_.begin();
715 if (!expect(TOK_LPAREN))
717 Expression *expr = expression();
720 if (!expect(TOK_RPAREN))
723 if (!expect(TOK_LBRACE))
726 SourcePosition defaultPos;
727 PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
729 Statement *defaultCase = NULL;
731 while (!peek(TOK_RBRACE)) {
732 Expression *expr = NULL;
733 ExpressionList *others = NULL;
734 if (match(TOK_DEFAULT)) {
736 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
740 defaultPos = scanner_.begin();
743 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
747 if (!expect(TOK_CASE))
750 // A limitation in the grammar is that |case <NAME>:| will be
751 // detected as a label.
752 AutoAllowTags<false> disableTags(scanner_);
754 if ((expr = expression()) == NULL)
757 if (peek(TOK_COMMA)) {
758 others = new (pool_) ExpressionList();
759 while (match(TOK_COMMA)) {
760 Expression *other = expression();
763 if (!others->append(other))
769 if (!expect(TOK_COLON))
772 Statement *statement = localStatement();
776 if (!peek(TOK_CASE) &&
777 !peek(TOK_DEFAULT) &&
780 cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
785 Case *caze = new (pool_) Case(expr, others, statement);
786 if (!cases->append(caze))
789 defaultCase = statement;
793 if (!expect(TOK_RBRACE))
796 return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
800 Parser::forStatement()
802 SourcePosition pos = scanner_.begin();
804 if (!expect(TOK_LPAREN))
807 Statement *decl = NULL;
808 if (!match(TOK_SEMICOLON)) {
809 if (match(TOK_NEW)) {
810 if ((decl = vars(Qual_None)) == NULL)
813 if ((decl = expressionStatement()) == NULL)
816 if (!expect(TOK_SEMICOLON))
820 Expression *condition = NULL;
821 if (!match(TOK_SEMICOLON)) {
822 if ((condition = expression()) == NULL)
824 if (!expect(TOK_SEMICOLON))
828 Statement *update = NULL;
829 if (!match(TOK_RPAREN)) {
830 if ((update = expressionStatement()) == NULL)
832 if (!expect(TOK_RPAREN))
837 if (scanner_.peek() == TOK_LBRACE)
840 body = localStatement();
844 return new (pool_) ForStatement(pos, decl, condition, update, body);
850 ExpressionList *postDimensions = new (pool_) ExpressionList();
851 while (match(TOK_LBRACKET)) {
852 Expression *dim = NULL;
853 if (!match(TOK_RBRACKET)) {
854 if ((dim = expression()) == NULL)
856 if (!expect(TOK_RBRACKET))
860 if (!postDimensions->append(dim))
863 return postDimensions;
866 VariableDeclaration *
867 Parser::var(TypeQualifiers qual)
870 Local<String> name(zone_);
872 if (!typeAndName(&type, name.ref()))
875 ExpressionList *dims = NULL;
876 if (peek(TOK_LBRACKET)) {
877 if ((dims = dimensions()) == NULL)
881 SourcePosition pos = scanner_.begin();
883 Expression *expr = NULL;
884 if (match(TOK_ASSIGN)) {
885 switch (scanner_.peek()) {
886 // Note: we don't support [] literals yet.
889 if ((expr = fixedArrayLiteral()) == NULL)
894 if ((expr = expression()) == NULL)
900 return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
904 Parser::vars(TypeQualifiers qual)
906 VariableDeclaration *decl = var(qual);
910 if (!peek(TOK_COMMA))
913 StatementList *statements = new (pool_) StatementList();
914 if (!statements->append(decl))
917 while (match(TOK_COMMA)) {
918 Statement *decl = var(qual);
921 if (!statements->append(decl))
925 // Create a fake-o block with no scope to create a statement list.
926 return new (pool_) BlockStatement(decl->pos(), statements);
930 Parser::returnStatement()
932 SourcePosition pos = scanner_.begin();
933 if (!expect(TOK_RETURN))
936 Expression *expr = NULL;
937 if (scanner_.peek() != TOK_SEMICOLON) {
938 if ((expr = expression()) == NULL)
941 // We only care about non-void returns when determining whether a
942 // tagless function is non-void.
943 encounteredReturn_ = true;
946 return new (pool_) ReturnStatement(pos, expr);
950 Parser::expressionStatement()
952 Expression *left = assignment();
956 return new (pool_) ExpressionStatement(left);
962 if (!expect(TOK_LBRACE))
965 SourcePosition pos = scanner_.begin();
967 StatementList *statements = new (pool_) StatementList();
968 while (!match(TOK_RBRACE)) {
969 Statement *statement = localStatement();
970 if (statement == NULL)
972 if (!statements->append(statement))
976 BlockStatement *block = new (pool_) BlockStatement(pos, statements);
985 SourcePosition pos = scanner_.begin();
986 if (!expect(TOK_LPAREN))
989 Expression *cond = expression();
993 if (!expect(TOK_RPAREN))
996 Statement *ifTrue = localStatement();
1000 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1002 IfStatement *last = outer;
1003 while (match(TOK_ELSE)) {
1004 if (!match(TOK_IF)) {
1005 Statement *ifFalse = localStatement();
1009 last->setIfFalse(ifFalse);
1013 SourcePosition pos = scanner_.begin();
1014 if (!expect(TOK_LPAREN))
1017 Expression *otherCond = expression();
1021 if (!expect(TOK_RPAREN))
1024 Statement *otherIfTrue = localStatement();
1028 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1029 last->setIfFalse(inner);
1037 Parser::localStatement()
1039 Statement *statement = NULL;
1041 // Statements which must be followed by a semicolon will break out of the
1042 // switch. If they may end in BlockStatements, they'll immediately return.
1044 TokenKind kind = scanner_.peek();
1049 TypeQualifiers quals = (kind == TOK_CONST)
1053 if ((statement = vars(quals)) == NULL)
1059 return forStatement();
1066 statement = new (pool_) BreakStatement(scanner_.begin());
1071 statement = new (pool_) ContinueStatement(scanner_.begin());
1075 if ((statement = do_()) == NULL)
1080 if ((statement = returnStatement()) == NULL)
1085 if ((statement = enum_()) == NULL)
1090 if ((statement = struct_()) == NULL)
1108 if ((statement = expressionStatement()) == NULL)
1112 if (!expect(TOK_SEMICOLON))
1123 Local<String> name(zone_, expectName());
1127 SourcePosition pos = scanner_.begin();
1129 if (!expect(TOK_LBRACE))
1132 FieldList *fields = new (pool_) FieldList();
1134 while (!peek(TOK_RBRACE)) {
1136 Local<String> fieldName(zone_);
1138 if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
1141 SourcePosition pos = scanner_.begin();
1143 if (!matchSemicolon())
1146 StructureStatement::Field *field =
1147 new (pool_) StructureStatement::Field(pos, type, fieldName);
1148 if (!field || !fields->append(field))
1152 if (!expect(TOK_RBRACE))
1155 if (fields->empty()) {
1156 cc_.reportError(pos, Message_StructCantBeEmpty);
1160 return new (pool_) StructureStatement(pos, name, fields);
1168 SourcePosition pos = scanner_.begin();
1170 Local<String> name(zone_);
1171 if (matchName(name.ref()) && !name)
1174 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1176 if (!expect(TOK_LBRACE))
1180 if (scanner_.peek() == TOK_RBRACE)
1183 Local<String> name(zone_, expectName());
1187 Expression *expr = NULL;
1188 if (match(TOK_ASSIGN)) {
1189 if ((expr = expression()) == NULL)
1193 if (!entries->append(EnumStatement::Entry(name, expr)))
1195 } while (match(TOK_COMMA));
1196 if (!expect(TOK_RBRACE))
1199 return new (pool_) EnumStatement(pos, name, entries);
1203 static inline ScopedRoot<T> *
1204 NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
1206 ScopedRoot<T> *root = pool.alloc<ScopedRoot<T> >();
1207 new (root) ScopedRoot<T>(obj);
1214 NameList *names = new (pool_) NameList();
1216 SourcePosition pos = scanner_.begin();
1218 Local<String> name(zone_, expectName());
1219 if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
1222 TokenKind suffix = TOK_NONE;
1223 while (match(TOK_DOT)) {
1224 if (match(TOK_STAR)) {
1229 if ((name = expectName()) == NULL)
1232 if (!names->append(NewScopedRoot<String>(pool_, name)))
1236 return new (pool_) ImportStatement(pos, names, suffix);
1240 Parser::function(TokenKind token)
1242 Expression *returnType;
1243 Local<String> name(zone_);
1245 if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
1248 SourcePosition pos = scanner_.begin();
1249 ParameterList *parameters = new (pool_) ParameterList();
1251 if (!expect(TOK_LPAREN))
1254 bool variadic = false;
1256 if (!match(TOK_RPAREN)) {
1258 bool isConst = match(TOK_CONST);
1259 bool ref = match(TOK_AMPERSAND);
1261 SourcePosition begin = scanner_.begin();
1263 Local<String> name(zone_);
1264 if (!fullTypeAndName(&type, name.ref(), DeclArg))
1268 if (isConst || ref) {
1269 cc_.reportError(begin, Message_InvalidVarArgs);
1273 if (token != TOK_NATIVE) {
1274 cc_.reportError(begin, Message_VarArgsOutsideNative);
1282 ExpressionList *dims = NULL;
1283 if (peek(TOK_LBRACKET)) {
1284 if ((dims = dimensions()) == NULL)
1288 Expression *expr = NULL;
1289 if (match(TOK_ASSIGN)) {
1290 if ((expr = expression()) == NULL)
1294 Parameter *parameter = new (pool_) Parameter(name, type, ref, isConst, dims, expr, begin);
1295 if (!parameters->append(parameter))
1298 if (!match(TOK_COMMA))
1301 if (!expect(TOK_RPAREN))
1305 encounteredReturn_ = false;
1307 Statement *body = NULL;
1308 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1314 FunctionSignature signature(returnType, parameters, variadic);
1315 if (token == TOK_TYPEDEF)
1316 return new (pool_) FunctionTypeStatement(pos, name, signature);
1318 return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
1322 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1324 Local<String> tag(zone, zone->makeSymbol(name));
1329 return false; //return !!scope->declareType(tag, type);
1333 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1335 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1337 return DeclareIntrinsicType(zone, scope, name, primitive);
1341 Parser::setupIntrinsics()
1344 if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1346 if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1348 if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1350 if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1353 Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1354 if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1357 Local<Type> voidType(zone_, zone_->types()->getVoid());
1358 if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1361 Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1362 if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1371 StatementList *statements = new (pool_) StatementList();
1373 if (!setupIntrinsics())
1377 Statement *statement = NULL;
1379 TokenKind kind = scanner_.peek();
1388 if ((statement = function(TOK_NAME)) == NULL)
1395 if (statements->length())
1396 cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
1397 ImportStatement *stmt = import();
1400 if (!imports_->append(stmt))
1402 if (!matchSemicolon())
1414 if (kind != TOK_LABEL)
1416 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1417 TypeQualifiers quals = TypeQualifiers(Qual_Public | Qual_Const);
1418 if ((statement = var(quals)) == NULL)
1420 if (!matchSemicolon())
1423 if ((statement = function(kind)) == NULL)
1425 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1434 TypeQualifiers quals = (kind == TOK_NEW) ? Qual_Const : Qual_None;
1435 // Note: at global scope, we don't accept comma-delimited
1436 // declarations yet, to see if we can get away with forcing
1437 // a nicer top-level style.
1439 if ((statement = var(quals)) == NULL)
1441 if (!matchSemicolon())
1447 if ((statement = enum_()) == NULL)
1449 if (!matchSemicolon())
1454 if ((statement = struct_()) == NULL)
1456 if (!matchSemicolon())
1461 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1468 if (!statements->append(statement))
1472 return new (pool_) ParseTree(statements, unbound_, imports_);
1475 class AstPrinter : public AstVisitor
1482 for (size_t i = 0; i < level_; i++)
1493 AstPrinter(FILE *fp)
1499 void dump(const FunctionSignature &sig) {
1501 fprintf(fp_, "()\n");
1503 void visitNameProxy(NameProxy *name) {
1505 fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
1507 void visitCallExpression(CallExpression *node) {
1509 fprintf(fp_, "[ CallExpression\n");
1511 node->callee()->accept(this);
1512 for (size_t i = 0; i < node->arguments()->length(); i++)
1513 node->arguments()->at(i)->accept(this);
1516 void visitFunctionTypeStatement(FunctionTypeStatement *node) {
1518 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
1520 dump(node->signature());
1523 void visitFunctionStatement(FunctionStatement *node) {
1525 fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
1527 dump(node->signature());
1529 node->body()->accept(this);
1532 void visitExpressionStatement(ExpressionStatement *node) {
1534 fprintf(fp_, "[ ExpressionStatement\n");
1536 node->expression()->accept(this);
1539 void visitAssignment(Assignment *node) {
1541 fprintf(fp_, "[ Assignment\n");
1543 node->lvalue()->accept(this);
1544 node->expression()->accept(this);
1547 void visitTernaryExpression(TernaryExpression *node) {
1549 fprintf(fp_, "[ TernaryExpression\n");
1551 node->condition()->accept(this);
1552 node->left()->accept(this);
1553 node->right()->accept(this);
1556 void visitBinaryExpression(BinaryExpression *node) {
1558 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1560 node->left()->accept(this);
1561 node->right()->accept(this);
1564 void visitUnaryExpression(UnaryExpression *node) {
1566 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1568 node->expression()->accept(this);
1571 void visitReturnStatement(ReturnStatement *node) {
1573 fprintf(fp_, "[ ReturnStatement\n");
1575 if (node->expression())
1576 node->expression()->accept(this);
1579 void visitForStatement(ForStatement *node) {
1581 fprintf(fp_, "[ ForStatement\n");
1583 if (node->initialization())
1584 node->initialization()->accept(this);
1585 if (node->condition())
1586 node->condition()->accept(this);
1588 node->update()->accept(this);
1589 node->body()->accept(this);
1592 void visitBlockStatement(BlockStatement *node) {
1594 fprintf(fp_, "[ BlockStatement\n");
1596 for (size_t i = 0; i < node->statements()->length(); i++)
1597 node->statements()->at(i)->accept(this);
1600 void visitVariableDeclaration(VariableDeclaration *node) {
1602 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
1604 if (node->initialization())
1605 node->initialization()->accept(this);
1608 void visitIntegerLiteral(IntegerLiteral *node) {
1610 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1612 void visitBooleanLiteral(BooleanLiteral *node) {
1614 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1615 (node->token() == TOK_TRUE) ? "true" : "false");
1617 void visitFloatLiteral(FloatLiteral *node) {
1619 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1621 void visitIfStatement(IfStatement *node) {
1623 fprintf(fp_, "[ IfStatement\n");
1625 node->ifTrue()->accept(this);
1626 if (node->ifFalse())
1627 node->ifFalse()->accept(this);
1630 void visitIndexExpression(IndexExpression *node) {
1632 fprintf(fp_, "[ IndexExpression\n");
1634 node->left()->accept(this);
1635 node->right()->accept(this);
1638 void visitEnumStatement(EnumStatement *node) {
1640 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1642 for (size_t i = 0; i < node->entries()->length(); i++) {
1644 fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
1645 if (node->entries()->at(i).expr) {
1647 node->entries()->at(i).expr->accept(this);
1653 void visitWhileStatement(WhileStatement *node) {
1655 fprintf(fp_, "[ WhileStatement (%s)\n",
1656 (node->token() == TOK_DO) ? "do" : "while");
1658 if (node->token() == TOK_DO) {
1659 node->condition()->accept(this);
1660 node->body()->accept(this);
1662 node->condition()->accept(this);
1663 node->body()->accept(this);
1667 void visitBreakStatement(BreakStatement *node) {
1669 fprintf(fp_, "[ BreakStatement\n");
1671 void visitContinueStatement(ContinueStatement *node) {
1673 fprintf(fp_, "[ ContinueStatement\n");
1675 void visitStringLiteral(StringLiteral *node) {
1677 fprintf(fp_, "[ StringLiteral\n");
1679 void visitIncDecExpression(IncDecExpression *node) {
1681 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1683 node->expression()->accept(this);
1686 void visitStructureStatement(StructureStatement *node) {
1688 fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
1690 void visitFieldExpression(FieldExpression *node) {
1692 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1694 node->left()->accept(this);
1697 void visitSwitchStatement(SwitchStatement *node) {
1699 fprintf(fp_, "[ SwitchStatement\n");
1701 node->expression()->accept(this);
1702 for (size_t i = 0; i < node->cases()->length(); i++) {
1703 Case *c = node->cases()->at(i);
1704 c->expression()->accept(this);
1706 for (size_t j = 0; j < c->others()->length(); j++)
1707 c->others()->at(j)->accept(this);
1710 c->statement()->accept(this);
1713 if (node->defaultCase())
1714 node->defaultCase()->accept(this);
1717 void visitArrayLiteral(ArrayLiteral *node) {
1719 fprintf(fp_, "[ ArrayLiteral\n");
1721 for (size_t i = 0; i < node->expressions()->length(); i++) {
1722 Expression *expr = node->expressions()->at(i);
1728 void visitImportStatement(ImportStatement *node) {
1730 fprintf(fp_, "[ ImportStatement\n");
1735 ParseTree::dump(FILE *fp)
1737 AstPrinter printer(fp);
1739 for (size_t i = 0; i < statements_->length(); i++)
1740 statements_->at(i)->accept(&printer);