| 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 4821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4832 AstNode* loop_var_assignment = NULL; | 4832 AstNode* loop_var_assignment = NULL; |
| 4833 if (loop_var != NULL) { | 4833 if (loop_var != NULL) { |
| 4834 // The for loop declares a new variable. Add it to the loop body scope. | 4834 // The for loop declares a new variable. Add it to the loop body scope. |
| 4835 current_block_->scope->AddVariable(loop_var); | 4835 current_block_->scope->AddVariable(loop_var); |
| 4836 loop_var_assignment = | 4836 loop_var_assignment = |
| 4837 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); | 4837 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); |
| 4838 } else { | 4838 } else { |
| 4839 AstNode* loop_var_primary = ResolveVarOrField(loop_var_pos, *loop_var_name); | 4839 AstNode* loop_var_primary = ResolveVarOrField(loop_var_pos, *loop_var_name); |
| 4840 ASSERT(!loop_var_primary->IsPrimaryNode()); | 4840 ASSERT(!loop_var_primary->IsPrimaryNode()); |
| 4841 loop_var_assignment = | 4841 loop_var_assignment = |
| 4842 loop_var_primary->MakeAssignmentNode(iterator_next); | 4842 CreateAssignmentNode(loop_var_primary, iterator_next); |
| 4843 if (loop_var_assignment == NULL) { | 4843 if (loop_var_assignment == NULL) { |
| 4844 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", | 4844 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", |
| 4845 loop_var_name->ToCString()); | 4845 loop_var_name->ToCString()); |
| 4846 } | 4846 } |
| 4847 } | 4847 } |
| 4848 current_block_->statements->Add(loop_var_assignment); | 4848 current_block_->statements->Add(loop_var_assignment); |
| 4849 | 4849 |
| 4850 // Now parse the for-in loop statement or block. | 4850 // Now parse the for-in loop statement or block. |
| 4851 if (CurrentToken() == Token::kLBRACE) { | 4851 if (CurrentToken() == Token::kLBRACE) { |
| 4852 ConsumeToken(); | 4852 ConsumeToken(); |
| (...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6102 new LoadLocalNode(token_index, *temp), | 6102 new LoadLocalNode(token_index, *temp), |
| 6103 right_node->field_name()); | 6103 right_node->field_name()); |
| 6104 } | 6104 } |
| 6105 *expr = right_node; | 6105 *expr = right_node; |
| 6106 return left_node; | 6106 return left_node; |
| 6107 } | 6107 } |
| 6108 return *expr; | 6108 return *expr; |
| 6109 } | 6109 } |
| 6110 | 6110 |
| 6111 | 6111 |
| 6112 // Ensure that the expression temp is allocated for nodes that may need it. |
| 6113 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { |
| 6114 AstNode* result = original->MakeAssignmentNode(rhs); |
| 6115 if ((result != NULL) && result->IsStoreIndexedNode()) { |
| 6116 EnsureExpressionTemp(); |
| 6117 } |
| 6118 return result; |
| 6119 } |
| 6120 |
| 6121 |
| 6112 AstNode* Parser::ParseExpr(bool require_compiletime_const) { | 6122 AstNode* Parser::ParseExpr(bool require_compiletime_const) { |
| 6113 TRACE_PARSER("ParseExpr"); | 6123 TRACE_PARSER("ParseExpr"); |
| 6114 const intptr_t expr_pos = token_index_; | 6124 const intptr_t expr_pos = token_index_; |
| 6115 AstNode* expr = ParseConditionalExpr(); | 6125 AstNode* expr = ParseConditionalExpr(); |
| 6116 if (!Token::IsAssignmentOperator(CurrentToken())) { | 6126 if (!Token::IsAssignmentOperator(CurrentToken())) { |
| 6117 if (require_compiletime_const) { | 6127 if (require_compiletime_const) { |
| 6118 expr = FoldConstExpr(expr_pos, expr); | 6128 expr = FoldConstExpr(expr_pos, expr); |
| 6119 } | 6129 } |
| 6120 return expr; | 6130 return expr; |
| 6121 } | 6131 } |
| 6122 // Assignment expressions. | 6132 // Assignment expressions. |
| 6123 Token::Kind assignment_op = CurrentToken(); | 6133 Token::Kind assignment_op = CurrentToken(); |
| 6124 const intptr_t assignment_pos = token_index_; | 6134 const intptr_t assignment_pos = token_index_; |
| 6125 ConsumeToken(); | 6135 ConsumeToken(); |
| 6126 const intptr_t right_expr_pos = token_index_; | 6136 const intptr_t right_expr_pos = token_index_; |
| 6127 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 6137 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 6128 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); | 6138 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); |
| 6129 } | 6139 } |
| 6130 AstNode* right_expr = ParseExpr(require_compiletime_const); | 6140 AstNode* right_expr = ParseExpr(require_compiletime_const); |
| 6131 AstNode* left_expr = expr; | 6141 AstNode* left_expr = expr; |
| 6132 if (assignment_op != Token::kASSIGN) { | 6142 if (assignment_op != Token::kASSIGN) { |
| 6133 // Compound assignment: store inputs with side effects into temp. locals. | 6143 // Compound assignment: store inputs with side effects into temp. locals. |
| 6134 left_expr = PrepareCompoundAssignmentNodes(&expr); | 6144 left_expr = PrepareCompoundAssignmentNodes(&expr); |
| 6135 } | 6145 } |
| 6136 right_expr = | 6146 right_expr = |
| 6137 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 6147 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 6138 AstNode* assign_expr = left_expr->MakeAssignmentNode(right_expr); | 6148 AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr); |
| 6139 if (assign_expr == NULL) { | 6149 if (assign_expr == NULL) { |
| 6140 ErrorMsg(assignment_pos, | 6150 ErrorMsg(assignment_pos, |
| 6141 "left hand side of '%s' is not assignable", | 6151 "left hand side of '%s' is not assignable", |
| 6142 Token::Str(assignment_op)); | 6152 Token::Str(assignment_op)); |
| 6143 } | 6153 } |
| 6144 return assign_expr; | 6154 return assign_expr; |
| 6145 } | 6155 } |
| 6146 | 6156 |
| 6147 | 6157 |
| 6148 LiteralNode* Parser::ParseConstExpr() { | 6158 LiteralNode* Parser::ParseConstExpr() { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6195 } | 6205 } |
| 6196 // Is prefix. | 6206 // Is prefix. |
| 6197 AstNode* left_expr = PrepareCompoundAssignmentNodes(&expr); | 6207 AstNode* left_expr = PrepareCompoundAssignmentNodes(&expr); |
| 6198 Token::Kind binary_op = | 6208 Token::Kind binary_op = |
| 6199 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 6209 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 6200 BinaryOpNode* add = new BinaryOpNode( | 6210 BinaryOpNode* add = new BinaryOpNode( |
| 6201 op_pos, | 6211 op_pos, |
| 6202 binary_op, | 6212 binary_op, |
| 6203 expr, | 6213 expr, |
| 6204 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1)))); | 6214 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1)))); |
| 6205 AstNode* store = left_expr->MakeAssignmentNode(add); | 6215 AstNode* store = CreateAssignmentNode(left_expr, add); |
| 6206 expr = store; | 6216 expr = store; |
| 6207 } else { | 6217 } else { |
| 6208 expr = ParsePostfixExpr(); | 6218 expr = ParsePostfixExpr(); |
| 6209 } | 6219 } |
| 6210 return expr; | 6220 return expr; |
| 6211 } | 6221 } |
| 6212 | 6222 |
| 6213 | 6223 |
| 6214 ArgumentListNode* Parser::ParseActualParameters( | 6224 ArgumentListNode* Parser::ParseActualParameters( |
| 6215 ArgumentListNode* implicit_arguments, | 6225 ArgumentListNode* implicit_arguments, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6360 ConsumeToken(); | 6370 ConsumeToken(); |
| 6361 AstNode* value = ParseExpr(kAllowConst); | 6371 AstNode* value = ParseExpr(kAllowConst); |
| 6362 AstNode* load_access = | 6372 AstNode* load_access = |
| 6363 new InstanceGetterNode(call_pos, receiver, field_name); | 6373 new InstanceGetterNode(call_pos, receiver, field_name); |
| 6364 AstNode* left_load_access = load_access; | 6374 AstNode* left_load_access = load_access; |
| 6365 if (assignment_op != Token::kASSIGN) { | 6375 if (assignment_op != Token::kASSIGN) { |
| 6366 // Compound assignment: store inputs with side effects into temp. locals. | 6376 // Compound assignment: store inputs with side effects into temp. locals. |
| 6367 left_load_access = PrepareCompoundAssignmentNodes(&load_access); | 6377 left_load_access = PrepareCompoundAssignmentNodes(&load_access); |
| 6368 } | 6378 } |
| 6369 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); | 6379 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); |
| 6370 access = left_load_access->MakeAssignmentNode(value); | 6380 access = CreateAssignmentNode(left_load_access, value); |
| 6371 } else { | 6381 } else { |
| 6372 access = CallGetter(call_pos, receiver, field_name); | 6382 access = CallGetter(call_pos, receiver, field_name); |
| 6373 } | 6383 } |
| 6374 return access; | 6384 return access; |
| 6375 } | 6385 } |
| 6376 | 6386 |
| 6377 | 6387 |
| 6378 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 6388 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
| 6379 intptr_t ident_pos) { | 6389 intptr_t ident_pos) { |
| 6380 // If the static field has an initializer, initialize the field at compile | 6390 // If the static field has an initializer, initialize the field at compile |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6443 // Field has been marked as final, report an error as the field | 6453 // Field has been marked as final, report an error as the field |
| 6444 // is not settable. | 6454 // is not settable. |
| 6445 ErrorMsg(ident_pos, | 6455 ErrorMsg(ident_pos, |
| 6446 "field '%s' is const static, cannot assign to it", | 6456 "field '%s' is const static, cannot assign to it", |
| 6447 field_name.ToCString()); | 6457 field_name.ToCString()); |
| 6448 return access; | 6458 return access; |
| 6449 } | 6459 } |
| 6450 load_access = GenerateStaticFieldLookup(field, token_index_); | 6460 load_access = GenerateStaticFieldLookup(field, token_index_); |
| 6451 } | 6461 } |
| 6452 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); | 6462 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); |
| 6453 access = load_access->MakeAssignmentNode(value); | 6463 access = CreateAssignmentNode(load_access, value); |
| 6454 } else { // Not Token::IsAssignmentOperator(CurrentToken()). | 6464 } else { // Not Token::IsAssignmentOperator(CurrentToken()). |
| 6455 if (field.IsNull()) { | 6465 if (field.IsNull()) { |
| 6456 // No field, check if we have an explicit getter function. | 6466 // No field, check if we have an explicit getter function. |
| 6457 const String& getter_name = | 6467 const String& getter_name = |
| 6458 String::ZoneHandle(Field::GetterName(field_name)); | 6468 String::ZoneHandle(Field::GetterName(field_name)); |
| 6459 const int kNumArguments = 0; // no arguments. | 6469 const int kNumArguments = 0; // no arguments. |
| 6460 const Array& kNoArgumentNames = Array::Handle(); | 6470 const Array& kNoArgumentNames = Array::Handle(); |
| 6461 func = Resolver::ResolveStatic(cls, | 6471 func = Resolver::ResolveStatic(cls, |
| 6462 getter_name, | 6472 getter_name, |
| 6463 kNumArguments, | 6473 kNumArguments, |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6686 const LocalVariable& temp = GetIncrementTempLocal(); | 6696 const LocalVariable& temp = GetIncrementTempLocal(); |
| 6687 AstNode* save = | 6697 AstNode* save = |
| 6688 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr); | 6698 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr); |
| 6689 Token::Kind binary_op = | 6699 Token::Kind binary_op = |
| 6690 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 6700 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 6691 BinaryOpNode* add = new BinaryOpNode( | 6701 BinaryOpNode* add = new BinaryOpNode( |
| 6692 postfix_expr_pos, | 6702 postfix_expr_pos, |
| 6693 binary_op, | 6703 binary_op, |
| 6694 save, | 6704 save, |
| 6695 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); | 6705 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); |
| 6696 AstNode* store = left_expr->MakeAssignmentNode(add); | 6706 AstNode* store = CreateAssignmentNode(left_expr, add); |
| 6697 LoadLocalNode* load_res = | 6707 LoadLocalNode* load_res = |
| 6698 new LoadLocalNode(postfix_expr_pos, temp, store); | 6708 new LoadLocalNode(postfix_expr_pos, temp, store); |
| 6699 return load_res; | 6709 return load_res; |
| 6700 } | 6710 } |
| 6701 return postfix_expr; | 6711 return postfix_expr; |
| 6702 } | 6712 } |
| 6703 | 6713 |
| 6704 | 6714 |
| 6705 // Resolve the given type and its type arguments from the given scope class | 6715 // Resolve the given type and its type arguments from the given scope class |
| 6706 // according to the given type finalization mode. | 6716 // according to the given type finalization mode. |
| (...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8506 void Parser::SkipQualIdent() { | 8516 void Parser::SkipQualIdent() { |
| 8507 ASSERT(IsIdentifier()); | 8517 ASSERT(IsIdentifier()); |
| 8508 ConsumeToken(); | 8518 ConsumeToken(); |
| 8509 if (CurrentToken() == Token::kPERIOD) { | 8519 if (CurrentToken() == Token::kPERIOD) { |
| 8510 ConsumeToken(); // Consume the kPERIOD token. | 8520 ConsumeToken(); // Consume the kPERIOD token. |
| 8511 ExpectIdentifier("identifier expected after '.'"); | 8521 ExpectIdentifier("identifier expected after '.'"); |
| 8512 } | 8522 } |
| 8513 } | 8523 } |
| 8514 | 8524 |
| 8515 } // namespace dart | 8525 } // namespace dart |
| OLD | NEW |