Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: runtime/vm/parser.cc

Issue 10830253: Support for new operator - (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/token.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 Clear(); 440 Clear();
441 } 441 }
442 void Clear() { 442 void Clear() {
443 has_abstract = false; 443 has_abstract = false;
444 has_external = false; 444 has_external = false;
445 has_final = false; 445 has_final = false;
446 has_const = false; 446 has_const = false;
447 has_static = false; 447 has_static = false;
448 has_var = false; 448 has_var = false;
449 has_factory = false; 449 has_factory = false;
450 has_operator = false;
450 type = NULL; 451 type = NULL;
451 name_pos = 0; 452 name_pos = 0;
452 name = NULL; 453 name = NULL;
453 redirect_name = NULL; 454 redirect_name = NULL;
454 params.Clear(); 455 params.Clear();
455 kind = RawFunction::kRegularFunction; 456 kind = RawFunction::kRegularFunction;
456 } 457 }
457 bool IsConstructor() const { 458 bool IsConstructor() const {
458 return (kind == RawFunction::kConstructor) && !has_static; 459 return (kind == RawFunction::kConstructor) && !has_static;
459 } 460 }
460 bool IsFactory() const { 461 bool IsFactory() const {
461 return (kind == RawFunction::kConstructor) && has_static; 462 return (kind == RawFunction::kConstructor) && has_static;
462 } 463 }
463 bool IsFactoryOrConstructor() const { 464 bool IsFactoryOrConstructor() const {
464 return (kind == RawFunction::kConstructor); 465 return (kind == RawFunction::kConstructor);
465 } 466 }
466 bool IsGetter() const { 467 bool IsGetter() const {
467 return kind == RawFunction::kGetterFunction; 468 return kind == RawFunction::kGetterFunction;
468 } 469 }
469 bool IsSetter() const { 470 bool IsSetter() const {
470 return kind == RawFunction::kSetterFunction; 471 return kind == RawFunction::kSetterFunction;
471 } 472 }
472 bool has_abstract; 473 bool has_abstract;
473 bool has_external; 474 bool has_external;
474 bool has_final; 475 bool has_final;
475 bool has_const; 476 bool has_const;
476 bool has_static; 477 bool has_static;
477 bool has_var; 478 bool has_var;
478 bool has_factory; 479 bool has_factory;
480 bool has_operator;
479 const AbstractType* type; 481 const AbstractType* type;
480 intptr_t name_pos; 482 intptr_t name_pos;
481 String* name; 483 String* name;
482 String* redirect_name; // For constructors: NULL or redirected constructor. 484 String* redirect_name; // For constructors: NULL or redirected constructor.
483 ParamList params; 485 ParamList params;
484 RawFunction::Kind kind; 486 RawFunction::Kind kind;
485 }; 487 };
486 488
487 489
488 class ClassDesc : public ValueObject { 490 class ClassDesc : public ValueObject {
(...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 } 2290 }
2289 if (method->has_abstract && members->is_interface()) { 2291 if (method->has_abstract && members->is_interface()) {
2290 ErrorMsg(method->name_pos, 2292 ErrorMsg(method->name_pos,
2291 "'abstract' method only allowed in class definition"); 2293 "'abstract' method only allowed in class definition");
2292 } 2294 }
2293 if (method->has_external && members->is_interface()) { 2295 if (method->has_external && members->is_interface()) {
2294 ErrorMsg(method->name_pos, 2296 ErrorMsg(method->name_pos,
2295 "'external' method only allowed in class definition"); 2297 "'external' method only allowed in class definition");
2296 } 2298 }
2297 2299
2298 if (members->FunctionNameExists(*method->name, method->kind)) {
2299 ErrorMsg(method->name_pos,
2300 "field or method '%s' already defined", method->name->ToCString());
2301 }
2302
2303 // Parse the formal parameters. 2300 // Parse the formal parameters.
2304 const bool are_implicitly_final = method->has_const; 2301 const bool are_implicitly_final = method->has_const;
2305 const bool allow_explicit_default_values = true; 2302 const bool allow_explicit_default_values = true;
2306 const intptr_t formal_param_pos = TokenPos(); 2303 const intptr_t formal_param_pos = TokenPos();
2307 method->params.Clear(); 2304 method->params.Clear();
2308 // Static functions do not have a receiver. 2305 // Static functions do not have a receiver.
2309 // The first parameter of a factory is the AbstractTypeArguments vector of 2306 // The first parameter of a factory is the AbstractTypeArguments vector of
2310 // the type of the instance to be allocated. 2307 // the type of the instance to be allocated.
2311 if (!method->has_static || method->IsConstructor()) { 2308 if (!method->has_static || method->IsConstructor()) {
2312 method->params.AddReceiver(ReceiverType(formal_param_pos)); 2309 method->params.AddReceiver(ReceiverType(formal_param_pos));
2313 } else if (method->has_factory) { 2310 } else if (method->has_factory) {
2314 method->params.AddFinalParameter( 2311 method->params.AddFinalParameter(
2315 formal_param_pos, 2312 formal_param_pos,
2316 &String::ZoneHandle(Symbols::TypeArgumentsParameter()), 2313 &String::ZoneHandle(Symbols::TypeArgumentsParameter()),
2317 &Type::ZoneHandle(Type::DynamicType())); 2314 &Type::ZoneHandle(Type::DynamicType()));
2318 } 2315 }
2319 // Constructors have an implicit parameter for the construction phase. 2316 // Constructors have an implicit parameter for the construction phase.
2320 if (method->IsConstructor()) { 2317 if (method->IsConstructor()) {
2321 method->params.AddFinalParameter( 2318 method->params.AddFinalParameter(
2322 TokenPos(), 2319 TokenPos(),
2323 &String::ZoneHandle(Symbols::PhaseParameter()), 2320 &String::ZoneHandle(Symbols::PhaseParameter()),
2324 &Type::ZoneHandle(Type::IntInterface())); 2321 &Type::ZoneHandle(Type::IntInterface()));
2325 } 2322 }
2326 if (are_implicitly_final) { 2323 if (are_implicitly_final) {
2327 method->params.SetImplicitlyFinal(); 2324 method->params.SetImplicitlyFinal();
2328 } 2325 }
2329 ParseFormalParameterList(allow_explicit_default_values, &method->params); 2326 ParseFormalParameterList(allow_explicit_default_values, &method->params);
2327
2328 // Now that we know the parameter list, we can distinguish between the
2329 // unary and binary operator -.
2330 if (method->has_operator &&
2331 ((method->name->Equals(Token::Str(Token::kNEGATE))) ||
2332 method->name->Equals("-")) &&
2333 (method->params.num_fixed_parameters == 1)) {
2334 // Patch up name for unary operator - so it does not clash with the
2335 // name for binary operator -.
2336 *method->name = Symbols::New("unary-");
2337 }
2338
2339 if (members->FunctionNameExists(*method->name, method->kind)) {
2340 ErrorMsg(method->name_pos,
2341 "field or method '%s' already defined", method->name->ToCString());
2342 }
2343
2344 // Mangle the name for getter and setter functions and check function
2345 // arity.
2330 if (method->IsGetter() || method->IsSetter()) { 2346 if (method->IsGetter() || method->IsSetter()) {
2331 int expected_num_parameters = 0; 2347 int expected_num_parameters = 0;
2332 if (method->IsGetter()) { 2348 if (method->IsGetter()) {
2333 expected_num_parameters = (method->has_static) ? 0 : 1; 2349 expected_num_parameters = (method->has_static) ? 0 : 1;
2334 method->name = &String::ZoneHandle(Field::GetterSymbol(*method->name)); 2350 method->name = &String::ZoneHandle(Field::GetterSymbol(*method->name));
2335 } else { 2351 } else {
2336 ASSERT(method->IsSetter()); 2352 ASSERT(method->IsSetter());
2337 expected_num_parameters = (method->has_static) ? 1 : 2; 2353 expected_num_parameters = (method->has_static) ? 1 : 2;
2338 method->name = &String::ZoneHandle(Field::SetterSymbol(*method->name)); 2354 method->name = &String::ZoneHandle(Field::SetterSymbol(*method->name));
2339 } 2355 }
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
2623 break; 2639 break;
2624 } 2640 }
2625 ConsumeToken(); 2641 ConsumeToken();
2626 field->name_pos = this->TokenPos(); 2642 field->name_pos = this->TokenPos();
2627 field->name = ExpectIdentifier("field name expected"); 2643 field->name = ExpectIdentifier("field name expected");
2628 } 2644 }
2629 ExpectSemicolon(); 2645 ExpectSemicolon();
2630 } 2646 }
2631 2647
2632 2648
2633 void Parser::CheckOperatorArity( 2649 void Parser::CheckOperatorArity(const MemberDesc& member,
2634 const MemberDesc& member, Token::Kind operator_token) { 2650 Token::Kind operator_token) {
2635 intptr_t expected_num_parameters; // Includes receiver. 2651 intptr_t expected_num_parameters; // Includes receiver.
2636 if (operator_token == Token::kASSIGN_INDEX) { 2652 if (operator_token == Token::kASSIGN_INDEX) {
2637 expected_num_parameters = 3; 2653 expected_num_parameters = 3;
2654 } else if (operator_token == Token::kSUB) {
2655 if (member.params.num_fixed_parameters == 1) {
2656 // Unary operator minus (i.e. negate).
2657 expected_num_parameters = 1;
2658 } else {
2659 expected_num_parameters = 2;
2660 }
2638 } else if ((operator_token == Token::kNEGATE) || 2661 } else if ((operator_token == Token::kNEGATE) ||
2639 (operator_token == Token::kBIT_NOT)) { 2662 (operator_token == Token::kBIT_NOT)) {
2663 // TODO(hausner): Remove support for keyword 'negate'.
2640 expected_num_parameters = 1; 2664 expected_num_parameters = 1;
2641 } else { 2665 } else {
2642 expected_num_parameters = 2; 2666 expected_num_parameters = 2;
2643 } 2667 }
2644 if ((member.params.num_optional_parameters > 0) || 2668 if ((member.params.num_optional_parameters > 0) ||
2645 (member.params.has_named_optional_parameters) || 2669 (member.params.has_named_optional_parameters) ||
2646 (member.params.num_fixed_parameters != expected_num_parameters)) { 2670 (member.params.num_fixed_parameters != expected_num_parameters)) {
2647 // Subtract receiver when reporting number of expected arguments. 2671 // Subtract receiver when reporting number of expected arguments.
2648 ErrorMsg(member.name_pos, "operator %s expects %d argument(s)", 2672 ErrorMsg(member.name_pos, "operator %s expects %d argument(s)",
2649 member.name->ToCString(), (expected_num_parameters - 1)); 2673 member.name->ToCString(), (expected_num_parameters - 1));
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 (LookaheadToken(1) != Token::kCOMMA) && 2841 (LookaheadToken(1) != Token::kCOMMA) &&
2818 (LookaheadToken(1) != Token::kSEMICOLON)) { 2842 (LookaheadToken(1) != Token::kSEMICOLON)) {
2819 ConsumeToken(); 2843 ConsumeToken();
2820 if (!Token::CanBeOverloaded(CurrentToken())) { 2844 if (!Token::CanBeOverloaded(CurrentToken())) {
2821 ErrorMsg("invalid operator overloading"); 2845 ErrorMsg("invalid operator overloading");
2822 } 2846 }
2823 if (member.has_static) { 2847 if (member.has_static) {
2824 ErrorMsg("operator overloading functions cannot be static"); 2848 ErrorMsg("operator overloading functions cannot be static");
2825 } 2849 }
2826 operator_token = CurrentToken(); 2850 operator_token = CurrentToken();
2851 member.has_operator = true;
2827 member.kind = RawFunction::kRegularFunction; 2852 member.kind = RawFunction::kRegularFunction;
2828 member.name_pos = this->TokenPos(); 2853 member.name_pos = this->TokenPos();
2829 member.name = 2854 member.name =
2830 &String::ZoneHandle(Symbols::New(Token::Str(operator_token))); 2855 &String::ZoneHandle(Symbols::New(Token::Str(operator_token)));
2831 ConsumeToken(); 2856 ConsumeToken();
2832 } else if (IsIdentifier()) { 2857 } else if (IsIdentifier()) {
2833 member.name = CurrentLiteral(); 2858 member.name = CurrentLiteral();
2834 member.name_pos = TokenPos(); 2859 member.name_pos = TokenPos();
2835 ConsumeToken(); 2860 ConsumeToken();
2836 } else { 2861 } else {
2837 ErrorMsg("identifier expected"); 2862 ErrorMsg("identifier expected");
2838 } 2863 }
2839 2864
2840 ASSERT(member.name != NULL); 2865 ASSERT(member.name != NULL);
2841 if (CurrentToken() == Token::kLPAREN) { 2866 if (CurrentToken() == Token::kLPAREN) {
2842 if (members->is_interface() && member.has_static) { 2867 if (members->is_interface() && member.has_static) {
2843 if (member.has_factory) { 2868 if (member.has_factory) {
2844 ErrorMsg("factory constructors are not allowed in interfaces"); 2869 ErrorMsg("factory constructors are not allowed in interfaces");
2845 } else { 2870 } else {
2846 ErrorMsg("static methods are not allowed in interfaces"); 2871 ErrorMsg("static methods are not allowed in interfaces");
2847 } 2872 }
2848 } 2873 }
2849 // Constructor or method. 2874 // Constructor or method.
2850 if (member.type == NULL) { 2875 if (member.type == NULL) {
2851 member.type = &Type::ZoneHandle(Type::DynamicType()); 2876 member.type = &Type::ZoneHandle(Type::DynamicType());
2852 } 2877 }
2853 ParseMethodOrConstructor(members, &member); 2878 ParseMethodOrConstructor(members, &member);
2854 if (operator_token != Token::kILLEGAL) { 2879 if (member.has_operator) {
2855 CheckOperatorArity(member, operator_token); 2880 CheckOperatorArity(member, operator_token);
2856 } 2881 }
2857 } else if (CurrentToken() == Token::kSEMICOLON || 2882 } else if (CurrentToken() == Token::kSEMICOLON ||
2858 CurrentToken() == Token::kCOMMA || 2883 CurrentToken() == Token::kCOMMA ||
2859 CurrentToken() == Token::kASSIGN) { 2884 CurrentToken() == Token::kASSIGN) {
2860 // Field definition. 2885 // Field definition.
2861 if (member.has_const) { 2886 if (member.has_const) {
2862 // const fields are implicitly final. 2887 // const fields are implicitly final.
2863 member.has_final = true; 2888 member.has_final = true;
2864 } 2889 }
(...skipping 6147 matching lines...) Expand 10 before | Expand all | Expand 10 after
9012 void Parser::SkipQualIdent() { 9037 void Parser::SkipQualIdent() {
9013 ASSERT(IsIdentifier()); 9038 ASSERT(IsIdentifier());
9014 ConsumeToken(); 9039 ConsumeToken();
9015 if (CurrentToken() == Token::kPERIOD) { 9040 if (CurrentToken() == Token::kPERIOD) {
9016 ConsumeToken(); // Consume the kPERIOD token. 9041 ConsumeToken(); // Consume the kPERIOD token.
9017 ExpectIdentifier("identifier expected after '.'"); 9042 ExpectIdentifier("identifier expected after '.'");
9018 } 9043 }
9019 } 9044 }
9020 9045
9021 } // namespace dart 9046 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/token.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698