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 5885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5896 SequenceNode* sequence = CloseBlock(); | 5896 SequenceNode* sequence = CloseBlock(); |
5897 sequence->set_label(label); | 5897 sequence->set_label(label); |
5898 if_node = sequence; | 5898 if_node = sequence; |
5899 } | 5899 } |
5900 return if_node; | 5900 return if_node; |
5901 } | 5901 } |
5902 | 5902 |
5903 | 5903 |
5904 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 5904 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
5905 SourceLabel* case_label) { | 5905 SourceLabel* case_label) { |
5906 TRACE_PARSER("ParseCaseStatement"); | 5906 TRACE_PARSER("ParseCaseClause"); |
5907 bool default_seen = false; | 5907 bool default_seen = false; |
5908 const intptr_t case_pos = TokenPos(); | 5908 const intptr_t case_pos = TokenPos(); |
5909 // The case expressions node sequence does not own the enclosing scope. | 5909 // The case expressions node sequence does not own the enclosing scope. |
5910 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); | 5910 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); |
5911 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 5911 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
5912 if (CurrentToken() == Token::kCASE) { | 5912 if (CurrentToken() == Token::kCASE) { |
5913 if (default_seen) { | 5913 if (default_seen) { |
5914 ErrorMsg("default clause must be last case"); | 5914 ErrorMsg("default clause must be last case"); |
5915 } | 5915 } |
5916 ConsumeToken(); // Keyword case. | 5916 ConsumeToken(); // Keyword case. |
5917 const intptr_t expr_pos = TokenPos(); | 5917 const intptr_t expr_pos = TokenPos(); |
5918 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 5918 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); |
5919 AstNode* switch_expr_load = new LoadLocalNode(case_pos, | 5919 AstNode* switch_expr_load = new LoadLocalNode(case_pos, |
5920 switch_expr_value); | 5920 switch_expr_value); |
5921 AstNode* case_comparison = new ComparisonNode(expr_pos, | 5921 AstNode* case_comparison = new ComparisonNode(expr_pos, |
5922 Token::kEQ, | 5922 Token::kEQ, |
5923 expr, | 5923 expr, |
5924 switch_expr_load); | 5924 switch_expr_load); |
5925 case_expressions->Add(case_comparison); | 5925 case_expressions->Add(case_comparison); |
5926 } else { | 5926 } else { |
5927 if (default_seen) { | 5927 if (default_seen) { |
5928 ErrorMsg("only one default clause is allowed"); | 5928 ErrorMsg("only one default clause is allowed"); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5977 } | 5977 } |
5978 | 5978 |
5979 | 5979 |
5980 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 5980 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
5981 TRACE_PARSER("ParseSwitchStatement"); | 5981 TRACE_PARSER("ParseSwitchStatement"); |
5982 ASSERT(CurrentToken() == Token::kSWITCH); | 5982 ASSERT(CurrentToken() == Token::kSWITCH); |
5983 const intptr_t switch_pos = TokenPos(); | 5983 const intptr_t switch_pos = TokenPos(); |
5984 SourceLabel* label = | 5984 SourceLabel* label = |
5985 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 5985 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
5986 ConsumeToken(); | 5986 ConsumeToken(); |
5987 const bool parens_are_mandatory = false; | 5987 ExpectToken(Token::kLPAREN); |
5988 bool paren_found = false; | |
5989 if (CurrentToken() == Token::kLPAREN) { | |
5990 paren_found = true; | |
5991 ConsumeToken(); | |
5992 } else if (parens_are_mandatory) { | |
5993 ErrorMsg("'(' expected"); | |
5994 } | |
5995 const intptr_t expr_pos = TokenPos(); | 5988 const intptr_t expr_pos = TokenPos(); |
5996 AstNode* switch_expr = ParseExpr(kAllowConst, kConsumeCascades); | 5989 AstNode* switch_expr = ParseExpr(kAllowConst, kConsumeCascades); |
5997 if (paren_found) { | 5990 ExpectToken(Token::kRPAREN); |
5998 ExpectToken(Token::kRPAREN); | |
5999 } | |
6000 ExpectToken(Token::kLBRACE); | 5991 ExpectToken(Token::kLBRACE); |
6001 OpenBlock(); | 5992 OpenBlock(); |
6002 current_block_->scope->AddLabel(label); | 5993 current_block_->scope->AddLabel(label); |
6003 | 5994 |
6004 // Store switch expression in temporary local variable. | 5995 // Store switch expression in temporary local variable. |
6005 LocalVariable* temp_variable = | 5996 LocalVariable* temp_variable = |
6006 new LocalVariable(expr_pos, | 5997 new LocalVariable(expr_pos, |
6007 Symbols::SwitchExpr(), | 5998 Symbols::SwitchExpr(), |
6008 Type::ZoneHandle(Type::DynamicType())); | 5999 Type::ZoneHandle(Type::DynamicType())); |
6009 current_block_->scope->AddVariable(temp_variable); | 6000 current_block_->scope->AddVariable(temp_variable); |
(...skipping 16 matching lines...) Expand all Loading... |
6026 if (case_label == NULL) { | 6017 if (case_label == NULL) { |
6027 // Label does not exist yet. Add it to scope of switch statement. | 6018 // Label does not exist yet. Add it to scope of switch statement. |
6028 case_label = | 6019 case_label = |
6029 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); | 6020 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); |
6030 current_block_->scope->AddLabel(case_label); | 6021 current_block_->scope->AddLabel(case_label); |
6031 } else if (case_label->kind() == SourceLabel::kForward) { | 6022 } else if (case_label->kind() == SourceLabel::kForward) { |
6032 // We have seen a 'continue' with this label name. Resolve | 6023 // We have seen a 'continue' with this label name. Resolve |
6033 // the forward reference. | 6024 // the forward reference. |
6034 case_label->ResolveForwardReference(); | 6025 case_label->ResolveForwardReference(); |
6035 } else { | 6026 } else { |
6036 ErrorMsg(label_pos, "name '%s' already exists in scope", | 6027 ErrorMsg(label_pos, "label '%s' already exists in scope", |
6037 label_name->ToCString()); | 6028 label_name->ToCString()); |
6038 } | 6029 } |
6039 ASSERT(case_label->kind() == SourceLabel::kCase); | 6030 ASSERT(case_label->kind() == SourceLabel::kCase); |
6040 } | 6031 } |
6041 if (CurrentToken() == Token::kCASE || | 6032 if (CurrentToken() == Token::kCASE || |
6042 CurrentToken() == Token::kDEFAULT) { | 6033 CurrentToken() == Token::kDEFAULT) { |
6043 if (default_seen) { | 6034 if (default_seen) { |
6044 ErrorMsg("no case clauses allowed after default clause"); | 6035 ErrorMsg("no case clauses allowed after default clause"); |
6045 } | 6036 } |
6046 CaseNode* case_clause = ParseCaseClause(temp_variable, case_label); | 6037 CaseNode* case_clause = ParseCaseClause(temp_variable, case_label); |
6047 default_seen = case_clause->contains_default(); | 6038 default_seen = case_clause->contains_default(); |
6048 current_block_->statements->Add(case_clause); | 6039 current_block_->statements->Add(case_clause); |
6049 } else if (CurrentToken() != Token::kRBRACE) { | 6040 } else if (CurrentToken() != Token::kRBRACE) { |
6050 ErrorMsg("'case' or '}' expected"); | 6041 ErrorMsg("'case' or '}' expected"); |
6051 } else if (case_label != NULL) { | 6042 } else if (case_label != NULL) { |
6052 ErrorMsg("expecting at least one case clause after label"); | 6043 ErrorMsg("expecting at least one case clause after label"); |
6053 } else { | 6044 } else { |
6054 break; | 6045 break; |
6055 } | 6046 } |
6056 } | 6047 } |
6057 | 6048 |
| 6049 // TODO(hausner): Check that all expressions in case clauses are |
| 6050 // of the same class, or implement int or String (issue 7307). |
| 6051 |
6058 // Check for unresolved label references. | 6052 // Check for unresolved label references. |
6059 SourceLabel* unresolved_label = | 6053 SourceLabel* unresolved_label = |
6060 current_block_->scope->CheckUnresolvedLabels(); | 6054 current_block_->scope->CheckUnresolvedLabels(); |
6061 if (unresolved_label != NULL) { | 6055 if (unresolved_label != NULL) { |
6062 ErrorMsg("unresolved reference to label '%s'", | 6056 ErrorMsg("unresolved reference to label '%s'", |
6063 unresolved_label->name().ToCString()); | 6057 unresolved_label->name().ToCString()); |
6064 } | 6058 } |
6065 | 6059 |
6066 SequenceNode* switch_body = CloseBlock(); | 6060 SequenceNode* switch_body = CloseBlock(); |
6067 ExpectToken(Token::kRBRACE); | 6061 ExpectToken(Token::kRBRACE); |
(...skipping 4365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10433 void Parser::SkipQualIdent() { | 10427 void Parser::SkipQualIdent() { |
10434 ASSERT(IsIdentifier()); | 10428 ASSERT(IsIdentifier()); |
10435 ConsumeToken(); | 10429 ConsumeToken(); |
10436 if (CurrentToken() == Token::kPERIOD) { | 10430 if (CurrentToken() == Token::kPERIOD) { |
10437 ConsumeToken(); // Consume the kPERIOD token. | 10431 ConsumeToken(); // Consume the kPERIOD token. |
10438 ExpectIdentifier("identifier expected after '.'"); | 10432 ExpectIdentifier("identifier expected after '.'"); |
10439 } | 10433 } |
10440 } | 10434 } |
10441 | 10435 |
10442 } // namespace dart | 10436 } // namespace dart |
OLD | NEW |