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

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

Issue 8234022: Implement index operator super call (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 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') | tests/language/src/SuperOperatorTest.dart » ('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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 984 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 if (!func.IsNull()) { 995 if (!func.IsNull()) {
996 return func.raw(); 996 return func.raw();
997 } 997 }
998 super_cls = super_cls.SuperClass(); 998 super_cls = super_cls.SuperClass();
999 } 999 }
1000 } 1000 }
1001 return func.raw(); 1001 return func.raw();
1002 } 1002 }
1003 1003
1004 1004
1005 RawFunction* Parser::GetSuperFunction(intptr_t token_pos,
1006 const String& name) {
1007 const Class& super_class = Class::Handle(current_class().SuperClass());
1008 if (super_class.IsNull()) {
1009 ErrorMsg(token_pos, "class '%s' does not have a superclass",
1010 String::Handle(current_class().Name()).ToCString());
1011 }
1012
1013 const Function& super_func =
1014 Function::Handle(ResolveDynamicFunction(super_class, name));
1015 if (super_func.IsNull()) {
1016 ErrorMsg(token_pos, "function '%s' not found in super class",
1017 name.ToCString());
1018 }
1019 CheckFunctionIsCallable(token_pos, super_func);
1020 return super_func.raw();
1021 }
1022
1023
1005 AstNode* Parser::ParseSuperCall(const String& function_name) { 1024 AstNode* Parser::ParseSuperCall(const String& function_name) {
1006 TRACE_PARSER("ParseSuperCall"); 1025 TRACE_PARSER("ParseSuperCall");
1007 ASSERT(CurrentToken() == Token::kLPAREN); 1026 ASSERT(CurrentToken() == Token::kLPAREN);
1008 const intptr_t supercall_pos = token_index_; 1027 const intptr_t supercall_pos = token_index_;
1009 const Class& super_class = Class::Handle(current_class().SuperClass()); 1028
1010 if (super_class.IsNull()) { 1029 const Function& super_function = Function::ZoneHandle(
1011 ErrorMsg("class '%s' does not have a superclass", 1030 GetSuperFunction(supercall_pos, function_name));
1012 String::Handle(current_class().Name()).ToCString()); 1031
1013 }
1014 // 'this' parameter is the first argument to super call. 1032 // 'this' parameter is the first argument to super call.
1015 AstNode* implicit_argument = LoadReceiver(supercall_pos); 1033 AstNode* receiver = LoadReceiver(supercall_pos);
1016 ArgumentListNode* arguments = 1034 ArgumentListNode* arguments =
1017 ParseActualParameters(implicit_argument, kAllowConst); 1035 ParseActualParameters(receiver, kAllowConst);
1018 // Resolve the function.
1019 const Function& super_function = Function::ZoneHandle(
1020 ResolveDynamicFunction(super_class, function_name));
1021 if (super_function.IsNull()) {
1022 ErrorMsg(supercall_pos,
1023 "function '%s' not found in super class",
1024 function_name.ToCString());
1025 }
1026 CheckFunctionIsCallable(supercall_pos, super_function);
1027 return new StaticCallNode(supercall_pos, super_function, arguments); 1036 return new StaticCallNode(supercall_pos, super_function, arguments);
1028 } 1037 }
1029 1038
1030 1039
1031 AstNode* Parser::ParseSuperOperator() { 1040 AstNode* Parser::ParseSuperOperator() {
1041 TRACE_PARSER("ParseSuperOperator");
1032 AstNode* super_op = NULL; 1042 AstNode* super_op = NULL;
1033 const intptr_t operator_pos = token_index_; 1043 const intptr_t operator_pos = token_index_;
1034 const Class& super_class = Class::Handle(current_class().SuperClass());
1035 if (super_class.IsNull()) {
1036 ErrorMsg(operator_pos, "class '%s' does not have a superclass",
1037 String::Handle(current_class().Name()).ToCString());
1038 }
1039 1044
1040 if (CurrentToken() == Token::kLBRACK) { 1045 if (CurrentToken() == Token::kLBRACK) {
1041 Unimplemented("Not yet implemented: super[expr]"); 1046 ConsumeToken();
1047 AstNode* index_expr = ParseExpr(kAllowConst);
1048 ExpectToken(Token::kRBRACK);
1049
1050 if (Token::IsAssignmentOperator(CurrentToken()) &&
1051 (CurrentToken() != Token::kASSIGN)) {
1052 // Compound assignment. Ensure side effects in index expression
1053 // only execute once. If the index is not a local variable or an
1054 // literal, evaluate and save in a temporary local.
1055 if (!index_expr->IsLoadLocalNode() && !index_expr->IsLiteralNode()) {
1056 LocalVariable* temp =
1057 CreateTempConstVariable(operator_pos, index_expr->id(), "lix");
1058 AstNode* save =
1059 new StoreLocalNode(operator_pos, *temp, index_expr);
1060 current_block_->statements->Add(save);
1061 index_expr = new LoadLocalNode(operator_pos, *temp);
1062 }
1063 }
1064
1065 // Resolve the [] operator function in the superclass.
1066 const String& index_operator_name =
1067 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX)));
1068 const Function& index_operator = Function::ZoneHandle(
1069 GetSuperFunction(operator_pos, index_operator_name));
1070
1071 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos);
1072 AstNode* receiver = LoadReceiver(operator_pos);
1073 index_op_arguments->Add(receiver);
1074 index_op_arguments->Add(index_expr);
1075
1076 super_op = new StaticCallNode(
1077 operator_pos, index_operator, index_op_arguments);
1078
1079 if (Token::IsAssignmentOperator(CurrentToken())) {
1080 Token::Kind assignment_op = CurrentToken();
1081 ConsumeToken();
1082 AstNode* value = ParseExpr(kAllowConst);
1083
1084 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value);
1085
1086 // Resolve the []= operator function in the superclass.
1087 const String& assign_index_operator_name = String::ZoneHandle(
1088 String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
1089 const Function& assign_index_operator = Function::ZoneHandle(
1090 GetSuperFunction(operator_pos, assign_index_operator_name));
1091
1092 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos);
1093 operator_args->Add(LoadReceiver(operator_pos));
1094 operator_args->Add(index_expr);
1095 operator_args->Add(value);
1096
1097 super_op = new StaticCallNode(
1098 operator_pos, assign_index_operator, operator_args);
1099 }
1042 } else if (Token::CanBeOverloaded(CurrentToken())) { 1100 } else if (Token::CanBeOverloaded(CurrentToken())) {
1043 Token::Kind op = CurrentToken(); 1101 Token::Kind op = CurrentToken();
1044 ConsumeToken(); 1102 ConsumeToken();
1045 1103
1046 // Resolve the operator function in the superclass. 1104 // Resolve the operator function in the superclass.
1047 const String& operator_function_name = 1105 const String& operator_function_name =
1048 String::ZoneHandle(String::NewSymbol(Token::Str(op))); 1106 String::Handle(String::NewSymbol(Token::Str(op)));
1049 const Function& super_operator = Function::ZoneHandle( 1107 const Function& super_operator = Function::ZoneHandle(
1050 ResolveDynamicFunction(super_class, operator_function_name)); 1108 GetSuperFunction(operator_pos, operator_function_name));
1051 if (super_operator.IsNull()) {
1052 ErrorMsg(operator_pos, "operator '%s' not found in super class",
1053 Token::Str(op));
1054 }
1055 1109
1056 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); 1110 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR));
1057 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); 1111 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1);
1058 1112
1059 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); 1113 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos);
1060 AstNode* receiver = LoadReceiver(operator_pos); 1114 AstNode* receiver = LoadReceiver(operator_pos);
1061 op_arguments->Add(receiver); 1115 op_arguments->Add(receiver);
1062 op_arguments->Add(other_operand); 1116 op_arguments->Add(other_operand);
1063 1117
1064 CheckFunctionIsCallable(operator_pos, super_operator); 1118 CheckFunctionIsCallable(operator_pos, super_operator);
(...skipping 5591 matching lines...) Expand 10 before | Expand all | Expand 10 after
6656 } 6710 }
6657 ConsumeToken(); 6711 ConsumeToken();
6658 if (CurrentToken() == Token::kPERIOD) { 6712 if (CurrentToken() == Token::kPERIOD) {
6659 ConsumeToken(); 6713 ConsumeToken();
6660 const String& ident = *ExpectIdentifier("identifier expected"); 6714 const String& ident = *ExpectIdentifier("identifier expected");
6661 if (CurrentToken() == Token::kLPAREN) { 6715 if (CurrentToken() == Token::kLPAREN) {
6662 primary = ParseSuperCall(ident); 6716 primary = ParseSuperCall(ident);
6663 } else { 6717 } else {
6664 primary = ParseSuperFieldAccess(ident); 6718 primary = ParseSuperFieldAccess(ident);
6665 } 6719 }
6666 } else if (Token::CanBeOverloaded(CurrentToken())) { 6720 } else if ((CurrentToken() == Token::kLBRACK) ||
6721 Token::CanBeOverloaded(CurrentToken())) {
6667 primary = ParseSuperOperator(); 6722 primary = ParseSuperOperator();
6668 } else { 6723 } else {
6669 ErrorMsg("Illegal super call"); 6724 ErrorMsg("Illegal super call");
6670 } 6725 }
6671 } else { 6726 } else {
6672 UnexpectedToken(); 6727 UnexpectedToken();
6673 } 6728 }
6674 return primary; 6729 return primary;
6675 } 6730 }
6676 6731
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
6927 } 6982 }
6928 6983
6929 6984
6930 void Parser::SkipNestedExpr() { 6985 void Parser::SkipNestedExpr() {
6931 const bool saved_mode = SetAllowFunctionLiterals(true); 6986 const bool saved_mode = SetAllowFunctionLiterals(true);
6932 SkipExpr(); 6987 SkipExpr();
6933 SetAllowFunctionLiterals(saved_mode); 6988 SetAllowFunctionLiterals(saved_mode);
6934 } 6989 }
6935 6990
6936 } // namespace dart 6991 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/src/SuperOperatorTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698