Added missing file.
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::arrayLiteral(TokenKind kind)
144 assert(kind == TOK_LBRACE || kind == TOK_LBRACKET);
146 TokenKind close = (kind == TOK_LBRACE)
150 SourcePosition pos = scanner_.begin();
152 ExpressionList *list = new (pool_) ExpressionList();
157 Expression *expr = NULL;
158 if (kind == TOK_LBRACE) {
159 if (peek(TOK_LBRACE))
160 expr = arrayLiteral(TOK_LBRACE);
169 if (!list->append(expr))
172 if (!match(TOK_COMMA)) {
179 return new (pool_) ArrayLiteral(pos, kind, list);
185 switch (scanner_.peek()) {
189 Expression *expr = expression();
192 if (!expect(TOK_RPAREN))
199 Local<String> name(zone_, expectName());
202 return new (pool_) NameProxy(scanner_.begin(), name);
210 // Parses only old-style declarations.
212 Parser::typeAndName(Expression **type, String **namep)
214 if (match(TOK_LABEL)) {
215 // Old-style declaration:
217 Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
221 *type = new (pool_) NameProxy(scanner_.begin(), name);
222 *namep = expectName();
227 *namep = expectName();
232 // Parses both old and new style declarations.
234 Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
237 // NewDecl ::= Type Ident
238 // OldDecl ::= Label? (Ident | "...")
240 // Label ::= Ident ":"
242 if (match(TOK_LABEL)) {
243 // We something of the form:
246 Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
250 *type = new (pool_) NameProxy(scanner_.begin(), name);
251 if (kind == DeclArg && match(TOK_ELLIPSES)) {
254 if ((*namep = expectName()) == NULL)
260 Local<String> name(zone_, expectName());
264 if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
265 // We got something of the form:
267 *type = new (pool_) NameProxy(scanner_.begin(), name);
268 if (peek(TOK_NAME)) {
269 if ((*namep = expectName()) == NULL)
277 // We got something of the form:
285 Parser::call(Expression *callee)
287 ExpressionList *arguments = new (pool_) ExpressionList();
289 SourcePosition pos = scanner_.begin();
292 if (!match(TOK_RPAREN)) {
294 Expression *expr = expression();
298 if (!arguments->append(expr))
301 if (!match(TOK_COMMA))
305 if (!expect(TOK_RPAREN))
309 return new (pool_) CallExpression(pos, callee, arguments);
313 Parser::index(Expression *left)
315 expect(TOK_LBRACKET);
317 SourcePosition pos = scanner_.begin();
318 Expression *expr = expression();
322 if (!expect(TOK_RBRACKET))
325 return new (pool_) IndexExpression(pos, left, expr);
329 Parser::field(Expression *left)
333 SourcePosition pos = scanner_.begin();
334 Local<String> name(zone_, expectName());
338 return new (pool_) FieldExpression(pos, left, name);
344 Expression *expr = prefix();
349 switch (scanner_.peek()) {
351 if ((expr = call(expr)) == NULL)
356 if ((expr = index(expr)) == NULL)
361 if ((expr = field(expr)) == NULL)
374 TokenKind token = scanner_.peek();
376 SourcePosition pos = scanner_.begin();
382 Expression *expr = unary();
385 return new (pool_) IncDecExpression(pos, token, expr, false);
393 Expression *expr = unary();
396 return new (pool_) UnaryExpression(pos, token, expr);
402 if (!expect(TOK_LPAREN))
404 Expression *expr = unary();
407 if (!expect(TOK_RPAREN))
409 return new (pool_) UnaryExpression(pos, token, expr);
415 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
419 NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
421 Expression *expr = unary();
425 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
432 Expression *expr = primary();
434 token = scanner_.peek();
435 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
437 return new (pool_) IncDecExpression(pos, token, expr, true);
444 Parser::multiplication()
446 Expression *left = unary();
448 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
450 SourcePosition pos = scanner_.begin();
451 TokenKind kind = scanner_.last();
452 Expression *right = unary();
455 left = new (pool_) BinaryExpression(pos, kind, left, right);
463 Expression *left = multiplication();
465 if (!match(TOK_PLUS) && !match(TOK_MINUS))
467 SourcePosition pos = scanner_.begin();
468 TokenKind kind = scanner_.last();
469 Expression *right = multiplication();
472 left = new (pool_) BinaryExpression(pos, kind, left, right);
480 Expression *left = addition();
482 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
484 SourcePosition pos = scanner_.begin();
485 TokenKind kind = scanner_.last();
486 Expression *right = addition();
489 left = new (pool_) BinaryExpression(pos, kind, left, right);
497 Expression *left = shift();
499 if (!match(TOK_BITAND))
501 SourcePosition pos = scanner_.begin();
502 Expression *right = shift();
505 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
513 Expression *left = bitand_();
515 if (!match(TOK_BITXOR))
517 SourcePosition pos = scanner_.begin();
518 Expression *right = shift();
521 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
529 Expression *left = bitxor();
531 if (!match(TOK_BITOR))
533 SourcePosition pos = scanner_.begin();
534 Expression *right = bitxor();
537 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
545 Expression *left = bitor_();
547 TokenKind kind = scanner_.peek();
548 if (kind < TOK_LT || kind > TOK_GE)
551 SourcePosition pos = scanner_.begin();
552 Expression *right = shift();
555 left = new (pool_) BinaryExpression(pos, kind, left, right);
563 Expression *left = relational();
565 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
567 TokenKind kind = scanner_.last();
568 SourcePosition pos = scanner_.begin();
569 Expression *right = relational();
572 left = new (pool_) BinaryExpression(pos, kind, left, right);
580 Expression *left = equals();
584 SourcePosition pos = scanner_.begin();
585 Expression *right = equals();
588 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
596 Expression *left = and_();
600 SourcePosition pos = scanner_.begin();
601 Expression *right = and_();
604 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
612 Expression *cond = or_();
616 if (!match(TOK_QMARK))
620 SourcePosition pos = scanner_.begin();
621 AutoAllowTags<false> disableTags(scanner_);
623 if ((left = expression()) == NULL)
627 if (!expect(TOK_COLON))
630 Expression *right = expression();
634 return new (pool_) TernaryExpression(pos, cond, left, right);
640 Expression *left = ternary();
642 TokenKind token = scanner_.peek();
643 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
646 SourcePosition pos = scanner_.begin();
647 Expression *expr = ternary();
651 left = new (pool_) Assignment(pos, token, left, expr);
665 SourcePosition pos = scanner_.begin();
668 if (!expect(TOK_LPAREN))
671 Expression *condition = expression();
675 if (!expect(TOK_RPAREN))
679 if (scanner_.peek() == TOK_LBRACE)
682 body = localStatement();
686 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
692 SourcePosition pos = scanner_.begin();
696 if (scanner_.peek() == TOK_LBRACE)
699 body = localStatement();
703 if (!expect(TOK_WHILE))
706 if (!expect(TOK_LPAREN))
708 Expression *condition = expression();
711 if (!expect(TOK_RPAREN))
714 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
722 SourcePosition pos = scanner_.begin();
724 if (!expect(TOK_LPAREN))
726 Expression *expr = expression();
729 if (!expect(TOK_RPAREN))
732 if (!expect(TOK_LBRACE))
735 SourcePosition defaultPos;
736 PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
738 Statement *defaultCase = NULL;
740 while (!peek(TOK_RBRACE)) {
741 Expression *expr = NULL;
742 ExpressionList *others = NULL;
743 if (match(TOK_DEFAULT)) {
745 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
749 defaultPos = scanner_.begin();
752 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
756 if (!expect(TOK_CASE))
759 // A limitation in the grammar is that |case <NAME>:| will be
760 // detected as a label.
761 AutoAllowTags<false> disableTags(scanner_);
763 if ((expr = expression()) == NULL)
766 if (peek(TOK_COMMA)) {
767 others = new (pool_) ExpressionList();
768 while (match(TOK_COMMA)) {
769 Expression *other = expression();
772 if (!others->append(other))
778 if (!expect(TOK_COLON))
781 Statement *statement = localStatement();
785 if (!peek(TOK_CASE) &&
786 !peek(TOK_DEFAULT) &&
789 cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
794 Case *caze = new (pool_) Case(expr, others, statement);
795 if (!cases->append(caze))
798 defaultCase = statement;
802 if (!expect(TOK_RBRACE))
805 return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
809 Parser::forStatement()
811 SourcePosition pos = scanner_.begin();
813 if (!expect(TOK_LPAREN))
816 Statement *decl = NULL;
817 if (!match(TOK_SEMICOLON)) {
818 if (match(TOK_NEW)) {
819 if ((decl = vars(Qual_None)) == NULL)
822 if ((decl = expressionStatement()) == NULL)
825 if (!expect(TOK_SEMICOLON))
829 Expression *condition = NULL;
830 if (!match(TOK_SEMICOLON)) {
831 if ((condition = expression()) == NULL)
833 if (!expect(TOK_SEMICOLON))
837 Statement *update = NULL;
838 if (!match(TOK_RPAREN)) {
839 if ((update = expressionStatement()) == NULL)
841 if (!expect(TOK_RPAREN))
846 if (scanner_.peek() == TOK_LBRACE)
849 body = localStatement();
853 return new (pool_) ForStatement(pos, decl, condition, update, body);
859 ExpressionList *postDimensions = new (pool_) ExpressionList();
860 while (match(TOK_LBRACKET)) {
861 Expression *dim = NULL;
862 if (!match(TOK_RBRACKET)) {
863 if ((dim = expression()) == NULL)
865 if (!expect(TOK_RBRACKET))
869 if (!postDimensions->append(dim))
872 return postDimensions;
875 VariableDeclaration *
876 Parser::var(TypeQualifiers qual)
879 Local<String> name(zone_);
881 if (!typeAndName(&type, name.ref()))
884 ExpressionList *dims = NULL;
885 if (match(TOK_LBRACE)) {
886 if ((dims = dimensions()) == NULL)
890 SourcePosition pos = scanner_.begin();
892 Expression *expr = NULL;
893 if (match(TOK_ASSIGN)) {
894 switch (scanner_.peek()) {
895 // Note: we don't support [] literals yet.
897 if ((expr = arrayLiteral(scanner_.scan())) == NULL)
902 if ((expr = expression()) == NULL)
908 return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
912 Parser::vars(TypeQualifiers qual)
914 VariableDeclaration *decl = var(qual);
918 if (!peek(TOK_COMMA))
921 StatementList *statements = new (pool_) StatementList();
922 if (!statements->append(decl))
925 while (match(TOK_COMMA)) {
926 Statement *decl = var(qual);
929 if (!statements->append(decl))
933 // Create a fake-o block with no scope to create a statement list.
934 return new (pool_) BlockStatement(decl->pos(), statements);
938 Parser::returnStatement()
940 SourcePosition pos = scanner_.begin();
941 if (!expect(TOK_RETURN))
944 Expression *expr = NULL;
945 if (scanner_.peek() != TOK_SEMICOLON) {
946 if ((expr = expression()) == NULL)
949 // We only care about non-void returns when determining whether a
950 // tagless function is non-void.
951 encounteredReturn_ = true;
954 return new (pool_) ReturnStatement(pos, expr);
958 Parser::expressionStatement()
960 Expression *left = assignment();
964 return new (pool_) ExpressionStatement(left);
970 if (!expect(TOK_LBRACE))
973 SourcePosition pos = scanner_.begin();
975 StatementList *statements = new (pool_) StatementList();
976 while (!match(TOK_RBRACE)) {
977 Statement *statement = localStatement();
978 if (statement == NULL)
980 if (!statements->append(statement))
984 BlockStatement *block = new (pool_) BlockStatement(pos, statements);
993 SourcePosition pos = scanner_.begin();
994 if (!expect(TOK_LPAREN))
997 Expression *cond = expression();
1001 if (!expect(TOK_RPAREN))
1004 Statement *ifTrue = localStatement();
1008 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1010 IfStatement *last = outer;
1011 while (match(TOK_ELSE)) {
1012 if (!match(TOK_IF)) {
1013 Statement *ifFalse = localStatement();
1017 last->setIfFalse(ifFalse);
1021 SourcePosition pos = scanner_.begin();
1022 if (!expect(TOK_LPAREN))
1025 Expression *otherCond = expression();
1029 if (!expect(TOK_RPAREN))
1032 Statement *otherIfTrue = localStatement();
1036 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1037 last->setIfFalse(inner);
1045 Parser::localStatement()
1047 Statement *statement = NULL;
1049 // Statements which must be followed by a semicolon will break out of the
1050 // switch. If they may end in BlockStatements, they'll immediately return.
1052 TokenKind kind = scanner_.peek();
1057 TypeQualifiers quals = (kind == TOK_CONST)
1061 if ((statement = vars(quals)) == NULL)
1067 return forStatement();
1074 statement = new (pool_) BreakStatement(scanner_.begin());
1079 statement = new (pool_) ContinueStatement(scanner_.begin());
1083 if ((statement = do_()) == NULL)
1088 if ((statement = returnStatement()) == NULL)
1093 if ((statement = enum_()) == NULL)
1098 if ((statement = struct_()) == NULL)
1116 if ((statement = expressionStatement()) == NULL)
1120 if (!expect(TOK_SEMICOLON))
1131 Local<String> name(zone_, expectName());
1135 SourcePosition pos = scanner_.begin();
1137 if (!expect(TOK_LBRACE))
1140 FieldList *fields = new (pool_) FieldList();
1142 while (!peek(TOK_RBRACE)) {
1144 Local<String> fieldName(zone_);
1146 if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
1149 SourcePosition pos = scanner_.begin();
1151 if (!matchSemicolon())
1154 StructureStatement::Field *field =
1155 new (pool_) StructureStatement::Field(pos, type, fieldName);
1156 if (!field || !fields->append(field))
1160 if (!expect(TOK_RBRACE))
1163 if (fields->empty()) {
1164 cc_.reportError(pos, Message_StructCantBeEmpty);
1168 return new (pool_) StructureStatement(pos, name, fields);
1176 SourcePosition pos = scanner_.begin();
1178 Local<String> name(zone_);
1179 if (matchName(name.ref()) && !name)
1182 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1184 if (!expect(TOK_LBRACE))
1188 if (scanner_.peek() == TOK_RBRACE)
1191 Local<String> name(zone_, expectName());
1195 Expression *expr = NULL;
1196 if (match(TOK_ASSIGN)) {
1197 if ((expr = expression()) == NULL)
1201 if (!entries->append(EnumStatement::Entry(name, expr)))
1203 } while (match(TOK_COMMA));
1204 if (!expect(TOK_RBRACE))
1207 return new (pool_) EnumStatement(pos, name, entries);
1211 static inline ScopedRoot<T> *
1212 NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
1214 ScopedRoot<T> *root = pool.alloc<ScopedRoot<T> >();
1215 new (root) ScopedRoot<T>(obj);
1222 NameList *names = new (pool_) NameList();
1224 SourcePosition pos = scanner_.begin();
1226 Local<String> name(zone_, expectName());
1227 if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
1230 TokenKind suffix = TOK_NONE;
1231 while (match(TOK_DOT)) {
1232 if (match(TOK_STAR)) {
1237 if ((name = expectName()) == NULL)
1240 if (!names->append(NewScopedRoot<String>(pool_, name)))
1244 return new (pool_) ImportStatement(pos, names, suffix);
1248 Parser::function(TokenKind token)
1250 Expression *returnType;
1251 Local<String> name(zone_);
1253 if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
1256 SourcePosition pos = scanner_.begin();
1257 ParameterList *parameters = new (pool_) ParameterList();
1259 if (!expect(TOK_LPAREN))
1262 bool variadic = false;
1264 if (!match(TOK_RPAREN)) {
1266 bool isConst = match(TOK_CONST);
1267 bool ref = match(TOK_AMPERSAND);
1269 SourcePosition begin = scanner_.begin();
1271 Local<String> name(zone_);
1272 if (!fullTypeAndName(&type, name.ref(), DeclArg))
1276 if (isConst || ref) {
1277 cc_.reportError(begin, Message_InvalidVarArgs);
1281 if (token != TOK_NATIVE) {
1282 cc_.reportError(begin, Message_VarArgsOutsideNative);
1290 Expression *expr = NULL;
1291 if (match(TOK_ASSIGN)) {
1292 if ((expr = expression()) == NULL)
1296 Parameter *parameter = new (pool_) Parameter(name, type, ref, isConst, expr, begin);
1297 if (!parameters->append(parameter))
1300 if (!match(TOK_COMMA))
1303 if (!expect(TOK_RPAREN))
1307 encounteredReturn_ = false;
1309 Statement *body = NULL;
1310 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1316 FunctionSignature signature(returnType, parameters, variadic);
1317 if (token == TOK_TYPEDEF)
1318 return new (pool_) FunctionTypeStatement(pos, name, signature);
1320 return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
1324 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1326 Local<String> tag(zone, zone->makeSymbol(name));
1331 return false; //return !!scope->declareType(tag, type);
1335 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1337 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1339 return DeclareIntrinsicType(zone, scope, name, primitive);
1343 Parser::setupIntrinsics()
1346 if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1348 if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1350 if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1352 if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1355 Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1356 if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1359 Local<Type> voidType(zone_, zone_->types()->getVoid());
1360 if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1363 Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1364 if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1373 StatementList *statements = new (pool_) StatementList();
1375 if (!setupIntrinsics())
1379 Statement *statement = NULL;
1381 TokenKind kind = scanner_.peek();
1390 if ((statement = function(TOK_NAME)) == NULL)
1397 if (statements->length())
1398 cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
1399 ImportStatement *stmt = import();
1402 if (!imports_->append(stmt))
1404 if (!matchSemicolon())
1416 if (kind != TOK_LABEL)
1418 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1419 TypeQualifiers quals = TypeQualifiers(Qual_Public | Qual_Const);
1420 if ((statement = var(quals)) == NULL)
1422 if (!matchSemicolon())
1425 if ((statement = function(kind)) == NULL)
1427 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1436 TypeQualifiers quals = (kind == TOK_NEW) ? Qual_Const : Qual_None;
1437 // Note: at global scope, we don't accept comma-delimited
1438 // declarations yet, to see if we can get away with forcing
1439 // a nicer top-level style.
1441 if ((statement = var(quals)) == NULL)
1443 if (!matchSemicolon())
1449 if ((statement = enum_()) == NULL)
1451 if (!matchSemicolon())
1456 if ((statement = struct_()) == NULL)
1458 if (!matchSemicolon())
1463 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1470 if (!statements->append(statement))
1474 return new (pool_) ParseTree(statements, unbound_, imports_);
1477 class AstPrinter : public AstVisitor
1484 for (size_t i = 0; i < level_; i++)
1495 AstPrinter(FILE *fp)
1501 void dump(const FunctionSignature &sig) {
1503 fprintf(fp_, "()\n");
1505 void visitNameProxy(NameProxy *name) {
1507 fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
1509 void visitCallExpression(CallExpression *node) {
1511 fprintf(fp_, "[ CallExpression\n");
1513 node->callee()->accept(this);
1514 for (size_t i = 0; i < node->arguments()->length(); i++)
1515 node->arguments()->at(i)->accept(this);
1518 void visitFunctionTypeStatement(FunctionTypeStatement *node) {
1520 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
1522 dump(node->signature());
1525 void visitFunctionStatement(FunctionStatement *node) {
1527 fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
1529 dump(node->signature());
1531 node->body()->accept(this);
1534 void visitExpressionStatement(ExpressionStatement *node) {
1536 fprintf(fp_, "[ ExpressionStatement\n");
1538 node->expression()->accept(this);
1541 void visitAssignment(Assignment *node) {
1543 fprintf(fp_, "[ Assignment\n");
1545 node->lvalue()->accept(this);
1546 node->expression()->accept(this);
1549 void visitTernaryExpression(TernaryExpression *node) {
1551 fprintf(fp_, "[ TernaryExpression\n");
1553 node->condition()->accept(this);
1554 node->left()->accept(this);
1555 node->right()->accept(this);
1558 void visitBinaryExpression(BinaryExpression *node) {
1560 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1562 node->left()->accept(this);
1563 node->right()->accept(this);
1566 void visitUnaryExpression(UnaryExpression *node) {
1568 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1570 node->expression()->accept(this);
1573 void visitReturnStatement(ReturnStatement *node) {
1575 fprintf(fp_, "[ ReturnStatement\n");
1577 if (node->expression())
1578 node->expression()->accept(this);
1581 void visitForStatement(ForStatement *node) {
1583 fprintf(fp_, "[ ForStatement\n");
1585 if (node->initialization())
1586 node->initialization()->accept(this);
1587 if (node->condition())
1588 node->condition()->accept(this);
1590 node->update()->accept(this);
1591 node->body()->accept(this);
1594 void visitBlockStatement(BlockStatement *node) {
1596 fprintf(fp_, "[ BlockStatement\n");
1598 for (size_t i = 0; i < node->statements()->length(); i++)
1599 node->statements()->at(i)->accept(this);
1602 void visitVariableDeclaration(VariableDeclaration *node) {
1604 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
1606 if (node->initialization())
1607 node->initialization()->accept(this);
1610 void visitIntegerLiteral(IntegerLiteral *node) {
1612 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1614 void visitBooleanLiteral(BooleanLiteral *node) {
1616 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1617 (node->token() == TOK_TRUE) ? "true" : "false");
1619 void visitFloatLiteral(FloatLiteral *node) {
1621 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1623 void visitIfStatement(IfStatement *node) {
1625 fprintf(fp_, "[ IfStatement\n");
1627 node->ifTrue()->accept(this);
1628 if (node->ifFalse())
1629 node->ifFalse()->accept(this);
1632 void visitIndexExpression(IndexExpression *node) {
1634 fprintf(fp_, "[ IndexExpression\n");
1636 node->left()->accept(this);
1637 node->right()->accept(this);
1640 void visitEnumStatement(EnumStatement *node) {
1642 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1644 for (size_t i = 0; i < node->entries()->length(); i++) {
1646 fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
1647 if (node->entries()->at(i).expr) {
1649 node->entries()->at(i).expr->accept(this);
1655 void visitWhileStatement(WhileStatement *node) {
1657 fprintf(fp_, "[ WhileStatement (%s)\n",
1658 (node->token() == TOK_DO) ? "do" : "while");
1660 if (node->token() == TOK_DO) {
1661 node->condition()->accept(this);
1662 node->body()->accept(this);
1664 node->condition()->accept(this);
1665 node->body()->accept(this);
1669 void visitBreakStatement(BreakStatement *node) {
1671 fprintf(fp_, "[ BreakStatement\n");
1673 void visitContinueStatement(ContinueStatement *node) {
1675 fprintf(fp_, "[ ContinueStatement\n");
1677 void visitStringLiteral(StringLiteral *node) {
1679 fprintf(fp_, "[ StringLiteral\n");
1681 void visitIncDecExpression(IncDecExpression *node) {
1683 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1685 node->expression()->accept(this);
1688 void visitStructureStatement(StructureStatement *node) {
1690 fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
1692 void visitFieldExpression(FieldExpression *node) {
1694 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1696 node->left()->accept(this);
1699 void visitSwitchStatement(SwitchStatement *node) {
1701 fprintf(fp_, "[ SwitchStatement\n");
1703 node->expression()->accept(this);
1704 for (size_t i = 0; i < node->cases()->length(); i++) {
1705 Case *c = node->cases()->at(i);
1706 c->expression()->accept(this);
1708 for (size_t j = 0; j < c->others()->length(); j++)
1709 c->others()->at(j)->accept(this);
1712 c->statement()->accept(this);
1715 if (node->defaultCase())
1716 node->defaultCase()->accept(this);
1719 void visitArrayLiteral(ArrayLiteral *node) {
1721 fprintf(fp_, "[ ArrayLiteral\n");
1723 for (size_t i = 0; i < node->expressions()->length(); i++) {
1724 Expression *expr = node->expressions()->at(i);
1730 void visitImportStatement(ImportStatement *node) {
1732 fprintf(fp_, "[ ImportStatement\n");
1737 ParseTree::dump(FILE *fp)
1739 AstPrinter printer(fp);
1741 for (size_t i = 0; i < statements_->length(); i++)
1742 statements_->at(i)->accept(&printer);