Revision: 19997
Author:   [email protected]
Date:     Mon Mar 17 13:54:42 2014 UTC
Log:      Move ParseBinaryExpression to ParserBase.

[email protected]
BUG=v8:3126
LOG=N

Review URL: https://codereview.chromium.org/196933005
http://code.google.com/p/v8/source/detail?r=19997

Modified:
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/preparser.cc
 /branches/bleeding_edge/src/preparser.h

=======================================
--- /branches/bleeding_edge/src/parser.cc       Mon Mar 17 13:36:39 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Mon Mar 17 13:54:42 2014 UTC
@@ -476,6 +476,66 @@
     *ok = false;
   }
 }
+
+
+bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
+    Expression** x, Expression* y, Token::Value op, int pos,
+    AstNodeFactory<AstConstructionVisitor>* factory) {
+  if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() &&
+      y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) {
+    double x_val = (*x)->AsLiteral()->value()->Number();
+    double y_val = y->AsLiteral()->value()->Number();
+    switch (op) {
+      case Token::ADD:
+        *x = factory->NewNumberLiteral(x_val + y_val, pos);
+        return true;
+      case Token::SUB:
+        *x = factory->NewNumberLiteral(x_val - y_val, pos);
+        return true;
+      case Token::MUL:
+        *x = factory->NewNumberLiteral(x_val * y_val, pos);
+        return true;
+      case Token::DIV:
+        *x = factory->NewNumberLiteral(x_val / y_val, pos);
+        return true;
+      case Token::BIT_OR: {
+        int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
+        *x = factory->NewNumberLiteral(value, pos);
+        return true;
+      }
+      case Token::BIT_AND: {
+        int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
+        *x = factory->NewNumberLiteral(value, pos);
+        return true;
+      }
+      case Token::BIT_XOR: {
+        int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
+        *x = factory->NewNumberLiteral(value, pos);
+        return true;
+      }
+      case Token::SHL: {
+        int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
+        *x = factory->NewNumberLiteral(value, pos);
+        return true;
+      }
+      case Token::SHR: {
+        uint32_t shift = DoubleToInt32(y_val) & 0x1f;
+        uint32_t value = DoubleToUint32(x_val) >> shift;
+        *x = factory->NewNumberLiteral(value, pos);
+        return true;
+      }
+      case Token::SAR: {
+        uint32_t shift = DoubleToInt32(y_val) & 0x1f;
+        int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
+        *x = factory->NewNumberLiteral(value, pos);
+        return true;
+      }
+      default:
+        break;
+    }
+  }
+  return false;
+}


 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
@@ -633,9 +693,8 @@
 }


-Expression* ParserTraits::ParseBinaryExpression(int prec, bool accept_IN,
-                                                bool* ok) {
-  return parser_->ParseBinaryExpression(prec, accept_IN, ok);
+Expression* ParserTraits::ParseUnaryExpression(bool* ok) {
+  return parser_->ParseUnaryExpression(ok);
 }


@@ -2921,100 +2980,6 @@
     return loop;
   }
 }
-
-
-// Precedence >= 4
-Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
-  ASSERT(prec >= 4);
-  Expression* x = ParseUnaryExpression(CHECK_OK);
-  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
-    // prec1 >= 4
-    while (Precedence(peek(), accept_IN) == prec1) {
-      Token::Value op = Next();
-      int pos = position();
- Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
-
-      // Compute some expressions involving only number literals.
-      if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() &&
-          y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) {
-        double x_val = x->AsLiteral()->value()->Number();
-        double y_val = y->AsLiteral()->value()->Number();
-
-        switch (op) {
-          case Token::ADD:
-            x = factory()->NewNumberLiteral(x_val + y_val, pos);
-            continue;
-          case Token::SUB:
-            x = factory()->NewNumberLiteral(x_val - y_val, pos);
-            continue;
-          case Token::MUL:
-            x = factory()->NewNumberLiteral(x_val * y_val, pos);
-            continue;
-          case Token::DIV:
-            x = factory()->NewNumberLiteral(x_val / y_val, pos);
-            continue;
-          case Token::BIT_OR: {
-            int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
-            x = factory()->NewNumberLiteral(value, pos);
-            continue;
-          }
-          case Token::BIT_AND: {
-            int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
-            x = factory()->NewNumberLiteral(value, pos);
-            continue;
-          }
-          case Token::BIT_XOR: {
-            int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
-            x = factory()->NewNumberLiteral(value, pos);
-            continue;
-          }
-          case Token::SHL: {
- int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
-            x = factory()->NewNumberLiteral(value, pos);
-            continue;
-          }
-          case Token::SHR: {
-            uint32_t shift = DoubleToInt32(y_val) & 0x1f;
-            uint32_t value = DoubleToUint32(x_val) >> shift;
-            x = factory()->NewNumberLiteral(value, pos);
-            continue;
-          }
-          case Token::SAR: {
-            uint32_t shift = DoubleToInt32(y_val) & 0x1f;
-            int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
-            x = factory()->NewNumberLiteral(value, pos);
-            continue;
-          }
-          default:
-            break;
-        }
-      }
-
-      // For now we distinguish between comparisons and other binary
-      // operations.  (We could combine the two and get rid of this
-      // code and AST node eventually.)
-      if (Token::IsCompareOp(op)) {
-        // We have a comparison.
-        Token::Value cmp = op;
-        switch (op) {
-          case Token::NE: cmp = Token::EQ; break;
-          case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
-          default: break;
-        }
-        x = factory()->NewCompareOperation(cmp, x, y, pos);
-        if (cmp != op) {
-          // The comparison was negated - add a NOT.
-          x = factory()->NewUnaryOperation(Token::NOT, x, pos);
-        }
-
-      } else {
-        // We have a "normal" binary operation.
-        x = factory()->NewBinaryOperation(op, x, y, pos);
-      }
-    }
-  }
-  return x;
-}


 Expression* Parser::ParseUnaryExpression(bool* ok) {
=======================================
--- /branches/bleeding_edge/src/parser.h        Mon Mar 17 13:36:39 2014 UTC
+++ /branches/bleeding_edge/src/parser.h        Mon Mar 17 13:54:42 2014 UTC
@@ -498,6 +498,13 @@
   // in strict mode.
   void CheckStrictModeLValue(Expression*expression, bool* ok);

+  // Returns true if we have a binary expression between two numeric
+ // literals. In that case, *x will be changed to an expression which is the
+  // computed value.
+  bool ShortcutNumericLiteralBinaryExpression(
+      Expression** x, Expression* y, Token::Value op, int pos,
+      AstNodeFactory<AstConstructionVisitor>* factory);
+
   // Reporting errors.
   void ReportMessageAt(Scanner::Location source_location,
                        const char* message,
@@ -561,7 +568,7 @@
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
-  Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
+  Expression* ParseUnaryExpression(bool* ok);

  private:
   Parser* parser_;
@@ -704,7 +711,6 @@
   // Support for hamony block scoped bindings.
   Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);

-  Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
   Expression* ParseUnaryExpression(bool* ok);
   Expression* ParsePostfixExpression(bool* ok);
   Expression* ParseLeftHandSideExpression(bool* ok);
=======================================
--- /branches/bleeding_edge/src/preparser.cc    Mon Mar 17 13:36:39 2014 UTC
+++ /branches/bleeding_edge/src/preparser.cc    Mon Mar 17 13:54:42 2014 UTC
@@ -146,10 +146,8 @@
 }


-PreParserExpression PreParserTraits::ParseBinaryExpression(int prec,
-                                                           bool accept_IN,
-                                                           bool* ok) {
-  return pre_parser_->ParseBinaryExpression(prec, accept_IN, ok);
+PreParserExpression PreParserTraits::ParseUnaryExpression(bool* ok) {
+  return pre_parser_->ParseUnaryExpression(ok);
 }


@@ -842,23 +840,6 @@
   ((void)0
 #define DUMMY )  // to make indentation work
 #undef DUMMY
-
-
-// Precedence >= 4
-PreParser::Expression PreParser::ParseBinaryExpression(int prec,
-                                                       bool accept_IN,
-                                                       bool* ok) {
-  Expression result = ParseUnaryExpression(CHECK_OK);
-  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
-    // prec1 >= 4
-    while (Precedence(peek(), accept_IN) == prec1) {
-      Next();
-      ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
-      result = Expression::Default();
-    }
-  }
-  return result;
-}


 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
=======================================
--- /branches/bleeding_edge/src/preparser.h     Mon Mar 17 13:36:39 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h     Mon Mar 17 13:54:42 2014 UTC
@@ -390,6 +390,9 @@
   typename Traits::Type::Expression ParseYieldExpression(bool* ok);
typename Traits::Type::Expression ParseConditionalExpression(bool accept_IN,
                                                                bool* ok);
+  typename Traits::Type::Expression ParseBinaryExpression(int prec,
+                                                          bool accept_IN,
+                                                          bool* ok);

   // Used to detect duplicates in object literals. Each of the values
   // kGetterProperty, kSetterProperty and kValueProperty represents
@@ -663,11 +666,21 @@
                                        int pos) {
     return PreParserExpression::Default();
   }
+  PreParserExpression NewUnaryOperation(Token::Value op,
+                                        PreParserExpression expression,
+                                        int pos) {
+    return PreParserExpression::Default();
+  }
   PreParserExpression NewBinaryOperation(Token::Value op,
                                          PreParserExpression left,
PreParserExpression right, int pos) {
     return PreParserExpression::Default();
   }
+  PreParserExpression NewCompareOperation(Token::Value op,
+                                          PreParserExpression left,
+ PreParserExpression right, int pos) {
+    return PreParserExpression::Default();
+  }
   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
                                       int literal_index,
                                       int pos) {
@@ -818,6 +831,13 @@
   // in strict mode.
   void CheckStrictModeLValue(PreParserExpression expression, bool* ok);

+  bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
+                                              PreParserExpression y,
+                                              Token::Value op,
+                                              int pos,
+                                              PreParserFactory* factory) {
+    return false;
+  }

   // Reporting errors.
   void ReportMessageAt(Scanner::Location location,
@@ -900,7 +920,7 @@
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
- PreParserExpression ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
+  PreParserExpression ParseUnaryExpression(bool* ok);

  private:
   PreParser* pre_parser_;
@@ -1066,7 +1086,6 @@
   Statement ParseTryStatement(bool* ok);
   Statement ParseDebuggerStatement(bool* ok);
   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
-  Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
   Expression ParseUnaryExpression(bool* ok);
   Expression ParsePostfixExpression(bool* ok);
   Expression ParseLeftHandSideExpression(bool* ok);
@@ -1727,6 +1746,52 @@
       ParseAssignmentExpression(accept_IN, CHECK_OK);
   return factory()->NewConditional(expression, left, right, pos);
 }
+
+
+// Precedence >= 4
+template <class Traits>
+typename Traits::Type::Expression
+ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
+  ASSERT(prec >= 4);
+ typename Traits::Type::Expression x = this->ParseUnaryExpression(CHECK_OK);
+  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
+    // prec1 >= 4
+    while (Precedence(peek(), accept_IN) == prec1) {
+      Token::Value op = Next();
+      int pos = position();
+      typename Traits::Type::Expression y =
+          ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
+
+      if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
+                                                       factory())) {
+        continue;
+      }
+
+      // For now we distinguish between comparisons and other binary
+      // operations.  (We could combine the two and get rid of this
+      // code and AST node eventually.)
+      if (Token::IsCompareOp(op)) {
+        // We have a comparison.
+        Token::Value cmp = op;
+        switch (op) {
+          case Token::NE: cmp = Token::EQ; break;
+          case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
+          default: break;
+        }
+        x = factory()->NewCompareOperation(cmp, x, y, pos);
+        if (cmp != op) {
+          // The comparison was negated - add a NOT.
+          x = factory()->NewUnaryOperation(Token::NOT, x, pos);
+        }
+
+      } else {
+        // We have a "normal" binary operation.
+        x = factory()->NewBinaryOperation(op, x, y, pos);
+      }
+    }
+  }
+  return x;
+}


 #undef CHECK_OK

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to