| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 6003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6014 ASSERT(!equal_op.IsNull()); | 6014 ASSERT(!equal_op.IsNull()); |
| 6015 cls = equal_op.Owner(); | 6015 cls = equal_op.Owner(); |
| 6016 return !cls.IsObjectClass(); | 6016 return !cls.IsObjectClass(); |
| 6017 } | 6017 } |
| 6018 | 6018 |
| 6019 | 6019 |
| 6020 // Check that all case expressions are of the same type, either int, String, | 6020 // Check that all case expressions are of the same type, either int, String, |
| 6021 // or any other class that does not override the == operator. | 6021 // or any other class that does not override the == operator. |
| 6022 // The expressions are compile-time constants and are thus in the form | 6022 // The expressions are compile-time constants and are thus in the form |
| 6023 // of a LiteralNode. | 6023 // of a LiteralNode. |
| 6024 void Parser::CheckCaseExpressions(const GrowableArray<LiteralNode*>& values) { | 6024 RawType* Parser::CheckCaseExpressions( |
| 6025 const GrowableArray<LiteralNode*>& values) { |
| 6025 const intptr_t num_expressions = values.length(); | 6026 const intptr_t num_expressions = values.length(); |
| 6026 if (num_expressions == 0) { | 6027 if (num_expressions == 0) { |
| 6027 return; | 6028 return Type::DynamicType(); |
| 6028 } | 6029 } |
| 6029 const Instance& first_value = values[0]->literal(); | 6030 const Instance& first_value = values[0]->literal(); |
| 6030 for (intptr_t i = 0; i < num_expressions; i++) { | 6031 for (intptr_t i = 0; i < num_expressions; i++) { |
| 6031 const Instance& val = values[i]->literal(); | 6032 const Instance& val = values[i]->literal(); |
| 6032 const intptr_t val_pos = values[i]->token_pos(); | 6033 const intptr_t val_pos = values[i]->token_pos(); |
| 6033 if (first_value.IsInteger()) { | 6034 if (first_value.IsInteger()) { |
| 6034 if (!val.IsInteger()) { | 6035 if (!val.IsInteger()) { |
| 6035 ErrorMsg(val_pos, "expected case expression of type int"); | 6036 ErrorMsg(val_pos, "expected case expression of type int"); |
| 6036 } | 6037 } |
| 6037 continue; | 6038 continue; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6052 // The value is of some type other than int, String or double. | 6053 // The value is of some type other than int, String or double. |
| 6053 // Check that the type class does not override the == operator. | 6054 // Check that the type class does not override the == operator. |
| 6054 // Check this only in the first loop iteration since all values | 6055 // Check this only in the first loop iteration since all values |
| 6055 // are of the same type, which we check above. | 6056 // are of the same type, which we check above. |
| 6056 if (ImplementsEqualOperator(val)) { | 6057 if (ImplementsEqualOperator(val)) { |
| 6057 ErrorMsg(val_pos, | 6058 ErrorMsg(val_pos, |
| 6058 "type class of case expression must not implement operator =="); | 6059 "type class of case expression must not implement operator =="); |
| 6059 } | 6060 } |
| 6060 } | 6061 } |
| 6061 } | 6062 } |
| 6063 if (first_value.IsInteger()) { |
| 6064 return Type::IntType(); |
| 6065 } else if (first_value.IsString()) { |
| 6066 return Type::StringType(); |
| 6067 } |
| 6068 return Type::NewNonParameterizedType(Class::Handle(first_value.clazz())); |
| 6062 } | 6069 } |
| 6063 | 6070 |
| 6064 | 6071 |
| 6065 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 6072 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 6066 GrowableArray<LiteralNode*>* case_expr_values, | 6073 GrowableArray<LiteralNode*>* case_expr_values, |
| 6067 SourceLabel* case_label) { | 6074 SourceLabel* case_label) { |
| 6068 TRACE_PARSER("ParseCaseClause"); | 6075 TRACE_PARSER("ParseCaseClause"); |
| 6069 bool default_seen = false; | 6076 bool default_seen = false; |
| 6070 const intptr_t case_pos = TokenPos(); | 6077 const intptr_t case_pos = TokenPos(); |
| 6071 // The case expressions node sequence does not own the enclosing scope. | 6078 // The case expressions node sequence does not own the enclosing scope. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6151 ConsumeToken(); | 6158 ConsumeToken(); |
| 6152 ExpectToken(Token::kLPAREN); | 6159 ExpectToken(Token::kLPAREN); |
| 6153 const intptr_t expr_pos = TokenPos(); | 6160 const intptr_t expr_pos = TokenPos(); |
| 6154 AstNode* switch_expr = ParseExpr(kAllowConst, kConsumeCascades); | 6161 AstNode* switch_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 6155 ExpectToken(Token::kRPAREN); | 6162 ExpectToken(Token::kRPAREN); |
| 6156 ExpectToken(Token::kLBRACE); | 6163 ExpectToken(Token::kLBRACE); |
| 6157 OpenBlock(); | 6164 OpenBlock(); |
| 6158 current_block_->scope->AddLabel(label); | 6165 current_block_->scope->AddLabel(label); |
| 6159 | 6166 |
| 6160 // Store switch expression in temporary local variable. | 6167 // Store switch expression in temporary local variable. |
| 6168 Type& temp_var_type = Type::ZoneHandle(Type::DynamicType()); |
| 6161 LocalVariable* temp_variable = | 6169 LocalVariable* temp_variable = |
| 6162 new LocalVariable(expr_pos, | 6170 new LocalVariable(expr_pos, Symbols::SwitchExpr(), temp_var_type); |
| 6163 Symbols::SwitchExpr(), | |
| 6164 Type::ZoneHandle(Type::DynamicType())); | |
| 6165 current_block_->scope->AddVariable(temp_variable); | 6171 current_block_->scope->AddVariable(temp_variable); |
| 6166 AstNode* save_switch_expr = | 6172 AstNode* save_switch_expr = |
| 6167 new StoreLocalNode(expr_pos, temp_variable, switch_expr); | 6173 new StoreLocalNode(expr_pos, temp_variable, switch_expr); |
| 6168 current_block_->statements->Add(save_switch_expr); | 6174 current_block_->statements->Add(save_switch_expr); |
| 6169 | 6175 |
| 6170 // Parse case clauses | 6176 // Parse case clauses |
| 6171 bool default_seen = false; | 6177 bool default_seen = false; |
| 6172 GrowableArray<LiteralNode*> case_expr_values; | 6178 GrowableArray<LiteralNode*> case_expr_values; |
| 6173 while (true) { | 6179 while (true) { |
| 6174 // Check for statement label | 6180 // Check for statement label |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6207 } else if (CurrentToken() != Token::kRBRACE) { | 6213 } else if (CurrentToken() != Token::kRBRACE) { |
| 6208 ErrorMsg("'case' or '}' expected"); | 6214 ErrorMsg("'case' or '}' expected"); |
| 6209 } else if (case_label != NULL) { | 6215 } else if (case_label != NULL) { |
| 6210 ErrorMsg("expecting at least one case clause after label"); | 6216 ErrorMsg("expecting at least one case clause after label"); |
| 6211 } else { | 6217 } else { |
| 6212 break; | 6218 break; |
| 6213 } | 6219 } |
| 6214 } | 6220 } |
| 6215 | 6221 |
| 6216 // Check that all expressions in case clauses are of the same class, | 6222 // Check that all expressions in case clauses are of the same class, |
| 6217 // or implement int, double or String. | 6223 // or implement int, double or String. Patch the type of the temporary |
| 6218 CheckCaseExpressions(case_expr_values); | 6224 // variable holding the switch expression to match the type of the |
| 6225 // case clause constants. |
| 6226 temp_var_type = CheckCaseExpressions(case_expr_values); |
| 6227 temp_variable->set_type(temp_var_type); |
| 6219 | 6228 |
| 6220 // Check for unresolved label references. | 6229 // Check for unresolved label references. |
| 6221 SourceLabel* unresolved_label = | 6230 SourceLabel* unresolved_label = |
| 6222 current_block_->scope->CheckUnresolvedLabels(); | 6231 current_block_->scope->CheckUnresolvedLabels(); |
| 6223 if (unresolved_label != NULL) { | 6232 if (unresolved_label != NULL) { |
| 6224 ErrorMsg("unresolved reference to label '%s'", | 6233 ErrorMsg("unresolved reference to label '%s'", |
| 6225 unresolved_label->name().ToCString()); | 6234 unresolved_label->name().ToCString()); |
| 6226 } | 6235 } |
| 6227 | 6236 |
| 6228 SequenceNode* switch_body = CloseBlock(); | 6237 SequenceNode* switch_body = CloseBlock(); |
| (...skipping 4339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10568 void Parser::SkipQualIdent() { | 10577 void Parser::SkipQualIdent() { |
| 10569 ASSERT(IsIdentifier()); | 10578 ASSERT(IsIdentifier()); |
| 10570 ConsumeToken(); | 10579 ConsumeToken(); |
| 10571 if (CurrentToken() == Token::kPERIOD) { | 10580 if (CurrentToken() == Token::kPERIOD) { |
| 10572 ConsumeToken(); // Consume the kPERIOD token. | 10581 ConsumeToken(); // Consume the kPERIOD token. |
| 10573 ExpectIdentifier("identifier expected after '.'"); | 10582 ExpectIdentifier("identifier expected after '.'"); |
| 10574 } | 10583 } |
| 10575 } | 10584 } |
| 10576 | 10585 |
| 10577 } // namespace dart | 10586 } // namespace dart |
| OLD | NEW |