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

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

Issue 10350003: Step toward eliminating increment nodes, starting with increment local. Fix a bug in evaluating sid… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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') | no next file » | 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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 : script_(script), 232 : script_(script),
233 tokens_(TokenStream::Handle(script.tokens())), 233 tokens_(TokenStream::Handle(script.tokens())),
234 token_index_(0), 234 token_index_(0),
235 current_block_(NULL), 235 current_block_(NULL),
236 is_top_level_(false), 236 is_top_level_(false),
237 current_member_(NULL), 237 current_member_(NULL),
238 allow_function_literals_(true), 238 allow_function_literals_(true),
239 current_function_(Function::Handle()), 239 current_function_(Function::Handle()),
240 current_class_(Class::Handle()), 240 current_class_(Class::Handle()),
241 library_(library), 241 library_(library),
242 try_blocks_list_(NULL) { 242 try_blocks_list_(NULL),
243 increment_temp_(NULL) {
243 ASSERT(!tokens_.IsNull()); 244 ASSERT(!tokens_.IsNull());
244 ASSERT(!library.IsNull()); 245 ASSERT(!library.IsNull());
245 SetPosition(0); 246 SetPosition(0);
246 } 247 }
247 248
248 249
249 Parser::Parser(const Script& script, 250 Parser::Parser(const Script& script,
250 const Function& function, 251 const Function& function,
251 intptr_t token_index) 252 intptr_t token_index)
252 : script_(script), 253 : script_(script),
253 tokens_(TokenStream::Handle(script.tokens())), 254 tokens_(TokenStream::Handle(script.tokens())),
254 token_index_(0), 255 token_index_(0),
255 current_block_(NULL), 256 current_block_(NULL),
256 is_top_level_(false), 257 is_top_level_(false),
257 current_member_(NULL), 258 current_member_(NULL),
258 allow_function_literals_(true), 259 allow_function_literals_(true),
259 current_function_(function), 260 current_function_(function),
260 current_class_(Class::Handle(current_function_.owner())), 261 current_class_(Class::Handle(current_function_.owner())),
261 library_(Library::Handle(current_class_.library())), 262 library_(Library::Handle(current_class_.library())),
262 try_blocks_list_(NULL) { 263 try_blocks_list_(NULL),
264 increment_temp_(NULL) {
263 ASSERT(!tokens_.IsNull()); 265 ASSERT(!tokens_.IsNull());
264 ASSERT(!function.IsNull()); 266 ASSERT(!function.IsNull());
265 SetPosition(token_index); 267 SetPosition(token_index);
266 } 268 }
267 269
268 270
269 bool Parser::SetAllowFunctionLiterals(bool value) { 271 bool Parser::SetAllowFunctionLiterals(bool value) {
270 bool current_value = allow_function_literals_; 272 bool current_value = allow_function_literals_;
271 allow_function_literals_ = value; 273 allow_function_literals_ = value;
272 return current_value; 274 return current_value;
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); 642 return seq->NodeAt(seq->length() - 1)->IsReturnNode();
641 } 643 }
642 } 644 }
643 645
644 646
645 void Parser::ParseFunction(ParsedFunction* parsed_function) { 647 void Parser::ParseFunction(ParsedFunction* parsed_function) {
646 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); 648 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer);
647 Isolate* isolate = Isolate::Current(); 649 Isolate* isolate = Isolate::Current();
648 ASSERT(isolate->long_jump_base()->IsSafeToJump()); 650 ASSERT(isolate->long_jump_base()->IsSafeToJump());
649 // Compilation can be nested, preserve the ast node id. 651 // Compilation can be nested, preserve the ast node id.
650 const int prev_ast_node_id = isolate->ast_node_id(); 652 const intptr_t prev_ast_node_id = isolate->ast_node_id();
651 isolate->set_ast_node_id(0); 653 isolate->set_ast_node_id(0);
652 ASSERT(parsed_function != NULL); 654 ASSERT(parsed_function != NULL);
653 const Function& func = parsed_function->function(); 655 const Function& func = parsed_function->function();
654 const Class& cls = Class::Handle(isolate, func.owner()); 656 const Class& cls = Class::Handle(isolate, func.owner());
655 const Script& script = Script::Handle(isolate, cls.script()); 657 const Script& script = Script::Handle(isolate, cls.script());
656 Parser parser(script, func, func.token_index()); 658 Parser parser(script, func, func.token_index());
657 SequenceNode* node_sequence = NULL; 659 SequenceNode* node_sequence = NULL;
658 Array& default_parameter_values = Array::Handle(isolate, Array::null()); 660 Array& default_parameter_values = Array::Handle(isolate, Array::null());
659 switch (func.kind()) { 661 switch (func.kind()) {
660 case RawFunction::kFunction: 662 case RawFunction::kFunction:
(...skipping 15 matching lines...) Expand all
676 node_sequence = parser.ParseStaticConstGetter(func); 678 node_sequence = parser.ParseStaticConstGetter(func);
677 break; 679 break;
678 default: 680 default:
679 UNREACHABLE(); 681 UNREACHABLE();
680 } 682 }
681 683
682 if (!HasReturnNode(node_sequence)) { 684 if (!HasReturnNode(node_sequence)) {
683 // Add implicit return node. 685 // Add implicit return node.
684 node_sequence->Add(new ReturnNode(parser.token_index_)); 686 node_sequence->Add(new ReturnNode(parser.token_index_));
685 } 687 }
688 if (parser.increment_temp_ != NULL) {
689 node_sequence->scope()->AddVariable(parser.increment_temp_);
690 }
686 parsed_function->SetNodeSequence(node_sequence); 691 parsed_function->SetNodeSequence(node_sequence);
687 692
688 // The instantiator may be required at run time for generic type checks or 693 // The instantiator may be required at run time for generic type checks or
689 // allocation of generic types. 694 // allocation of generic types.
690 if (parser.IsInstantiatorRequired()) { 695 if (parser.IsInstantiatorRequired()) {
691 // In the case of a local function, only set the instantiator if the 696 // In the case of a local function, only set the instantiator if the
692 // receiver was captured. 697 // receiver was captured.
693 const bool kTestOnly = true; 698 const bool kTestOnly = true;
694 LocalVariable* receiver = 699 LocalVariable* receiver =
695 parser.LookupReceiver(node_sequence->scope(), 700 parser.LookupReceiver(node_sequence->scope(),
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 1213
1209 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); 1214 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1210 // 'this' parameter is the first argument to super call. 1215 // 'this' parameter is the first argument to super call.
1211 AstNode* receiver = LoadReceiver(supercall_pos); 1216 AstNode* receiver = LoadReceiver(supercall_pos);
1212 arguments->Add(receiver); 1217 arguments->Add(receiver);
1213 ParseActualParameters(arguments, kAllowConst); 1218 ParseActualParameters(arguments, kAllowConst);
1214 return new StaticCallNode(supercall_pos, super_function, arguments); 1219 return new StaticCallNode(supercall_pos, super_function, arguments);
1215 } 1220 }
1216 1221
1217 1222
1223 // Simple test if a node is side effect free.
1224 static bool IsSimpleLocalOrLiteralNode(AstNode* node) {
1225 if (node->IsLiteralNode()) {
1226 return true;
1227 }
1228 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) {
1229 return true;
1230 }
1231 return false;
1232 }
1233
1234
1218 AstNode* Parser::ParseSuperOperator() { 1235 AstNode* Parser::ParseSuperOperator() {
1219 TRACE_PARSER("ParseSuperOperator"); 1236 TRACE_PARSER("ParseSuperOperator");
1220 AstNode* super_op = NULL; 1237 AstNode* super_op = NULL;
1221 const intptr_t operator_pos = token_index_; 1238 const intptr_t operator_pos = token_index_;
1222 1239
1223 if (CurrentToken() == Token::kLBRACK) { 1240 if (CurrentToken() == Token::kLBRACK) {
1224 ConsumeToken(); 1241 ConsumeToken();
1225 AstNode* index_expr = ParseExpr(kAllowConst); 1242 AstNode* index_expr = ParseExpr(kAllowConst);
1226 ExpectToken(Token::kRBRACK); 1243 ExpectToken(Token::kRBRACK);
1227 1244
1228 if (Token::IsAssignmentOperator(CurrentToken()) && 1245 if (Token::IsAssignmentOperator(CurrentToken()) &&
1229 (CurrentToken() != Token::kASSIGN)) { 1246 (CurrentToken() != Token::kASSIGN)) {
1230 // Compound assignment. Ensure side effects in index expression 1247 // Compound assignment. Ensure side effects in index expression
1231 // only execute once. If the index is not a local variable or an 1248 // only execute once. If the index is not a local variable or an
1232 // literal, evaluate and save in a temporary local. 1249 // literal, evaluate and save in a temporary local.
1233 if (!index_expr->IsLoadLocalNode() && !index_expr->IsLiteralNode()) { 1250 if (!IsSimpleLocalOrLiteralNode(index_expr)) {
1234 LocalVariable* temp = 1251 LocalVariable* temp =
1235 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); 1252 CreateTempConstVariable(operator_pos, index_expr->id(), "lix");
1236 AstNode* save = 1253 AstNode* save =
1237 new StoreLocalNode(operator_pos, *temp, index_expr); 1254 new StoreLocalNode(operator_pos, *temp, index_expr);
1238 current_block_->statements->Add(save); 1255 current_block_->statements->Add(save);
1239 index_expr = new LoadLocalNode(operator_pos, *temp); 1256 index_expr = new LoadLocalNode(operator_pos, *temp);
1240 } 1257 }
1241 } 1258 }
1242 1259
1243 // Resolve the [] operator function in the superclass. 1260 // Resolve the [] operator function in the superclass.
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
1846 // We need to patch the super _initializer_ call so that it 1863 // We need to patch the super _initializer_ call so that it
1847 // saves the evaluated actual arguments in temporary variables. 1864 // saves the evaluated actual arguments in temporary variables.
1848 // The temporary variables are necessary so that the argument 1865 // The temporary variables are necessary so that the argument
1849 // expressions are not evaluated twice. 1866 // expressions are not evaluated twice.
1850 ArgumentListNode* ctor_args = super_call->arguments(); 1867 ArgumentListNode* ctor_args = super_call->arguments();
1851 // The super initializer call has at least 2 arguments: the 1868 // The super initializer call has at least 2 arguments: the
1852 // implicit receiver, and the hidden construction phase. 1869 // implicit receiver, and the hidden construction phase.
1853 ASSERT(ctor_args->length() >= 2); 1870 ASSERT(ctor_args->length() >= 2);
1854 for (int i = 2; i < ctor_args->length(); i++) { 1871 for (int i = 2; i < ctor_args->length(); i++) {
1855 AstNode* arg = ctor_args->NodeAt(i); 1872 AstNode* arg = ctor_args->NodeAt(i);
1856 if (!arg->IsLoadLocalNode() && !arg->IsLiteralNode()) { 1873 if (!IsSimpleLocalOrLiteralNode(arg)) {
1857 LocalVariable* temp = 1874 LocalVariable* temp =
1858 CreateTempConstVariable(arg->token_index(), arg->id(), "sca"); 1875 CreateTempConstVariable(arg->token_index(), arg->id(), "sca");
1859 AstNode* save_temp = 1876 AstNode* save_temp =
1860 new StoreLocalNode(arg->token_index(), *temp, arg); 1877 new StoreLocalNode(arg->token_index(), *temp, arg);
1861 ctor_args->SetNodeAt(i, save_temp); 1878 ctor_args->SetNodeAt(i, save_temp);
1862 } 1879 }
1863 } 1880 }
1864 } 1881 }
1865 OpenBlock(); // Block to collect constructor body nodes. 1882 OpenBlock(); // Block to collect constructor body nodes.
1866 1883
(...skipping 3986 matching lines...) Expand 10 before | Expand all | Expand 10 after
5853 } 5870 }
5854 } 5871 }
5855 current_preced--; 5872 current_preced--;
5856 } 5873 }
5857 return left_operand; 5874 return left_operand;
5858 } 5875 }
5859 5876
5860 5877
5861 bool Parser::IsAssignableExpr(AstNode* expr) { 5878 bool Parser::IsAssignableExpr(AstNode* expr) {
5862 return expr->IsPrimaryNode() 5879 return expr->IsPrimaryNode()
5863 || expr->IsLoadLocalNode() 5880 || (expr->IsLoadLocalNode() && !expr->AsLoadLocalNode()->HasPseudo())
5864 || expr->IsLoadStaticFieldNode() 5881 || expr->IsLoadStaticFieldNode()
5865 || expr->IsStaticGetterNode() 5882 || expr->IsStaticGetterNode()
5866 || expr->IsInstanceGetterNode() 5883 || expr->IsInstanceGetterNode()
5867 || expr->IsLoadIndexedNode(); 5884 || expr->IsLoadIndexedNode();
5868 } 5885 }
5869 5886
5870 5887
5871 AstNode* Parser::ParseExprList() { 5888 AstNode* Parser::ParseExprList() {
5872 TRACE_PARSER("ParseExprList"); 5889 TRACE_PARSER("ParseExprList");
5873 AstNode* expressions = ParseExpr(kAllowConst); 5890 AstNode* expressions = ParseExpr(kAllowConst);
5874 if (CurrentToken() == Token::kCOMMA) { 5891 if (CurrentToken() == Token::kCOMMA) {
5875 // Collect comma-separated expressions in a non scope owning sequence node. 5892 // Collect comma-separated expressions in a non scope owning sequence node.
5876 SequenceNode* list = new SequenceNode(token_index_, NULL); 5893 SequenceNode* list = new SequenceNode(token_index_, NULL);
5877 list->Add(expressions); 5894 list->Add(expressions);
5878 while (CurrentToken() == Token::kCOMMA) { 5895 while (CurrentToken() == Token::kCOMMA) {
5879 ConsumeToken(); 5896 ConsumeToken();
5880 AstNode* expr = ParseExpr(kAllowConst); 5897 AstNode* expr = ParseExpr(kAllowConst);
5881 list->Add(expr); 5898 list->Add(expr);
5882 } 5899 }
5883 expressions = list; 5900 expressions = list;
5884 } 5901 }
5885 return expressions; 5902 return expressions;
5886 } 5903 }
5887 5904
5888 5905
5889 static bool IsLocalOrLiteralNode(AstNode* node) { 5906 const LocalVariable& Parser::GetIncrementTempLocal() {
5890 return node->IsLoadLocalNode() || node->IsLiteralNode(); 5907 if (increment_temp_ == NULL) {
5908 increment_temp_ =
5909 new LocalVariable(current_function_.token_index(),
5910 String::ZoneHandle(String::NewSymbol(":incrtemp")),
5911 Type::ZoneHandle(Type::DynamicType()));
5912 }
5913 return *increment_temp_;
5891 } 5914 }
5892 5915
5893
5894 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index, 5916 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index,
5895 intptr_t token_id, 5917 intptr_t token_id,
5896 const char* s) { 5918 const char* s) {
5897 char name[64]; 5919 char name[64];
5898 OS::SNPrint(name, 64, ":%s%d", s, token_id); 5920 OS::SNPrint(name, 64, ":%s%d", s, token_id);
5899 LocalVariable* temp = 5921 LocalVariable* temp =
5900 new LocalVariable(token_index, 5922 new LocalVariable(token_index,
5901 String::ZoneHandle(String::NewSymbol(name)), 5923 String::ZoneHandle(String::NewSymbol(name)),
5902 Type::ZoneHandle(Type::DynamicType())); 5924 Type::ZoneHandle(Type::DynamicType()));
5903 temp->set_is_final(); 5925 temp->set_is_final();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
5990 // left and right nodes. 'expr' becomes the right node, left node is returned as 6012 // left and right nodes. 'expr' becomes the right node, left node is returned as
5991 // result. 6013 // result.
5992 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { 6014 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) {
5993 AstNode* node = *expr; 6015 AstNode* node = *expr;
5994 if (node->IsLoadIndexedNode()) { 6016 if (node->IsLoadIndexedNode()) {
5995 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); 6017 LoadIndexedNode* left_node = node->AsLoadIndexedNode();
5996 LoadIndexedNode* right_node = left_node; 6018 LoadIndexedNode* right_node = left_node;
5997 intptr_t node_id = node->id(); 6019 intptr_t node_id = node->id();
5998 intptr_t token_index = node->token_index(); 6020 intptr_t token_index = node->token_index();
5999 node = NULL; // Do not use it. 6021 node = NULL; // Do not use it.
6000 if (!IsLocalOrLiteralNode(left_node->array())) { 6022 if (!IsSimpleLocalOrLiteralNode(left_node->array())) {
6001 LocalVariable* temp = 6023 LocalVariable* temp =
6002 CreateTempConstVariable(token_index, node_id, "lia"); 6024 CreateTempConstVariable(token_index, node_id, "lia");
6003 StoreLocalNode* save = 6025 StoreLocalNode* save =
6004 new StoreLocalNode(token_index, *temp, left_node->array()); 6026 new StoreLocalNode(token_index, *temp, left_node->array());
6005 left_node = 6027 left_node =
6006 new LoadIndexedNode(token_index, save, left_node->index_expr()); 6028 new LoadIndexedNode(token_index, save, left_node->index_expr());
6007 right_node = new LoadIndexedNode(token_index, 6029 right_node = new LoadIndexedNode(token_index,
6008 new LoadLocalNode(token_index, *temp), 6030 new LoadLocalNode(token_index, *temp),
6009 right_node->index_expr()); 6031 right_node->index_expr());
6010 } 6032 }
6011 if (!IsLocalOrLiteralNode(left_node->index_expr())) { 6033 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) {
6012 LocalVariable* temp = 6034 LocalVariable* temp =
6013 CreateTempConstVariable(token_index, node_id, "lix"); 6035 CreateTempConstVariable(token_index, node_id, "lix");
6014 StoreLocalNode* save = 6036 StoreLocalNode* save =
6015 new StoreLocalNode(token_index, *temp, left_node->index_expr()); 6037 new StoreLocalNode(token_index, *temp, left_node->index_expr());
6016 left_node = new LoadIndexedNode(token_index, 6038 left_node = new LoadIndexedNode(token_index,
6017 left_node->array(), 6039 left_node->array(),
6018 save); 6040 save);
6019 right_node = new LoadIndexedNode(token_index, 6041 right_node = new LoadIndexedNode(token_index,
6020 right_node->array(), 6042 right_node->array(),
6021 new LoadLocalNode(token_index, *temp)); 6043 new LoadLocalNode(token_index, *temp));
6022 } 6044 }
6023 *expr = right_node; 6045 *expr = right_node;
6024 return left_node; 6046 return left_node;
6025 } 6047 }
6026 if (node->IsInstanceGetterNode()) { 6048 if (node->IsInstanceGetterNode()) {
6027 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); 6049 InstanceGetterNode* left_node = node->AsInstanceGetterNode();
6028 InstanceGetterNode* right_node = left_node; 6050 InstanceGetterNode* right_node = left_node;
6029 intptr_t node_id = node->id(); 6051 intptr_t node_id = node->id();
6030 intptr_t token_index = node->token_index(); 6052 intptr_t token_index = node->token_index();
6031 node = NULL; // Do not use it. 6053 node = NULL; // Do not use it.
6032 if (!IsLocalOrLiteralNode(left_node->receiver())) { 6054 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) {
6033 LocalVariable* temp = 6055 LocalVariable* temp =
6034 CreateTempConstVariable(token_index, node_id, "igr"); 6056 CreateTempConstVariable(token_index, node_id, "igr");
6035 StoreLocalNode* save = 6057 StoreLocalNode* save =
6036 new StoreLocalNode(token_index, *temp, left_node->receiver()); 6058 new StoreLocalNode(token_index, *temp, left_node->receiver());
6037 left_node = new InstanceGetterNode(token_index, 6059 left_node = new InstanceGetterNode(token_index,
6038 save, 6060 save,
6039 left_node->field_name()); 6061 left_node->field_name());
6040 right_node = new InstanceGetterNode(token_index, 6062 right_node = new InstanceGetterNode(token_index,
6041 new LoadLocalNode(token_index, *temp), 6063 new LoadLocalNode(token_index, *temp),
6042 right_node->field_name()); 6064 right_node->field_name());
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
6619 } 6641 }
6620 if (IsIncrementOperator(CurrentToken())) { 6642 if (IsIncrementOperator(CurrentToken())) {
6621 TRACE_PARSER("IncrementOperator"); 6643 TRACE_PARSER("IncrementOperator");
6622 Token::Kind incr_op = CurrentToken(); 6644 Token::Kind incr_op = CurrentToken();
6623 if (!IsAssignableExpr(postfix_expr)) { 6645 if (!IsAssignableExpr(postfix_expr)) {
6624 ErrorMsg("expression is not assignable"); 6646 ErrorMsg("expression is not assignable");
6625 } 6647 }
6626 ConsumeToken(); 6648 ConsumeToken();
6627 // Not prefix. 6649 // Not prefix.
6628 if (postfix_expr->IsLoadStaticFieldNode() || 6650 if (postfix_expr->IsLoadStaticFieldNode() ||
6629 postfix_expr->IsStaticGetterNode()) { 6651 postfix_expr->IsStaticGetterNode() ||
6630 LocalVariable* temp = CreateTempConstVariable( 6652 postfix_expr->IsLoadLocalNode()) {
6631 postfix_expr_pos, postfix_expr->id(), "incoplix"); 6653 const LocalVariable& temp = GetIncrementTempLocal();
6632 AstNode* save = 6654 AstNode* save =
6633 new StoreLocalNode(postfix_expr_pos, *temp, postfix_expr); 6655 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr);
6634 Token::Kind binary_op = 6656 Token::Kind binary_op =
6635 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 6657 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
6636 BinaryOpNode* add = new BinaryOpNode( 6658 BinaryOpNode* add = new BinaryOpNode(
6637 postfix_expr_pos, 6659 postfix_expr_pos,
6638 binary_op, 6660 binary_op,
6639 save, 6661 save,
6640 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); 6662 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1))));
6641 AstNode* store = postfix_expr->MakeAssignmentNode(add); 6663 AstNode* store = postfix_expr->MakeAssignmentNode(add);
6642 LoadLocalNode* load_res = 6664 LoadLocalNode* load_res =
6643 new LoadLocalNode(postfix_expr_pos, *temp, store); 6665 new LoadLocalNode(postfix_expr_pos, temp, store);
6644 return load_res; 6666 return load_res;
6645 } else { 6667 } else {
6646 AstNode* incr_op_node = 6668 AstNode* incr_op_node =
6647 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); 6669 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false);
6648 if (incr_op_node == NULL) { 6670 if (incr_op_node == NULL) {
6649 Unimplemented("incr op not implemented"); 6671 Unimplemented("incr op not implemented");
6650 } 6672 }
6651 postfix_expr = incr_op_node; 6673 postfix_expr = incr_op_node;
6652 } 6674 }
6653 } 6675 }
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after
8426 void Parser::SkipQualIdent() { 8448 void Parser::SkipQualIdent() {
8427 ASSERT(IsIdentifier()); 8449 ASSERT(IsIdentifier());
8428 ConsumeToken(); 8450 ConsumeToken();
8429 if (CurrentToken() == Token::kPERIOD) { 8451 if (CurrentToken() == Token::kPERIOD) {
8430 ConsumeToken(); // Consume the kPERIOD token. 8452 ConsumeToken(); // Consume the kPERIOD token.
8431 ExpectIdentifier("identifier expected after '.'"); 8453 ExpectIdentifier("identifier expected after '.'");
8432 } 8454 }
8433 } 8455 }
8434 8456
8435 } // namespace dart 8457 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698