Chromium Code Reviews| 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 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |