Chromium Code Reviews| 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 8626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8637 } | 8637 } |
| 8638 current_block_->scope->AddVariable(loop_var); | 8638 current_block_->scope->AddVariable(loop_var); |
| 8639 loop_var_assignment = new(Z) StoreLocalNode( | 8639 loop_var_assignment = new(Z) StoreLocalNode( |
| 8640 loop_var_assignment_pos, loop_var, iterator_current); | 8640 loop_var_assignment_pos, loop_var, iterator_current); |
| 8641 } else { | 8641 } else { |
| 8642 AstNode* loop_var_primary = | 8642 AstNode* loop_var_primary = |
| 8643 ResolveIdent(loop_var_pos, *loop_var_name, false); | 8643 ResolveIdent(loop_var_pos, *loop_var_name, false); |
| 8644 ASSERT(!loop_var_primary->IsPrimaryNode()); | 8644 ASSERT(!loop_var_primary->IsPrimaryNode()); |
| 8645 loop_var_assignment = CreateAssignmentNode(loop_var_primary, | 8645 loop_var_assignment = CreateAssignmentNode(loop_var_primary, |
| 8646 iterator_current, | 8646 iterator_current, |
| 8647 false, | |
|
srdjan
2015/08/11 19:26:10
Add comment /*is_compound */
| |
| 8647 loop_var_name, | 8648 loop_var_name, |
| 8648 loop_var_assignment_pos); | 8649 loop_var_assignment_pos); |
| 8649 ASSERT(loop_var_assignment != NULL); | 8650 ASSERT(loop_var_assignment != NULL); |
| 8650 } | 8651 } |
| 8651 current_block_->statements->Add(loop_var_assignment); | 8652 current_block_->statements->Add(loop_var_assignment); |
| 8652 | 8653 |
| 8653 // Now parse the for-in loop statement or block. | 8654 // Now parse the for-in loop statement or block. |
| 8654 if (CurrentToken() == Token::kLBRACE) { | 8655 if (CurrentToken() == Token::kLBRACE) { |
| 8655 ConsumeToken(); | 8656 ConsumeToken(); |
| 8656 ParseStatementSequence(); | 8657 ParseStatementSequence(); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8855 } | 8856 } |
| 8856 current_block_->scope->AddVariable(loop_var); | 8857 current_block_->scope->AddVariable(loop_var); |
| 8857 loop_var_assignment = new(Z) StoreLocalNode( | 8858 loop_var_assignment = new(Z) StoreLocalNode( |
| 8858 loop_var_assignment_pos, loop_var, iterator_current); | 8859 loop_var_assignment_pos, loop_var, iterator_current); |
| 8859 } else { | 8860 } else { |
| 8860 AstNode* loop_var_primary = | 8861 AstNode* loop_var_primary = |
| 8861 ResolveIdent(loop_var_pos, *loop_var_name, false); | 8862 ResolveIdent(loop_var_pos, *loop_var_name, false); |
| 8862 ASSERT(!loop_var_primary->IsPrimaryNode()); | 8863 ASSERT(!loop_var_primary->IsPrimaryNode()); |
| 8863 loop_var_assignment = CreateAssignmentNode(loop_var_primary, | 8864 loop_var_assignment = CreateAssignmentNode(loop_var_primary, |
| 8864 iterator_current, | 8865 iterator_current, |
| 8866 false, | |
|
srdjan
2015/08/11 19:26:10
ditto
| |
| 8865 loop_var_name, | 8867 loop_var_name, |
| 8866 loop_var_assignment_pos); | 8868 loop_var_assignment_pos); |
| 8867 ASSERT(loop_var_assignment != NULL); | 8869 ASSERT(loop_var_assignment != NULL); |
| 8868 } | 8870 } |
| 8869 current_block_->statements->Add(loop_var_assignment); | 8871 current_block_->statements->Add(loop_var_assignment); |
| 8870 | 8872 |
| 8871 // Now parse the for-in loop statement or block. | 8873 // Now parse the for-in loop statement or block. |
| 8872 if (CurrentToken() == Token::kLBRACE) { | 8874 if (CurrentToken() == Token::kLBRACE) { |
| 8873 ConsumeToken(); | 8875 ConsumeToken(); |
| 8874 ParseStatementSequence(); | 8876 ParseStatementSequence(); |
| (...skipping 1687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10562 token = CurrentToken(); | 10564 token = CurrentToken(); |
| 10563 ConsumeToken(); | 10565 ConsumeToken(); |
| 10564 } | 10566 } |
| 10565 ASSERT(TokenPos() == end_pos); | 10567 ASSERT(TokenPos() == end_pos); |
| 10566 return Token::IsIdentifier(token) || (token == Token::kRBRACK); | 10568 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
| 10567 } | 10569 } |
| 10568 | 10570 |
| 10569 | 10571 |
| 10570 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 10572 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
| 10571 AstNode* rhs, | 10573 AstNode* rhs, |
| 10574 bool is_compound, | |
| 10572 const String* left_ident, | 10575 const String* left_ident, |
| 10573 intptr_t left_pos) { | 10576 intptr_t left_pos) { |
| 10574 AstNode* result = original->MakeAssignmentNode(rhs); | 10577 AstNode* result = original->MakeAssignmentNode(rhs); |
| 10575 if (result == NULL) { | 10578 if (result == NULL) { |
| 10576 String& name = String::ZoneHandle(Z); | 10579 String& name = String::ZoneHandle(Z); |
| 10577 const Class* target_cls = ¤t_class(); | 10580 const Class* target_cls = ¤t_class(); |
| 10578 if (original->IsTypeNode()) { | 10581 if (original->IsTypeNode()) { |
| 10579 name = Symbols::New(original->AsTypeNode()->TypeName()); | 10582 name = Symbols::New(original->AsTypeNode()->TypeName()); |
| 10580 } else if (original->IsLoadStaticFieldNode()) { | 10583 } else if (original->IsLoadStaticFieldNode()) { |
| 10581 name = original->AsLoadStaticFieldNode()->field().name(); | 10584 name = original->AsLoadStaticFieldNode()->field().name(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 10601 InvocationMirror::kLocalVar : InvocationMirror::kSetter, | 10604 InvocationMirror::kLocalVar : InvocationMirror::kSetter, |
| 10602 NULL)); // No existing function. | 10605 NULL)); // No existing function. |
| 10603 result = let_node; | 10606 result = let_node; |
| 10604 } | 10607 } |
| 10605 // The compound assignment operator a ??= b is different from other | 10608 // 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 | 10609 // a op= b assignments. If a is non-null, the assignment to a must be |
| 10607 // dropped: | 10610 // dropped: |
| 10608 // normally: a op= b ==> a = a op b | 10611 // normally: a op= b ==> a = a op b |
| 10609 // however: a ??= b ==> a ?? (a = b) | 10612 // however: a ??= b ==> a ?? (a = b) |
| 10610 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) | 10613 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) |
| 10611 if (rhs->IsBinaryOpNode() && | 10614 if (is_compound && |
| 10615 rhs->IsBinaryOpNode() && | |
| 10612 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { | 10616 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { |
| 10613 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); | 10617 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); |
| 10614 AstNode* modified_assign = | 10618 AstNode* modified_assign = |
| 10615 CreateAssignmentNode(ifnull->left(), | 10619 CreateAssignmentNode(original, |
| 10616 ifnull->right(), | 10620 ifnull->right(), |
| 10621 false, | |
|
srdjan
2015/08/11 19:26:10
ditto
| |
| 10617 left_ident, | 10622 left_ident, |
| 10618 left_pos); | 10623 left_pos); |
| 10619 result = new(Z) BinaryOpNode(rhs->token_pos(), | 10624 result = new(Z) BinaryOpNode(rhs->token_pos(), |
| 10620 Token::kIFNULL, | 10625 Token::kIFNULL, |
| 10621 original, | 10626 ifnull->left(), |
| 10622 modified_assign); | 10627 modified_assign); |
| 10623 } | 10628 } |
| 10624 return result; | 10629 return result; |
| 10625 } | 10630 } |
| 10626 | 10631 |
| 10627 | 10632 |
| 10628 AstNode* Parser::ParseCascades(AstNode* expr) { | 10633 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 10629 intptr_t cascade_pos = TokenPos(); | 10634 intptr_t cascade_pos = TokenPos(); |
| 10630 LetNode* cascade = new(Z) LetNode(cascade_pos); | 10635 LetNode* cascade = new(Z) LetNode(cascade_pos); |
| 10631 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 10636 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 10653 const intptr_t assignment_pos = TokenPos(); | 10658 const intptr_t assignment_pos = TokenPos(); |
| 10654 ConsumeToken(); | 10659 ConsumeToken(); |
| 10655 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); | 10660 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); |
| 10656 if (assignment_op != Token::kASSIGN) { | 10661 if (assignment_op != Token::kASSIGN) { |
| 10657 // Compound assignment: store inputs with side effects into | 10662 // Compound assignment: store inputs with side effects into |
| 10658 // temporary locals. | 10663 // temporary locals. |
| 10659 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10664 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10660 right_expr = | 10665 right_expr = |
| 10661 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10666 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 10662 AstNode* assign_expr = | 10667 AstNode* assign_expr = |
| 10663 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); | 10668 CreateAssignmentNode(expr, right_expr, true, expr_ident, expr_pos); |
|
srdjan
2015/08/11 19:26:10
comment what true means (and below false). Also at
| |
| 10664 ASSERT(assign_expr != NULL); | 10669 ASSERT(assign_expr != NULL); |
| 10665 let_expr->AddNode(assign_expr); | 10670 let_expr->AddNode(assign_expr); |
| 10666 expr = let_expr; | 10671 expr = let_expr; |
| 10667 } else { | 10672 } else { |
| 10668 right_expr = | 10673 right_expr = |
| 10669 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10674 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 10670 AstNode* assign_expr = | 10675 AstNode* assign_expr = |
| 10671 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); | 10676 CreateAssignmentNode(expr, right_expr, false, expr_ident, expr_pos); |
| 10672 ASSERT(assign_expr != NULL); | 10677 ASSERT(assign_expr != NULL); |
| 10673 expr = assign_expr; | 10678 expr = assign_expr; |
| 10674 } | 10679 } |
| 10675 } | 10680 } |
| 10676 cascade->AddNode(expr); | 10681 cascade->AddNode(expr); |
| 10677 } | 10682 } |
| 10678 // The result is an expression with the (side effects of the) cascade | 10683 // The result is an expression with the (side effects of the) cascade |
| 10679 // sequence followed by the (value of the) receiver temp variable load. | 10684 // sequence followed by the (value of the) receiver temp variable load. |
| 10680 cascade->AddNode(new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); | 10685 cascade->AddNode(new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); |
| 10681 return cascade; | 10686 return cascade; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10766 ReportError(right_expr_pos, | 10771 ReportError(right_expr_pos, |
| 10767 "expression is not a valid compile-time constant"); | 10772 "expression is not a valid compile-time constant"); |
| 10768 } | 10773 } |
| 10769 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 10774 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 10770 if (assignment_op != Token::kASSIGN) { | 10775 if (assignment_op != Token::kASSIGN) { |
| 10771 // Compound assignment: store inputs with side effects into temp. locals. | 10776 // Compound assignment: store inputs with side effects into temp. locals. |
| 10772 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10777 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10773 AstNode* assigned_value = | 10778 AstNode* assigned_value = |
| 10774 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10779 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 10775 AstNode* assign_expr = | 10780 AstNode* assign_expr = |
| 10776 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 10781 CreateAssignmentNode(expr, assigned_value, true, expr_ident, expr_pos); |
| 10777 ASSERT(assign_expr != NULL); | 10782 ASSERT(assign_expr != NULL); |
| 10778 let_expr->AddNode(assign_expr); | 10783 let_expr->AddNode(assign_expr); |
| 10779 return let_expr; | 10784 return let_expr; |
| 10780 } else { | 10785 } else { |
| 10781 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); | 10786 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); |
| 10782 AstNode* assign_expr = | 10787 AstNode* assign_expr = |
| 10783 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 10788 CreateAssignmentNode(expr, assigned_value, false, expr_ident, expr_pos); |
| 10784 ASSERT(assign_expr != NULL); | 10789 ASSERT(assign_expr != NULL); |
| 10785 return assign_expr; | 10790 return assign_expr; |
| 10786 } | 10791 } |
| 10787 } | 10792 } |
| 10788 | 10793 |
| 10789 | 10794 |
| 10790 LiteralNode* Parser::ParseConstExpr() { | 10795 LiteralNode* Parser::ParseConstExpr() { |
| 10791 TRACE_PARSER("ParseConstExpr"); | 10796 TRACE_PARSER("ParseConstExpr"); |
| 10792 intptr_t expr_pos = TokenPos(); | 10797 intptr_t expr_pos = TokenPos(); |
| 10793 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 10798 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10867 } | 10872 } |
| 10868 // Is prefix. | 10873 // Is prefix. |
| 10869 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10874 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10870 Token::Kind binary_op = | 10875 Token::Kind binary_op = |
| 10871 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 10876 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 10872 BinaryOpNode* add = new(Z) BinaryOpNode( | 10877 BinaryOpNode* add = new(Z) BinaryOpNode( |
| 10873 op_pos, | 10878 op_pos, |
| 10874 binary_op, | 10879 binary_op, |
| 10875 expr, | 10880 expr, |
| 10876 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); | 10881 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); |
| 10877 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 10882 AstNode* store = |
| 10883 CreateAssignmentNode(expr, add, true, expr_ident, expr_pos); | |
| 10878 ASSERT(store != NULL); | 10884 ASSERT(store != NULL); |
| 10879 let_expr->AddNode(store); | 10885 let_expr->AddNode(store); |
| 10880 expr = let_expr; | 10886 expr = let_expr; |
| 10881 } else { | 10887 } else { |
| 10882 expr = ParsePostfixExpr(); | 10888 expr = ParsePostfixExpr(); |
| 10883 } | 10889 } |
| 10884 return expr; | 10890 return expr; |
| 10885 } | 10891 } |
| 10886 | 10892 |
| 10887 | 10893 |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11584 // Not prefix. | 11590 // Not prefix. |
| 11585 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11591 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 11586 LocalVariable* temp = let_expr->AddInitializer(expr); | 11592 LocalVariable* temp = let_expr->AddInitializer(expr); |
| 11587 Token::Kind binary_op = | 11593 Token::Kind binary_op = |
| 11588 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 11594 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 11589 BinaryOpNode* add = new(Z) BinaryOpNode( | 11595 BinaryOpNode* add = new(Z) BinaryOpNode( |
| 11590 expr_pos, | 11596 expr_pos, |
| 11591 binary_op, | 11597 binary_op, |
| 11592 new(Z) LoadLocalNode(expr_pos, temp), | 11598 new(Z) LoadLocalNode(expr_pos, temp), |
| 11593 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1)))); | 11599 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1)))); |
| 11594 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 11600 AstNode* store = |
| 11601 CreateAssignmentNode(expr, add, true, expr_ident, expr_pos); | |
| 11595 ASSERT(store != NULL); | 11602 ASSERT(store != NULL); |
| 11596 // The result is a pair of the (side effects of the) store followed by | 11603 // The result is a pair of the (side effects of the) store followed by |
| 11597 // the (value of the) initial value temp variable load. | 11604 // the (value of the) initial value temp variable load. |
| 11598 let_expr->AddNode(store); | 11605 let_expr->AddNode(store); |
| 11599 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp)); | 11606 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp)); |
| 11600 return let_expr; | 11607 return let_expr; |
| 11601 } | 11608 } |
| 11602 return expr; | 11609 return expr; |
| 11603 } | 11610 } |
| 11604 | 11611 |
| (...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14064 void Parser::SkipQualIdent() { | 14071 void Parser::SkipQualIdent() { |
| 14065 ASSERT(IsIdentifier()); | 14072 ASSERT(IsIdentifier()); |
| 14066 ConsumeToken(); | 14073 ConsumeToken(); |
| 14067 if (CurrentToken() == Token::kPERIOD) { | 14074 if (CurrentToken() == Token::kPERIOD) { |
| 14068 ConsumeToken(); // Consume the kPERIOD token. | 14075 ConsumeToken(); // Consume the kPERIOD token. |
| 14069 ExpectIdentifier("identifier expected after '.'"); | 14076 ExpectIdentifier("identifier expected after '.'"); |
| 14070 } | 14077 } |
| 14071 } | 14078 } |
| 14072 | 14079 |
| 14073 } // namespace dart | 14080 } // namespace dart |
| OLD | NEW |