Allow structs to contain arrays.
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 SourcePosition pos = scanner_.begin();
870 if (BoundName *other = scope_->localLookup(name)) {
871 redeclarationError(other);
875 ExpressionList *postDimensions = NULL;
876 if (peek(TOK_LBRACKET)) {
877 if ((postDimensions = dimensions()) == NULL)
881 Expression *expr = NULL;
882 if (match(TOK_ASSIGN)) {
883 switch (scanner_.peek()) {
884 // Note: we don't support [] literals yet.
886 if ((expr = arrayLiteral(scanner_.scan())) == NULL)
891 if ((expr = expression()) == NULL)
897 Variable *var = scope_->declareVariable(name, pos);
901 if (scope == TOK_PUBLIC)
904 return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr);
908 Parser::vars(TokenKind scope, TokenKind kind)
910 VariableDeclaration *decl = var(scope, kind);
914 if (!peek(TOK_COMMA))
917 StatementList *statements = new (pool_) StatementList();
918 if (!statements->append(decl))
921 while (match(TOK_COMMA)) {
922 Statement *decl = var(scope, kind);
925 if (!statements->append(decl))
929 // Create a fake-o block with no scope to create a statement list.
930 return new (pool_) BlockStatement(decl->pos(), NULL, statements);
934 Parser::returnStatement()
936 SourcePosition pos = scanner_.begin();
937 if (!expect(TOK_RETURN))
940 Expression *expr = NULL;
941 if (scanner_.peek() != TOK_SEMICOLON) {
942 if ((expr = expression()) == NULL)
945 // We only care about non-void returns when determining whether a
946 // tagless function is non-void.
947 encounteredReturn_ = true;
950 return new (pool_) ReturnStatement(pos, expr);
954 Parser::expressionStatement()
956 Expression *left = assignment();
960 return new (pool_) ExpressionStatement(left);
964 Parser::block(Scope *scope)
966 if (!expect(TOK_LBRACE))
969 SourcePosition pos = scanner_.begin();
970 if (!scope && !enterScope(Scope::BLOCK))
973 StatementList *statements = new (pool_) StatementList();
974 while (!match(TOK_RBRACE)) {
975 Statement *statement = localStatement();
976 if (statement == NULL)
978 if (!statements->append(statement))
983 scope = scope_->unlinkIfEmpty();
984 scope_ = scope_->enclosing();
986 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
995 SourcePosition pos = scanner_.begin();
996 if (!expect(TOK_LPAREN))
999 Expression *cond = expression();
1003 if (!expect(TOK_RPAREN))
1006 Statement *ifTrue = localStatement();
1010 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1012 IfStatement *last = outer;
1013 while (match(TOK_ELSE)) {
1014 if (!match(TOK_IF)) {
1015 Statement *ifFalse = localStatement();
1019 last->setIfFalse(ifFalse);
1023 SourcePosition pos = scanner_.begin();
1024 if (!expect(TOK_LPAREN))
1027 Expression *otherCond = expression();
1031 if (!expect(TOK_RPAREN))
1034 Statement *otherIfTrue = localStatement();
1038 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1039 last->setIfFalse(inner);
1047 Parser::localStatement()
1049 Statement *statement = NULL;
1051 // Statements which must be followed by a semicolon will break out of the
1052 // switch. If they may end in BlockStatements, they'll immediately return.
1054 TokenKind kind = scanner_.peek();
1059 if ((statement = vars(TOK_STOCK, kind)) == NULL)
1064 return forStatement();
1071 statement = new (pool_) BreakStatement(scanner_.begin());
1076 statement = new (pool_) ContinueStatement(scanner_.begin());
1080 if ((statement = do_()) == NULL)
1085 if ((statement = returnStatement()) == NULL)
1090 if ((statement = enum_()) == NULL)
1095 if ((statement = struct_()) == NULL)
1113 if ((statement = expressionStatement()) == NULL)
1117 if (!expect(TOK_SEMICOLON))
1128 Local<String> name(zone_, expectName());
1132 SourcePosition pos = scanner_.begin();
1134 if (BoundName *other = scope_->localLookup(name)) {
1135 redeclarationError(other);
1140 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1143 if (!expect(TOK_LBRACE))
1146 FieldList *fields = new (pool_) FieldList();
1148 while (!peek(TOK_RBRACE)) {
1149 if (matchName(name.ref(), TOK_LABEL) && !name)
1152 BoundName *type = NULL;
1154 if ((type = bindType(name)) == NULL)
1158 name = expectName();
1162 SourcePosition pos = scanner_.begin();
1164 ExpressionList *postDimensions = NULL;
1165 if (peek(TOK_LBRACKET)) {
1166 if ((postDimensions = dimensions()) == NULL)
1170 if (!matchSemicolon())
1173 StructureStatement::Field *field =
1174 new (pool_) StructureStatement::Field(pos, type, name, postDimensions);
1175 if (!field || !fields->append(field))
1179 if (!expect(TOK_RBRACE))
1182 if (fields->empty()) {
1183 cc_.reportError(pos, Message_StructCantBeEmpty);
1187 return new (pool_) StructureStatement(pos, type, fields);
1195 NamedType *type = NULL;
1196 SourcePosition pos = scanner_.begin();
1198 Local<String> name(zone_);
1199 if (matchName(name.ref())) {
1203 if (BoundName *other = scope_->localLookup(name)) {
1204 redeclarationError(other);
1208 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1212 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1214 if (!expect(TOK_LBRACE))
1218 if (scanner_.peek() == TOK_RBRACE)
1221 Local<String> name(zone_, expectName());
1225 if (BoundName *other = scope_->localLookup(name)) {
1226 redeclarationError(other);
1230 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
1234 Expression *expr = NULL;
1235 if (match(TOK_ASSIGN)) {
1236 if ((expr = expression()) == NULL)
1240 if (!entries->append(EnumStatement::Entry(constant, expr)))
1242 } while (match(TOK_COMMA));
1243 if (!expect(TOK_RBRACE))
1246 return new (pool_) EnumStatement(pos, type, name, entries);
1250 Parser::function(TokenKind token)
1252 Local<String> returnTag(zone_);
1253 if (token == TOK_LABEL) {
1254 returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1260 if (peek(TOK_LABEL)) {
1261 if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
1263 } else if (peek(TOK_NAME)) {
1264 // Peek for a type that has no :
1265 returnTag = expectName();
1271 Local<String> name(zone_);
1272 ExpressionList *returnDimensions = NULL;
1274 bool allowArrayReturns = token != TOK_NATIVE &&
1275 token != TOK_PUBLIC &&
1276 token != TOK_FORWARD;
1278 if (allowArrayReturns && peek(TOK_LBRACKET)) {
1279 if ((returnDimensions = dimensions()) == NULL)
1281 if ((name = expectName()) == NULL)
1283 } else if (peek(TOK_NAME)) {
1284 if ((name = expectName()) == NULL)
1287 // We predicted |type name|, but just got |name| instead.
1292 BoundName *returnType = NULL;
1294 returnType = bindType(returnTag);
1296 SourcePosition pos = scanner_.begin();
1298 // The function name goes into the outer (global) scope.
1299 assert(!scope_->enclosing());
1301 NamedType *type = NULL;
1302 NamedFunction *fun = NULL;
1303 if (BoundName *other = scope_->localLookup(name)) {
1304 // We allow a redeclaration if the new type is a public, and the old
1305 // type was a forward. However, the forward must come first.
1306 if (token == TOK_TYPEDEF || other->kind() != BoundName::FUNCTION) {
1307 redeclarationError(other);
1311 fun = other->toNamedFunction();
1312 if (!fun->isForward() || token != TOK_PUBLIC) {
1313 redeclarationError(other);
1317 // We've got the same name, but the original is a forward, so let it
1318 // slide and re-use the original declaration.
1319 fun->setImplemented(scanner_.begin());
1320 } else if (token == TOK_TYPEDEF) {
1321 type = scope_->declareType(name, scanner_.begin());
1325 fun = scope_->declareFunction(name, scanner_.begin(), token);
1330 if (fun && fun->isPublic())
1333 Scope *scope = enterScope(Scope::FUNCTION);
1337 ParameterList *parameters = new (pool_) ParameterList();
1339 if (!expect(TOK_LPAREN))
1342 if (!match(TOK_RPAREN)) {
1344 bool isConst = match(TOK_CONST);
1345 bool ref = match(TOK_AMPERSAND);
1347 SourcePosition begin = scanner_.begin();
1348 Local<String> tag(zone_);
1349 if (matchName(tag.ref(), TOK_LABEL) && !tag)
1352 BoundName *type = NULL;
1354 type = bindType(tag);
1356 if (match(TOK_ELLIPSES)) {
1357 if (isConst || ref) {
1358 cc_.reportError(begin, Message_InvalidVarArgs);
1362 if (token != TOK_NATIVE) {
1363 cc_.reportError(begin, Message_VarArgsOutsideNative);
1367 fun->markNativeVariadic();
1371 Local<String> name(zone_, expectName());
1375 if (BoundName *other = scope_->localLookup(name)) {
1376 redeclarationError(other);
1379 Variable *arg = scope_->declareArgument(name, scanner_.begin());
1383 // Look for dimensions.
1384 ExpressionList *postDimensions = NULL;
1385 if (peek(TOK_LBRACKET)) {
1386 if ((postDimensions = dimensions()) == NULL)
1390 Expression *expr = NULL;
1391 if (match(TOK_ASSIGN)) {
1392 if ((expr = expression()) == NULL)
1396 Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
1398 if (!parameters->append(parameter))
1401 if (!match(TOK_COMMA))
1404 if (!expect(TOK_RPAREN))
1408 encounteredReturn_ = false;
1410 Statement *body = NULL;
1411 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1417 scope_ = scope_->enclosing();
1419 FunctionSignature signature(returnType, returnDimensions, parameters);
1420 if (token == TOK_TYPEDEF)
1421 return new (pool_) FunctionTypeStatement(pos, type, signature);
1423 return new (pool_) FunctionStatement(pos, scope, fun, body, signature, encounteredReturn_);
1427 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1429 Local<String> tag(zone, zone->makeSymbol(name));
1433 return !!scope->declareType(tag, type);
1437 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1439 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1441 return DeclareIntrinsicType(zone, scope, name, primitive);
1445 Parser::setupIntrinsics()
1447 if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1449 if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1451 if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1453 if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1456 Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1457 if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1460 Local<Type> voidType(zone_, zone_->types()->getVoid());
1461 if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1464 Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1465 if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1474 StatementList *statements = new (pool_) StatementList();
1476 if (!enterScope(Scope::GLOBAL))
1479 if (!setupIntrinsics())
1483 Statement *statement = NULL;
1485 TokenKind kind = scanner_.peek();
1494 if ((statement = function(TOK_NAME)) == NULL)
1506 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1507 if ((statement = var(TOK_PUBLIC, scanner_.scan())) == NULL)
1509 if (!matchSemicolon())
1512 if ((statement = function(kind)) == NULL)
1514 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1523 // Note: at global scope, we don't accept comma-delimited
1524 // declarations yet, to see if we can get away with forcing
1525 // a nicer top-level style.
1527 if ((statement = var(TOK_STOCK, kind)) == NULL)
1529 if (!matchSemicolon())
1535 if ((statement = enum_()) == NULL)
1537 if (!matchSemicolon())
1542 if ((statement = struct_()) == NULL)
1544 if (!matchSemicolon())
1549 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1556 if (!statements->append(statement))
1560 return new (pool_) ParseTree(scope_, statements, unbound_);
1563 class AstPrinter : public AstVisitor
1570 for (size_t i = 0; i < level_; i++)
1581 AstPrinter(FILE *fp)
1587 void dump(const FunctionSignature &sig) {
1589 fprintf(fp_, "%s", sig.returnType()
1590 ? sig.returnType()->name()->chars()
1592 if (sig.returnDimensions()) {
1593 for (size_t i = 0; i < sig.returnDimensions()->length(); i++)
1596 fprintf(fp_, "()\n");
1598 void visit(NameProxy *name) {
1600 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1601 (name->binding() ? "" : " unbound"));
1603 void visit(CallExpression *node) {
1605 fprintf(fp_, "[ CallExpression\n");
1607 node->callee()->accept(this);
1608 for (size_t i = 0; i < node->arguments()->length(); i++)
1609 node->arguments()->at(i)->accept(this);
1612 void visit(FunctionTypeStatement *node) {
1614 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->decl()->name()->chars());
1616 dump(node->signature());
1619 void visit(FunctionStatement *node) {
1621 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1623 dump(node->signature());
1625 node->body()->accept(this);
1628 void visit(ExpressionStatement *node) {
1630 fprintf(fp_, "[ ExpressionStatement\n");
1632 node->expression()->accept(this);
1635 void visit(Assignment *node) {
1637 fprintf(fp_, "[ Assignment\n");
1639 node->lvalue()->accept(this);
1640 node->expression()->accept(this);
1643 void visit(TernaryExpression *node) {
1645 fprintf(fp_, "[ TernaryExpression\n");
1647 node->condition()->accept(this);
1648 node->left()->accept(this);
1649 node->right()->accept(this);
1652 void visit(BinaryExpression *node) {
1654 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1656 node->left()->accept(this);
1657 node->right()->accept(this);
1660 void visit(UnaryExpression *node) {
1662 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1664 node->expression()->accept(this);
1667 void visit(ReturnStatement *node) {
1669 fprintf(fp_, "[ ReturnStatement\n");
1671 if (node->expression())
1672 node->expression()->accept(this);
1675 void visit(ForStatement *node) {
1677 fprintf(fp_, "[ ForStatement\n");
1679 if (node->initialization())
1680 node->initialization()->accept(this);
1681 if (node->condition())
1682 node->condition()->accept(this);
1684 node->update()->accept(this);
1685 node->body()->accept(this);
1688 void visit(BlockStatement *node) {
1690 fprintf(fp_, "[ BlockStatement\n");
1692 for (size_t i = 0; i < node->statements()->length(); i++)
1693 node->statements()->at(i)->accept(this);
1696 void visit(VariableDeclaration *node) {
1698 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1700 if (node->initialization())
1701 node->initialization()->accept(this);
1704 void visit(IntegerLiteral *node) {
1706 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1708 void visit(BooleanLiteral *node) {
1710 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1711 (node->token() == TOK_TRUE) ? "true" : "false");
1713 void visit(FloatLiteral *node) {
1715 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1717 void visit(IfStatement *node) {
1719 fprintf(fp_, "[ IfStatement\n");
1721 node->ifTrue()->accept(this);
1722 if (node->ifFalse())
1723 node->ifFalse()->accept(this);
1726 void visit(IndexExpression *node) {
1728 fprintf(fp_, "[ IndexExpression\n");
1730 node->left()->accept(this);
1731 node->right()->accept(this);
1734 void visit(EnumStatement *node) {
1736 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1738 for (size_t i = 0; i < node->entries()->length(); i++) {
1740 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1741 if (node->entries()->at(i).expr) {
1743 node->entries()->at(i).expr->accept(this);
1749 void visit(WhileStatement *node) {
1751 fprintf(fp_, "[ WhileStatement (%s)\n",
1752 (node->token() == TOK_DO) ? "do" : "while");
1754 if (node->token() == TOK_DO) {
1755 node->condition()->accept(this);
1756 node->body()->accept(this);
1758 node->condition()->accept(this);
1759 node->body()->accept(this);
1763 void visit(BreakStatement *node) {
1765 fprintf(fp_, "[ BreakStatement\n");
1767 void visit(ContinueStatement *node) {
1769 fprintf(fp_, "[ ContinueStatement\n");
1771 void visit(StringLiteral *node) {
1773 fprintf(fp_, "[ StringLiteral\n");
1775 void visit(IncDecExpression *node) {
1777 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1779 node->expression()->accept(this);
1782 void visit(StructureStatement *node) {
1784 fprintf(fp_, "[ StructureStatement %s\n", node->decl()->name()->chars());
1786 void visit(FieldExpression *node) {
1788 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1790 node->left()->accept(this);
1793 void visit(SwitchStatement *node) {
1795 fprintf(fp_, "[ SwitchStatement\n");
1797 node->expression()->accept(this);
1798 for (size_t i = 0; i < node->cases()->length(); i++) {
1799 Case *c = node->cases()->at(i);
1800 c->expression()->accept(this);
1802 for (size_t j = 0; j < c->others()->length(); j++)
1803 c->others()->at(j)->accept(this);
1806 c->statement()->accept(this);
1809 if (node->defaultCase())
1810 node->defaultCase()->accept(this);
1813 void visit(ArrayLiteral *node) {
1815 fprintf(fp_, "[ ArrayLiteral\n");
1817 for (size_t i = 0; i < node->expressions()->length(); i++) {
1818 Expression *expr = node->expressions()->at(i);
1827 ParseTree::dump(FILE *fp)
1829 AstPrinter printer(fp);
1831 for (size_t i = 0; i < statements_->length(); i++)
1832 statements_->at(i)->accept(&printer);