OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 | 6 |
7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
(...skipping 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1388 | 1388 |
1389 AstNode* Parser::ParseSuperOperator() { | 1389 AstNode* Parser::ParseSuperOperator() { |
1390 TRACE_PARSER("ParseSuperOperator"); | 1390 TRACE_PARSER("ParseSuperOperator"); |
1391 AstNode* super_op = NULL; | 1391 AstNode* super_op = NULL; |
1392 const intptr_t operator_pos = TokenPos(); | 1392 const intptr_t operator_pos = TokenPos(); |
1393 | 1393 |
1394 if (CurrentToken() == Token::kLBRACK) { | 1394 if (CurrentToken() == Token::kLBRACK) { |
1395 ConsumeToken(); | 1395 ConsumeToken(); |
1396 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 1396 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
1397 ExpectToken(Token::kRBRACK); | 1397 ExpectToken(Token::kRBRACK); |
1398 | |
1399 if (Token::IsAssignmentOperator(CurrentToken()) && | |
1400 (CurrentToken() != Token::kASSIGN)) { | |
1401 // Compound assignment. Ensure side effects in index expression | |
1402 // only execute once. If the index is not a local variable or an | |
1403 // literal, evaluate and save in a temporary local. | |
1404 if (!IsSimpleLocalOrLiteralNode(index_expr)) { | |
1405 LocalVariable* temp = | |
1406 CreateTempConstVariable(operator_pos, "lix"); | |
1407 AstNode* save = new StoreLocalNode(operator_pos, temp, index_expr); | |
1408 current_block_->statements->Add(save); | |
1409 index_expr = new LoadLocalNode(operator_pos, temp); | |
1410 } | |
1411 } | |
1412 | |
1413 // Resolve the [] operator function in the superclass. | |
1414 const String& index_operator_name = | |
1415 String::ZoneHandle(Symbols::IndexToken()); | |
1416 const bool kResolveGetter = false; | |
1417 bool is_no_such_method = false; | |
1418 const Function& index_operator = Function::ZoneHandle( | |
1419 GetSuperFunction(operator_pos, | |
1420 index_operator_name, | |
1421 kResolveGetter, | |
1422 &is_no_such_method)); | |
1423 | |
1424 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos); | |
1425 AstNode* receiver = LoadReceiver(operator_pos); | 1398 AstNode* receiver = LoadReceiver(operator_pos); |
1426 index_op_arguments->Add(receiver); | 1399 const Class& super_class = Class::ZoneHandle(current_class().SuperClass()); |
1427 index_op_arguments->Add(index_expr); | 1400 ASSERT(!super_class.IsNull()); |
1428 | 1401 super_op = |
1429 if (is_no_such_method) { | 1402 new LoadIndexedNode(operator_pos, receiver, index_expr, super_class); |
1430 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name, | |
1431 *index_op_arguments); | |
1432 } | |
1433 super_op = new StaticCallNode( | |
1434 operator_pos, index_operator, index_op_arguments); | |
1435 | |
1436 if (Token::IsAssignmentOperator(CurrentToken())) { | |
1437 Token::Kind assignment_op = CurrentToken(); | |
1438 ConsumeToken(); | |
1439 AstNode* value = ParseExpr(kAllowConst, kConsumeCascades); | |
1440 | |
1441 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value); | |
1442 | |
1443 // Resolve the []= operator function in the superclass. | |
1444 const String& assign_index_operator_name = | |
1445 String::ZoneHandle(Symbols::AssignIndexToken()); | |
1446 const bool kResolveGetter = false; | |
1447 bool is_no_such_method = false; | |
1448 const Function& assign_index_operator = Function::ZoneHandle( | |
1449 GetSuperFunction(operator_pos, | |
1450 assign_index_operator_name, | |
1451 kResolveGetter, | |
1452 &is_no_such_method)); | |
1453 | |
1454 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos); | |
1455 operator_args->Add(LoadReceiver(operator_pos)); | |
1456 operator_args->Add(index_expr); | |
1457 operator_args->Add(value); | |
1458 | |
1459 if (is_no_such_method) { | |
1460 operator_args = BuildNoSuchMethodArguments(assign_index_operator_name, | |
1461 *operator_args); | |
1462 } | |
1463 super_op = new StaticCallNode( | |
1464 operator_pos, assign_index_operator, operator_args); | |
1465 } | |
1466 } else if (Token::CanBeOverloaded(CurrentToken()) || | 1403 } else if (Token::CanBeOverloaded(CurrentToken()) || |
1467 (CurrentToken() == Token::kNE)) { | 1404 (CurrentToken() == Token::kNE)) { |
1468 Token::Kind op = CurrentToken(); | 1405 Token::Kind op = CurrentToken(); |
1469 ConsumeToken(); | 1406 ConsumeToken(); |
1470 | 1407 |
1471 bool negate_result = false; | 1408 bool negate_result = false; |
1472 if (op == Token::kNE) { | 1409 if (op == Token::kNE) { |
1473 op = Token::kEQ; | 1410 op = Token::kEQ; |
1474 negate_result = true; | 1411 negate_result = true; |
1475 } | 1412 } |
(...skipping 5453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6929 if (node->IsLoadIndexedNode()) { | 6866 if (node->IsLoadIndexedNode()) { |
6930 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); | 6867 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); |
6931 LoadIndexedNode* right_node = left_node; | 6868 LoadIndexedNode* right_node = left_node; |
6932 intptr_t token_pos = node->token_pos(); | 6869 intptr_t token_pos = node->token_pos(); |
6933 node = NULL; // Do not use it. | 6870 node = NULL; // Do not use it. |
6934 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { | 6871 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { |
6935 LocalVariable* temp = | 6872 LocalVariable* temp = |
6936 CreateTempConstVariable(token_pos, "lia"); | 6873 CreateTempConstVariable(token_pos, "lia"); |
6937 StoreLocalNode* save = | 6874 StoreLocalNode* save = |
6938 new StoreLocalNode(token_pos, temp, left_node->array()); | 6875 new StoreLocalNode(token_pos, temp, left_node->array()); |
6939 left_node = | 6876 left_node = new LoadIndexedNode(token_pos, |
6940 new LoadIndexedNode(token_pos, save, left_node->index_expr()); | 6877 save, |
| 6878 left_node->index_expr(), |
| 6879 left_node->super_class()); |
6941 right_node = new LoadIndexedNode(token_pos, | 6880 right_node = new LoadIndexedNode(token_pos, |
6942 new LoadLocalNode(token_pos, temp), | 6881 new LoadLocalNode(token_pos, temp), |
6943 right_node->index_expr()); | 6882 right_node->index_expr(), |
| 6883 right_node->super_class()); |
6944 } | 6884 } |
6945 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { | 6885 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { |
6946 LocalVariable* temp = | 6886 LocalVariable* temp = |
6947 CreateTempConstVariable(token_pos, "lix"); | 6887 CreateTempConstVariable(token_pos, "lix"); |
6948 StoreLocalNode* save = | 6888 StoreLocalNode* save = |
6949 new StoreLocalNode(token_pos, temp, left_node->index_expr()); | 6889 new StoreLocalNode(token_pos, temp, left_node->index_expr()); |
6950 left_node = new LoadIndexedNode(token_pos, | 6890 left_node = new LoadIndexedNode(token_pos, |
6951 left_node->array(), | 6891 left_node->array(), |
6952 save); | 6892 save, |
| 6893 left_node->super_class()); |
6953 right_node = new LoadIndexedNode(token_pos, | 6894 right_node = new LoadIndexedNode(token_pos, |
6954 right_node->array(), | 6895 right_node->array(), |
6955 new LoadLocalNode(token_pos, temp)); | 6896 new LoadLocalNode(token_pos, temp), |
| 6897 right_node->super_class()); |
6956 } | 6898 } |
6957 *expr = right_node; | 6899 *expr = right_node; |
6958 return left_node; | 6900 return left_node; |
6959 } | 6901 } |
6960 if (node->IsInstanceGetterNode()) { | 6902 if (node->IsInstanceGetterNode()) { |
6961 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); | 6903 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); |
6962 InstanceGetterNode* right_node = left_node; | 6904 InstanceGetterNode* right_node = left_node; |
6963 intptr_t token_pos = node->token_pos(); | 6905 intptr_t token_pos = node->token_pos(); |
6964 node = NULL; // Do not use it. | 6906 node = NULL; // Do not use it. |
6965 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { | 6907 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7506 if (left->IsPrimaryNode()) { | 7448 if (left->IsPrimaryNode()) { |
7507 PrimaryNode* primary = left->AsPrimaryNode(); | 7449 PrimaryNode* primary = left->AsPrimaryNode(); |
7508 if (primary->primary().IsFunction()) { | 7450 if (primary->primary().IsFunction()) { |
7509 array = LoadClosure(primary); | 7451 array = LoadClosure(primary); |
7510 } else if (primary->primary().IsClass()) { | 7452 } else if (primary->primary().IsClass()) { |
7511 ErrorMsg(bracket_pos, "cannot apply index operator to class"); | 7453 ErrorMsg(bracket_pos, "cannot apply index operator to class"); |
7512 } else { | 7454 } else { |
7513 UNREACHABLE(); // Internal parser error. | 7455 UNREACHABLE(); // Internal parser error. |
7514 } | 7456 } |
7515 } | 7457 } |
7516 selector = new LoadIndexedNode(bracket_pos, array, index); | 7458 selector = new LoadIndexedNode(bracket_pos, |
| 7459 array, |
| 7460 index, |
| 7461 Class::ZoneHandle()); |
7517 } else if (CurrentToken() == Token::kLPAREN) { | 7462 } else if (CurrentToken() == Token::kLPAREN) { |
7518 if (left->IsPrimaryNode()) { | 7463 if (left->IsPrimaryNode()) { |
7519 PrimaryNode* primary = left->AsPrimaryNode(); | 7464 PrimaryNode* primary = left->AsPrimaryNode(); |
7520 const intptr_t primary_pos = primary->token_pos(); | 7465 const intptr_t primary_pos = primary->token_pos(); |
7521 if (primary->primary().IsFunction()) { | 7466 if (primary->primary().IsFunction()) { |
7522 Function& func = Function::CheckedHandle(primary->primary().raw()); | 7467 Function& func = Function::CheckedHandle(primary->primary().raw()); |
7523 String& func_name = String::ZoneHandle(func.name()); | 7468 String& func_name = String::ZoneHandle(func.name()); |
7524 if (func.is_static()) { | 7469 if (func.is_static()) { |
7525 // Parse static function call. | 7470 // Parse static function call. |
7526 Class& cls = Class::Handle(func.Owner()); | 7471 Class& cls = Class::Handle(func.Owner()); |
(...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9502 } | 9447 } |
9503 } else if (CurrentToken() == Token::kLT || | 9448 } else if (CurrentToken() == Token::kLT || |
9504 CurrentToken() == Token::kLBRACK || | 9449 CurrentToken() == Token::kLBRACK || |
9505 CurrentToken() == Token::kINDEX || | 9450 CurrentToken() == Token::kINDEX || |
9506 CurrentToken() == Token::kLBRACE) { | 9451 CurrentToken() == Token::kLBRACE) { |
9507 primary = ParseCompoundLiteral(); | 9452 primary = ParseCompoundLiteral(); |
9508 } else if (CurrentToken() == Token::kSUPER) { | 9453 } else if (CurrentToken() == Token::kSUPER) { |
9509 if (current_function().is_static()) { | 9454 if (current_function().is_static()) { |
9510 ErrorMsg("cannot access superclass from static method"); | 9455 ErrorMsg("cannot access superclass from static method"); |
9511 } | 9456 } |
| 9457 if (current_class().SuperClass() == Class::null()) { |
| 9458 ErrorMsg("class '%s' does not have a superclass", |
| 9459 String::Handle(current_class().Name()).ToCString()); |
| 9460 } |
9512 ConsumeToken(); | 9461 ConsumeToken(); |
9513 if (CurrentToken() == Token::kPERIOD) { | 9462 if (CurrentToken() == Token::kPERIOD) { |
9514 ConsumeToken(); | 9463 ConsumeToken(); |
9515 const String& ident = *ExpectIdentifier("identifier expected"); | 9464 const String& ident = *ExpectIdentifier("identifier expected"); |
9516 if (CurrentToken() == Token::kLPAREN) { | 9465 if (CurrentToken() == Token::kLPAREN) { |
9517 primary = ParseSuperCall(ident); | 9466 primary = ParseSuperCall(ident); |
9518 } else { | 9467 } else { |
9519 primary = ParseSuperFieldAccess(ident); | 9468 primary = ParseSuperFieldAccess(ident); |
9520 } | 9469 } |
9521 } else if ((CurrentToken() == Token::kLBRACK) || | 9470 } else if ((CurrentToken() == Token::kLBRACK) || |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9839 void Parser::SkipQualIdent() { | 9788 void Parser::SkipQualIdent() { |
9840 ASSERT(IsIdentifier()); | 9789 ASSERT(IsIdentifier()); |
9841 ConsumeToken(); | 9790 ConsumeToken(); |
9842 if (CurrentToken() == Token::kPERIOD) { | 9791 if (CurrentToken() == Token::kPERIOD) { |
9843 ConsumeToken(); // Consume the kPERIOD token. | 9792 ConsumeToken(); // Consume the kPERIOD token. |
9844 ExpectIdentifier("identifier expected after '.'"); | 9793 ExpectIdentifier("identifier expected after '.'"); |
9845 } | 9794 } |
9846 } | 9795 } |
9847 | 9796 |
9848 } // namespace dart | 9797 } // namespace dart |
OLD | NEW |