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