Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 0d1ba004b5862a9c6a560f0abeeca769a151ef35..01bd85348f5744bae34f0f93f7e3c7fb1e76973c 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -433,12 +433,6 @@ bool ParserTraits::IsThisProperty(Expression* expression) { |
} |
-bool ParserTraits::IsIdentifier(Expression* expression) { |
- VariableProxy* operand = expression->AsVariableProxy(); |
- return operand != NULL && !operand->is_this(); |
-} |
- |
- |
void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
Expression* right) { |
ASSERT(left != NULL); |
@@ -531,52 +525,6 @@ bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
} |
-Expression* ParserTraits::BuildUnaryExpression( |
- Expression* expression, Token::Value op, int pos, |
- AstNodeFactory<AstConstructionVisitor>* factory) { |
- ASSERT(expression != NULL); |
- if (expression->AsLiteral() != NULL) { |
- Handle<Object> literal = expression->AsLiteral()->value(); |
- if (op == Token::NOT) { |
- // Convert the literal to a boolean condition and negate it. |
- bool condition = literal->BooleanValue(); |
- Handle<Object> result = |
- parser_->isolate()->factory()->ToBoolean(!condition); |
- return factory->NewLiteral(result, pos); |
- } else if (literal->IsNumber()) { |
- // Compute some expressions involving only number literals. |
- double value = literal->Number(); |
- switch (op) { |
- case Token::ADD: |
- return expression; |
- case Token::SUB: |
- return factory->NewNumberLiteral(-value, pos); |
- case Token::BIT_NOT: |
- return factory->NewNumberLiteral(~DoubleToInt32(value), pos); |
- default: |
- break; |
- } |
- } |
- } |
- // Desugar '+foo' => 'foo*1' |
- if (op == Token::ADD) { |
- return factory->NewBinaryOperation( |
- Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos); |
- } |
- // The same idea for '-foo' => 'foo*(-1)'. |
- if (op == Token::SUB) { |
- return factory->NewBinaryOperation( |
- Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos); |
- } |
- // ...and one more time for '~foo' => 'foo^(~0)'. |
- if (op == Token::BIT_NOT) { |
- return factory->NewBinaryOperation( |
- Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
- } |
- return factory->NewUnaryOperation(op, expression, pos); |
-} |
- |
- |
void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
const char* message, |
Vector<const char*> args, |
@@ -740,8 +688,8 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
} |
-Expression* ParserTraits::ParsePostfixExpression(bool* ok) { |
- return parser_->ParsePostfixExpression(ok); |
+Expression* ParserTraits::ParseUnaryExpression(bool* ok) { |
+ return parser_->ParseUnaryExpression(ok); |
} |
@@ -3042,6 +2990,111 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
} |
+Expression* Parser::ParseUnaryExpression(bool* ok) { |
+ // UnaryExpression :: |
+ // PostfixExpression |
+ // 'delete' UnaryExpression |
+ // 'void' UnaryExpression |
+ // 'typeof' UnaryExpression |
+ // '++' UnaryExpression |
+ // '--' UnaryExpression |
+ // '+' UnaryExpression |
+ // '-' UnaryExpression |
+ // '~' UnaryExpression |
+ // '!' UnaryExpression |
+ |
+ Token::Value op = peek(); |
+ if (Token::IsUnaryOp(op)) { |
+ op = Next(); |
+ int pos = position(); |
+ Expression* expression = ParseUnaryExpression(CHECK_OK); |
+ |
+ if (expression != NULL && (expression->AsLiteral() != NULL)) { |
+ Handle<Object> literal = expression->AsLiteral()->value(); |
+ if (op == Token::NOT) { |
+ // Convert the literal to a boolean condition and negate it. |
+ bool condition = literal->BooleanValue(); |
+ Handle<Object> result = isolate()->factory()->ToBoolean(!condition); |
+ return factory()->NewLiteral(result, pos); |
+ } else if (literal->IsNumber()) { |
+ // Compute some expressions involving only number literals. |
+ double value = literal->Number(); |
+ switch (op) { |
+ case Token::ADD: |
+ return expression; |
+ case Token::SUB: |
+ return factory()->NewNumberLiteral(-value, pos); |
+ case Token::BIT_NOT: |
+ return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); |
+ default: |
+ break; |
+ } |
+ } |
+ } |
+ |
+ // "delete identifier" is a syntax error in strict mode. |
+ if (op == Token::DELETE && strict_mode() == STRICT) { |
+ VariableProxy* operand = expression->AsVariableProxy(); |
+ if (operand != NULL && !operand->is_this()) { |
+ ReportMessage("strict_delete", Vector<const char*>::empty()); |
+ *ok = false; |
+ return NULL; |
+ } |
+ } |
+ |
+ // Desugar '+foo' into 'foo*1', this enables the collection of type feedback |
+ // without any special stub and the multiplication is removed later in |
+ // Crankshaft's canonicalization pass. |
+ if (op == Token::ADD) { |
+ return factory()->NewBinaryOperation(Token::MUL, |
+ expression, |
+ factory()->NewNumberLiteral(1, pos), |
+ pos); |
+ } |
+ // The same idea for '-foo' => 'foo*(-1)'. |
+ if (op == Token::SUB) { |
+ return factory()->NewBinaryOperation(Token::MUL, |
+ expression, |
+ factory()->NewNumberLiteral(-1, pos), |
+ pos); |
+ } |
+ // ...and one more time for '~foo' => 'foo^(~0)'. |
+ if (op == Token::BIT_NOT) { |
+ return factory()->NewBinaryOperation(Token::BIT_XOR, |
+ expression, |
+ factory()->NewNumberLiteral(~0, pos), |
+ pos); |
+ } |
+ |
+ return factory()->NewUnaryOperation(op, expression, pos); |
+ |
+ } else if (Token::IsCountOp(op)) { |
+ op = Next(); |
+ Scanner::Location lhs_location = scanner()->peek_location(); |
+ Expression* expression = ParseUnaryExpression(CHECK_OK); |
+ if (expression == NULL || !expression->IsValidLeftHandSide()) { |
+ ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true); |
+ *ok = false; |
+ return NULL; |
+ } |
+ |
+ if (strict_mode() == STRICT) { |
+ // Prefix expression operand in strict mode may not be eval or arguments. |
+ CheckStrictModeLValue(expression, CHECK_OK); |
+ } |
+ MarkExpressionAsLValue(expression); |
+ |
+ return factory()->NewCountOperation(op, |
+ true /* prefix */, |
+ expression, |
+ position()); |
+ |
+ } else { |
+ return ParsePostfixExpression(ok); |
+ } |
+} |
+ |
+ |
Expression* Parser::ParsePostfixExpression(bool* ok) { |
// PostfixExpression :: |
// LeftHandSideExpression ('++' | '--')? |