Add support for array reference semantics.
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_HEX_LITERAL:
149 int value = strtol(scanner_.literal(), NULL, 16);
150 return new (pool_) IntegerLiteral(scanner_.begin(), value);
153 case TOK_INTEGER_LITERAL:
156 int value = atoi(scanner_.literal());
157 return new (pool_) IntegerLiteral(scanner_.begin(), value);
163 return new (pool_) BooleanLiteral(scanner_.begin(), kind);
165 case TOK_STRING_LITERAL:
168 Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
171 memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
172 return new (pool_) StringLiteral(scanner_.begin(), array);
177 if (kind != TOK_ERROR)
178 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
187 switch (scanner_.peek()) {
191 Expression *expr = expression();
194 if (!expect(TOK_RPAREN))
205 Parser::call(Expression *callee)
207 ExpressionList *arguments = new (pool_) ExpressionList();
209 SourcePosition pos = scanner_.begin();
212 if (!match(TOK_RPAREN)) {
214 Expression *expr = expression();
218 if (!arguments->append(expr))
221 if (!match(TOK_COMMA))
225 if (!expect(TOK_RPAREN))
229 return new (pool_) CallExpression(pos, callee, arguments);
233 Parser::index(Expression *left)
235 expect(TOK_LBRACKET);
237 SourcePosition pos = scanner_.begin();
238 Expression *expr = expression();
242 if (!expect(TOK_RBRACKET))
245 return new (pool_) IndexExpression(pos, left, expr);
249 Parser::field(Expression *left)
253 SourcePosition pos = scanner_.begin();
254 Local<String> name(zone_, expectName());
258 return new (pool_) FieldExpression(pos, left, name);
264 Expression *expr = prefix();
269 switch (scanner_.peek()) {
271 if ((expr = call(expr)) == NULL)
276 if ((expr = index(expr)) == NULL)
281 if ((expr = field(expr)) == NULL)
294 TokenKind token = scanner_.peek();
296 SourcePosition pos = scanner_.begin();
302 Expression *expr = unary();
305 return new (pool_) IncDecExpression(pos, token, expr, false);
313 Expression *expr = unary();
316 return new (pool_) UnaryExpression(pos, token, expr);
322 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
326 BoundName *type = NULL;
328 type = bindType(tag);
330 Expression *expr = unary();
334 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, type);
341 Expression *expr = primary();
343 token = scanner_.peek();
344 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
346 return new (pool_) IncDecExpression(pos, token, expr, true);
353 Parser::multiplication()
355 Expression *left = unary();
357 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
359 SourcePosition pos = scanner_.begin();
360 TokenKind kind = scanner_.last();
361 Expression *right = unary();
364 left = new (pool_) BinaryExpression(pos, kind, left, right);
372 Expression *left = multiplication();
374 if (!match(TOK_PLUS) && !match(TOK_MINUS))
376 SourcePosition pos = scanner_.begin();
377 TokenKind kind = scanner_.last();
378 Expression *right = multiplication();
381 left = new (pool_) BinaryExpression(pos, kind, left, right);
389 Expression *left = addition();
391 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
393 SourcePosition pos = scanner_.begin();
394 TokenKind kind = scanner_.last();
395 Expression *right = addition();
398 left = new (pool_) BinaryExpression(pos, kind, left, right);
406 Expression *left = shift();
408 if (!match(TOK_BITAND))
410 SourcePosition pos = scanner_.begin();
411 Expression *right = shift();
414 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
422 Expression *left = bitand_();
424 if (!match(TOK_BITXOR))
426 SourcePosition pos = scanner_.begin();
427 Expression *right = shift();
430 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
438 Expression *left = bitxor();
440 if (!match(TOK_BITOR))
442 SourcePosition pos = scanner_.begin();
443 Expression *right = bitxor();
446 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
454 Expression *left = bitor_();
456 TokenKind kind = scanner_.peek();
457 if (kind < TOK_LT || kind > TOK_GE)
460 SourcePosition pos = scanner_.begin();
461 Expression *right = shift();
464 left = new (pool_) BinaryExpression(pos, kind, left, right);
472 Expression *left = relational();
474 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
476 TokenKind kind = scanner_.last();
477 SourcePosition pos = scanner_.begin();
478 Expression *right = relational();
481 left = new (pool_) BinaryExpression(pos, kind, left, right);
489 Expression *left = equals();
493 SourcePosition pos = scanner_.begin();
494 Expression *right = equals();
497 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
505 Expression *left = and_();
509 SourcePosition pos = scanner_.begin();
510 Expression *right = and_();
513 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
521 Expression *cond = or_();
525 if (!match(TOK_QMARK))
529 SourcePosition pos = scanner_.begin();
530 AutoAllowTags<false> disableTags(scanner_);
532 if ((left = expression()) == NULL)
536 if (!expect(TOK_COLON))
539 Expression *right = expression();
543 return new (pool_) TernaryExpression(pos, cond, left, right);
549 Expression *left = ternary();
551 TokenKind token = scanner_.peek();
552 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
555 SourcePosition pos = scanner_.begin();
556 Expression *expr = ternary();
560 left = new (pool_) Assignment(pos, token, left, expr);
574 SourcePosition pos = scanner_.begin();
577 if (!expect(TOK_LPAREN))
580 Expression *condition = expression();
584 if (!expect(TOK_RPAREN))
587 // Inside a loop, we force the creation of a scope object. Normally, we
588 // will cull scopes if they have no variables. However inside a loop,
589 // function calls that take references may compute a LIFO object, and to
590 // avoid temporarily leaking many such objects, we ensure that a scope
591 // is present so a LIFO slot can be allocated.
592 if (!enterScope(Scope::BLOCK))
596 if (scanner_.peek() == TOK_LBRACE)
597 body = block(scope_);
599 body = localStatement();
603 scope_ = scope_->enclosing();
604 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
610 SourcePosition pos = scanner_.begin();
613 // See the comment in ::while_() as to why we force a scope.
614 if (!enterScope(Scope::BLOCK))
618 if (scanner_.peek() == TOK_LBRACE)
619 body = block(scope_);
621 body = localStatement();
625 scope_ = scope_->enclosing();
627 if (!expect(TOK_WHILE))
630 if (!expect(TOK_LPAREN))
632 Expression *condition = expression();
635 if (!expect(TOK_RPAREN))
638 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
646 SourcePosition pos = scanner_.begin();
648 if (!expect(TOK_LPAREN))
650 Expression *expr = expression();
653 if (!expect(TOK_RPAREN))
656 if (!expect(TOK_LBRACE))
659 SourcePosition defaultPos;
660 PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
662 Statement *defaultCase = NULL;
664 while (!peek(TOK_RBRACE)) {
665 Expression *expr = NULL;
666 ExpressionList *others = NULL;
667 if (match(TOK_DEFAULT)) {
669 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
673 defaultPos = scanner_.begin();
676 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
680 if (!expect(TOK_CASE))
683 // A limitation in the grammar is that |case <NAME>:| will be
684 // detected as a label.
685 AutoAllowTags<false> disableTags(scanner_);
687 if ((expr = expression()) == NULL)
690 if (peek(TOK_COMMA)) {
691 others = new (pool_) ExpressionList();
692 while (match(TOK_COMMA)) {
693 Expression *other = expression();
696 if (!others->append(other))
702 if (!expect(TOK_COLON))
705 Statement *statement = localStatement();
709 if (!peek(TOK_CASE) &&
710 !peek(TOK_DEFAULT) &&
713 cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
718 Case *caze = new (pool_) Case(expr, others, statement);
719 if (!cases->append(caze))
722 defaultCase = statement;
726 if (!expect(TOK_RBRACE))
729 return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
733 Parser::forStatement()
735 SourcePosition pos = scanner_.begin();
737 if (!expect(TOK_LPAREN))
740 Statement *decl = NULL;
741 if (!match(TOK_SEMICOLON)) {
742 if (match(TOK_NEW)) {
743 if (!enterScope(Scope::BLOCK))
745 if ((decl = vars(TOK_STOCK, TOK_NEW)) == NULL)
748 if ((decl = expressionStatement()) == NULL)
751 if (!expect(TOK_SEMICOLON))
755 Expression *condition = NULL;
756 if (!match(TOK_SEMICOLON)) {
757 if ((condition = expression()) == NULL)
759 if (!expect(TOK_SEMICOLON))
763 Statement *update = NULL;
764 if (!match(TOK_RPAREN)) {
765 if ((update = expressionStatement()) == NULL)
767 if (!expect(TOK_RPAREN))
771 // See the comment in ::while_() as to why we force a scope.
772 if (!enterScope(Scope::BLOCK))
776 if (scanner_.peek() == TOK_LBRACE)
777 body = block(scope_);
779 body = localStatement();
783 scope_ = scope_->enclosing();
785 Scope *declScope = NULL;
786 if (decl && (decl->isVariableDeclaration() || decl->isBlockStatement())) {
787 declScope = scope_->unlinkIfEmpty();
788 scope_ = scope_->enclosing();
790 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
796 ExpressionList *postDimensions = new (pool_) ExpressionList();
797 while (match(TOK_LBRACKET)) {
798 Expression *dim = NULL;
799 if (!match(TOK_RBRACKET)) {
800 if ((dim = expression()) == NULL)
802 if (!expect(TOK_RBRACKET))
806 if (!postDimensions->append(dim))
809 return postDimensions;
812 VariableDeclaration *
813 Parser::var(TokenKind scope, TokenKind kind)
815 Local<String> tag(zone_);
816 if (matchName(tag.ref(), TOK_LABEL) && !tag)
819 BoundName *type = NULL;
821 type = bindType(tag);
823 Local<String> name(zone_, expectName());
827 if (BoundName *other = scope_->localLookup(name)) {
828 redeclarationError(other);
832 Variable *var = scope_->declareVariable(name, scanner_.begin());
836 if (scope == TOK_PUBLIC)
839 ExpressionList *postDimensions = NULL;
840 if (peek(TOK_LBRACKET)) {
841 if ((postDimensions = dimensions()) == NULL)
845 Expression *expr = NULL;
846 if (match(TOK_ASSIGN)) {
847 if ((expr = expression()) == NULL)
851 return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr);
855 Parser::vars(TokenKind scope, TokenKind kind)
857 VariableDeclaration *decl = var(scope, kind);
861 if (!peek(TOK_COMMA))
864 StatementList *statements = new (pool_) StatementList();
865 if (!statements->append(decl))
868 while (match(TOK_COMMA)) {
869 Statement *decl = var(scope, kind);
872 if (!statements->append(decl))
876 // Create a fake-o block with no scope to create a statement list.
877 return new (pool_) BlockStatement(decl->pos(), NULL, statements);
881 Parser::returnStatement()
883 SourcePosition pos = scanner_.begin();
884 if (!expect(TOK_RETURN))
887 Expression *expr = NULL;
888 if (scanner_.peek() != TOK_SEMICOLON) {
889 if ((expr = expression()) == NULL)
892 // We only care about non-void returns when determining whether a
893 // tagless function is non-void.
894 encounteredReturn_ = true;
897 return new (pool_) ReturnStatement(pos, expr);
901 Parser::expressionStatement()
903 Expression *left = assignment();
907 return new (pool_) ExpressionStatement(left);
911 Parser::block(Scope *scope)
913 if (!expect(TOK_LBRACE))
916 SourcePosition pos = scanner_.begin();
917 if (!scope && !enterScope(Scope::BLOCK))
920 StatementList *statements = new (pool_) StatementList();
921 while (!match(TOK_RBRACE)) {
922 Statement *statement = localStatement();
923 if (statement == NULL)
925 if (!statements->append(statement))
930 scope = scope_->unlinkIfEmpty();
931 scope_ = scope_->enclosing();
933 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
942 SourcePosition pos = scanner_.begin();
943 if (!expect(TOK_LPAREN))
946 Expression *cond = expression();
950 if (!expect(TOK_RPAREN))
953 Statement *ifTrue = localStatement();
957 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
959 IfStatement *last = outer;
960 while (match(TOK_ELSE)) {
961 if (!match(TOK_IF)) {
962 Statement *ifFalse = localStatement();
966 last->setIfFalse(ifFalse);
970 SourcePosition pos = scanner_.begin();
971 if (!expect(TOK_LPAREN))
974 Expression *otherCond = expression();
978 if (!expect(TOK_RPAREN))
981 Statement *otherIfTrue = localStatement();
985 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
986 last->setIfFalse(inner);
994 Parser::localStatement()
996 Statement *statement = NULL;
998 // Statements which must be followed by a semicolon will break out of the
999 // switch. If they may end in BlockStatements, they'll immediately return.
1001 TokenKind kind = scanner_.peek();
1006 if ((statement = vars(TOK_STOCK, kind)) == NULL)
1011 return forStatement();
1018 statement = new (pool_) BreakStatement(scanner_.begin());
1023 statement = new (pool_) ContinueStatement(scanner_.begin());
1027 if ((statement = do_()) == NULL)
1032 if ((statement = returnStatement()) == NULL)
1037 if ((statement = enum_()) == NULL)
1042 if ((statement = struct_()) == NULL)
1060 if ((statement = expressionStatement()) == NULL)
1064 if (!expect(TOK_SEMICOLON))
1075 Local<String> name(zone_, expectName());
1079 SourcePosition pos = scanner_.begin();
1081 if (BoundName *other = scope_->localLookup(name)) {
1082 redeclarationError(other);
1087 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1090 if (!expect(TOK_LBRACE))
1093 FieldList *fields = new (pool_) FieldList();
1095 while (!peek(TOK_RBRACE)) {
1096 if (matchName(name.ref(), TOK_LABEL) && !name)
1099 BoundName *type = NULL;
1101 if ((type = bindType(name)) == NULL)
1105 name = expectName();
1109 SourcePosition pos = scanner_.begin();
1111 ExpressionList *postDimensions = NULL;
1112 //if (peek(TOK_LBRACKET)) {
1113 // if ((postDimensions = dimensions()) == NULL)
1117 if (!matchSemicolon())
1120 StructureStatement::Field *field =
1121 new (pool_) StructureStatement::Field(pos, type, name, postDimensions);
1122 if (!field || !fields->append(field))
1126 if (!expect(TOK_RBRACE))
1129 if (fields->empty()) {
1130 cc_.reportError(pos, Message_StructCantBeEmpty);
1134 return new (pool_) StructureStatement(pos, type, fields);
1142 NamedType *type = NULL;
1143 SourcePosition pos = scanner_.begin();
1145 Local<String> name(zone_);
1146 if (matchName(name.ref())) {
1150 if (BoundName *other = scope_->localLookup(name)) {
1151 redeclarationError(other);
1155 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1159 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1161 if (!expect(TOK_LBRACE))
1165 if (scanner_.peek() == TOK_RBRACE)
1168 Local<String> name(zone_, expectName());
1172 if (BoundName *other = scope_->localLookup(name)) {
1173 redeclarationError(other);
1177 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
1181 Expression *expr = NULL;
1182 if (match(TOK_ASSIGN)) {
1183 if ((expr = expression()) == NULL)
1187 if (!entries->append(EnumStatement::Entry(constant, expr)))
1189 } while (match(TOK_COMMA));
1190 if (!expect(TOK_RBRACE))
1193 return new (pool_) EnumStatement(pos, type, name, entries);
1197 Parser::function(TokenKind token)
1199 Local<String> returnTag(zone_);
1200 if (token == TOK_LABEL) {
1201 returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1207 if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
1211 BoundName *returnType = NULL;
1213 returnType = bindType(returnTag);
1215 Local<String> name(zone_, expectName());
1219 SourcePosition pos = scanner_.begin();
1221 // The function name goes into the outer (global) scope.
1222 assert(!scope_->enclosing());
1224 NamedType *type = NULL;
1225 NamedFunction *fun = NULL;
1226 if (BoundName *other = scope_->localLookup(name)) {
1227 // We allow a redeclaration if the new type is a public, and the old
1228 // type was a forward. However, the forward must come first.
1229 if (token == TOK_TYPEDEF || other->kind() != BoundName::FUNCTION) {
1230 redeclarationError(other);
1234 fun = other->toNamedFunction();
1235 if (!fun->isForward() || token != TOK_PUBLIC) {
1236 redeclarationError(other);
1240 // We've got the same name, but the original is a forward, so let it
1241 // slide and re-use the original declaration.
1242 fun->setImplemented(scanner_.begin());
1243 } else if (token == TOK_TYPEDEF) {
1244 type = scope_->declareType(name, scanner_.begin());
1248 fun = scope_->declareFunction(name, scanner_.begin(), token);
1253 if (fun && fun->isPublic())
1256 Scope *scope = enterScope(Scope::FUNCTION);
1260 ParameterList *parameters = new (pool_) ParameterList();
1262 if (!expect(TOK_LPAREN))
1265 if (!match(TOK_RPAREN)) {
1267 bool isConst = match(TOK_CONST);
1268 bool ref = match(TOK_AMPERSAND);
1270 SourcePosition begin = scanner_.begin();
1271 Local<String> tag(zone_);
1272 if (matchName(tag.ref(), TOK_LABEL) && !tag)
1275 BoundName *type = NULL;
1277 type = bindType(tag);
1279 if (match(TOK_ELLIPSES)) {
1280 if (isConst || ref) {
1281 cc_.reportError(begin, Message_InvalidVarArgs);
1285 if (token != TOK_NATIVE) {
1286 cc_.reportError(begin, Message_VarArgsOutsideNative);
1290 fun->markNativeVariadic();
1294 Local<String> name(zone_, expectName());
1298 if (BoundName *other = scope_->localLookup(name)) {
1299 redeclarationError(other);
1302 Variable *arg = scope_->declareArgument(name, scanner_.begin());
1306 // Look for dimensions.
1307 ExpressionList *postDimensions = NULL;
1308 if (peek(TOK_LBRACKET)) {
1309 if ((postDimensions = dimensions()) == NULL)
1313 Expression *expr = NULL;
1314 if (match(TOK_ASSIGN)) {
1315 if ((expr = expression()) == NULL)
1319 Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
1321 if (!parameters->append(parameter))
1324 if (!match(TOK_COMMA))
1327 if (!expect(TOK_RPAREN))
1331 encounteredReturn_ = false;
1333 Statement *body = NULL;
1334 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1340 scope_ = scope_->enclosing();
1342 FunctionSignature signature(returnType, parameters);
1343 if (token == TOK_TYPEDEF)
1344 return new (pool_) FunctionTypeStatement(pos, type, signature);
1346 return new (pool_) FunctionStatement(pos, scope, fun, body, signature, encounteredReturn_);
1350 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1352 Local<String> tag(zone, zone->makeSymbol(name));
1356 return !!scope->declareType(tag, type);
1360 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1362 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1364 return DeclareIntrinsicType(zone, scope, name, primitive);
1368 Parser::setupIntrinsics()
1370 if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1372 if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1374 if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1376 if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1379 Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1380 if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1383 Local<Type> voidType(zone_, zone_->types()->getVoid());
1384 if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1387 Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1388 if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1397 StatementList *statements = new (pool_) StatementList();
1399 if (!enterScope(Scope::GLOBAL))
1402 if (!setupIntrinsics())
1406 Statement *statement = NULL;
1408 TokenKind kind = scanner_.peek();
1417 if ((statement = function(TOK_NAME)) == NULL)
1429 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1430 if ((statement = var(TOK_PUBLIC, scanner_.scan())) == NULL)
1432 if (!matchSemicolon())
1435 if ((statement = function(kind)) == NULL)
1437 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1446 // Note: at global scope, we don't accept comma-delimited
1447 // declarations yet, to see if we can get away with forcing
1448 // a nicer top-level style.
1450 if ((statement = var(TOK_STOCK, kind)) == NULL)
1452 if (!matchSemicolon())
1458 if ((statement = enum_()) == NULL)
1460 if (!matchSemicolon())
1465 if ((statement = struct_()) == NULL)
1467 if (!matchSemicolon())
1472 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1479 if (!statements->append(statement))
1483 return new (pool_) ParseTree(scope_, statements, unbound_);
1486 class AstPrinter : public AstVisitor
1493 for (size_t i = 0; i < level_; i++)
1504 AstPrinter(FILE *fp)
1510 void visit(NameProxy *name) {
1512 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1513 (name->binding() ? "" : " unbound"));
1515 void visit(CallExpression *node) {
1517 fprintf(fp_, "[ CallExpression\n");
1519 node->callee()->accept(this);
1520 for (size_t i = 0; i < node->arguments()->length(); i++)
1521 node->arguments()->at(i)->accept(this);
1524 void visit(FunctionTypeStatement *node) {
1526 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->decl()->name()->chars());
1528 void visit(FunctionStatement *node) {
1530 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1533 node->body()->accept(this);
1536 void visit(ExpressionStatement *node) {
1538 fprintf(fp_, "[ ExpressionStatement\n");
1540 node->expression()->accept(this);
1543 void visit(Assignment *node) {
1545 fprintf(fp_, "[ Assignment\n");
1547 node->lvalue()->accept(this);
1548 node->expression()->accept(this);
1551 void visit(TernaryExpression *node) {
1553 fprintf(fp_, "[ TernaryExpression\n");
1555 node->condition()->accept(this);
1556 node->left()->accept(this);
1557 node->right()->accept(this);
1560 void visit(BinaryExpression *node) {
1562 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1564 node->left()->accept(this);
1565 node->right()->accept(this);
1568 void visit(UnaryExpression *node) {
1570 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1572 node->expression()->accept(this);
1575 void visit(ReturnStatement *node) {
1577 fprintf(fp_, "[ ReturnStatement\n");
1579 if (node->expression())
1580 node->expression()->accept(this);
1583 void visit(ForStatement *node) {
1585 fprintf(fp_, "[ ForStatement\n");
1587 if (node->initialization())
1588 node->initialization()->accept(this);
1589 if (node->condition())
1590 node->condition()->accept(this);
1592 node->update()->accept(this);
1593 node->body()->accept(this);
1596 void visit(BlockStatement *node) {
1598 fprintf(fp_, "[ BlockStatement\n");
1600 for (size_t i = 0; i < node->statements()->length(); i++)
1601 node->statements()->at(i)->accept(this);
1604 void visit(VariableDeclaration *node) {
1606 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1608 if (node->initialization())
1609 node->initialization()->accept(this);
1612 void visit(IntegerLiteral *node) {
1614 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1616 void visit(BooleanLiteral *node) {
1618 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1619 (node->token() == TOK_TRUE) ? "true" : "false");
1621 void visit(FloatLiteral *node) {
1623 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1625 void visit(IfStatement *node) {
1627 fprintf(fp_, "[ IfStatement\n");
1629 node->ifTrue()->accept(this);
1630 if (node->ifFalse())
1631 node->ifFalse()->accept(this);
1634 void visit(IndexExpression *node) {
1636 fprintf(fp_, "[ IndexExpression\n");
1638 node->left()->accept(this);
1639 node->right()->accept(this);
1642 void visit(EnumStatement *node) {
1644 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1646 for (size_t i = 0; i < node->entries()->length(); i++) {
1648 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1649 if (node->entries()->at(i).expr) {
1651 node->entries()->at(i).expr->accept(this);
1657 void visit(WhileStatement *node) {
1659 fprintf(fp_, "[ WhileStatement (%s)\n",
1660 (node->token() == TOK_DO) ? "do" : "while");
1662 if (node->token() == TOK_DO) {
1663 node->condition()->accept(this);
1664 node->body()->accept(this);
1666 node->condition()->accept(this);
1667 node->body()->accept(this);
1671 void visit(BreakStatement *node) {
1673 fprintf(fp_, "[ BreakStatement\n");
1675 void visit(ContinueStatement *node) {
1677 fprintf(fp_, "[ ContinueStatement\n");
1679 void visit(StringLiteral *node) {
1681 fprintf(fp_, "[ StringLiteral\n");
1683 void visit(IncDecExpression *node) {
1685 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1687 node->expression()->accept(this);
1690 void visit(StructureStatement *node) {
1692 fprintf(fp_, "[ StructureStatement %s\n", node->decl()->name()->chars());
1694 void visit(FieldExpression *node) {
1696 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1698 node->left()->accept(this);
1701 void visit(SwitchStatement *node) {
1703 fprintf(fp_, "[ SwitchStatement\n");
1705 node->expression()->accept(this);
1706 for (size_t i = 0; i < node->cases()->length(); i++) {
1707 Case *c = node->cases()->at(i);
1708 c->expression()->accept(this);
1710 for (size_t j = 0; j < c->others()->length(); j++)
1711 c->others()->at(j)->accept(this);
1714 c->statement()->accept(this);
1717 if (node->defaultCase())
1718 node->defaultCase()->accept(this);
1724 ParseTree::dump(FILE *fp)
1726 AstPrinter printer(fp);
1728 for (size_t i = 0; i < statements_->length(); i++)
1729 statements_->at(i)->accept(&printer);