| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index 41b3a31f0e1169068eaf2968fe55b67fc3904ee4..3afe81b6f6cceccfc7e26db3fe43c05a8c948c13 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -117,7 +117,9 @@ class ParserBase : public Traits {
|
| bool allow_harmony_rest_params() const {
|
| return allow_harmony_rest_params_;
|
| }
|
| -
|
| + bool allow_harmony_exponentiation() const {
|
| + return scanner()->HarmonyExponentiation();
|
| + }
|
| bool allow_strong_mode() const { return allow_strong_mode_; }
|
|
|
| // Setters that determine whether certain syntactical constructs are
|
| @@ -157,6 +159,9 @@ class ParserBase : public Traits {
|
| void set_allow_harmony_rest_params(bool allow) {
|
| allow_harmony_rest_params_ = allow;
|
| }
|
| + void set_allow_harmony_exponentiation(bool allow) {
|
| + scanner()->SetHarmonyExponentiation(allow);
|
| + }
|
| void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
|
|
|
| protected:
|
| @@ -1172,6 +1177,12 @@ class PreParserFactory {
|
| int pos) {
|
| return PreParserExpression::Default();
|
| }
|
| + PreParserExpression NewCallRuntime(const AstRawString* name,
|
| + const Runtime::Function* func,
|
| + PreParserExpressionList arguments,
|
| + int pos) {
|
| + return PreParserExpression::Call();
|
| + }
|
| PreParserStatement NewReturnStatement(PreParserExpression expression,
|
| int pos) {
|
| return PreParserStatement::Default();
|
| @@ -2340,6 +2351,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
|
| return expression;
|
| }
|
|
|
| + bool desugar_exponentiation = false;
|
| if (!Token::IsAssignmentOp(peek())) {
|
| if (fni_ != NULL) fni_->Leave();
|
| // Parsed conditional expression only (no assignment).
|
| @@ -2351,6 +2363,14 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
|
| expression = this->MarkExpressionAsAssigned(expression);
|
|
|
| Token::Value op = Next(); // Get assignment operator.
|
| + if (op == Token::ASSIGN_EXP) {
|
| + // TODO(caitp): Desugaring in the parser makes it observable that lhs is
|
| + // retrieved twice. Fixed by moving implementation to compiler rather than
|
| + // desugaring, or by allocating a temporary variable.
|
| + op = Token::ASSIGN;
|
| + desugar_exponentiation = true;
|
| + }
|
| +
|
| int pos = position();
|
| ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
|
|
|
| @@ -2380,6 +2400,16 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
|
| fni_->Leave();
|
| }
|
|
|
| + if (desugar_exponentiation) {
|
| + // Desugar to runtime call
|
| + typename Traits::Type::ExpressionList args =
|
| + this->NewExpressionList(2, zone_);
|
| + args->Add(expression, zone_);
|
| + args->Add(right, zone_);
|
| + right = factory()->NewCallRuntime(
|
| + ast_value_factory()->math_pow_string(), NULL, args, pos);
|
| + }
|
| +
|
| return factory()->NewAssignment(op, expression, right, pos);
|
| }
|
|
|
| @@ -2465,7 +2495,15 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
|
| Token::Value op = Next();
|
| Scanner::Location op_location = scanner()->location();
|
| int pos = position();
|
| - ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
|
| + ExpressionT y = Traits::EmptyExpression();
|
| +
|
| + if (op != Token::EXP) {
|
| + // Left-to-right associativity
|
| + y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
|
| + } else {
|
| + // Right-to-left associativity
|
| + y = ParseBinaryExpression(prec1, accept_IN, CHECK_OK);
|
| + }
|
|
|
| if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
|
| factory())) {
|
|
|