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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 10548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10559 (lhs->AsBinaryOpNode()->kind() == Token::kSHL)) { | 10559 (lhs->AsBinaryOpNode()->kind() == Token::kSHL)) { |
10560 // Merge SHL and BIT_AND into one "SHL with mask" node. | 10560 // Merge SHL and BIT_AND into one "SHL with mask" node. |
10561 BinaryOpNode* old = lhs->AsBinaryOpNode(); | 10561 BinaryOpNode* old = lhs->AsBinaryOpNode(); |
10562 BinaryOpWithMask32Node* binop = new(Z) BinaryOpWithMask32Node( | 10562 BinaryOpWithMask32Node* binop = new(Z) BinaryOpWithMask32Node( |
10563 old->token_pos(), old->kind(), old->left(), old->right(), val); | 10563 old->token_pos(), old->kind(), old->left(), old->right(), val); |
10564 return binop; | 10564 return binop; |
10565 } | 10565 } |
10566 } | 10566 } |
10567 } | 10567 } |
10568 } | 10568 } |
| 10569 if (binary_op == Token::kIFNULL) { |
| 10570 // Handle a ?? b. |
| 10571 LetNode* result = new(Z) LetNode(op_pos); |
| 10572 LocalVariable* left_temp = result->AddInitializer(lhs); |
| 10573 const intptr_t no_pos = Scanner::kNoSourcePos; |
| 10574 LiteralNode* null_operand = |
| 10575 new(Z) LiteralNode(no_pos, Instance::ZoneHandle(Z)); |
| 10576 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); |
| 10577 ComparisonNode* null_compare = |
| 10578 new(Z) ComparisonNode(no_pos, |
| 10579 Token::kNE_STRICT, |
| 10580 load_left_temp, |
| 10581 null_operand); |
| 10582 result->AddNode(new(Z) ConditionalExprNode(op_pos, |
| 10583 null_compare, |
| 10584 load_left_temp, |
| 10585 rhs)); |
| 10586 return result; |
| 10587 } |
10569 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 10588 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
10570 } | 10589 } |
10571 | 10590 |
10572 | 10591 |
10573 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, | 10592 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, |
10574 Token::Kind assignment_op, | 10593 Token::Kind assignment_op, |
10575 AstNode* lhs, | 10594 AstNode* lhs, |
10576 AstNode* rhs) { | 10595 AstNode* rhs) { |
10577 TRACE_PARSER("ExpandAssignableOp"); | 10596 TRACE_PARSER("ExpandAssignableOp"); |
10578 switch (assignment_op) { | 10597 switch (assignment_op) { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10730 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) | 10749 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) |
10731 if (is_compound && | 10750 if (is_compound && |
10732 rhs->IsBinaryOpNode() && | 10751 rhs->IsBinaryOpNode() && |
10733 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { | 10752 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { |
10734 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); | 10753 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); |
10735 AstNode* modified_assign = | 10754 AstNode* modified_assign = |
10736 CreateAssignmentNode(original, | 10755 CreateAssignmentNode(original, |
10737 ifnull->right(), | 10756 ifnull->right(), |
10738 left_ident, | 10757 left_ident, |
10739 left_pos); | 10758 left_pos); |
10740 result = new(Z) BinaryOpNode(rhs->token_pos(), | 10759 result = OptimizeBinaryOpNode(ifnull->token_pos(), |
10741 Token::kIFNULL, | 10760 ifnull->kind(), |
10742 ifnull->left(), | 10761 ifnull->left(), |
10743 modified_assign); | 10762 modified_assign); |
10744 } | 10763 } |
10745 return result; | 10764 return result; |
10746 } | 10765 } |
10747 | 10766 |
10748 | 10767 |
10749 AstNode* Parser::ParseCascades(AstNode* expr) { | 10768 AstNode* Parser::ParseCascades(AstNode* expr) { |
10750 intptr_t cascade_pos = TokenPos(); | 10769 intptr_t cascade_pos = TokenPos(); |
10751 LetNode* cascade = new(Z) LetNode(cascade_pos); | 10770 LetNode* cascade = new(Z) LetNode(cascade_pos); |
10752 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 10771 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
10753 while (CurrentToken() == Token::kCASCADE) { | 10772 while (CurrentToken() == Token::kCASCADE) { |
(...skipping 3577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14331 void Parser::SkipQualIdent() { | 14350 void Parser::SkipQualIdent() { |
14332 ASSERT(IsIdentifier()); | 14351 ASSERT(IsIdentifier()); |
14333 ConsumeToken(); | 14352 ConsumeToken(); |
14334 if (CurrentToken() == Token::kPERIOD) { | 14353 if (CurrentToken() == Token::kPERIOD) { |
14335 ConsumeToken(); // Consume the kPERIOD token. | 14354 ConsumeToken(); // Consume the kPERIOD token. |
14336 ExpectIdentifier("identifier expected after '.'"); | 14355 ExpectIdentifier("identifier expected after '.'"); |
14337 } | 14356 } |
14338 } | 14357 } |
14339 | 14358 |
14340 } // namespace dart | 14359 } // namespace dart |
OLD | NEW |