Restructure Array so the elements vector can be replaced.
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();
131 case TOK_FLOAT_LITERAL:
134 double value = Scanner::ParseDouble(scanner_.literal());
135 return new (pool_) FloatLiteral(scanner_.begin(), value);
138 case TOK_HEX_LITERAL:
141 int value = strtol(scanner_.literal(), NULL, 16);
142 return new (pool_) IntegerLiteral(scanner_.begin(), value);
145 case TOK_INTEGER_LITERAL:
148 int value = atoi(scanner_.literal());
149 return new (pool_) IntegerLiteral(scanner_.begin(), value);
155 return new (pool_) BooleanLiteral(scanner_.begin(), kind);
157 case TOK_STRING_LITERAL:
160 Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
163 memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
164 return new (pool_) StringLiteral(scanner_.begin(), array);
169 if (kind != TOK_ERROR)
170 cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
177 Parser::arrayLiteral(TokenKind kind)
179 assert(kind == TOK_LBRACE || kind == TOK_LBRACKET);
181 TokenKind close = (kind == TOK_LBRACE)
185 SourcePosition pos = scanner_.begin();
187 ExpressionList *list = new (pool_) ExpressionList();
192 Expression *expr = NULL;
193 if (kind == TOK_LBRACE) {
194 if (peek(TOK_LBRACE))
195 expr = arrayLiteral(TOK_LBRACE);
204 if (!list->append(expr))
207 if (!match(TOK_COMMA)) {
214 return new (pool_) ArrayLiteral(pos, kind, list);
220 switch (scanner_.peek()) {
224 Expression *expr = expression();
227 if (!expect(TOK_RPAREN))
234 Local<String> name(zone_, expectName());
246 Parser::call(Expression *callee)
248 ExpressionList *arguments = new (pool_) ExpressionList();
250 SourcePosition pos = scanner_.begin();
253 if (!match(TOK_RPAREN)) {
255 Expression *expr = expression();
259 if (!arguments->append(expr))
262 if (!match(TOK_COMMA))
266 if (!expect(TOK_RPAREN))
270 return new (pool_) CallExpression(pos, callee, arguments);
274 Parser::index(Expression *left)
276 expect(TOK_LBRACKET);
278 SourcePosition pos = scanner_.begin();
279 Expression *expr = expression();
283 if (!expect(TOK_RBRACKET))
286 return new (pool_) IndexExpression(pos, left, expr);
290 Parser::field(Expression *left)
294 SourcePosition pos = scanner_.begin();
295 Local<String> name(zone_, expectName());
299 return new (pool_) FieldExpression(pos, left, name);
305 Expression *expr = prefix();
310 switch (scanner_.peek()) {
312 if ((expr = call(expr)) == NULL)
317 if ((expr = index(expr)) == NULL)
322 if ((expr = field(expr)) == NULL)
335 TokenKind token = scanner_.peek();
337 SourcePosition pos = scanner_.begin();
343 Expression *expr = unary();
346 return new (pool_) IncDecExpression(pos, token, expr, false);
354 Expression *expr = unary();
357 return new (pool_) UnaryExpression(pos, token, expr);
363 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
367 BoundName *type = NULL;
369 type = bindType(tag);
371 Expression *expr = unary();
375 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, type);
382 Expression *expr = primary();
384 token = scanner_.peek();
385 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
387 return new (pool_) IncDecExpression(pos, token, expr, true);
394 Parser::multiplication()
396 Expression *left = unary();
398 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
400 SourcePosition pos = scanner_.begin();
401 TokenKind kind = scanner_.last();
402 Expression *right = unary();
405 left = new (pool_) BinaryExpression(pos, kind, left, right);
413 Expression *left = multiplication();
415 if (!match(TOK_PLUS) && !match(TOK_MINUS))
417 SourcePosition pos = scanner_.begin();
418 TokenKind kind = scanner_.last();
419 Expression *right = multiplication();
422 left = new (pool_) BinaryExpression(pos, kind, left, right);
430 Expression *left = addition();
432 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
434 SourcePosition pos = scanner_.begin();
435 TokenKind kind = scanner_.last();
436 Expression *right = addition();
439 left = new (pool_) BinaryExpression(pos, kind, left, right);
447 Expression *left = shift();
449 if (!match(TOK_BITAND))
451 SourcePosition pos = scanner_.begin();
452 Expression *right = shift();
455 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
463 Expression *left = bitand_();
465 if (!match(TOK_BITXOR))
467 SourcePosition pos = scanner_.begin();
468 Expression *right = shift();
471 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
479 Expression *left = bitxor();
481 if (!match(TOK_BITOR))
483 SourcePosition pos = scanner_.begin();
484 Expression *right = bitxor();
487 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
495 Expression *left = bitor_();
497 TokenKind kind = scanner_.peek();
498 if (kind < TOK_LT || kind > TOK_GE)
501 SourcePosition pos = scanner_.begin();
502 Expression *right = shift();
505 left = new (pool_) BinaryExpression(pos, kind, left, right);
513 Expression *left = relational();
515 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
517 TokenKind kind = scanner_.last();
518 SourcePosition pos = scanner_.begin();
519 Expression *right = relational();
522 left = new (pool_) BinaryExpression(pos, kind, left, right);
530 Expression *left = equals();
534 SourcePosition pos = scanner_.begin();
535 Expression *right = equals();
538 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
546 Expression *left = and_();
550 SourcePosition pos = scanner_.begin();
551 Expression *right = and_();
554 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
562 Expression *cond = or_();
566 if (!match(TOK_QMARK))
570 SourcePosition pos = scanner_.begin();
571 AutoAllowTags<false> disableTags(scanner_);
573 if ((left = expression()) == NULL)
577 if (!expect(TOK_COLON))
580 Expression *right = expression();
584 return new (pool_) TernaryExpression(pos, cond, left, right);
590 Expression *left = ternary();
592 TokenKind token = scanner_.peek();
593 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
596 SourcePosition pos = scanner_.begin();
597 Expression *expr = ternary();
601 left = new (pool_) Assignment(pos, token, left, expr);
615 SourcePosition pos = scanner_.begin();
618 if (!expect(TOK_LPAREN))
621 Expression *condition = expression();
625 if (!expect(TOK_RPAREN))
628 // Inside a loop, we force the creation of a scope object. Normally, we
629 // will cull scopes if they have no variables. However inside a loop,
630 // function calls that take references may compute a LIFO object, and to
631 // avoid temporarily leaking many such objects, we ensure that a scope
632 // is present so a LIFO slot can be allocated.
633 if (!enterScope(Scope::BLOCK))
637 if (scanner_.peek() == TOK_LBRACE)
638 body = block(scope_);
640 body = localStatement();
644 scope_ = scope_->enclosing();
645 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
651 SourcePosition pos = scanner_.begin();
654 // See the comment in ::while_() as to why we force a scope.
655 if (!enterScope(Scope::BLOCK))
659 if (scanner_.peek() == TOK_LBRACE)
660 body = block(scope_);
662 body = localStatement();
666 scope_ = scope_->enclosing();
668 if (!expect(TOK_WHILE))
671 if (!expect(TOK_LPAREN))
673 Expression *condition = expression();
676 if (!expect(TOK_RPAREN))
679 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
687 SourcePosition pos = scanner_.begin();
689 if (!expect(TOK_LPAREN))
691 Expression *expr = expression();
694 if (!expect(TOK_RPAREN))
697 if (!expect(TOK_LBRACE))
700 SourcePosition defaultPos;
701 PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
703 Statement *defaultCase = NULL;
705 while (!peek(TOK_RBRACE)) {
706 Expression *expr = NULL;
707 ExpressionList *others = NULL;
708 if (match(TOK_DEFAULT)) {
710 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
714 defaultPos = scanner_.begin();
717 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
721 if (!expect(TOK_CASE))
724 // A limitation in the grammar is that |case <NAME>:| will be
725 // detected as a label.
726 AutoAllowTags<false> disableTags(scanner_);
728 if ((expr = expression()) == NULL)
731 if (peek(TOK_COMMA)) {
732 others = new (pool_) ExpressionList();
733 while (match(TOK_COMMA)) {
734 Expression *other = expression();
737 if (!others->append(other))
743 if (!expect(TOK_COLON))
746 Statement *statement = localStatement();
750 if (!peek(TOK_CASE) &&
751 !peek(TOK_DEFAULT) &&
754 cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
759 Case *caze = new (pool_) Case(expr, others, statement);
760 if (!cases->append(caze))
763 defaultCase = statement;
767 if (!expect(TOK_RBRACE))
770 return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
774 Parser::forStatement()
776 SourcePosition pos = scanner_.begin();
778 if (!expect(TOK_LPAREN))
781 Statement *decl = NULL;
782 if (!match(TOK_SEMICOLON)) {
783 if (match(TOK_NEW)) {
784 if (!enterScope(Scope::BLOCK))
786 if ((decl = vars(TOK_STOCK, TOK_NEW)) == NULL)
789 if ((decl = expressionStatement()) == NULL)
792 if (!expect(TOK_SEMICOLON))
796 Expression *condition = NULL;
797 if (!match(TOK_SEMICOLON)) {
798 if ((condition = expression()) == NULL)
800 if (!expect(TOK_SEMICOLON))
804 Statement *update = NULL;
805 if (!match(TOK_RPAREN)) {
806 if ((update = expressionStatement()) == NULL)
808 if (!expect(TOK_RPAREN))
812 // See the comment in ::while_() as to why we force a scope.
813 if (!enterScope(Scope::BLOCK))
817 if (scanner_.peek() == TOK_LBRACE)
818 body = block(scope_);
820 body = localStatement();
824 scope_ = scope_->enclosing();
826 Scope *declScope = NULL;
827 if (decl && (decl->isVariableDeclaration() || decl->isBlockStatement())) {
828 declScope = scope_->unlinkIfEmpty();
829 scope_ = scope_->enclosing();
831 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
837 ExpressionList *postDimensions = new (pool_) ExpressionList();
838 while (match(TOK_LBRACKET)) {
839 Expression *dim = NULL;
840 if (!match(TOK_RBRACKET)) {
841 if ((dim = expression()) == NULL)
843 if (!expect(TOK_RBRACKET))
847 if (!postDimensions->append(dim))
850 return postDimensions;
853 VariableDeclaration *
854 Parser::var(TokenKind scope, TokenKind kind)
856 Local<String> tag(zone_);
857 if (matchName(tag.ref(), TOK_LABEL) && !tag)
860 BoundName *type = NULL;
862 type = bindType(tag);
864 Local<String> name(zone_, expectName());
868 if (BoundName *other = scope_->localLookup(name)) {
869 redeclarationError(other);
873 Variable *var = scope_->declareVariable(name, scanner_.begin());
877 if (scope == TOK_PUBLIC)
880 ExpressionList *postDimensions = NULL;
881 if (peek(TOK_LBRACKET)) {
882 if ((postDimensions = dimensions()) == NULL)
886 Expression *expr = NULL;
887 if (match(TOK_ASSIGN)) {
888 switch (scanner_.peek()) {
889 // Note: we don't support [] literals yet.
891 if ((expr = arrayLiteral(scanner_.scan())) == NULL)
896 if ((expr = expression()) == NULL)
902 return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr);
906 Parser::vars(TokenKind scope, TokenKind kind)
908 VariableDeclaration *decl = var(scope, kind);
912 if (!peek(TOK_COMMA))
915 StatementList *statements = new (pool_) StatementList();
916 if (!statements->append(decl))
919 while (match(TOK_COMMA)) {
920 Statement *decl = var(scope, kind);
923 if (!statements->append(decl))
927 // Create a fake-o block with no scope to create a statement list.
928 return new (pool_) BlockStatement(decl->pos(), NULL, statements);
932 Parser::returnStatement()
934 SourcePosition pos = scanner_.begin();
935 if (!expect(TOK_RETURN))
938 Expression *expr = NULL;
939 if (scanner_.peek() != TOK_SEMICOLON) {
940 if ((expr = expression()) == NULL)
943 // We only care about non-void returns when determining whether a
944 // tagless function is non-void.
945 encounteredReturn_ = true;
948 return new (pool_) ReturnStatement(pos, expr);
952 Parser::expressionStatement()
954 Expression *left = assignment();
958 return new (pool_) ExpressionStatement(left);
962 Parser::block(Scope *scope)
964 if (!expect(TOK_LBRACE))
967 SourcePosition pos = scanner_.begin();
968 if (!scope && !enterScope(Scope::BLOCK))
971 StatementList *statements = new (pool_) StatementList();
972 while (!match(TOK_RBRACE)) {
973 Statement *statement = localStatement();
974 if (statement == NULL)
976 if (!statements->append(statement))
981 scope = scope_->unlinkIfEmpty();
982 scope_ = scope_->enclosing();
984 BlockStatement *block = new (pool_) BlockStatement(pos, scope, 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 if ((statement = vars(TOK_STOCK, kind)) == NULL)
1062 return forStatement();
1069 statement = new (pool_) BreakStatement(scanner_.begin());
1074 statement = new (pool_) ContinueStatement(scanner_.begin());
1078 if ((statement = do_()) == NULL)
1083 if ((statement = returnStatement()) == NULL)
1088 if ((statement = enum_()) == NULL)
1093 if ((statement = struct_()) == NULL)
1111 if ((statement = expressionStatement()) == NULL)
1115 if (!expect(TOK_SEMICOLON))
1126 Local<String> name(zone_, expectName());
1130 SourcePosition pos = scanner_.begin();
1132 if (BoundName *other = scope_->localLookup(name)) {
1133 redeclarationError(other);
1138 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1141 if (!expect(TOK_LBRACE))
1144 FieldList *fields = new (pool_) FieldList();
1146 while (!peek(TOK_RBRACE)) {
1147 if (matchName(name.ref(), TOK_LABEL) && !name)
1150 BoundName *type = NULL;
1152 if ((type = bindType(name)) == NULL)
1156 name = expectName();
1160 SourcePosition pos = scanner_.begin();
1162 ExpressionList *postDimensions = NULL;
1163 //if (peek(TOK_LBRACKET)) {
1164 // if ((postDimensions = dimensions()) == NULL)
1168 if (!matchSemicolon())
1171 StructureStatement::Field *field =
1172 new (pool_) StructureStatement::Field(pos, type, name, postDimensions);
1173 if (!field || !fields->append(field))
1177 if (!expect(TOK_RBRACE))
1180 if (fields->empty()) {
1181 cc_.reportError(pos, Message_StructCantBeEmpty);
1185 return new (pool_) StructureStatement(pos, type, fields);
1193 NamedType *type = NULL;
1194 SourcePosition pos = scanner_.begin();
1196 Local<String> name(zone_);
1197 if (matchName(name.ref())) {
1201 if (BoundName *other = scope_->localLookup(name)) {
1202 redeclarationError(other);
1206 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1210 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1212 if (!expect(TOK_LBRACE))
1216 if (scanner_.peek() == TOK_RBRACE)
1219 Local<String> name(zone_, expectName());
1223 if (BoundName *other = scope_->localLookup(name)) {
1224 redeclarationError(other);
1228 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
1232 Expression *expr = NULL;
1233 if (match(TOK_ASSIGN)) {
1234 if ((expr = expression()) == NULL)
1238 if (!entries->append(EnumStatement::Entry(constant, expr)))
1240 } while (match(TOK_COMMA));
1241 if (!expect(TOK_RBRACE))
1244 return new (pool_) EnumStatement(pos, type, name, entries);
1248 Parser::function(TokenKind token)
1250 Local<String> returnTag(zone_);
1251 if (token == TOK_LABEL) {
1252 returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1258 if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
1262 BoundName *returnType = NULL;
1264 returnType = bindType(returnTag);
1266 Local<String> name(zone_, expectName());
1270 SourcePosition pos = scanner_.begin();
1272 // The function name goes into the outer (global) scope.
1273 assert(!scope_->enclosing());
1275 NamedType *type = NULL;
1276 NamedFunction *fun = NULL;
1277 if (BoundName *other = scope_->localLookup(name)) {
1278 // We allow a redeclaration if the new type is a public, and the old
1279 // type was a forward. However, the forward must come first.
1280 if (token == TOK_TYPEDEF || other->kind() != BoundName::FUNCTION) {
1281 redeclarationError(other);
1285 fun = other->toNamedFunction();
1286 if (!fun->isForward() || token != TOK_PUBLIC) {
1287 redeclarationError(other);
1291 // We've got the same name, but the original is a forward, so let it
1292 // slide and re-use the original declaration.
1293 fun->setImplemented(scanner_.begin());
1294 } else if (token == TOK_TYPEDEF) {
1295 type = scope_->declareType(name, scanner_.begin());
1299 fun = scope_->declareFunction(name, scanner_.begin(), token);
1304 if (fun && fun->isPublic())
1307 Scope *scope = enterScope(Scope::FUNCTION);
1311 ParameterList *parameters = new (pool_) ParameterList();
1313 if (!expect(TOK_LPAREN))
1316 if (!match(TOK_RPAREN)) {
1318 bool isConst = match(TOK_CONST);
1319 bool ref = match(TOK_AMPERSAND);
1321 SourcePosition begin = scanner_.begin();
1322 Local<String> tag(zone_);
1323 if (matchName(tag.ref(), TOK_LABEL) && !tag)
1326 BoundName *type = NULL;
1328 type = bindType(tag);
1330 if (match(TOK_ELLIPSES)) {
1331 if (isConst || ref) {
1332 cc_.reportError(begin, Message_InvalidVarArgs);
1336 if (token != TOK_NATIVE) {
1337 cc_.reportError(begin, Message_VarArgsOutsideNative);
1341 fun->markNativeVariadic();
1345 Local<String> name(zone_, expectName());
1349 if (BoundName *other = scope_->localLookup(name)) {
1350 redeclarationError(other);
1353 Variable *arg = scope_->declareArgument(name, scanner_.begin());
1357 // Look for dimensions.
1358 ExpressionList *postDimensions = NULL;
1359 if (peek(TOK_LBRACKET)) {
1360 if ((postDimensions = dimensions()) == NULL)
1364 Expression *expr = NULL;
1365 if (match(TOK_ASSIGN)) {
1366 if ((expr = expression()) == NULL)
1370 Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
1372 if (!parameters->append(parameter))
1375 if (!match(TOK_COMMA))
1378 if (!expect(TOK_RPAREN))
1382 encounteredReturn_ = false;
1384 Statement *body = NULL;
1385 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1391 scope_ = scope_->enclosing();
1393 FunctionSignature signature(returnType, parameters);
1394 if (token == TOK_TYPEDEF)
1395 return new (pool_) FunctionTypeStatement(pos, type, signature);
1397 return new (pool_) FunctionStatement(pos, scope, fun, body, signature, encounteredReturn_);
1401 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1403 Local<String> tag(zone, zone->makeSymbol(name));
1407 return !!scope->declareType(tag, type);
1411 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1413 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1415 return DeclareIntrinsicType(zone, scope, name, primitive);
1419 Parser::setupIntrinsics()
1421 if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1423 if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1425 if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1427 if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1430 Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1431 if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1434 Local<Type> voidType(zone_, zone_->types()->getVoid());
1435 if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1438 Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1439 if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1448 StatementList *statements = new (pool_) StatementList();
1450 if (!enterScope(Scope::GLOBAL))
1453 if (!setupIntrinsics())
1457 Statement *statement = NULL;
1459 TokenKind kind = scanner_.peek();
1468 if ((statement = function(TOK_NAME)) == NULL)
1480 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1481 if ((statement = var(TOK_PUBLIC, scanner_.scan())) == NULL)
1483 if (!matchSemicolon())
1486 if ((statement = function(kind)) == NULL)
1488 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1497 // Note: at global scope, we don't accept comma-delimited
1498 // declarations yet, to see if we can get away with forcing
1499 // a nicer top-level style.
1501 if ((statement = var(TOK_STOCK, kind)) == NULL)
1503 if (!matchSemicolon())
1509 if ((statement = enum_()) == NULL)
1511 if (!matchSemicolon())
1516 if ((statement = struct_()) == NULL)
1518 if (!matchSemicolon())
1523 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1530 if (!statements->append(statement))
1534 return new (pool_) ParseTree(scope_, statements, unbound_);
1537 class AstPrinter : public AstVisitor
1544 for (size_t i = 0; i < level_; i++)
1555 AstPrinter(FILE *fp)
1561 void visit(NameProxy *name) {
1563 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1564 (name->binding() ? "" : " unbound"));
1566 void visit(CallExpression *node) {
1568 fprintf(fp_, "[ CallExpression\n");
1570 node->callee()->accept(this);
1571 for (size_t i = 0; i < node->arguments()->length(); i++)
1572 node->arguments()->at(i)->accept(this);
1575 void visit(FunctionTypeStatement *node) {
1577 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->decl()->name()->chars());
1579 void visit(FunctionStatement *node) {
1581 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1584 node->body()->accept(this);
1587 void visit(ExpressionStatement *node) {
1589 fprintf(fp_, "[ ExpressionStatement\n");
1591 node->expression()->accept(this);
1594 void visit(Assignment *node) {
1596 fprintf(fp_, "[ Assignment\n");
1598 node->lvalue()->accept(this);
1599 node->expression()->accept(this);
1602 void visit(TernaryExpression *node) {
1604 fprintf(fp_, "[ TernaryExpression\n");
1606 node->condition()->accept(this);
1607 node->left()->accept(this);
1608 node->right()->accept(this);
1611 void visit(BinaryExpression *node) {
1613 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1615 node->left()->accept(this);
1616 node->right()->accept(this);
1619 void visit(UnaryExpression *node) {
1621 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1623 node->expression()->accept(this);
1626 void visit(ReturnStatement *node) {
1628 fprintf(fp_, "[ ReturnStatement\n");
1630 if (node->expression())
1631 node->expression()->accept(this);
1634 void visit(ForStatement *node) {
1636 fprintf(fp_, "[ ForStatement\n");
1638 if (node->initialization())
1639 node->initialization()->accept(this);
1640 if (node->condition())
1641 node->condition()->accept(this);
1643 node->update()->accept(this);
1644 node->body()->accept(this);
1647 void visit(BlockStatement *node) {
1649 fprintf(fp_, "[ BlockStatement\n");
1651 for (size_t i = 0; i < node->statements()->length(); i++)
1652 node->statements()->at(i)->accept(this);
1655 void visit(VariableDeclaration *node) {
1657 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1659 if (node->initialization())
1660 node->initialization()->accept(this);
1663 void visit(IntegerLiteral *node) {
1665 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1667 void visit(BooleanLiteral *node) {
1669 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1670 (node->token() == TOK_TRUE) ? "true" : "false");
1672 void visit(FloatLiteral *node) {
1674 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1676 void visit(IfStatement *node) {
1678 fprintf(fp_, "[ IfStatement\n");
1680 node->ifTrue()->accept(this);
1681 if (node->ifFalse())
1682 node->ifFalse()->accept(this);
1685 void visit(IndexExpression *node) {
1687 fprintf(fp_, "[ IndexExpression\n");
1689 node->left()->accept(this);
1690 node->right()->accept(this);
1693 void visit(EnumStatement *node) {
1695 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1697 for (size_t i = 0; i < node->entries()->length(); i++) {
1699 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1700 if (node->entries()->at(i).expr) {
1702 node->entries()->at(i).expr->accept(this);
1708 void visit(WhileStatement *node) {
1710 fprintf(fp_, "[ WhileStatement (%s)\n",
1711 (node->token() == TOK_DO) ? "do" : "while");
1713 if (node->token() == TOK_DO) {
1714 node->condition()->accept(this);
1715 node->body()->accept(this);
1717 node->condition()->accept(this);
1718 node->body()->accept(this);
1722 void visit(BreakStatement *node) {
1724 fprintf(fp_, "[ BreakStatement\n");
1726 void visit(ContinueStatement *node) {
1728 fprintf(fp_, "[ ContinueStatement\n");
1730 void visit(StringLiteral *node) {
1732 fprintf(fp_, "[ StringLiteral\n");
1734 void visit(IncDecExpression *node) {
1736 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1738 node->expression()->accept(this);
1741 void visit(StructureStatement *node) {
1743 fprintf(fp_, "[ StructureStatement %s\n", node->decl()->name()->chars());
1745 void visit(FieldExpression *node) {
1747 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1749 node->left()->accept(this);
1752 void visit(SwitchStatement *node) {
1754 fprintf(fp_, "[ SwitchStatement\n");
1756 node->expression()->accept(this);
1757 for (size_t i = 0; i < node->cases()->length(); i++) {
1758 Case *c = node->cases()->at(i);
1759 c->expression()->accept(this);
1761 for (size_t j = 0; j < c->others()->length(); j++)
1762 c->others()->at(j)->accept(this);
1765 c->statement()->accept(this);
1768 if (node->defaultCase())
1769 node->defaultCase()->accept(this);
1772 void visit(ArrayLiteral *node) {
1774 fprintf(fp_, "[ ArrayLiteral\n");
1776 for (size_t i = 0; i < node->expressions()->length(); i++) {
1777 Expression *expr = node->expressions()->at(i);
1786 ParseTree::dump(FILE *fp)
1788 AstPrinter printer(fp);
1790 for (size_t i = 0; i < statements_->length(); i++)
1791 statements_->at(i)->accept(&printer);