Implemented callbacks.
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();
133 Local<String> name(zone_, expectName());
139 case TOK_FLOAT_LITERAL:
142 double value = Scanner::ParseDouble(scanner_.literal());
143 return new (pool_) FloatLiteral(scanner_.begin(), value);
146 case TOK_INTEGER_LITERAL:
149 int value = atoi(scanner_.literal());
150 return new (pool_) IntegerLiteral(scanner_.begin(), value);
156 return new (pool_) BooleanLiteral(scanner_.begin(), kind);
158 case TOK_STRING_LITERAL:
161 Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
164 memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
165 return new (pool_) StringLiteral(scanner_.begin(), array);
170 if (kind != TOK_ERROR)
171 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
180 switch (scanner_.peek()) {
184 Expression *expr = expression();
187 if (!expect(TOK_RPAREN))
198 Parser::call(Expression *callee)
200 ExpressionList *arguments = new (pool_) ExpressionList();
202 SourcePosition pos = scanner_.begin();
205 if (!match(TOK_RPAREN)) {
207 Expression *expr = expression();
211 if (!arguments->append(expr))
214 if (!match(TOK_COMMA))
218 if (!expect(TOK_RPAREN))
222 return new (pool_) CallExpression(pos, callee, arguments);
226 Parser::index(Expression *left)
228 expect(TOK_LBRACKET);
230 SourcePosition pos = scanner_.begin();
231 Expression *expr = expression();
235 if (!expect(TOK_RBRACKET))
238 return new (pool_) IndexExpression(pos, left, expr);
242 Parser::field(Expression *left)
246 SourcePosition pos = scanner_.begin();
247 Local<String> name(zone_, expectName());
251 return new (pool_) FieldExpression(pos, left, name);
257 Expression *expr = prefix();
262 switch (scanner_.peek()) {
264 if ((expr = call(expr)) == NULL)
269 if ((expr = index(expr)) == NULL)
274 if ((expr = field(expr)) == NULL)
287 TokenKind token = scanner_.peek();
289 SourcePosition pos = scanner_.begin();
295 Expression *expr = unary();
298 return new (pool_) IncDecExpression(pos, token, expr, false);
306 Expression *expr = unary();
309 return new (pool_) UnaryExpression(pos, token, expr);
315 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
319 BoundName *type = NULL;
321 type = bindType(tag);
323 Expression *expr = unary();
327 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, type);
334 Expression *expr = primary();
336 token = scanner_.peek();
337 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
339 return new (pool_) IncDecExpression(pos, token, expr, true);
346 Parser::multiplication()
348 Expression *left = unary();
350 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
352 SourcePosition pos = scanner_.begin();
353 TokenKind kind = scanner_.last();
354 Expression *right = unary();
357 left = new (pool_) BinaryExpression(pos, kind, left, right);
365 Expression *left = multiplication();
367 if (!match(TOK_PLUS) && !match(TOK_MINUS))
369 SourcePosition pos = scanner_.begin();
370 TokenKind kind = scanner_.last();
371 Expression *right = multiplication();
374 left = new (pool_) BinaryExpression(pos, kind, left, right);
382 Expression *left = addition();
384 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
386 SourcePosition pos = scanner_.begin();
387 TokenKind kind = scanner_.last();
388 Expression *right = addition();
391 left = new (pool_) BinaryExpression(pos, kind, left, right);
399 Expression *left = shift();
401 if (!match(TOK_BITAND))
403 SourcePosition pos = scanner_.begin();
404 Expression *right = shift();
407 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
415 Expression *left = bitand_();
417 if (!match(TOK_BITXOR))
419 SourcePosition pos = scanner_.begin();
420 Expression *right = shift();
423 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
431 Expression *left = bitxor();
433 if (!match(TOK_BITOR))
435 SourcePosition pos = scanner_.begin();
436 Expression *right = bitxor();
439 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
447 Expression *left = bitor_();
449 TokenKind kind = scanner_.peek();
450 if (kind < TOK_LT || kind > TOK_GE)
453 SourcePosition pos = scanner_.begin();
454 Expression *right = shift();
457 left = new (pool_) BinaryExpression(pos, kind, left, right);
465 Expression *left = relational();
467 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
469 TokenKind kind = scanner_.last();
470 SourcePosition pos = scanner_.begin();
471 Expression *right = relational();
474 left = new (pool_) BinaryExpression(pos, kind, left, right);
482 Expression *left = equals();
486 SourcePosition pos = scanner_.begin();
487 Expression *right = equals();
490 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
498 Expression *left = and_();
502 SourcePosition pos = scanner_.begin();
503 Expression *right = and_();
506 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
514 Expression *cond = or_();
518 if (!match(TOK_QMARK))
522 SourcePosition pos = scanner_.begin();
523 AutoAllowTags<false> disableTags(scanner_);
525 if ((left = expression()) == NULL)
529 if (!expect(TOK_COLON))
532 Expression *right = expression();
536 return new (pool_) TernaryExpression(pos, cond, left, right);
542 Expression *left = ternary();
544 TokenKind token = scanner_.peek();
545 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
548 SourcePosition pos = scanner_.begin();
549 Expression *expr = ternary();
553 left = new (pool_) Assignment(pos, token, left, expr);
567 SourcePosition pos = scanner_.begin();
570 if (!expect(TOK_LPAREN))
573 Expression *condition = expression();
577 if (!expect(TOK_RPAREN))
580 // Inside a loop, we force the creation of a scope object. Normally, we
581 // will cull scopes if they have no variables. However inside a loop,
582 // function calls that take references may compute a LIFO object, and to
583 // avoid temporarily leaking many such objects, we ensure that a scope
584 // is present so a LIFO slot can be allocated.
585 if (!enterScope(Scope::BLOCK))
589 if (scanner_.peek() == TOK_LBRACE)
590 body = block(scope_);
592 body = localStatement();
596 scope_ = scope_->enclosing();
597 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
603 SourcePosition pos = scanner_.begin();
606 // See the comment in ::while_() as to why we force a scope.
607 if (!enterScope(Scope::BLOCK))
611 if (scanner_.peek() == TOK_LBRACE)
612 body = block(scope_);
614 body = localStatement();
618 scope_ = scope_->enclosing();
620 if (!expect(TOK_WHILE))
623 if (!expect(TOK_LPAREN))
625 Expression *condition = expression();
628 if (!expect(TOK_RPAREN))
631 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
639 SourcePosition pos = scanner_.begin();
641 if (!expect(TOK_LPAREN))
643 Expression *expr = expression();
646 if (!expect(TOK_RPAREN))
649 if (!expect(TOK_LBRACE))
652 SourcePosition defaultPos;
653 PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
655 Statement *defaultCase = NULL;
657 while (!peek(TOK_RBRACE)) {
658 Expression *expr = NULL;
659 ExpressionList *others = NULL;
660 if (match(TOK_DEFAULT)) {
662 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
666 defaultPos = scanner_.begin();
669 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
673 if (!expect(TOK_CASE))
676 // A limitation in the grammar is that |case <NAME>:| will be
677 // detected as a label.
678 AutoAllowTags<false> disableTags(scanner_);
680 if ((expr = expression()) == NULL)
683 if (peek(TOK_COMMA)) {
684 others = new (pool_) ExpressionList();
685 while (match(TOK_COMMA)) {
686 Expression *other = expression();
689 if (!others->append(other))
695 if (!expect(TOK_COLON))
698 Statement *statement = localStatement();
702 if (!peek(TOK_CASE) &&
703 !peek(TOK_DEFAULT) &&
706 cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
711 Case *caze = new (pool_) Case(expr, others, statement);
712 if (!cases->append(caze))
715 defaultCase = statement;
719 if (!expect(TOK_RBRACE))
722 return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
726 Parser::forStatement()
728 SourcePosition pos = scanner_.begin();
730 if (!expect(TOK_LPAREN))
733 Statement *decl = NULL;
734 if (!match(TOK_SEMICOLON)) {
735 if (match(TOK_NEW)) {
736 if (!enterScope(Scope::BLOCK))
738 if ((decl = vars(TOK_STOCK, TOK_NEW)) == NULL)
741 if ((decl = expressionStatement()) == NULL)
744 if (!expect(TOK_SEMICOLON))
748 Expression *condition = NULL;
749 if (!match(TOK_SEMICOLON)) {
750 if ((condition = expression()) == NULL)
752 if (!expect(TOK_SEMICOLON))
756 Statement *update = NULL;
757 if (!match(TOK_RPAREN)) {
758 if ((update = expressionStatement()) == NULL)
760 if (!expect(TOK_RPAREN))
764 // See the comment in ::while_() as to why we force a scope.
765 if (!enterScope(Scope::BLOCK))
769 if (scanner_.peek() == TOK_LBRACE)
770 body = block(scope_);
772 body = localStatement();
776 scope_ = scope_->enclosing();
778 Scope *declScope = NULL;
779 if (decl && (decl->isVariableDeclaration() || decl->isBlockStatement())) {
780 declScope = scope_->unlinkIfEmpty();
781 scope_ = scope_->enclosing();
783 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
789 ExpressionList *postDimensions = new (pool_) ExpressionList();
790 while (match(TOK_LBRACKET)) {
791 Expression *dim = NULL;
792 if (!match(TOK_RBRACKET)) {
793 if ((dim = expression()) == NULL)
795 if (!expect(TOK_RBRACKET))
799 if (!postDimensions->append(dim))
802 return postDimensions;
805 VariableDeclaration *
806 Parser::var(TokenKind scope, TokenKind kind)
808 Local<String> tag(zone_);
809 if (matchName(tag.ref(), TOK_LABEL) && !tag)
812 BoundName *type = NULL;
814 type = bindType(tag);
816 Local<String> name(zone_, expectName());
820 if (BoundName *other = scope_->localLookup(name)) {
821 redeclarationError(other);
825 Variable *var = scope_->declareVariable(name, scanner_.begin());
829 if (scope == TOK_PUBLIC)
832 ExpressionList *postDimensions = NULL;
833 if (peek(TOK_LBRACKET)) {
834 if ((postDimensions = dimensions()) == NULL)
838 Expression *expr = NULL;
839 if (match(TOK_ASSIGN)) {
840 if ((expr = expression()) == NULL)
844 return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr);
848 Parser::vars(TokenKind scope, TokenKind kind)
850 VariableDeclaration *decl = var(scope, kind);
854 if (!peek(TOK_COMMA))
857 StatementList *statements = new (pool_) StatementList();
858 if (!statements->append(decl))
861 while (match(TOK_COMMA)) {
862 Statement *decl = var(scope, kind);
865 if (!statements->append(decl))
869 // Create a fake-o block with no scope to create a statement list.
870 return new (pool_) BlockStatement(decl->pos(), NULL, statements);
874 Parser::returnStatement()
876 SourcePosition pos = scanner_.begin();
877 if (!expect(TOK_RETURN))
880 Expression *expr = NULL;
881 if (scanner_.peek() != TOK_SEMICOLON) {
882 if ((expr = expression()) == NULL)
885 // We only care about non-void returns when determining whether a
886 // tagless function is non-void.
887 encounteredReturn_ = true;
890 return new (pool_) ReturnStatement(pos, expr);
894 Parser::expressionStatement()
896 Expression *left = assignment();
900 return new (pool_) ExpressionStatement(left);
904 Parser::block(Scope *scope)
906 if (!expect(TOK_LBRACE))
909 SourcePosition pos = scanner_.begin();
910 if (!scope && !enterScope(Scope::BLOCK))
913 StatementList *statements = new (pool_) StatementList();
914 while (!match(TOK_RBRACE)) {
915 Statement *statement = localStatement();
916 if (statement == NULL)
918 if (!statements->append(statement))
923 scope = scope_->unlinkIfEmpty();
924 scope_ = scope_->enclosing();
926 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
935 SourcePosition pos = scanner_.begin();
936 if (!expect(TOK_LPAREN))
939 Expression *cond = expression();
943 if (!expect(TOK_RPAREN))
946 Statement *ifTrue = localStatement();
950 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
952 IfStatement *last = outer;
953 while (match(TOK_ELSE)) {
954 if (!match(TOK_IF)) {
955 Statement *ifFalse = localStatement();
959 last->setIfFalse(ifFalse);
963 SourcePosition pos = scanner_.begin();
964 if (!expect(TOK_LPAREN))
967 Expression *otherCond = expression();
971 if (!expect(TOK_RPAREN))
974 Statement *otherIfTrue = localStatement();
978 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
979 last->setIfFalse(inner);
987 Parser::localStatement()
989 Statement *statement = NULL;
991 // Statements which must be followed by a semicolon will break out of the
992 // switch. If they may end in BlockStatements, they'll immediately return.
994 TokenKind kind = scanner_.peek();
999 if ((statement = vars(TOK_STOCK, kind)) == NULL)
1004 return forStatement();
1011 statement = new (pool_) BreakStatement(scanner_.begin());
1016 statement = new (pool_) ContinueStatement(scanner_.begin());
1020 if ((statement = do_()) == NULL)
1025 if ((statement = returnStatement()) == NULL)
1030 if ((statement = enum_()) == NULL)
1035 if ((statement = struct_()) == NULL)
1053 if ((statement = expressionStatement()) == NULL)
1057 if (!expect(TOK_SEMICOLON))
1068 Local<String> name(zone_, expectName());
1072 SourcePosition pos = scanner_.begin();
1074 if (BoundName *other = scope_->localLookup(name)) {
1075 redeclarationError(other);
1080 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1083 if (!expect(TOK_LBRACE))
1086 FieldList *fields = new (pool_) FieldList();
1088 while (!peek(TOK_RBRACE)) {
1089 if (matchName(name.ref(), TOK_LABEL) && !name)
1092 BoundName *type = NULL;
1094 if ((type = bindType(name)) == NULL)
1098 name = expectName();
1102 SourcePosition pos = scanner_.begin();
1104 ExpressionList *postDimensions = NULL;
1105 //if (peek(TOK_LBRACKET)) {
1106 // if ((postDimensions = dimensions()) == NULL)
1110 if (!matchSemicolon())
1113 StructureStatement::Field *field =
1114 new (pool_) StructureStatement::Field(pos, type, name, postDimensions);
1115 if (!field || !fields->append(field))
1119 if (!expect(TOK_RBRACE))
1122 return new (pool_) StructureStatement(pos, type, fields);
1130 NamedType *type = NULL;
1131 SourcePosition pos = scanner_.begin();
1133 Local<String> name(zone_);
1134 if (matchName(name.ref())) {
1138 if (BoundName *other = scope_->localLookup(name)) {
1139 redeclarationError(other);
1143 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1147 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1149 if (!expect(TOK_LBRACE))
1153 if (scanner_.peek() == TOK_RBRACE)
1156 Local<String> name(zone_, expectName());
1160 if (BoundName *other = scope_->localLookup(name)) {
1161 redeclarationError(other);
1165 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
1169 Expression *expr = NULL;
1170 if (match(TOK_ASSIGN)) {
1171 if ((expr = expression()) == NULL)
1175 if (!entries->append(EnumStatement::Entry(constant, expr)))
1177 } while (match(TOK_COMMA));
1178 if (!expect(TOK_RBRACE))
1181 return new (pool_) EnumStatement(pos, type, name, entries);
1185 Parser::function(TokenKind token)
1187 Local<String> returnTag(zone_);
1188 if (token == TOK_LABEL) {
1189 returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1195 if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
1199 BoundName *returnType = NULL;
1201 returnType = bindType(returnTag);
1203 Local<String> name(zone_, expectName());
1207 SourcePosition pos = scanner_.begin();
1209 // The function name goes into the outer (global) scope.
1210 assert(!scope_->enclosing());
1212 NamedType *type = NULL;
1213 NamedFunction *fun = NULL;
1214 if (BoundName *other = scope_->localLookup(name)) {
1215 // We allow a redeclaration if the new type is a public, and the old
1216 // type was a forward. However, the forward must come first.
1217 if (token == TOK_TYPEDEF || other->kind() != BoundName::FUNCTION) {
1218 redeclarationError(other);
1222 fun = other->toNamedFunction();
1223 if (!fun->isForward() || token != TOK_PUBLIC) {
1224 redeclarationError(other);
1228 // We've got the same name, but the original is a forward, so let it
1229 // slide and re-use the original declaration.
1230 fun->setImplemented(scanner_.begin());
1231 } else if (token == TOK_TYPEDEF) {
1232 type = scope_->declareType(name, scanner_.begin());
1236 fun = scope_->declareFunction(name, scanner_.begin(), token);
1241 if (fun && fun->isPublic())
1244 Scope *scope = enterScope(Scope::FUNCTION);
1248 ParameterList *parameters = new (pool_) ParameterList();
1250 if (!expect(TOK_LPAREN))
1253 if (!match(TOK_RPAREN)) {
1255 bool isConst = match(TOK_CONST);
1256 bool ref = match(TOK_AMPERSAND);
1258 SourcePosition begin = scanner_.begin();
1259 Local<String> tag(zone_);
1260 if (matchName(tag.ref(), TOK_LABEL) && !tag)
1263 BoundName *type = NULL;
1265 type = bindType(tag);
1267 if (match(TOK_ELLIPSES)) {
1268 if (isConst || ref) {
1269 cc_.reportError(begin, Message_InvalidVarArgs);
1273 if (token != TOK_NATIVE) {
1274 cc_.reportError(begin, Message_VarArgsOutsideNative);
1278 fun->markNativeVariadic();
1282 Local<String> name(zone_, expectName());
1286 if (BoundName *other = scope_->localLookup(name)) {
1287 redeclarationError(other);
1290 Variable *arg = scope_->declareArgument(name, scanner_.begin());
1294 // Look for dimensions.
1295 ExpressionList *postDimensions = NULL;
1296 if (peek(TOK_LBRACKET)) {
1297 if ((postDimensions = dimensions()) == NULL)
1301 Expression *expr = NULL;
1302 if (match(TOK_ASSIGN)) {
1303 if ((expr = expression()) == NULL)
1307 Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
1309 if (!parameters->append(parameter))
1312 if (!match(TOK_COMMA))
1315 if (!expect(TOK_RPAREN))
1319 encounteredReturn_ = false;
1321 Statement *body = NULL;
1322 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1328 scope_ = scope_->enclosing();
1330 FunctionSignature signature(returnType, parameters);
1331 if (token == TOK_TYPEDEF)
1332 return new (pool_) FunctionTypeStatement(pos, type, signature);
1334 return new (pool_) FunctionStatement(pos, scope, fun, body, signature, encounteredReturn_);
1338 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1340 Local<String> tag(zone, zone->makeSymbol(name));
1344 return !!scope->declareType(tag, type);
1348 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1350 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1352 return DeclareIntrinsicType(zone, scope, name, primitive);
1356 Parser::setupIntrinsics()
1358 if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1360 if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1362 if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1364 if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1367 Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1368 if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1371 Local<Type> voidType(zone_, zone_->types()->getVoid());
1372 if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1375 Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1376 if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1385 StatementList *statements = new (pool_) StatementList();
1387 if (!enterScope(Scope::GLOBAL))
1390 if (!setupIntrinsics())
1394 Statement *statement = NULL;
1396 TokenKind kind = scanner_.peek();
1405 if ((statement = function(TOK_NAME)) == NULL)
1417 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1418 if ((statement = var(TOK_PUBLIC, scanner_.scan())) == NULL)
1420 if (!matchSemicolon())
1423 if ((statement = function(kind)) == NULL)
1425 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1434 // Note: at global scope, we don't accept comma-delimited
1435 // declarations yet, to see if we can get away with forcing
1436 // a nicer top-level style.
1438 if ((statement = var(TOK_STOCK, kind)) == NULL)
1440 if (!matchSemicolon())
1446 if ((statement = enum_()) == NULL)
1448 if (!matchSemicolon())
1453 if ((statement = struct_()) == NULL)
1455 if (!matchSemicolon())
1460 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1467 if (!statements->append(statement))
1471 return new (pool_) ParseTree(scope_, statements, unbound_);
1474 class AstPrinter : public AstVisitor
1481 for (size_t i = 0; i < level_; i++)
1492 AstPrinter(FILE *fp)
1498 void visit(NameProxy *name) {
1500 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1501 (name->binding() ? "" : " unbound"));
1503 void visit(CallExpression *node) {
1505 fprintf(fp_, "[ CallExpression\n");
1507 node->callee()->accept(this);
1508 for (size_t i = 0; i < node->arguments()->length(); i++)
1509 node->arguments()->at(i)->accept(this);
1512 void visit(FunctionTypeStatement *node) {
1514 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->decl()->name()->chars());
1516 void visit(FunctionStatement *node) {
1518 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1521 node->body()->accept(this);
1524 void visit(ExpressionStatement *node) {
1526 fprintf(fp_, "[ ExpressionStatement\n");
1528 node->expression()->accept(this);
1531 void visit(Assignment *node) {
1533 fprintf(fp_, "[ Assignment\n");
1535 node->lvalue()->accept(this);
1536 node->expression()->accept(this);
1539 void visit(TernaryExpression *node) {
1541 fprintf(fp_, "[ TernaryExpression\n");
1543 node->condition()->accept(this);
1544 node->left()->accept(this);
1545 node->right()->accept(this);
1548 void visit(BinaryExpression *node) {
1550 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1552 node->left()->accept(this);
1553 node->right()->accept(this);
1556 void visit(UnaryExpression *node) {
1558 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1560 node->expression()->accept(this);
1563 void visit(ReturnStatement *node) {
1565 fprintf(fp_, "[ ReturnStatement\n");
1567 if (node->expression())
1568 node->expression()->accept(this);
1571 void visit(ForStatement *node) {
1573 fprintf(fp_, "[ ForStatement\n");
1575 if (node->initialization())
1576 node->initialization()->accept(this);
1577 if (node->condition())
1578 node->condition()->accept(this);
1580 node->update()->accept(this);
1581 node->body()->accept(this);
1584 void visit(BlockStatement *node) {
1586 fprintf(fp_, "[ BlockStatement\n");
1588 for (size_t i = 0; i < node->statements()->length(); i++)
1589 node->statements()->at(i)->accept(this);
1592 void visit(VariableDeclaration *node) {
1594 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1596 if (node->initialization())
1597 node->initialization()->accept(this);
1600 void visit(IntegerLiteral *node) {
1602 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1604 void visit(BooleanLiteral *node) {
1606 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1607 (node->token() == TOK_TRUE) ? "true" : "false");
1609 void visit(FloatLiteral *node) {
1611 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1613 void visit(IfStatement *node) {
1615 fprintf(fp_, "[ IfStatement\n");
1617 node->ifTrue()->accept(this);
1618 if (node->ifFalse())
1619 node->ifFalse()->accept(this);
1622 void visit(IndexExpression *node) {
1624 fprintf(fp_, "[ IndexExpression\n");
1626 node->left()->accept(this);
1627 node->right()->accept(this);
1630 void visit(EnumStatement *node) {
1632 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1634 for (size_t i = 0; i < node->entries()->length(); i++) {
1636 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1637 if (node->entries()->at(i).expr) {
1639 node->entries()->at(i).expr->accept(this);
1645 void visit(WhileStatement *node) {
1647 fprintf(fp_, "[ WhileStatement (%s)\n",
1648 (node->token() == TOK_DO) ? "do" : "while");
1650 if (node->token() == TOK_DO) {
1651 node->condition()->accept(this);
1652 node->body()->accept(this);
1654 node->condition()->accept(this);
1655 node->body()->accept(this);
1659 void visit(BreakStatement *node) {
1661 fprintf(fp_, "[ BreakStatement\n");
1663 void visit(ContinueStatement *node) {
1665 fprintf(fp_, "[ ContinueStatement\n");
1667 void visit(StringLiteral *node) {
1669 fprintf(fp_, "[ StringLiteral\n");
1671 void visit(IncDecExpression *node) {
1673 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1675 node->expression()->accept(this);
1678 void visit(StructureStatement *node) {
1680 fprintf(fp_, "[ StructureStatement %s\n", node->decl()->name()->chars());
1682 void visit(FieldExpression *node) {
1684 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1686 node->left()->accept(this);
1689 void visit(SwitchStatement *node) {
1691 fprintf(fp_, "[ SwitchStatement\n");
1693 node->expression()->accept(this);
1694 for (size_t i = 0; i < node->cases()->length(); i++) {
1695 Case *c = node->cases()->at(i);
1696 c->expression()->accept(this);
1698 for (size_t j = 0; j < c->others()->length(); j++)
1699 c->others()->at(j)->accept(this);
1702 c->statement()->accept(this);
1705 if (node->defaultCase())
1706 node->defaultCase()->accept(this);
1712 ParseTree::dump(FILE *fp)
1714 AstPrinter printer(fp);
1716 for (size_t i = 0; i < statements_->length(); i++)
1717 statements_->at(i)->accept(&printer);