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

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

Issue 9264051: Fix for bug 1229: Unary operator plus is not allowed ... except for literals. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 10 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
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 5339 matching lines...) Expand 10 before | Expand all | Expand 10 after
5350 return IsIdentifier() && CurrentLiteral()->Equals(characters, len); 5350 return IsIdentifier() && CurrentLiteral()->Equals(characters, len);
5351 } 5351 }
5352 5352
5353 5353
5354 bool Parser::IsIncrementOperator(Token::Kind token) { 5354 bool Parser::IsIncrementOperator(Token::Kind token) {
5355 return token == Token::kINCR || token == Token::kDECR; 5355 return token == Token::kINCR || token == Token::kDECR;
5356 } 5356 }
5357 5357
5358 5358
5359 bool Parser::IsPrefixOperator(Token::Kind token) { 5359 bool Parser::IsPrefixOperator(Token::Kind token) {
5360 return token == Token::kADD || token == Token::kSUB 5360 return (token == Token::kTIGHTADD) || // Valid for literals only!
5361 || token == Token::kNOT || token == Token::kBIT_NOT; 5361 (token == Token::kSUB) ||
5362 (token == Token::kNOT) ||
5363 (token == Token::kBIT_NOT);
5362 } 5364 }
5363 5365
5364 5366
5365 SequenceNode* Parser::NodeAsSequenceNode(intptr_t sequence_pos, 5367 SequenceNode* Parser::NodeAsSequenceNode(intptr_t sequence_pos,
5366 AstNode* node, 5368 AstNode* node,
5367 LocalScope* scope) { 5369 LocalScope* scope) {
5368 if ((node == NULL) || !node->IsSequenceNode()) { 5370 if ((node == NULL) || !node->IsSequenceNode()) {
5369 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); 5371 SequenceNode* sequence = new SequenceNode(sequence_pos, scope);
5370 if (node != NULL) { 5372 if (node != NULL) {
5371 sequence->Add(node); 5373 sequence->Add(node);
5372 } 5374 }
5373 return sequence; 5375 return sequence;
5374 } 5376 }
5375 return node->AsSequenceNode(); 5377 return node->AsSequenceNode();
5376 } 5378 }
5377 5379
5378 5380
5379 AstNode* Parser::ParseBinaryExpr(int min_preced) { 5381 AstNode* Parser::ParseBinaryExpr(int min_preced) {
5380 TRACE_PARSER("ParseBinaryExpr"); 5382 TRACE_PARSER("ParseBinaryExpr");
5381 ASSERT(min_preced >= 4); 5383 ASSERT(min_preced >= 4);
5382 AstNode* left_operand = ParseUnaryExpr(); 5384 AstNode* left_operand = ParseUnaryExpr();
5383 int current_preced = Token::Precedence(CurrentToken()); 5385 int current_preced = Token::Precedence(CurrentToken());
5384 while (current_preced >= min_preced) { 5386 while (current_preced >= min_preced) {
5385 while (Token::Precedence(CurrentToken()) == current_preced) { 5387 while (Token::Precedence(CurrentToken()) == current_preced) {
5386 Token::Kind op_kind = CurrentToken(); 5388 Token::Kind op_kind = CurrentToken();
5389 if (op_kind == Token::kTIGHTADD) {
5390 op_kind = Token::kADD;
5391 }
5387 const intptr_t op_pos = token_index_; 5392 const intptr_t op_pos = token_index_;
5388 ConsumeToken(); 5393 ConsumeToken();
5389 AstNode* right_operand = NULL; 5394 AstNode* right_operand = NULL;
5390 if (op_kind != Token::kIS) { 5395 if (op_kind != Token::kIS) {
5391 right_operand = ParseBinaryExpr(current_preced + 1); 5396 right_operand = ParseBinaryExpr(current_preced + 1);
5392 } else { 5397 } else {
5393 // For 'is' we expect the right operand to be a type. 5398 // For 'is' we expect the right operand to be a type.
5394 if (CurrentToken() == Token::kNOT) { 5399 if (CurrentToken() == Token::kNOT) {
5395 ConsumeToken(); 5400 ConsumeToken();
5396 op_kind = Token::kISNOT; 5401 op_kind = Token::kISNOT;
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
5676 5681
5677 5682
5678 AstNode* Parser::ParseUnaryExpr() { 5683 AstNode* Parser::ParseUnaryExpr() {
5679 TRACE_PARSER("ParseUnaryExpr"); 5684 TRACE_PARSER("ParseUnaryExpr");
5680 AstNode* expr = NULL; 5685 AstNode* expr = NULL;
5681 const intptr_t op_pos = token_index_; 5686 const intptr_t op_pos = token_index_;
5682 if (IsPrefixOperator(CurrentToken())) { 5687 if (IsPrefixOperator(CurrentToken())) {
5683 Token::Kind unary_op = CurrentToken(); 5688 Token::Kind unary_op = CurrentToken();
5684 ConsumeToken(); 5689 ConsumeToken();
5685 expr = ParseUnaryExpr(); 5690 expr = ParseUnaryExpr();
5686 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); 5691 if (unary_op == Token::kTIGHTADD) {
5692 if (!expr->IsLiteralNode()) {
hausner 2012/01/31 18:09:46 This test is not strict enough. This also allows +
srdjan 2012/01/31 19:26:37 Changed scanner to produce TIGHTADD only if the +
5693 ErrorMsg("'+' is not a valid prefix");
hausner 2012/01/31 18:09:46 I wouldn't call + a prefix. How about "unexpected
srdjan 2012/01/31 19:26:37 Using "unexpected". The other option would have be
5694 }
5695 // Expression is the literal itself.
5696 } else {
5697 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr);
5698 }
5687 } else if (IsIncrementOperator(CurrentToken())) { 5699 } else if (IsIncrementOperator(CurrentToken())) {
5688 Token::Kind incr_op = CurrentToken(); 5700 Token::Kind incr_op = CurrentToken();
5689 ConsumeToken(); 5701 ConsumeToken();
5690 expr = ParseUnaryExpr(); 5702 expr = ParseUnaryExpr();
5691 if (!IsAssignableExpr(expr)) { 5703 if (!IsAssignableExpr(expr)) {
5692 ErrorMsg("expression is not assignable"); 5704 ErrorMsg("expression is not assignable");
5693 } 5705 }
5694 // is_prefix. 5706 // is_prefix.
5695 AstNode* incr_op_node = expr->MakeIncrOpNode(op_pos, incr_op, true); 5707 AstNode* incr_op_node = expr->MakeIncrOpNode(op_pos, incr_op, true);
5696 if (incr_op_node == NULL) { 5708 if (incr_op_node == NULL) {
(...skipping 2032 matching lines...) Expand 10 before | Expand all | Expand 10 after
7729 void Parser::SkipQualIdent() { 7741 void Parser::SkipQualIdent() {
7730 ASSERT(IsIdentifier()); 7742 ASSERT(IsIdentifier());
7731 ConsumeToken(); 7743 ConsumeToken();
7732 if (CurrentToken() == Token::kPERIOD) { 7744 if (CurrentToken() == Token::kPERIOD) {
7733 ConsumeToken(); // Consume the kPERIOD token. 7745 ConsumeToken(); // Consume the kPERIOD token.
7734 ExpectIdentifier("identifier expected after '.'"); 7746 ExpectIdentifier("identifier expected after '.'");
7735 } 7747 }
7736 } 7748 }
7737 7749
7738 } // namespace dart 7750 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/bigint_operations.cc ('k') | runtime/vm/scanner.cc » ('j') | runtime/vm/scanner.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698