Implement sizeof operator.
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 if (!expect(TOK_LPAREN))
365 Expression *expr = unary();
368 if (!expect(TOK_RPAREN))
370 return new (pool_) UnaryExpression(pos, token, expr);
376 Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
380 BoundName *type = NULL;
382 type = bindType(tag);
384 Expression *expr = unary();
388 return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, type);
395 Expression *expr = primary();
397 token = scanner_.peek();
398 if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
400 return new (pool_) IncDecExpression(pos, token, expr, true);
407 Parser::multiplication()
409 Expression *left = unary();
411 if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
413 SourcePosition pos = scanner_.begin();
414 TokenKind kind = scanner_.last();
415 Expression *right = unary();
418 left = new (pool_) BinaryExpression(pos, kind, left, right);
426 Expression *left = multiplication();
428 if (!match(TOK_PLUS) && !match(TOK_MINUS))
430 SourcePosition pos = scanner_.begin();
431 TokenKind kind = scanner_.last();
432 Expression *right = multiplication();
435 left = new (pool_) BinaryExpression(pos, kind, left, right);
443 Expression *left = addition();
445 if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
447 SourcePosition pos = scanner_.begin();
448 TokenKind kind = scanner_.last();
449 Expression *right = addition();
452 left = new (pool_) BinaryExpression(pos, kind, left, right);
460 Expression *left = shift();
462 if (!match(TOK_BITAND))
464 SourcePosition pos = scanner_.begin();
465 Expression *right = shift();
468 left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
476 Expression *left = bitand_();
478 if (!match(TOK_BITXOR))
480 SourcePosition pos = scanner_.begin();
481 Expression *right = shift();
484 left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
492 Expression *left = bitxor();
494 if (!match(TOK_BITOR))
496 SourcePosition pos = scanner_.begin();
497 Expression *right = bitxor();
500 left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
508 Expression *left = bitor_();
510 TokenKind kind = scanner_.peek();
511 if (kind < TOK_LT || kind > TOK_GE)
514 SourcePosition pos = scanner_.begin();
515 Expression *right = shift();
518 left = new (pool_) BinaryExpression(pos, kind, left, right);
526 Expression *left = relational();
528 if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
530 TokenKind kind = scanner_.last();
531 SourcePosition pos = scanner_.begin();
532 Expression *right = relational();
535 left = new (pool_) BinaryExpression(pos, kind, left, right);
543 Expression *left = equals();
547 SourcePosition pos = scanner_.begin();
548 Expression *right = equals();
551 left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
559 Expression *left = and_();
563 SourcePosition pos = scanner_.begin();
564 Expression *right = and_();
567 left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
575 Expression *cond = or_();
579 if (!match(TOK_QMARK))
583 SourcePosition pos = scanner_.begin();
584 AutoAllowTags<false> disableTags(scanner_);
586 if ((left = expression()) == NULL)
590 if (!expect(TOK_COLON))
593 Expression *right = expression();
597 return new (pool_) TernaryExpression(pos, cond, left, right);
603 Expression *left = ternary();
605 TokenKind token = scanner_.peek();
606 if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
609 SourcePosition pos = scanner_.begin();
610 Expression *expr = ternary();
614 left = new (pool_) Assignment(pos, token, left, expr);
628 SourcePosition pos = scanner_.begin();
631 if (!expect(TOK_LPAREN))
634 Expression *condition = expression();
638 if (!expect(TOK_RPAREN))
641 // Inside a loop, we force the creation of a scope object. Normally, we
642 // will cull scopes if they have no variables. However inside a loop,
643 // function calls that take references may compute a LIFO object, and to
644 // avoid temporarily leaking many such objects, we ensure that a scope
645 // is present so a LIFO slot can be allocated.
646 if (!enterScope(Scope::BLOCK))
650 if (scanner_.peek() == TOK_LBRACE)
651 body = block(scope_);
653 body = localStatement();
657 scope_ = scope_->enclosing();
658 return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
664 SourcePosition pos = scanner_.begin();
667 // See the comment in ::while_() as to why we force a scope.
668 if (!enterScope(Scope::BLOCK))
672 if (scanner_.peek() == TOK_LBRACE)
673 body = block(scope_);
675 body = localStatement();
679 scope_ = scope_->enclosing();
681 if (!expect(TOK_WHILE))
684 if (!expect(TOK_LPAREN))
686 Expression *condition = expression();
689 if (!expect(TOK_RPAREN))
692 return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
700 SourcePosition pos = scanner_.begin();
702 if (!expect(TOK_LPAREN))
704 Expression *expr = expression();
707 if (!expect(TOK_RPAREN))
710 if (!expect(TOK_LBRACE))
713 SourcePosition defaultPos;
714 PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
716 Statement *defaultCase = NULL;
718 while (!peek(TOK_RBRACE)) {
719 Expression *expr = NULL;
720 ExpressionList *others = NULL;
721 if (match(TOK_DEFAULT)) {
723 cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
727 defaultPos = scanner_.begin();
730 cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
734 if (!expect(TOK_CASE))
737 // A limitation in the grammar is that |case <NAME>:| will be
738 // detected as a label.
739 AutoAllowTags<false> disableTags(scanner_);
741 if ((expr = expression()) == NULL)
744 if (peek(TOK_COMMA)) {
745 others = new (pool_) ExpressionList();
746 while (match(TOK_COMMA)) {
747 Expression *other = expression();
750 if (!others->append(other))
756 if (!expect(TOK_COLON))
759 Statement *statement = localStatement();
763 if (!peek(TOK_CASE) &&
764 !peek(TOK_DEFAULT) &&
767 cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
772 Case *caze = new (pool_) Case(expr, others, statement);
773 if (!cases->append(caze))
776 defaultCase = statement;
780 if (!expect(TOK_RBRACE))
783 return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
787 Parser::forStatement()
789 SourcePosition pos = scanner_.begin();
791 if (!expect(TOK_LPAREN))
794 Statement *decl = NULL;
795 if (!match(TOK_SEMICOLON)) {
796 if (match(TOK_NEW)) {
797 if (!enterScope(Scope::BLOCK))
799 if ((decl = vars(TOK_STOCK, TOK_NEW)) == NULL)
802 if ((decl = expressionStatement()) == NULL)
805 if (!expect(TOK_SEMICOLON))
809 Expression *condition = NULL;
810 if (!match(TOK_SEMICOLON)) {
811 if ((condition = expression()) == NULL)
813 if (!expect(TOK_SEMICOLON))
817 Statement *update = NULL;
818 if (!match(TOK_RPAREN)) {
819 if ((update = expressionStatement()) == NULL)
821 if (!expect(TOK_RPAREN))
825 // See the comment in ::while_() as to why we force a scope.
826 if (!enterScope(Scope::BLOCK))
830 if (scanner_.peek() == TOK_LBRACE)
831 body = block(scope_);
833 body = localStatement();
837 scope_ = scope_->enclosing();
839 Scope *declScope = NULL;
840 if (decl && (decl->isVariableDeclaration() || decl->isBlockStatement())) {
841 declScope = scope_->unlinkIfEmpty();
842 scope_ = scope_->enclosing();
844 return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
850 ExpressionList *postDimensions = new (pool_) ExpressionList();
851 while (match(TOK_LBRACKET)) {
852 Expression *dim = NULL;
853 if (!match(TOK_RBRACKET)) {
854 if ((dim = expression()) == NULL)
856 if (!expect(TOK_RBRACKET))
860 if (!postDimensions->append(dim))
863 return postDimensions;
866 VariableDeclaration *
867 Parser::var(TokenKind scope, TokenKind kind)
869 Local<String> tag(zone_);
870 if (matchName(tag.ref(), TOK_LABEL) && !tag)
873 BoundName *type = NULL;
875 type = bindType(tag);
877 Local<String> name(zone_, expectName());
881 SourcePosition pos = scanner_.begin();
883 if (BoundName *other = scope_->localLookup(name)) {
884 redeclarationError(other);
888 ExpressionList *postDimensions = NULL;
889 if (peek(TOK_LBRACKET)) {
890 if ((postDimensions = dimensions()) == NULL)
894 Expression *expr = NULL;
895 if (match(TOK_ASSIGN)) {
896 switch (scanner_.peek()) {
897 // Note: we don't support [] literals yet.
899 if ((expr = arrayLiteral(scanner_.scan())) == NULL)
904 if ((expr = expression()) == NULL)
910 Variable *var = scope_->declareVariable(name, pos);
914 if (scope == TOK_PUBLIC)
917 return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr);
921 Parser::vars(TokenKind scope, TokenKind kind)
923 VariableDeclaration *decl = var(scope, kind);
927 if (!peek(TOK_COMMA))
930 StatementList *statements = new (pool_) StatementList();
931 if (!statements->append(decl))
934 while (match(TOK_COMMA)) {
935 Statement *decl = var(scope, kind);
938 if (!statements->append(decl))
942 // Create a fake-o block with no scope to create a statement list.
943 return new (pool_) BlockStatement(decl->pos(), NULL, statements);
947 Parser::returnStatement()
949 SourcePosition pos = scanner_.begin();
950 if (!expect(TOK_RETURN))
953 Expression *expr = NULL;
954 if (scanner_.peek() != TOK_SEMICOLON) {
955 if ((expr = expression()) == NULL)
958 // We only care about non-void returns when determining whether a
959 // tagless function is non-void.
960 encounteredReturn_ = true;
963 return new (pool_) ReturnStatement(pos, expr);
967 Parser::expressionStatement()
969 Expression *left = assignment();
973 return new (pool_) ExpressionStatement(left);
977 Parser::block(Scope *scope)
979 if (!expect(TOK_LBRACE))
982 SourcePosition pos = scanner_.begin();
983 if (!scope && !enterScope(Scope::BLOCK))
986 StatementList *statements = new (pool_) StatementList();
987 while (!match(TOK_RBRACE)) {
988 Statement *statement = localStatement();
989 if (statement == NULL)
991 if (!statements->append(statement))
996 scope = scope_->unlinkIfEmpty();
997 scope_ = scope_->enclosing();
999 BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
1008 SourcePosition pos = scanner_.begin();
1009 if (!expect(TOK_LPAREN))
1012 Expression *cond = expression();
1016 if (!expect(TOK_RPAREN))
1019 Statement *ifTrue = localStatement();
1023 IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1025 IfStatement *last = outer;
1026 while (match(TOK_ELSE)) {
1027 if (!match(TOK_IF)) {
1028 Statement *ifFalse = localStatement();
1032 last->setIfFalse(ifFalse);
1036 SourcePosition pos = scanner_.begin();
1037 if (!expect(TOK_LPAREN))
1040 Expression *otherCond = expression();
1044 if (!expect(TOK_RPAREN))
1047 Statement *otherIfTrue = localStatement();
1051 IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1052 last->setIfFalse(inner);
1060 Parser::localStatement()
1062 Statement *statement = NULL;
1064 // Statements which must be followed by a semicolon will break out of the
1065 // switch. If they may end in BlockStatements, they'll immediately return.
1067 TokenKind kind = scanner_.peek();
1072 if ((statement = vars(TOK_STOCK, kind)) == NULL)
1077 return forStatement();
1084 statement = new (pool_) BreakStatement(scanner_.begin());
1089 statement = new (pool_) ContinueStatement(scanner_.begin());
1093 if ((statement = do_()) == NULL)
1098 if ((statement = returnStatement()) == NULL)
1103 if ((statement = enum_()) == NULL)
1108 if ((statement = struct_()) == NULL)
1126 if ((statement = expressionStatement()) == NULL)
1130 if (!expect(TOK_SEMICOLON))
1141 Local<String> name(zone_, expectName());
1145 SourcePosition pos = scanner_.begin();
1147 if (BoundName *other = scope_->localLookup(name)) {
1148 redeclarationError(other);
1153 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1156 if (!expect(TOK_LBRACE))
1159 FieldList *fields = new (pool_) FieldList();
1161 while (!peek(TOK_RBRACE)) {
1162 if (matchName(name.ref(), TOK_LABEL) && !name)
1165 BoundName *type = NULL;
1167 if ((type = bindType(name)) == NULL)
1171 name = expectName();
1175 SourcePosition pos = scanner_.begin();
1177 ExpressionList *postDimensions = NULL;
1178 if (peek(TOK_LBRACKET)) {
1179 if ((postDimensions = dimensions()) == NULL)
1183 if (!matchSemicolon())
1186 StructureStatement::Field *field =
1187 new (pool_) StructureStatement::Field(pos, type, name, postDimensions);
1188 if (!field || !fields->append(field))
1192 if (!expect(TOK_RBRACE))
1195 if (fields->empty()) {
1196 cc_.reportError(pos, Message_StructCantBeEmpty);
1200 return new (pool_) StructureStatement(pos, type, fields);
1208 NamedType *type = NULL;
1209 SourcePosition pos = scanner_.begin();
1211 Local<String> name(zone_);
1212 if (matchName(name.ref())) {
1216 if (BoundName *other = scope_->localLookup(name)) {
1217 redeclarationError(other);
1221 if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
1225 EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1227 if (!expect(TOK_LBRACE))
1231 if (scanner_.peek() == TOK_RBRACE)
1234 Local<String> name(zone_, expectName());
1238 if (BoundName *other = scope_->localLookup(name)) {
1239 redeclarationError(other);
1243 NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
1247 Expression *expr = NULL;
1248 if (match(TOK_ASSIGN)) {
1249 if ((expr = expression()) == NULL)
1253 if (!entries->append(EnumStatement::Entry(constant, expr)))
1255 } while (match(TOK_COMMA));
1256 if (!expect(TOK_RBRACE))
1259 return new (pool_) EnumStatement(pos, type, name, entries);
1263 Parser::function(TokenKind token)
1265 Local<String> returnTag(zone_);
1266 if (token == TOK_LABEL) {
1267 returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1273 if (peek(TOK_LABEL)) {
1274 if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
1276 } else if (peek(TOK_NAME)) {
1277 // Peek for a type that has no :
1278 returnTag = expectName();
1284 Local<String> name(zone_);
1285 ExpressionList *returnDimensions = NULL;
1287 bool allowArrayReturns = token != TOK_NATIVE &&
1288 token != TOK_PUBLIC &&
1289 token != TOK_FORWARD;
1291 if (allowArrayReturns && peek(TOK_LBRACKET)) {
1292 if ((returnDimensions = dimensions()) == NULL)
1294 if ((name = expectName()) == NULL)
1296 } else if (peek(TOK_NAME)) {
1297 if ((name = expectName()) == NULL)
1300 // We predicted |type name|, but just got |name| instead.
1305 BoundName *returnType = NULL;
1307 returnType = bindType(returnTag);
1309 SourcePosition pos = scanner_.begin();
1311 // The function name goes into the outer (global) scope.
1312 assert(!scope_->enclosing());
1314 NamedType *type = NULL;
1315 NamedFunction *fun = NULL;
1316 if (BoundName *other = scope_->localLookup(name)) {
1317 // We allow a redeclaration if the new type is a public, and the old
1318 // type was a forward. However, the forward must come first.
1319 if (token == TOK_TYPEDEF || other->kind() != BoundName::FUNCTION) {
1320 redeclarationError(other);
1324 fun = other->toNamedFunction();
1325 if (!fun->isForward() || token != TOK_PUBLIC) {
1326 redeclarationError(other);
1330 // We've got the same name, but the original is a forward, so let it
1331 // slide and re-use the original declaration.
1332 fun->setImplemented(scanner_.begin());
1333 } else if (token == TOK_TYPEDEF) {
1334 type = scope_->declareType(name, scanner_.begin());
1338 fun = scope_->declareFunction(name, scanner_.begin(), token);
1343 if (fun && fun->isPublic())
1346 Scope *scope = enterScope(Scope::FUNCTION);
1350 ParameterList *parameters = new (pool_) ParameterList();
1352 if (!expect(TOK_LPAREN))
1355 if (!match(TOK_RPAREN)) {
1357 bool isConst = match(TOK_CONST);
1358 bool ref = match(TOK_AMPERSAND);
1360 SourcePosition begin = scanner_.begin();
1361 Local<String> tag(zone_);
1362 if (matchName(tag.ref(), TOK_LABEL) && !tag)
1365 BoundName *type = NULL;
1367 type = bindType(tag);
1369 if (match(TOK_ELLIPSES)) {
1370 if (isConst || ref) {
1371 cc_.reportError(begin, Message_InvalidVarArgs);
1375 if (token != TOK_NATIVE) {
1376 cc_.reportError(begin, Message_VarArgsOutsideNative);
1380 fun->markNativeVariadic();
1384 Local<String> name(zone_, expectName());
1388 if (BoundName *other = scope_->localLookup(name)) {
1389 redeclarationError(other);
1392 Variable *arg = scope_->declareArgument(name, scanner_.begin());
1396 // Look for dimensions.
1397 ExpressionList *postDimensions = NULL;
1398 if (peek(TOK_LBRACKET)) {
1399 if ((postDimensions = dimensions()) == NULL)
1403 Expression *expr = NULL;
1404 if (match(TOK_ASSIGN)) {
1405 if ((expr = expression()) == NULL)
1409 Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
1411 if (!parameters->append(parameter))
1414 if (!match(TOK_COMMA))
1417 if (!expect(TOK_RPAREN))
1421 encounteredReturn_ = false;
1423 Statement *body = NULL;
1424 if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1430 scope_ = scope_->enclosing();
1432 FunctionSignature signature(returnType, returnDimensions, parameters);
1433 if (token == TOK_TYPEDEF)
1434 return new (pool_) FunctionTypeStatement(pos, type, signature);
1436 return new (pool_) FunctionStatement(pos, scope, fun, body, signature, encounteredReturn_);
1440 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1442 Local<String> tag(zone, zone->makeSymbol(name));
1446 return !!scope->declareType(tag, type);
1450 DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1452 Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1454 return DeclareIntrinsicType(zone, scope, name, primitive);
1458 Parser::setupIntrinsics()
1460 if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1462 if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1464 if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1466 if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1469 Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1470 if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1473 Local<Type> voidType(zone_, zone_->types()->getVoid());
1474 if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1477 Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1478 if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1487 StatementList *statements = new (pool_) StatementList();
1489 if (!enterScope(Scope::GLOBAL))
1492 if (!setupIntrinsics())
1496 Statement *statement = NULL;
1498 TokenKind kind = scanner_.peek();
1507 if ((statement = function(TOK_NAME)) == NULL)
1519 if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1520 if ((statement = var(TOK_PUBLIC, scanner_.scan())) == NULL)
1522 if (!matchSemicolon())
1525 if ((statement = function(kind)) == NULL)
1527 if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1536 // Note: at global scope, we don't accept comma-delimited
1537 // declarations yet, to see if we can get away with forcing
1538 // a nicer top-level style.
1540 if ((statement = var(TOK_STOCK, kind)) == NULL)
1542 if (!matchSemicolon())
1548 if ((statement = enum_()) == NULL)
1550 if (!matchSemicolon())
1555 if ((statement = struct_()) == NULL)
1557 if (!matchSemicolon())
1562 cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1569 if (!statements->append(statement))
1573 return new (pool_) ParseTree(scope_, statements, unbound_);
1576 class AstPrinter : public AstVisitor
1583 for (size_t i = 0; i < level_; i++)
1594 AstPrinter(FILE *fp)
1600 void dump(const FunctionSignature &sig) {
1602 fprintf(fp_, "%s", sig.returnType()
1603 ? sig.returnType()->name()->chars()
1605 if (sig.returnDimensions()) {
1606 for (size_t i = 0; i < sig.returnDimensions()->length(); i++)
1609 fprintf(fp_, "()\n");
1611 void visit(NameProxy *name) {
1613 fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1614 (name->binding() ? "" : " unbound"));
1616 void visit(CallExpression *node) {
1618 fprintf(fp_, "[ CallExpression\n");
1620 node->callee()->accept(this);
1621 for (size_t i = 0; i < node->arguments()->length(); i++)
1622 node->arguments()->at(i)->accept(this);
1625 void visit(FunctionTypeStatement *node) {
1627 fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->decl()->name()->chars());
1629 dump(node->signature());
1632 void visit(FunctionStatement *node) {
1634 fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1636 dump(node->signature());
1638 node->body()->accept(this);
1641 void visit(ExpressionStatement *node) {
1643 fprintf(fp_, "[ ExpressionStatement\n");
1645 node->expression()->accept(this);
1648 void visit(Assignment *node) {
1650 fprintf(fp_, "[ Assignment\n");
1652 node->lvalue()->accept(this);
1653 node->expression()->accept(this);
1656 void visit(TernaryExpression *node) {
1658 fprintf(fp_, "[ TernaryExpression\n");
1660 node->condition()->accept(this);
1661 node->left()->accept(this);
1662 node->right()->accept(this);
1665 void visit(BinaryExpression *node) {
1667 fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1669 node->left()->accept(this);
1670 node->right()->accept(this);
1673 void visit(UnaryExpression *node) {
1675 fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1677 node->expression()->accept(this);
1680 void visit(ReturnStatement *node) {
1682 fprintf(fp_, "[ ReturnStatement\n");
1684 if (node->expression())
1685 node->expression()->accept(this);
1688 void visit(ForStatement *node) {
1690 fprintf(fp_, "[ ForStatement\n");
1692 if (node->initialization())
1693 node->initialization()->accept(this);
1694 if (node->condition())
1695 node->condition()->accept(this);
1697 node->update()->accept(this);
1698 node->body()->accept(this);
1701 void visit(BlockStatement *node) {
1703 fprintf(fp_, "[ BlockStatement\n");
1705 for (size_t i = 0; i < node->statements()->length(); i++)
1706 node->statements()->at(i)->accept(this);
1709 void visit(VariableDeclaration *node) {
1711 fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1713 if (node->initialization())
1714 node->initialization()->accept(this);
1717 void visit(IntegerLiteral *node) {
1719 fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1721 void visit(BooleanLiteral *node) {
1723 fprintf(fp_, "[ BooleanLiteral (%s)\n",
1724 (node->token() == TOK_TRUE) ? "true" : "false");
1726 void visit(FloatLiteral *node) {
1728 fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1730 void visit(IfStatement *node) {
1732 fprintf(fp_, "[ IfStatement\n");
1734 node->ifTrue()->accept(this);
1735 if (node->ifFalse())
1736 node->ifFalse()->accept(this);
1739 void visit(IndexExpression *node) {
1741 fprintf(fp_, "[ IndexExpression\n");
1743 node->left()->accept(this);
1744 node->right()->accept(this);
1747 void visit(EnumStatement *node) {
1749 fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1751 for (size_t i = 0; i < node->entries()->length(); i++) {
1753 fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1754 if (node->entries()->at(i).expr) {
1756 node->entries()->at(i).expr->accept(this);
1762 void visit(WhileStatement *node) {
1764 fprintf(fp_, "[ WhileStatement (%s)\n",
1765 (node->token() == TOK_DO) ? "do" : "while");
1767 if (node->token() == TOK_DO) {
1768 node->condition()->accept(this);
1769 node->body()->accept(this);
1771 node->condition()->accept(this);
1772 node->body()->accept(this);
1776 void visit(BreakStatement *node) {
1778 fprintf(fp_, "[ BreakStatement\n");
1780 void visit(ContinueStatement *node) {
1782 fprintf(fp_, "[ ContinueStatement\n");
1784 void visit(StringLiteral *node) {
1786 fprintf(fp_, "[ StringLiteral\n");
1788 void visit(IncDecExpression *node) {
1790 fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1792 node->expression()->accept(this);
1795 void visit(StructureStatement *node) {
1797 fprintf(fp_, "[ StructureStatement %s\n", node->decl()->name()->chars());
1799 void visit(FieldExpression *node) {
1801 fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1803 node->left()->accept(this);
1806 void visit(SwitchStatement *node) {
1808 fprintf(fp_, "[ SwitchStatement\n");
1810 node->expression()->accept(this);
1811 for (size_t i = 0; i < node->cases()->length(); i++) {
1812 Case *c = node->cases()->at(i);
1813 c->expression()->accept(this);
1815 for (size_t j = 0; j < c->others()->length(); j++)
1816 c->others()->at(j)->accept(this);
1819 c->statement()->accept(this);
1822 if (node->defaultCase())
1823 node->defaultCase()->accept(this);
1826 void visit(ArrayLiteral *node) {
1828 fprintf(fp_, "[ ArrayLiteral\n");
1830 for (size_t i = 0; i < node->expressions()->length(); i++) {
1831 Expression *expr = node->expressions()->at(i);
1840 ParseTree::dump(FILE *fp)
1842 AstPrinter printer(fp);
1844 for (size_t i = 0; i < statements_->length(); i++)
1845 statements_->at(i)->accept(&printer);