Add |from x import names| 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<String> string(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
126 return new (pool_) StringLiteral(scanner_.begin(), string);
131 if (kind != TOK_ERROR)
132 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
139 Parser::fixedArrayLiteral()
141 SourcePosition pos = scanner_.begin();
143 ExpressionList *list = new (pool_) ExpressionList();
145 // { } is an illegal array literal.
146 if (list->length() > 0 && match(TOK_LBRACE))
149 Expression *expr = NULL;
150 if (peek(TOK_LBRACE))
151 expr = fixedArrayLiteral();
157 if (!list->append(expr))
160 if (!match(TOK_COMMA)) {
161 if (!expect(TOK_RBRACE))
167 return new (pool_) ArrayLiteral(pos, TOK_LBRACE, list);
173 switch (scanner_.peek()) {
177 Expression *expr = expression();
180 if (!expect(TOK_RPAREN))
187 Local<String> name(zone_, expectName());
190 return new (pool_) NameProxy(scanner_.begin(), name);
198 // Parses only old-style declarations.
200 Parser::typeAndName(Expression **type, String **namep)
202 if (match(TOK_LABEL)) {
203 // Old-style declaration:
205 Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
209 *type = new (pool_) NameProxy(scanner_.begin(), name);
210 *namep = expectName();
215 *namep = expectName();
220 // Parses both old and new style declarations.
222 Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
224 // decl ::= newdecl | olddecl
225 // newdecl ::= Type Ident
226 // olddecl ::= Label? (Ident | "...")
228 // label ::= Ident ":"
230 if (match(TOK_LABEL)) {
231 // We something of the form:
234 Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
238 *type = new (pool_) NameProxy(scanner_.begin(), name);
239 if (kind == DeclArg && match(TOK_ELLIPSES)) {
242 if ((*namep = expectName()) == NULL)
248 Local<String> name(zone_, expectName());
252 if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
253 // We got something of the form:
255 *type = new (pool_) NameProxy(scanner_.begin(), name);
256 if (peek(TOK_NAME)) {
257 if ((*namep = expectName()) == NULL)
265 // We got something of the form:
273 Parser::call(Expression *callee)
275 ExpressionList *arguments = new (pool_) ExpressionList();
277 SourcePosition pos = scanner_.begin();
280 if (!match(TOK_RPAREN)) {
282 Expression *expr = expression();
286 if (!arguments->append(expr))
289 if (!match(TOK_COMMA))
293 if (!expect(TOK_RPAREN))
297 return new (pool_) CallExpression(pos, callee, arguments);
301 Parser::index(Expression *left)
303 expect(TOK_LBRACKET);
305 SourcePosition pos = scanner_.begin();
306 Expression *expr = expression();
310 if (!expect(TOK_RBRACKET))
313 return new (pool_) IndexExpression(pos, left, expr);
317 Parser::field(Expression *left)
321 SourcePosition pos = scanner_.begin();
322 Local<String> name(zone_, expectName());
326 return new (pool_) FieldExpression(pos, left, name);
332 Expression *expr = prefix();
337 switch (scanner_.peek()) {
339 if ((expr = call(expr)) == NULL)
344 if ((expr = index(expr)) == NULL)
349 if ((expr = field(expr)) == NULL)
362 TokenKind token = scanner_.peek();
364 SourcePosition pos = scanner_.begin();
370 Expression *expr = unary();
373 return new (pool_) IncDecExpression(pos, token, expr, false);
381 Expression *expr = unary();
384 return new (pool_) UnaryExpression(pos, token, expr);
390 if (!expect(TOK_LPAREN))
392 Expression *expr = unary();
395 if (!expect(TOK_RPAREN))
397 return new (pool_) UnaryExpression(pos, token, expr);
403 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
407 NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
409 Expression *expr = unary();
413 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
420 Expression *expr = primary();
422 token = scanner_.peek();
423 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
425 return new (pool_) IncDecExpression(pos, token, expr, true);
432 Parser::multiplication()
434 Expression *left = unary();
436 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
438 SourcePosition pos = scanner_.begin();
439 TokenKind kind = scanner_.last();
440 Expression *right = unary();
443 left = new (pool_) BinaryExpression(pos, kind, left, right);
451 Expression *left = multiplication();
453 if (!match(TOK_PLUS) && !match(TOK_MINUS))
455 SourcePosition pos = scanner_.begin();
456 TokenKind kind = scanner_.last();
457 Expression *right = multiplication();
460 left = new (pool_) BinaryExpression(pos, kind, left, right);
468 Expression *left = addition();
470 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
472 SourcePosition pos = scanner_.begin();
473 TokenKind kind = scanner_.last();
474 Expression *right = addition();
477 left = new (pool_) BinaryExpression(pos, kind, left, right);
485 Expression *left = shift();
487 if (!match(TOK_BITAND))
489 SourcePosition pos = scanner_.begin();
490 Expression *right = shift();
493 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
501 Expression *left = bitand_();
503 if (!match(TOK_BITXOR))
505 SourcePosition pos = scanner_.begin();
506 Expression *right = shift();
509 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
517 Expression *left = bitxor();
519 if (!match(TOK_BITOR))
521 SourcePosition pos = scanner_.begin();
522 Expression *right = bitxor();
525 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
533 Expression *left = bitor_();
535 TokenKind kind = scanner_.peek();
536 if (kind < TOK_LT || kind > TOK_GE)
539 SourcePosition pos = scanner_.begin();
540 Expression *right = shift();
543 left = new (pool_) BinaryExpression(pos, kind, left, right);
551 Expression *left = relational();
553 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
555 TokenKind kind = scanner_.last();
556 SourcePosition pos = scanner_.begin();
557 Expression *right = relational();
560 left = new (pool_) BinaryExpression(pos, kind, left, right);
568 Expression *left = equals();
572 SourcePosition pos = scanner_.begin();
573 Expression *right = equals();
576 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
584 Expression *left = and_();
588 SourcePosition pos = scanner_.begin();
589 Expression *right = and_();
592 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
600 Expression *cond = or_();
604 if (!match(TOK_QMARK))
608 SourcePosition pos = scanner_.begin();
609 AutoAllowTags<false> disableTags(scanner_);
611 if ((left = expression()) == NULL)
615 if (!expect(TOK_COLON))
618 Expression *right = expression();
622 return new (pool_) TernaryExpression(pos, cond, left, right);
628 Expression *left = ternary();
630 TokenKind token = scanner_.peek();
631 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
634 SourcePosition pos = scanner_.begin();
635 Expression *expr = ternary();
639 left = new (pool_) Assignment(pos, token, left, expr);
653 // while ::= "while" "(" expr ")" statement
654 SourcePosition pos = scanner_.begin();
657 if (!expect(TOK_LPAREN))
660 Expression *condition = expression();
664 if (!expect(TOK_RPAREN))
668 if (scanner_.peek() == TOK_LBRACE)
671 body = localStatement();
675 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
681 // do ::= "do" block "while" "(" expr ")"
682 SourcePosition pos = scanner_.begin();
685 Statement *body = block();
689 if (!expect(TOK_WHILE))
692 if (!expect(TOK_LPAREN))
694 Expression *condition = expression();
697 if (!expect(TOK_RPAREN))
700 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
706 // switch ::= "switch" "(" expr ")" "{" case* defaultcase? "}"
707 // case ::= "case" casevals ":" statement
708 // defaultcase ::= "default" ":" statement
712 SourcePosition pos = scanner_.begin();
714 if (!expect(TOK_LPAREN))
716 Expression *expr = expression();
719 if (!expect(TOK_RPAREN))
722 if (!expect(TOK_LBRACE))
725 SourcePosition defaultPos;
726 PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
728 Statement *defaultCase = NULL;
730 while (!peek(TOK_RBRACE)) {
731 Expression *expr = NULL;
732 ExpressionList *others = NULL;
733 if (match(TOK_DEFAULT)) {
735 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
739 defaultPos = scanner_.begin();
742 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
746 if (!expect(TOK_CASE))
749 // A limitation in the grammar is that |case <NAME>:| will be
750 // detected as a label.
751 AutoAllowTags<false> disableTags(scanner_);
753 if ((expr = expression()) == NULL)
756 if (peek(TOK_COMMA)) {
757 others = new (pool_) ExpressionList();
758 while (match(TOK_COMMA)) {
759 Expression *other = expression();
762 if (!others->append(other))
768 if (!expect(TOK_COLON))
771 Statement *statement = localStatement();
775 if (!peek(TOK_CASE) &&
776 !peek(TOK_DEFAULT) &&
779 cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
784 Case *caze = new (pool_) Case(expr, others, statement);
785 if (!cases->append(caze))
788 defaultCase = statement;
792 if (!expect(TOK_RBRACE))
795 return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
799 Parser::forStatement()
801 // for ::= "for" "(" forinit? ";" forcond? ";" forstep ")" statement
802 // forint ::= "new" vardecl |
805 // forstep ::= exprstmt
807 SourcePosition pos = scanner_.begin();
809 if (!expect(TOK_LPAREN))
812 Statement *decl = NULL;
813 if (!match(TOK_SEMICOLON)) {
814 if (match(TOK_NEW)) {
815 if ((decl = vars(TypeQual_None)) == NULL)
818 if ((decl = expressionStatement()) == NULL)
821 if (!expect(TOK_SEMICOLON))
825 Expression *condition = NULL;
826 if (!match(TOK_SEMICOLON)) {
827 if ((condition = expression()) == NULL)
829 if (!expect(TOK_SEMICOLON))
833 Statement *update = NULL;
834 if (!match(TOK_RPAREN)) {
835 if ((update = expressionStatement()) == NULL)
837 if (!expect(TOK_RPAREN))
842 if (scanner_.peek() == TOK_LBRACE)
845 body = localStatement();
849 return new (pool_) ForStatement(pos, decl, condition, update, body);
855 // dimensions ::= ("[" expr? "]")*
857 ExpressionList *postDimensions = new (pool_) ExpressionList();
858 while (match(TOK_LBRACKET)) {
859 Expression *dim = NULL;
860 if (!match(TOK_RBRACKET)) {
861 if ((dim = expression()) == NULL)
863 if (!expect(TOK_RBRACKET))
867 if (!postDimensions->append(dim))
870 return postDimensions;
873 VariableDeclaration *
874 Parser::var(TypeQualifiers qual)
876 // vardecl ::= decl ("=" expr)?
879 Local<String> name(zone_);
881 if (!typeAndName(&type, name.ref()))
884 ExpressionList *dims = NULL;
885 if (peek(TOK_LBRACKET)) {
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.
898 if ((expr = fixedArrayLiteral()) == NULL)
903 if ((expr = expression()) == NULL)
909 return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
913 Parser::vars(TypeQualifiers qual)
915 // localvars ::= ("new" | "const" | "decl") vardecl ("," vardecl)*
916 // globalvars ::= ("public" | "const" | "new" | "public" "const") vardecl
917 VariableDeclaration *decl = var(qual);
921 if (!peek(TOK_COMMA))
924 StatementList *statements = new (pool_) StatementList();
925 if (!statements->append(decl))
928 while (match(TOK_COMMA)) {
929 Statement *decl = var(qual);
932 if (!statements->append(decl))
936 // Create a fake-o block with no scope to create a statement list.
937 return new (pool_) BlockStatement(decl->pos(), statements, TOK_NEW);
941 Parser::returnStatement()
943 // return ::= "return" term |
946 SourcePosition pos = scanner_.begin();
947 if (!expect(TOK_RETURN))
950 Expression *expr = NULL;
951 if (scanner_.peek() != TOK_SEMICOLON) {
952 if ((expr = expression()) == NULL)
955 // We only care about non-void returns when determining whether a
956 // tagless function is non-void.
957 encounteredReturn_ = true;
960 return new (pool_) ReturnStatement(pos, expr);
964 Parser::expressionStatement()
967 Expression *left = assignment();
971 return new (pool_) ExpressionStatement(left);
977 // block ::= "{" statement* "}"
979 if (!expect(TOK_LBRACE))
982 SourcePosition pos = scanner_.begin();
984 StatementList *statements = new (pool_) StatementList();
985 while (!match(TOK_RBRACE)) {
986 Statement *statement = localStatement();
987 if (statement == NULL)
989 if (!statements->append(statement))
993 BlockStatement *block = new (pool_) BlockStatement(pos, statements, TOK_LBRACE);
1000 // if ::= "if" "(" expr ")" statement elseif* else?
1001 // elseif ::= "elseif" "(" expr ")" statement
1002 // else ::= "else" statement
1005 SourcePosition pos = scanner_.begin();
1006 if (!expect(TOK_LPAREN))
1009 Expression *cond = expression();
1013 if (!expect(TOK_RPAREN))
1016 Statement *ifTrue = localStatement();
1020 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1022 IfStatement *last = outer;
1023 while (match(TOK_ELSE)) {
1024 if (!match(TOK_IF)) {
1025 Statement *ifFalse = localStatement();
1029 last->setIfFalse(ifFalse);
1033 SourcePosition pos = scanner_.begin();
1034 if (!expect(TOK_LPAREN))
1037 Expression *otherCond = expression();
1041 if (!expect(TOK_RPAREN))
1044 Statement *otherIfTrue = localStatement();
1048 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1049 last->setIfFalse(inner);
1057 Parser::localStatement()
1059 // statement ::= stmt term
1060 // stmt ::= do | for | if | while | struct | enum |
1061 // localvars | return | switch | break | continue
1063 Statement *statement = NULL;
1065 // Statements which must be followed by a semicolon will break out of the
1066 // switch. If they may end in BlockStatements, they'll immediately return.
1068 TokenKind kind = scanner_.peek();
1073 TypeQualifiers quals = (kind == TOK_CONST)
1077 if ((statement = vars(quals)) == NULL)
1083 return forStatement();
1090 statement = new (pool_) BreakStatement(scanner_.begin());
1095 statement = new (pool_) ContinueStatement(scanner_.begin());
1099 if ((statement = do_()) == NULL)
1104 if ((statement = returnStatement()) == NULL)
1109 if ((statement = enum_()) == NULL)
1114 if ((statement = struct_()) == NULL)
1132 if ((statement = expressionStatement()) == NULL)
1136 if (!expect(TOK_SEMICOLON))
1145 // struct ::= "struct" name { struct_fields }
1146 // struct_fields ::= struct_field |
1147 // struct_field struct_fields
1148 // struct_field ::= label? name term
1151 Local<String> name(zone_, expectName());
1155 SourcePosition pos = scanner_.begin();
1157 if (!expect(TOK_LBRACE))
1160 FieldList *fields = new (pool_) FieldList();
1162 while (!peek(TOK_RBRACE)) {
1164 Local<String> fieldName(zone_);
1166 if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
1169 SourcePosition pos = scanner_.begin();
1171 if (!matchSemicolon())
1174 StructureStatement::Field *field =
1175 new (pool_) StructureStatement::Field(pos, type, fieldName);
1176 if (!field || !fields->append(field))
1180 if (!expect(TOK_RBRACE))
1183 if (fields->empty()) {
1184 cc_.reportError(pos, Message_StructCantBeEmpty);
1188 return new (pool_) StructureStatement(pos, name, fields);
1194 // enum ::= "enum" name? { enum_members? }
1195 // enum_members ::= enum_member ","? |
1196 // enum_member "," enum_members
1197 // enum_member ::= ident ("=" constexpr)?
1200 SourcePosition pos = scanner_.begin();
1202 Local<String> name(zone_);
1203 if (matchName(name.ref()) && !name)
1206 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1208 if (!expect(TOK_LBRACE))
1212 if (scanner_.peek() == TOK_RBRACE)
1215 SourcePosition pos = scanner_.begin();
1216 Local<String> name(zone_, expectName());
1220 Expression *expr = NULL;
1221 if (match(TOK_ASSIGN)) {
1222 if ((expr = expression()) == NULL)
1226 if (!entries->append(EnumStatement::Entry(name, expr, pos)))
1228 } while (match(TOK_COMMA));
1229 if (!expect(TOK_RBRACE))
1232 return new (pool_) EnumStatement(pos, name, entries);
1236 static inline ScopedRoot<T> *
1237 NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
1239 return new (pool) ScopedRoot<T>(obj);
1243 Parser::import(TokenKind kind)
1245 SourcePosition pos = scanner_.begin();
1247 // import ::= "from" import_path "import" import_names
1248 // | "import" import_path
1249 // | "import" import_path ".*"
1250 // import_path ::= name
1251 // | name "." import_path
1252 // import_names ::= "*"
1253 // | import_name_list
1254 // import_name_list ::= name
1255 // | name "," import_name_list
1257 Local<String> name(zone_, expectName());
1261 PathComponent *root = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
1262 PathComponent *current = root;
1264 // NULL namelist means that we do not import any names. An empty namelist
1265 // means we import all names.
1266 NameList *names = NULL;
1268 while (match(TOK_DOT)) {
1269 if (kind == TOK_IMPORT && match(TOK_STAR)) {
1270 names = new (pool_) NameList();
1274 if ((name = expectName()) == NULL)
1277 current->next = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
1278 current = current->next;
1281 if (kind == TOK_FROM) {
1282 if (!expect(TOK_IMPORT))
1285 names = new (pool_) NameList();
1287 if (!match(TOK_STAR)) {
1288 if (!matchName(name.address())) {
1289 cc_.reportError(scanner_.begin(), Message_BadImportFrom);
1293 if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
1296 while (match(TOK_COMMA)) {
1297 if ((name = expectName()) == NULL)
1299 if (!names->append(NewScopedRoot<String>(pool_, name)))
1305 return new (pool_) ImportStatement(pos, root, names);
1309 Parser::function(TokenKind token)
1311 Expression *returnType;
1312 Local<String> name(zone_);
1314 if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
1317 SourcePosition pos = scanner_.begin();
1318 ParameterList *parameters = new (pool_) ParameterList();
1320 if (!expect(TOK_LPAREN))
1323 bool variadic = false;
1325 if (!match(TOK_RPAREN)) {
1327 TypeQualifiers quals = TypeQual_None;
1328 if (match(TOK_CONST))
1329 quals = TypeQualifiers(quals | TypeQual_Const);
1331 bool ref = match(TOK_AMPERSAND);
1333 SourcePosition begin = scanner_.begin();
1335 Local<String> name(zone_);
1336 if (!fullTypeAndName(&type, name.ref(), DeclArg))
1340 if ((quals & TypeQual_Const) || ref) {
1341 cc_.reportError(begin, Message_InvalidVarArgs);
1345 if (token != TOK_NATIVE) {
1346 cc_.reportError(begin, Message_VarArgsOutsideNative);
1354 ExpressionList *dims = NULL;
1355 if (peek(TOK_LBRACKET)) {
1356 if ((dims = dimensions()) == NULL)
1360 Expression *expr = NULL;
1361 if (match(TOK_ASSIGN)) {
1362 if ((expr = expression()) == NULL)
1366 Parameter *parameter = new (pool_) Parameter(name, type, ref, quals, dims, expr, begin);
1367 if (!parameters->append(parameter))
1370 if (!match(TOK_COMMA))
1373 if (!expect(TOK_RPAREN))
1377 encounteredReturn_ = false;
1379 Statement *body = NULL;
1380 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1386 FunctionSignature signature(returnType, parameters, variadic);
1387 if (token == TOK_TYPEDEF)
1388 return new (pool_) FunctionTypeStatement(pos, name, signature);
1390 return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
1394 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1396 Local<String> tag(zone, zone->makeSymbol(name));
1401 return false; //return !!scope->declareType(tag, type);
1405 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1407 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1409 return DeclareIntrinsicType(zone, scope, name, primitive);
1415 StatementList *statements = new (pool_) StatementList();
1418 Statement *statement = NULL;
1420 TokenKind kind = scanner_.peek();
1429 if ((statement = function(TOK_NAME)) == NULL)
1437 if (statements->length())
1438 cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
1439 ImportStatement *stmt = import(kind);
1442 if (!imports_->append(stmt))
1444 if (!matchSemicolon())
1456 if (kind != TOK_LABEL)
1458 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1459 if ((statement = var(TypeQual_Const)) == NULL)
1461 if (!matchSemicolon())
1464 if ((statement = function(kind)) == NULL)
1466 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1475 TypeQualifiers quals = (kind == TOK_CONST) ? TypeQual_Const : TypeQual_None;
1476 // Note: at global scope, we don't accept comma-delimited
1477 // declarations yet, to see if we can get away with forcing
1478 // a nicer top-level style.
1480 if ((statement = var(quals)) == NULL)
1482 if (!matchSemicolon())
1488 if ((statement = enum_()) == NULL)
1490 if (!matchSemicolon())
1495 if ((statement = struct_()) == NULL)
1497 if (!matchSemicolon())
1502 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1509 if (!statements->append(statement))
1513 return new (pool_) ParseTree(statements, unbound_, imports_);
1516 class AstPrinter : public AstVisitor
1523 for (size_t i = 0; i < level_; i++)
1534 AstPrinter(FILE *fp)
1540 void dump(const FunctionSignature &sig) {
1542 fprintf(fp_, "()\n");
1544 void visitNameProxy(NameProxy *name) {
1546 fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
1548 void visitCallExpression(CallExpression *node) {
1550 fprintf(fp_, "[ CallExpression\n");
1552 node->callee()->accept(this);
1553 for (size_t i = 0; i < node->arguments()->length(); i++)
1554 node->arguments()->at(i)->accept(this);
1557 void visitFunctionTypeStatement(FunctionTypeStatement *node) {
1559 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
1561 dump(node->signature());
1564 void visitFunctionStatement(FunctionStatement *node) {
1566 fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
1568 dump(node->signature());
1570 node->body()->accept(this);
1573 void visitExpressionStatement(ExpressionStatement *node) {
1575 fprintf(fp_, "[ ExpressionStatement\n");
1577 node->expression()->accept(this);
1580 void visitAssignment(Assignment *node) {
1582 fprintf(fp_, "[ Assignment\n");
1584 node->lvalue()->accept(this);
1585 node->expression()->accept(this);
1588 void visitTernaryExpression(TernaryExpression *node) {
1590 fprintf(fp_, "[ TernaryExpression\n");
1592 node->condition()->accept(this);
1593 node->left()->accept(this);
1594 node->right()->accept(this);
1597 void visitBinaryExpression(BinaryExpression *node) {
1599 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1601 node->left()->accept(this);
1602 node->right()->accept(this);
1605 void visitUnaryExpression(UnaryExpression *node) {
1607 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1609 node->expression()->accept(this);
1612 void visitReturnStatement(ReturnStatement *node) {
1614 fprintf(fp_, "[ ReturnStatement\n");
1616 if (node->expression())
1617 node->expression()->accept(this);
1620 void visitForStatement(ForStatement *node) {
1622 fprintf(fp_, "[ ForStatement\n");
1624 if (node->initialization())
1625 node->initialization()->accept(this);
1626 if (node->condition())
1627 node->condition()->accept(this);
1629 node->update()->accept(this);
1630 node->body()->accept(this);
1633 void visitBlockStatement(BlockStatement *node) {
1635 fprintf(fp_, "[ BlockStatement\n");
1637 for (size_t i = 0; i < node->statements()->length(); i++)
1638 node->statements()->at(i)->accept(this);
1641 void visitVariableDeclaration(VariableDeclaration *node) {
1643 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
1645 if (node->initialization())
1646 node->initialization()->accept(this);
1649 void visitIntegerLiteral(IntegerLiteral *node) {
1651 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1653 void visitBooleanLiteral(BooleanLiteral *node) {
1655 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1656 (node->token() == TOK_TRUE) ? "true" : "false");
1658 void visitFloatLiteral(FloatLiteral *node) {
1660 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1662 void visitIfStatement(IfStatement *node) {
1664 fprintf(fp_, "[ IfStatement\n");
1666 node->ifTrue()->accept(this);
1667 if (node->ifFalse())
1668 node->ifFalse()->accept(this);
1671 void visitIndexExpression(IndexExpression *node) {
1673 fprintf(fp_, "[ IndexExpression\n");
1675 node->left()->accept(this);
1676 node->right()->accept(this);
1679 void visitEnumStatement(EnumStatement *node) {
1681 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1683 for (size_t i = 0; i < node->entries()->length(); i++) {
1685 fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
1686 if (node->entries()->at(i).expr) {
1688 node->entries()->at(i).expr->accept(this);
1694 void visitWhileStatement(WhileStatement *node) {
1696 fprintf(fp_, "[ WhileStatement (%s)\n",
1697 (node->token() == TOK_DO) ? "do" : "while");
1699 if (node->token() == TOK_DO) {
1700 node->condition()->accept(this);
1701 node->body()->accept(this);
1703 node->condition()->accept(this);
1704 node->body()->accept(this);
1708 void visitBreakStatement(BreakStatement *node) {
1710 fprintf(fp_, "[ BreakStatement\n");
1712 void visitContinueStatement(ContinueStatement *node) {
1714 fprintf(fp_, "[ ContinueStatement\n");
1716 void visitStringLiteral(StringLiteral *node) {
1718 fprintf(fp_, "[ StringLiteral\n");
1720 void visitIncDecExpression(IncDecExpression *node) {
1722 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1724 node->expression()->accept(this);
1727 void visitStructureStatement(StructureStatement *node) {
1729 fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
1731 void visitFieldExpression(FieldExpression *node) {
1733 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1735 node->left()->accept(this);
1738 void visitSwitchStatement(SwitchStatement *node) {
1740 fprintf(fp_, "[ SwitchStatement\n");
1742 node->expression()->accept(this);
1743 for (size_t i = 0; i < node->cases()->length(); i++) {
1744 Case *c = node->cases()->at(i);
1745 c->expression()->accept(this);
1747 for (size_t j = 0; j < c->others()->length(); j++)
1748 c->others()->at(j)->accept(this);
1751 c->statement()->accept(this);
1754 if (node->defaultCase())
1755 node->defaultCase()->accept(this);
1758 void visitArrayLiteral(ArrayLiteral *node) {
1760 fprintf(fp_, "[ ArrayLiteral\n");
1762 for (size_t i = 0; i < node->expressions()->length(); i++) {
1763 Expression *expr = node->expressions()->at(i);
1769 void visitImportStatement(ImportStatement *node) {
1771 fprintf(fp_, "[ ImportStatement\n");
1776 ParseTree::dump(FILE *fp)
1778 AstPrinter printer(fp);
1780 for (size_t i = 0; i < statements_->length(); i++)
1781 statements_->at(i)->accept(&printer);