| 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 10552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10563 ConsumeToken(); | 10563 ConsumeToken(); |
| 10564 } | 10564 } |
| 10565 ASSERT(TokenPos() == end_pos); | 10565 ASSERT(TokenPos() == end_pos); |
| 10566 return Token::IsIdentifier(token) || (token == Token::kRBRACK); | 10566 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
| 10567 } | 10567 } |
| 10568 | 10568 |
| 10569 | 10569 |
| 10570 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 10570 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
| 10571 AstNode* rhs, | 10571 AstNode* rhs, |
| 10572 const String* left_ident, | 10572 const String* left_ident, |
| 10573 intptr_t left_pos) { | 10573 intptr_t left_pos, |
| 10574 bool is_compound /* = false */) { |
| 10574 AstNode* result = original->MakeAssignmentNode(rhs); | 10575 AstNode* result = original->MakeAssignmentNode(rhs); |
| 10575 if (result == NULL) { | 10576 if (result == NULL) { |
| 10576 String& name = String::ZoneHandle(Z); | 10577 String& name = String::ZoneHandle(Z); |
| 10577 const Class* target_cls = ¤t_class(); | 10578 const Class* target_cls = ¤t_class(); |
| 10578 if (original->IsTypeNode()) { | 10579 if (original->IsTypeNode()) { |
| 10579 name = Symbols::New(original->AsTypeNode()->TypeName()); | 10580 name = Symbols::New(original->AsTypeNode()->TypeName()); |
| 10580 } else if (original->IsLoadStaticFieldNode()) { | 10581 } else if (original->IsLoadStaticFieldNode()) { |
| 10581 name = original->AsLoadStaticFieldNode()->field().name(); | 10582 name = original->AsLoadStaticFieldNode()->field().name(); |
| 10582 target_cls = &Class::Handle(Z, | 10583 target_cls = &Class::Handle(Z, |
| 10583 original->AsLoadStaticFieldNode()->field().owner()); | 10584 original->AsLoadStaticFieldNode()->field().owner()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 10601 InvocationMirror::kLocalVar : InvocationMirror::kSetter, | 10602 InvocationMirror::kLocalVar : InvocationMirror::kSetter, |
| 10602 NULL)); // No existing function. | 10603 NULL)); // No existing function. |
| 10603 result = let_node; | 10604 result = let_node; |
| 10604 } | 10605 } |
| 10605 // The compound assignment operator a ??= b is different from other | 10606 // The compound assignment operator a ??= b is different from other |
| 10606 // a op= b assignments. If a is non-null, the assignment to a must be | 10607 // a op= b assignments. If a is non-null, the assignment to a must be |
| 10607 // dropped: | 10608 // dropped: |
| 10608 // normally: a op= b ==> a = a op b | 10609 // normally: a op= b ==> a = a op b |
| 10609 // however: a ??= b ==> a ?? (a = b) | 10610 // however: a ??= b ==> a ?? (a = b) |
| 10610 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) | 10611 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) |
| 10611 if (rhs->IsBinaryOpNode() && | 10612 if (is_compound && |
| 10613 rhs->IsBinaryOpNode() && |
| 10612 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { | 10614 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { |
| 10613 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); | 10615 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); |
| 10614 AstNode* modified_assign = | 10616 AstNode* modified_assign = |
| 10615 CreateAssignmentNode(ifnull->left(), | 10617 CreateAssignmentNode(original, |
| 10616 ifnull->right(), | 10618 ifnull->right(), |
| 10617 left_ident, | 10619 left_ident, |
| 10618 left_pos); | 10620 left_pos); |
| 10619 result = new(Z) BinaryOpNode(rhs->token_pos(), | 10621 result = new(Z) BinaryOpNode(rhs->token_pos(), |
| 10620 Token::kIFNULL, | 10622 Token::kIFNULL, |
| 10621 original, | 10623 ifnull->left(), |
| 10622 modified_assign); | 10624 modified_assign); |
| 10623 } | 10625 } |
| 10624 return result; | 10626 return result; |
| 10625 } | 10627 } |
| 10626 | 10628 |
| 10627 | 10629 |
| 10628 AstNode* Parser::ParseCascades(AstNode* expr) { | 10630 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 10629 intptr_t cascade_pos = TokenPos(); | 10631 intptr_t cascade_pos = TokenPos(); |
| 10630 LetNode* cascade = new(Z) LetNode(cascade_pos); | 10632 LetNode* cascade = new(Z) LetNode(cascade_pos); |
| 10631 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 10633 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 10653 const intptr_t assignment_pos = TokenPos(); | 10655 const intptr_t assignment_pos = TokenPos(); |
| 10654 ConsumeToken(); | 10656 ConsumeToken(); |
| 10655 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); | 10657 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); |
| 10656 if (assignment_op != Token::kASSIGN) { | 10658 if (assignment_op != Token::kASSIGN) { |
| 10657 // Compound assignment: store inputs with side effects into | 10659 // Compound assignment: store inputs with side effects into |
| 10658 // temporary locals. | 10660 // temporary locals. |
| 10659 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10661 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10660 right_expr = | 10662 right_expr = |
| 10661 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10663 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 10662 AstNode* assign_expr = | 10664 AstNode* assign_expr = |
| 10663 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); | 10665 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos, true); |
| 10664 ASSERT(assign_expr != NULL); | 10666 ASSERT(assign_expr != NULL); |
| 10665 let_expr->AddNode(assign_expr); | 10667 let_expr->AddNode(assign_expr); |
| 10666 expr = let_expr; | 10668 expr = let_expr; |
| 10667 } else { | 10669 } else { |
| 10668 right_expr = | 10670 right_expr = |
| 10669 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10671 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 10670 AstNode* assign_expr = | 10672 AstNode* assign_expr = |
| 10671 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); | 10673 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); |
| 10672 ASSERT(assign_expr != NULL); | 10674 ASSERT(assign_expr != NULL); |
| 10673 expr = assign_expr; | 10675 expr = assign_expr; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10766 ReportError(right_expr_pos, | 10768 ReportError(right_expr_pos, |
| 10767 "expression is not a valid compile-time constant"); | 10769 "expression is not a valid compile-time constant"); |
| 10768 } | 10770 } |
| 10769 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 10771 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 10770 if (assignment_op != Token::kASSIGN) { | 10772 if (assignment_op != Token::kASSIGN) { |
| 10771 // Compound assignment: store inputs with side effects into temp. locals. | 10773 // Compound assignment: store inputs with side effects into temp. locals. |
| 10772 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10774 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10773 AstNode* assigned_value = | 10775 AstNode* assigned_value = |
| 10774 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10776 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 10775 AstNode* assign_expr = | 10777 AstNode* assign_expr = |
| 10776 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 10778 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos, true); |
| 10777 ASSERT(assign_expr != NULL); | 10779 ASSERT(assign_expr != NULL); |
| 10778 let_expr->AddNode(assign_expr); | 10780 let_expr->AddNode(assign_expr); |
| 10779 return let_expr; | 10781 return let_expr; |
| 10780 } else { | 10782 } else { |
| 10781 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); | 10783 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); |
| 10782 AstNode* assign_expr = | 10784 AstNode* assign_expr = |
| 10783 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 10785 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
| 10784 ASSERT(assign_expr != NULL); | 10786 ASSERT(assign_expr != NULL); |
| 10785 return assign_expr; | 10787 return assign_expr; |
| 10786 } | 10788 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10867 } | 10869 } |
| 10868 // Is prefix. | 10870 // Is prefix. |
| 10869 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10871 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10870 Token::Kind binary_op = | 10872 Token::Kind binary_op = |
| 10871 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 10873 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 10872 BinaryOpNode* add = new(Z) BinaryOpNode( | 10874 BinaryOpNode* add = new(Z) BinaryOpNode( |
| 10873 op_pos, | 10875 op_pos, |
| 10874 binary_op, | 10876 binary_op, |
| 10875 expr, | 10877 expr, |
| 10876 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); | 10878 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); |
| 10877 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 10879 AstNode* store = |
| 10880 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); |
| 10878 ASSERT(store != NULL); | 10881 ASSERT(store != NULL); |
| 10879 let_expr->AddNode(store); | 10882 let_expr->AddNode(store); |
| 10880 expr = let_expr; | 10883 expr = let_expr; |
| 10881 } else { | 10884 } else { |
| 10882 expr = ParsePostfixExpr(); | 10885 expr = ParsePostfixExpr(); |
| 10883 } | 10886 } |
| 10884 return expr; | 10887 return expr; |
| 10885 } | 10888 } |
| 10886 | 10889 |
| 10887 | 10890 |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11584 // Not prefix. | 11587 // Not prefix. |
| 11585 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11588 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 11586 LocalVariable* temp = let_expr->AddInitializer(expr); | 11589 LocalVariable* temp = let_expr->AddInitializer(expr); |
| 11587 Token::Kind binary_op = | 11590 Token::Kind binary_op = |
| 11588 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 11591 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 11589 BinaryOpNode* add = new(Z) BinaryOpNode( | 11592 BinaryOpNode* add = new(Z) BinaryOpNode( |
| 11590 expr_pos, | 11593 expr_pos, |
| 11591 binary_op, | 11594 binary_op, |
| 11592 new(Z) LoadLocalNode(expr_pos, temp), | 11595 new(Z) LoadLocalNode(expr_pos, temp), |
| 11593 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1)))); | 11596 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1)))); |
| 11594 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 11597 AstNode* store = |
| 11598 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); |
| 11595 ASSERT(store != NULL); | 11599 ASSERT(store != NULL); |
| 11596 // The result is a pair of the (side effects of the) store followed by | 11600 // The result is a pair of the (side effects of the) store followed by |
| 11597 // the (value of the) initial value temp variable load. | 11601 // the (value of the) initial value temp variable load. |
| 11598 let_expr->AddNode(store); | 11602 let_expr->AddNode(store); |
| 11599 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp)); | 11603 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp)); |
| 11600 return let_expr; | 11604 return let_expr; |
| 11601 } | 11605 } |
| 11602 return expr; | 11606 return expr; |
| 11603 } | 11607 } |
| 11604 | 11608 |
| (...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14064 void Parser::SkipQualIdent() { | 14068 void Parser::SkipQualIdent() { |
| 14065 ASSERT(IsIdentifier()); | 14069 ASSERT(IsIdentifier()); |
| 14066 ConsumeToken(); | 14070 ConsumeToken(); |
| 14067 if (CurrentToken() == Token::kPERIOD) { | 14071 if (CurrentToken() == Token::kPERIOD) { |
| 14068 ConsumeToken(); // Consume the kPERIOD token. | 14072 ConsumeToken(); // Consume the kPERIOD token. |
| 14069 ExpectIdentifier("identifier expected after '.'"); | 14073 ExpectIdentifier("identifier expected after '.'"); |
| 14070 } | 14074 } |
| 14071 } | 14075 } |
| 14072 | 14076 |
| 14073 } // namespace dart | 14077 } // namespace dart |
| OLD | NEW |