| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 | 43 |
| 44 class TraceParser : public ValueObject { | 44 class TraceParser : public ValueObject { |
| 45 public: | 45 public: |
| 46 TraceParser(intptr_t token_pos, const Script& script, const char* msg) { | 46 TraceParser(intptr_t token_pos, const Script& script, const char* msg) { |
| 47 if (FLAG_trace_parser) { | 47 if (FLAG_trace_parser) { |
| 48 // Skips tracing of bootstrap libraries. | 48 // Skips tracing of bootstrap libraries. |
| 49 if (script.HasSource()) { | 49 if (script.HasSource()) { |
| 50 intptr_t line, column; | 50 intptr_t line, column; |
| 51 script.GetTokenLocation(token_pos, &line, &column); | 51 script.GetTokenLocation(token_pos, &line, &column); |
| 52 PrintIndent(); | 52 PrintIndent(); |
| 53 OS::Print("%s (line %d, col %d, token %d)\n", | 53 OS::Print("%s (line %"Pd", col %"Pd", token %"Pd")\n", |
| 54 msg, line, column, token_pos); | 54 msg, line, column, token_pos); |
| 55 } | 55 } |
| 56 indent_++; | 56 indent_++; |
| 57 } | 57 } |
| 58 } | 58 } |
| 59 ~TraceParser() { indent_--; } | 59 ~TraceParser() { indent_--; } |
| 60 private: | 60 private: |
| 61 void PrintIndent() { | 61 void PrintIndent() { |
| 62 for (int i = 0; i < indent_; i++) { OS::Print(". "); } | 62 for (int i = 0; i < indent_; i++) { OS::Print(". "); } |
| 63 } | 63 } |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 339 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 340 Parser parser(script, library); | 340 Parser parser(script, library); |
| 341 parser.ParseTopLevel(); | 341 parser.ParseTopLevel(); |
| 342 } | 342 } |
| 343 | 343 |
| 344 | 344 |
| 345 Token::Kind Parser::CurrentToken() { | 345 Token::Kind Parser::CurrentToken() { |
| 346 if (token_kind_ == Token::kILLEGAL) { | 346 if (token_kind_ == Token::kILLEGAL) { |
| 347 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 347 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
| 348 if (token_kind_ == Token::kERROR) { | 348 if (token_kind_ == Token::kERROR) { |
| 349 ErrorMsg(TokenPos(), CurrentLiteral()->ToCString()); | 349 ErrorMsg(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 CompilerStats::num_token_checks++; | 352 CompilerStats::num_token_checks++; |
| 353 return token_kind_; | 353 return token_kind_; |
| 354 } | 354 } |
| 355 | 355 |
| 356 | 356 |
| 357 Token::Kind Parser::LookaheadToken(int num_tokens) { | 357 Token::Kind Parser::LookaheadToken(int num_tokens) { |
| 358 CompilerStats::num_tokens_lookahead++; | 358 CompilerStats::num_tokens_lookahead++; |
| 359 CompilerStats::num_token_checks++; | 359 CompilerStats::num_token_checks++; |
| (...skipping 2377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2737 (operator_token == Token::kBIT_NOT)) { | 2737 (operator_token == Token::kBIT_NOT)) { |
| 2738 // TODO(hausner): Remove support for keyword 'negate'. | 2738 // TODO(hausner): Remove support for keyword 'negate'. |
| 2739 expected_num_parameters = 1; | 2739 expected_num_parameters = 1; |
| 2740 } else { | 2740 } else { |
| 2741 expected_num_parameters = 2; | 2741 expected_num_parameters = 2; |
| 2742 } | 2742 } |
| 2743 if ((member.params.num_optional_parameters > 0) || | 2743 if ((member.params.num_optional_parameters > 0) || |
| 2744 (member.params.has_named_optional_parameters) || | 2744 (member.params.has_named_optional_parameters) || |
| 2745 (member.params.num_fixed_parameters != expected_num_parameters)) { | 2745 (member.params.num_fixed_parameters != expected_num_parameters)) { |
| 2746 // Subtract receiver when reporting number of expected arguments. | 2746 // Subtract receiver when reporting number of expected arguments. |
| 2747 ErrorMsg(member.name_pos, "operator %s expects %d argument(s)", | 2747 ErrorMsg(member.name_pos, "operator %s expects %"Pd" argument(s)", |
| 2748 member.name->ToCString(), (expected_num_parameters - 1)); | 2748 member.name->ToCString(), (expected_num_parameters - 1)); |
| 2749 } | 2749 } |
| 2750 } | 2750 } |
| 2751 | 2751 |
| 2752 | 2752 |
| 2753 void Parser::ParseClassMemberDefinition(ClassDesc* members) { | 2753 void Parser::ParseClassMemberDefinition(ClassDesc* members) { |
| 2754 TRACE_PARSER("ParseClassMemberDefinition"); | 2754 TRACE_PARSER("ParseClassMemberDefinition"); |
| 2755 MemberDesc member; | 2755 MemberDesc member; |
| 2756 current_member_ = &member; | 2756 current_member_ = &member; |
| 2757 if ((CurrentToken() == Token::kABSTRACT) && | 2757 if ((CurrentToken() == Token::kABSTRACT) && |
| (...skipping 3410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6168 intptr_t message_buffer_size, | 6168 intptr_t message_buffer_size, |
| 6169 const char* format, va_list args) { | 6169 const char* format, va_list args) { |
| 6170 intptr_t msg_len = 0; | 6170 intptr_t msg_len = 0; |
| 6171 if (!script.IsNull()) { | 6171 if (!script.IsNull()) { |
| 6172 const String& script_url = String::CheckedHandle(script.url()); | 6172 const String& script_url = String::CheckedHandle(script.url()); |
| 6173 if (token_pos >= 0) { | 6173 if (token_pos >= 0) { |
| 6174 intptr_t line, column; | 6174 intptr_t line, column; |
| 6175 script.GetTokenLocation(token_pos, &line, &column); | 6175 script.GetTokenLocation(token_pos, &line, &column); |
| 6176 msg_len += OS::SNPrint(message_buffer + msg_len, | 6176 msg_len += OS::SNPrint(message_buffer + msg_len, |
| 6177 message_buffer_size - msg_len, | 6177 message_buffer_size - msg_len, |
| 6178 "'%s': %s: line %d pos %d: ", | 6178 "'%s': %s: line %"Pd" pos %"Pd": ", |
| 6179 script_url.ToCString(), | 6179 script_url.ToCString(), |
| 6180 message_header, | 6180 message_header, |
| 6181 line, | 6181 line, |
| 6182 column); | 6182 column); |
| 6183 if (msg_len < message_buffer_size) { | 6183 if (msg_len < message_buffer_size) { |
| 6184 // Append the formatted error or warning message. | 6184 // Append the formatted error or warning message. |
| 6185 msg_len += OS::VSNPrint(message_buffer + msg_len, | 6185 msg_len += OS::VSNPrint(message_buffer + msg_len, |
| 6186 message_buffer_size - msg_len, | 6186 message_buffer_size - msg_len, |
| 6187 format, | 6187 format, |
| 6188 args); | 6188 args); |
| 6189 if (msg_len < message_buffer_size) { | 6189 if (msg_len < message_buffer_size) { |
| 6190 // Append the source line. | 6190 // Append the source line. |
| 6191 const String& script_line = String::Handle(script.GetLine(line)); | 6191 const String& script_line = String::Handle(script.GetLine(line)); |
| 6192 ASSERT(!script_line.IsNull()); | 6192 ASSERT(!script_line.IsNull()); |
| 6193 msg_len += OS::SNPrint(message_buffer + msg_len, | 6193 msg_len += OS::SNPrint(message_buffer + msg_len, |
| 6194 message_buffer_size - msg_len, | 6194 message_buffer_size - msg_len, |
| 6195 "\n%s\n%*s\n", | 6195 "\n%s\n%*s\n", |
| 6196 script_line.ToCString(), | 6196 script_line.ToCString(), |
| 6197 column, | 6197 static_cast<int>(column), |
| 6198 "^"); | 6198 "^"); |
| 6199 } | 6199 } |
| 6200 } | 6200 } |
| 6201 } else { | 6201 } else { |
| 6202 // Token position is unknown. | 6202 // Token position is unknown. |
| 6203 msg_len += OS::SNPrint(message_buffer + msg_len, | 6203 msg_len += OS::SNPrint(message_buffer + msg_len, |
| 6204 message_buffer_size - msg_len, | 6204 message_buffer_size - msg_len, |
| 6205 "'%s': %s: ", | 6205 "'%s': %s: ", |
| 6206 script_url.ToCString(), | 6206 script_url.ToCString(), |
| 6207 message_header); | 6207 message_header); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6306 if (FLAG_warning_as_error) { | 6306 if (FLAG_warning_as_error) { |
| 6307 Isolate::Current()->long_jump_base()->Jump(1, error); | 6307 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 6308 UNREACHABLE(); | 6308 UNREACHABLE(); |
| 6309 } else { | 6309 } else { |
| 6310 OS::Print("%s", error.ToErrorCString()); | 6310 OS::Print("%s", error.ToErrorCString()); |
| 6311 } | 6311 } |
| 6312 } | 6312 } |
| 6313 | 6313 |
| 6314 | 6314 |
| 6315 void Parser::Unimplemented(const char* msg) { | 6315 void Parser::Unimplemented(const char* msg) { |
| 6316 ErrorMsg(TokenPos(), msg); | 6316 ErrorMsg(TokenPos(), "%s", msg); |
| 6317 } | 6317 } |
| 6318 | 6318 |
| 6319 | 6319 |
| 6320 void Parser::ExpectToken(Token::Kind token_expected) { | 6320 void Parser::ExpectToken(Token::Kind token_expected) { |
| 6321 if (CurrentToken() != token_expected) { | 6321 if (CurrentToken() != token_expected) { |
| 6322 ErrorMsg("'%s' expected", Token::Str(token_expected)); | 6322 ErrorMsg("'%s' expected", Token::Str(token_expected)); |
| 6323 } | 6323 } |
| 6324 ConsumeToken(); | 6324 ConsumeToken(); |
| 6325 } | 6325 } |
| 6326 | 6326 |
| 6327 | 6327 |
| 6328 void Parser::ExpectSemicolon() { | 6328 void Parser::ExpectSemicolon() { |
| 6329 if (CurrentToken() != Token::kSEMICOLON) { | 6329 if (CurrentToken() != Token::kSEMICOLON) { |
| 6330 ErrorMsg("semicolon expected"); | 6330 ErrorMsg("semicolon expected"); |
| 6331 } | 6331 } |
| 6332 ConsumeToken(); | 6332 ConsumeToken(); |
| 6333 } | 6333 } |
| 6334 | 6334 |
| 6335 | 6335 |
| 6336 void Parser::UnexpectedToken() { | 6336 void Parser::UnexpectedToken() { |
| 6337 ErrorMsg("unexpected token '%s'", | 6337 ErrorMsg("unexpected token '%s'", |
| 6338 CurrentToken() == Token::kIDENT ? | 6338 CurrentToken() == Token::kIDENT ? |
| 6339 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); | 6339 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); |
| 6340 } | 6340 } |
| 6341 | 6341 |
| 6342 | 6342 |
| 6343 String* Parser::ExpectClassIdentifier(const char* msg) { | 6343 String* Parser::ExpectClassIdentifier(const char* msg) { |
| 6344 if (CurrentToken() != Token::kIDENT) { | 6344 if (CurrentToken() != Token::kIDENT) { |
| 6345 ErrorMsg(msg); | 6345 ErrorMsg("%s", msg); |
| 6346 } | 6346 } |
| 6347 String* ident = CurrentLiteral(); | 6347 String* ident = CurrentLiteral(); |
| 6348 if (ident->Equals("Dynamic")) { | 6348 if (ident->Equals("Dynamic")) { |
| 6349 ErrorMsg(msg); | 6349 ErrorMsg("%s", msg); |
| 6350 } | 6350 } |
| 6351 ConsumeToken(); | 6351 ConsumeToken(); |
| 6352 return ident; | 6352 return ident; |
| 6353 } | 6353 } |
| 6354 | 6354 |
| 6355 | 6355 |
| 6356 // Check whether current token is an identifier or a built-in identifier. | 6356 // Check whether current token is an identifier or a built-in identifier. |
| 6357 String* Parser::ExpectIdentifier(const char* msg) { | 6357 String* Parser::ExpectIdentifier(const char* msg) { |
| 6358 if (!IsIdentifier()) { | 6358 if (!IsIdentifier()) { |
| 6359 ErrorMsg(msg); | 6359 ErrorMsg("%s", msg); |
| 6360 } | 6360 } |
| 6361 String* ident = CurrentLiteral(); | 6361 String* ident = CurrentLiteral(); |
| 6362 ConsumeToken(); | 6362 ConsumeToken(); |
| 6363 return ident; | 6363 return ident; |
| 6364 } | 6364 } |
| 6365 | 6365 |
| 6366 | 6366 |
| 6367 bool Parser::IsLiteral(const char* literal) { | 6367 bool Parser::IsLiteral(const char* literal) { |
| 6368 const uint8_t* characters = reinterpret_cast<const uint8_t*>(literal); | 6368 const uint8_t* characters = reinterpret_cast<const uint8_t*>(literal); |
| 6369 intptr_t len = strlen(literal); | 6369 intptr_t len = strlen(literal); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6527 | 6527 |
| 6528 void Parser::EnsureExpressionTemp() { | 6528 void Parser::EnsureExpressionTemp() { |
| 6529 // Temporary used later by the flow_graph_builder. | 6529 // Temporary used later by the flow_graph_builder. |
| 6530 GetIncrementTempLocal(); | 6530 GetIncrementTempLocal(); |
| 6531 } | 6531 } |
| 6532 | 6532 |
| 6533 | 6533 |
| 6534 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 6534 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, |
| 6535 const char* s) { | 6535 const char* s) { |
| 6536 char name[64]; | 6536 char name[64]; |
| 6537 OS::SNPrint(name, 64, ":%s%d", s, token_pos); | 6537 OS::SNPrint(name, 64, ":%s%"Pd, s, token_pos); |
| 6538 LocalVariable* temp = | 6538 LocalVariable* temp = |
| 6539 new LocalVariable(token_pos, | 6539 new LocalVariable(token_pos, |
| 6540 String::ZoneHandle(Symbols::New(name)), | 6540 String::ZoneHandle(Symbols::New(name)), |
| 6541 Type::ZoneHandle(Type::DynamicType())); | 6541 Type::ZoneHandle(Type::DynamicType())); |
| 6542 temp->set_is_final(); | 6542 temp->set_is_final(); |
| 6543 current_block_->scope->AddVariable(temp); | 6543 current_block_->scope->AddVariable(temp); |
| 6544 return temp; | 6544 return temp; |
| 6545 } | 6545 } |
| 6546 | 6546 |
| 6547 | 6547 |
| (...skipping 2372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8920 intptr_t param_index; | 8920 intptr_t param_index; |
| 8921 if (!IsFormalParameter(*ident, &owner_function, &owner_scope, ¶m_index)) { | 8921 if (!IsFormalParameter(*ident, &owner_function, &owner_scope, ¶m_index)) { |
| 8922 ErrorMsg(ident_pos, "formal parameter name expected"); | 8922 ErrorMsg(ident_pos, "formal parameter name expected"); |
| 8923 } | 8923 } |
| 8924 if (param_index < owner_function.num_fixed_parameters()) { | 8924 if (param_index < owner_function.num_fixed_parameters()) { |
| 8925 // The formal parameter is not optional, therefore the corresponding | 8925 // The formal parameter is not optional, therefore the corresponding |
| 8926 // argument is always passed and defined. | 8926 // argument is always passed and defined. |
| 8927 return new LiteralNode(test_pos, Bool::ZoneHandle(Bool::True())); | 8927 return new LiteralNode(test_pos, Bool::ZoneHandle(Bool::True())); |
| 8928 } | 8928 } |
| 8929 char name[64]; | 8929 char name[64]; |
| 8930 OS::SNPrint(name, 64, "%s_%d", | 8930 OS::SNPrint(name, 64, "%s_%"Pd"", |
| 8931 Symbols::Name(Symbols::kSavedArgDescVarPrefix), | 8931 Symbols::Name(Symbols::kSavedArgDescVarPrefix), |
| 8932 owner_function.token_pos()); | 8932 owner_function.token_pos()); |
| 8933 const String& saved_args_desc_name = String::ZoneHandle(Symbols::New(name)); | 8933 const String& saved_args_desc_name = String::ZoneHandle(Symbols::New(name)); |
| 8934 LocalVariable* saved_args_desc_var = LookupLocalScope(saved_args_desc_name); | 8934 LocalVariable* saved_args_desc_var = LookupLocalScope(saved_args_desc_name); |
| 8935 if (saved_args_desc_var == NULL) { | 8935 if (saved_args_desc_var == NULL) { |
| 8936 ASSERT(owner_scope != NULL); | 8936 ASSERT(owner_scope != NULL); |
| 8937 saved_args_desc_var = | 8937 saved_args_desc_var = |
| 8938 new LocalVariable(owner_function.token_pos(), | 8938 new LocalVariable(owner_function.token_pos(), |
| 8939 saved_args_desc_name, | 8939 saved_args_desc_name, |
| 8940 Type::ZoneHandle(Type::ListInterface())); | 8940 Type::ZoneHandle(Type::ListInterface())); |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9385 void Parser::SkipQualIdent() { | 9385 void Parser::SkipQualIdent() { |
| 9386 ASSERT(IsIdentifier()); | 9386 ASSERT(IsIdentifier()); |
| 9387 ConsumeToken(); | 9387 ConsumeToken(); |
| 9388 if (CurrentToken() == Token::kPERIOD) { | 9388 if (CurrentToken() == Token::kPERIOD) { |
| 9389 ConsumeToken(); // Consume the kPERIOD token. | 9389 ConsumeToken(); // Consume the kPERIOD token. |
| 9390 ExpectIdentifier("identifier expected after '.'"); | 9390 ExpectIdentifier("identifier expected after '.'"); |
| 9391 } | 9391 } |
| 9392 } | 9392 } |
| 9393 | 9393 |
| 9394 } // namespace dart | 9394 } // namespace dart |
| OLD | NEW |