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

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

Issue 11199002: Remove built-in identifier 'negate' from VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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/parser.h ('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 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 } 480 }
481 void Clear() { 481 void Clear() {
482 has_abstract = false; 482 has_abstract = false;
483 has_external = false; 483 has_external = false;
484 has_final = false; 484 has_final = false;
485 has_const = false; 485 has_const = false;
486 has_static = false; 486 has_static = false;
487 has_var = false; 487 has_var = false;
488 has_factory = false; 488 has_factory = false;
489 has_operator = false; 489 has_operator = false;
490 operator_token = Token::kILLEGAL;
490 type = NULL; 491 type = NULL;
491 name_pos = 0; 492 name_pos = 0;
492 name = NULL; 493 name = NULL;
493 redirect_name = NULL; 494 redirect_name = NULL;
494 constructor_name = NULL; 495 constructor_name = NULL;
495 params.Clear(); 496 params.Clear();
496 kind = RawFunction::kRegularFunction; 497 kind = RawFunction::kRegularFunction;
497 } 498 }
498 bool IsConstructor() const { 499 bool IsConstructor() const {
499 return (kind == RawFunction::kConstructor) && !has_static; 500 return (kind == RawFunction::kConstructor) && !has_static;
(...skipping 11 matching lines...) Expand all
511 return kind == RawFunction::kSetterFunction; 512 return kind == RawFunction::kSetterFunction;
512 } 513 }
513 bool has_abstract; 514 bool has_abstract;
514 bool has_external; 515 bool has_external;
515 bool has_final; 516 bool has_final;
516 bool has_const; 517 bool has_const;
517 bool has_static; 518 bool has_static;
518 bool has_var; 519 bool has_var;
519 bool has_factory; 520 bool has_factory;
520 bool has_operator; 521 bool has_operator;
522 Token::Kind operator_token;
521 const AbstractType* type; 523 const AbstractType* type;
522 intptr_t name_pos; 524 intptr_t name_pos;
523 String* name; 525 String* name;
524 // For constructors: NULL or name of redirected to constructor. 526 // For constructors: NULL or name of redirected to constructor.
525 String* redirect_name; 527 String* redirect_name;
526 // For constructors: NULL for unnamed constructor, 528 // For constructors: NULL for unnamed constructor,
527 // identifier after classname for named constructors. 529 // identifier after classname for named constructors.
528 String* constructor_name; 530 String* constructor_name;
529 ParamList params; 531 ParamList params;
530 RawFunction::Kind kind; 532 RawFunction::Kind kind;
(...skipping 1907 matching lines...) Expand 10 before | Expand all | Expand 10 after
2438 // TODO(hausner): Remove this once the old getter syntax with 2440 // TODO(hausner): Remove this once the old getter syntax with
2439 // empty parameter list is no longer supported. 2441 // empty parameter list is no longer supported.
2440 if (CurrentToken() == Token::kLPAREN) { 2442 if (CurrentToken() == Token::kLPAREN) {
2441 ConsumeToken(); 2443 ConsumeToken();
2442 ExpectToken(Token::kRPAREN); 2444 ExpectToken(Token::kRPAREN);
2443 } 2445 }
2444 } 2446 }
2445 2447
2446 // Now that we know the parameter list, we can distinguish between the 2448 // Now that we know the parameter list, we can distinguish between the
2447 // unary and binary operator -. 2449 // unary and binary operator -.
2448 if (method->has_operator && 2450 if (method->has_operator) {
2449 method->name->Equals("-") && 2451 if ((method->operator_token == Token::kSUB) &&
2450 (method->params.num_fixed_parameters == 1)) { 2452 (method->params.num_fixed_parameters == 1)) {
2451 // Patch up name for unary operator - so it does not clash with the 2453 // Patch up name for unary operator - so it does not clash with the
2452 // name for binary operator -. 2454 // name for binary operator -.
2453 *method->name = Symbols::New("unary-"); 2455 method->operator_token = Token::kNEGATE;
2456 *method->name = Symbols::New(Token::Str(Token::kNEGATE));
2457 }
2458 CheckOperatorArity(*method);
2454 } 2459 }
2455 2460
2456 if (members->FunctionNameExists(*method->name, method->kind)) { 2461 if (members->FunctionNameExists(*method->name, method->kind)) {
2457 ErrorMsg(method->name_pos, 2462 ErrorMsg(method->name_pos,
2458 "field or method '%s' already defined", method->name->ToCString()); 2463 "field or method '%s' already defined", method->name->ToCString());
2459 } 2464 }
2460 2465
2461 // Mangle the name for getter and setter functions and check function 2466 // Mangle the name for getter and setter functions and check function
2462 // arity. 2467 // arity.
2463 if (method->IsGetter() || method->IsSetter()) { 2468 if (method->IsGetter() || method->IsSetter()) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
2804 break; 2809 break;
2805 } 2810 }
2806 ConsumeToken(); 2811 ConsumeToken();
2807 field->name_pos = this->TokenPos(); 2812 field->name_pos = this->TokenPos();
2808 field->name = ExpectIdentifier("field name expected"); 2813 field->name = ExpectIdentifier("field name expected");
2809 } 2814 }
2810 ExpectSemicolon(); 2815 ExpectSemicolon();
2811 } 2816 }
2812 2817
2813 2818
2814 void Parser::CheckOperatorArity(const MemberDesc& member, 2819 void Parser::CheckOperatorArity(const MemberDesc& member) {
2815 Token::Kind operator_token) {
2816 intptr_t expected_num_parameters; // Includes receiver. 2820 intptr_t expected_num_parameters; // Includes receiver.
2817 if (operator_token == Token::kASSIGN_INDEX) { 2821 Token::Kind op = member.operator_token;
2822 if (op == Token::kASSIGN_INDEX) {
2818 expected_num_parameters = 3; 2823 expected_num_parameters = 3;
2819 } else if (operator_token == Token::kSUB) { 2824 } else if ((op == Token::kBIT_NOT) || (op == Token::kNEGATE)) {
2820 if (member.params.num_fixed_parameters == 1) {
2821 // Unary operator minus (i.e. negate).
2822 expected_num_parameters = 1;
2823 } else {
2824 expected_num_parameters = 2;
2825 }
2826 } else if (operator_token == Token::kBIT_NOT) {
2827 expected_num_parameters = 1; 2825 expected_num_parameters = 1;
2828 } else { 2826 } else {
2829 expected_num_parameters = 2; 2827 expected_num_parameters = 2;
2830 } 2828 }
2831 if ((member.params.num_optional_parameters > 0) || 2829 if ((member.params.num_optional_parameters > 0) ||
2832 member.params.has_optional_positional_parameters || 2830 member.params.has_optional_positional_parameters ||
2833 member.params.has_optional_named_parameters || 2831 member.params.has_optional_named_parameters ||
2834 (member.params.num_fixed_parameters != expected_num_parameters)) { 2832 (member.params.num_fixed_parameters != expected_num_parameters)) {
2835 // Subtract receiver when reporting number of expected arguments. 2833 // Subtract receiver when reporting number of expected arguments.
2836 ErrorMsg(member.name_pos, "operator %s expects %"Pd" argument(s)", 2834 ErrorMsg(member.name_pos, "operator %s expects %"Pd" argument(s)",
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2910 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. 2908 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr.
2911 ASSERT(is_top_level_); 2909 ASSERT(is_top_level_);
2912 // The declared type of fields is never ignored, even in unchecked mode, 2910 // The declared type of fields is never ignored, even in unchecked mode,
2913 // because getters and setters could be closurized at some time (not 2911 // because getters and setters could be closurized at some time (not
2914 // supported yet). 2912 // supported yet).
2915 member.type = &AbstractType::ZoneHandle( 2913 member.type = &AbstractType::ZoneHandle(
2916 ParseType(ClassFinalizer::kTryResolve)); 2914 ParseType(ClassFinalizer::kTryResolve));
2917 } 2915 }
2918 } 2916 }
2919 } 2917 }
2920 Token::Kind operator_token = Token::kILLEGAL; 2918
2921 // Optionally parse a (possibly named) constructor name or factory. 2919 // Optionally parse a (possibly named) constructor name or factory.
2922 if (IsIdentifier() && 2920 if (IsIdentifier() &&
2923 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { 2921 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) {
2924 if (member.has_factory) { 2922 if (member.has_factory) {
2925 // The factory name may be qualified. 2923 // The factory name may be qualified.
2926 QualIdent factory_name; 2924 QualIdent factory_name;
2927 ParseQualIdent(&factory_name); 2925 ParseQualIdent(&factory_name);
2928 member.name_pos = factory_name.ident_pos; 2926 member.name_pos = factory_name.ident_pos;
2929 member.name = factory_name.ident; // Unqualified identifier. 2927 member.name = factory_name.ident; // Unqualified identifier.
2930 // The class of the factory result type is specified by the factory name. 2928 // The class of the factory result type is specified by the factory name.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 (LookaheadToken(1) != Token::kASSIGN) && 3005 (LookaheadToken(1) != Token::kASSIGN) &&
3008 (LookaheadToken(1) != Token::kCOMMA) && 3006 (LookaheadToken(1) != Token::kCOMMA) &&
3009 (LookaheadToken(1) != Token::kSEMICOLON)) { 3007 (LookaheadToken(1) != Token::kSEMICOLON)) {
3010 ConsumeToken(); 3008 ConsumeToken();
3011 if (!Token::CanBeOverloaded(CurrentToken())) { 3009 if (!Token::CanBeOverloaded(CurrentToken())) {
3012 ErrorMsg("invalid operator overloading"); 3010 ErrorMsg("invalid operator overloading");
3013 } 3011 }
3014 if (member.has_static) { 3012 if (member.has_static) {
3015 ErrorMsg("operator overloading functions cannot be static"); 3013 ErrorMsg("operator overloading functions cannot be static");
3016 } 3014 }
3017 operator_token = CurrentToken(); 3015 member.operator_token = CurrentToken();
3018 member.has_operator = true; 3016 member.has_operator = true;
3019 member.kind = RawFunction::kRegularFunction; 3017 member.kind = RawFunction::kRegularFunction;
3020 member.name_pos = this->TokenPos(); 3018 member.name_pos = this->TokenPos();
3021 member.name = 3019 member.name =
3022 &String::ZoneHandle(Symbols::New(Token::Str(operator_token))); 3020 &String::ZoneHandle(Symbols::New(Token::Str(member.operator_token)));
3023 ConsumeToken(); 3021 ConsumeToken();
3024 } else if (IsIdentifier()) { 3022 } else if (IsIdentifier()) {
3025 member.name = CurrentLiteral(); 3023 member.name = CurrentLiteral();
3026 member.name_pos = TokenPos(); 3024 member.name_pos = TokenPos();
3027 ConsumeToken(); 3025 ConsumeToken();
3028 } else { 3026 } else {
3029 ErrorMsg("identifier expected"); 3027 ErrorMsg("identifier expected");
3030 } 3028 }
3031 3029
3032 ASSERT(member.name != NULL); 3030 ASSERT(member.name != NULL);
3033 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { 3031 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) {
3034 if (members->is_interface() && member.has_static) { 3032 if (members->is_interface() && member.has_static) {
3035 if (member.has_factory) { 3033 if (member.has_factory) {
3036 ErrorMsg("factory constructors are not allowed in interfaces"); 3034 ErrorMsg("factory constructors are not allowed in interfaces");
3037 } else { 3035 } else {
3038 ErrorMsg("static methods are not allowed in interfaces"); 3036 ErrorMsg("static methods are not allowed in interfaces");
3039 } 3037 }
3040 } 3038 }
3041 // Constructor or method. 3039 // Constructor or method.
3042 if (member.type == NULL) { 3040 if (member.type == NULL) {
3043 member.type = &Type::ZoneHandle(Type::DynamicType()); 3041 member.type = &Type::ZoneHandle(Type::DynamicType());
3044 } 3042 }
3045 ASSERT(member.IsFactory() == member.has_factory); 3043 ASSERT(member.IsFactory() == member.has_factory);
3046 ParseMethodOrConstructor(members, &member); 3044 ParseMethodOrConstructor(members, &member);
3047 if (member.has_operator) {
3048 CheckOperatorArity(member, operator_token);
3049 }
3050 } else if (CurrentToken() == Token::kSEMICOLON || 3045 } else if (CurrentToken() == Token::kSEMICOLON ||
3051 CurrentToken() == Token::kCOMMA || 3046 CurrentToken() == Token::kCOMMA ||
3052 CurrentToken() == Token::kASSIGN) { 3047 CurrentToken() == Token::kASSIGN) {
3053 // Field definition. 3048 // Field definition.
3054 if (member.has_const) { 3049 if (member.has_const) {
3055 // const fields are implicitly final. 3050 // const fields are implicitly final.
3056 member.has_final = true; 3051 member.has_final = true;
3057 } 3052 }
3058 if (member.type == NULL) { 3053 if (member.type == NULL) {
3059 if (member.has_final) { 3054 if (member.has_final) {
(...skipping 3550 matching lines...) Expand 10 before | Expand all | Expand 10 after
6610 } 6605 }
6611 6606
6612 6607
6613 bool Parser::IsLiteral(const char* literal) { 6608 bool Parser::IsLiteral(const char* literal) {
6614 const uint8_t* characters = reinterpret_cast<const uint8_t*>(literal); 6609 const uint8_t* characters = reinterpret_cast<const uint8_t*>(literal);
6615 intptr_t len = strlen(literal); 6610 intptr_t len = strlen(literal);
6616 return IsIdentifier() && CurrentLiteral()->Equals(characters, len); 6611 return IsIdentifier() && CurrentLiteral()->Equals(characters, len);
6617 } 6612 }
6618 6613
6619 6614
6620 bool Parser::IsIncrementOperator(Token::Kind token) { 6615 static bool IsIncrementOperator(Token::Kind token) {
6621 return token == Token::kINCR || token == Token::kDECR; 6616 return token == Token::kINCR || token == Token::kDECR;
srdjan 2012/10/16 19:43:41 Does this belong into class Token with all the oth
hausner 2012/10/16 20:19:44 I prefer not to have these functions in class Toke
6622 } 6617 }
6623 6618
6624 6619
6625 bool Parser::IsPrefixOperator(Token::Kind token) { 6620 static bool IsPrefixOperator(Token::Kind token) {
6626 return (token == Token::kTIGHTADD) || // Valid for literals only! 6621 return (token == Token::kTIGHTADD) || // Valid for literals only!
6627 (token == Token::kSUB) || 6622 (token == Token::kSUB) ||
6628 (token == Token::kNOT) || 6623 (token == Token::kNOT) ||
6629 (token == Token::kBIT_NOT); 6624 (token == Token::kBIT_NOT);
srdjan 2012/10/16 19:43:41 Why does it differ from Token::IsPrefixOperator?
hausner 2012/10/16 20:19:44 Because this function is called before the parser
6630 } 6625 }
6631 6626
6632 6627
6633 SequenceNode* Parser::NodeAsSequenceNode(intptr_t sequence_pos, 6628 SequenceNode* Parser::NodeAsSequenceNode(intptr_t sequence_pos,
6634 AstNode* node, 6629 AstNode* node,
6635 LocalScope* scope) { 6630 LocalScope* scope) {
6636 if ((node == NULL) || !node->IsSequenceNode()) { 6631 if ((node == NULL) || !node->IsSequenceNode()) {
6637 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); 6632 SequenceNode* sequence = new SequenceNode(sequence_pos, scope);
6638 if (node != NULL) { 6633 if (node != NULL) {
6639 sequence->Add(node); 6634 sequence->Add(node);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
7088 return expr; 7083 return expr;
7089 } 7084 }
7090 7085
7091 7086
7092 AstNode* Parser::ParseUnaryExpr() { 7087 AstNode* Parser::ParseUnaryExpr() {
7093 TRACE_PARSER("ParseUnaryExpr"); 7088 TRACE_PARSER("ParseUnaryExpr");
7094 AstNode* expr = NULL; 7089 AstNode* expr = NULL;
7095 const intptr_t op_pos = TokenPos(); 7090 const intptr_t op_pos = TokenPos();
7096 if (IsPrefixOperator(CurrentToken())) { 7091 if (IsPrefixOperator(CurrentToken())) {
7097 Token::Kind unary_op = CurrentToken(); 7092 Token::Kind unary_op = CurrentToken();
7093 if (unary_op == Token::kSUB) {
7094 unary_op = Token::kNEGATE;
7095 }
7098 ConsumeToken(); 7096 ConsumeToken();
7099 expr = ParseUnaryExpr(); 7097 expr = ParseUnaryExpr();
7100 if (unary_op == Token::kTIGHTADD) { 7098 if (unary_op == Token::kTIGHTADD) {
7101 // kTIGHADD is added only in front of a number literal. 7099 // kTIGHADD is added only in front of a number literal.
7102 if (!expr->IsLiteralNode()) { 7100 if (!expr->IsLiteralNode()) {
7103 ErrorMsg(op_pos, "unexpected operator '+'"); 7101 ErrorMsg(op_pos, "unexpected operator '+'");
7104 } 7102 }
7105 // Expression is the literal itself. 7103 // Expression is the literal itself.
7106 } else { 7104 } else {
7107 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); 7105 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr);
(...skipping 2628 matching lines...) Expand 10 before | Expand all | Expand 10 after
9736 void Parser::SkipQualIdent() { 9734 void Parser::SkipQualIdent() {
9737 ASSERT(IsIdentifier()); 9735 ASSERT(IsIdentifier());
9738 ConsumeToken(); 9736 ConsumeToken();
9739 if (CurrentToken() == Token::kPERIOD) { 9737 if (CurrentToken() == Token::kPERIOD) {
9740 ConsumeToken(); // Consume the kPERIOD token. 9738 ConsumeToken(); // Consume the kPERIOD token.
9741 ExpectIdentifier("identifier expected after '.'"); 9739 ExpectIdentifier("identifier expected after '.'");
9742 } 9740 }
9743 } 9741 }
9744 9742
9745 } // namespace dart 9743 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/token.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698