Author: [EMAIL PROTECTED]
Date: Tue Nov 11 00:50:37 2008
New Revision: 729

Modified:
    branches/experimental/regexp2000/src/globals.h
    branches/experimental/regexp2000/src/jsregexp-inl.h
    branches/experimental/regexp2000/src/jsregexp.cc
    branches/experimental/regexp2000/src/jsregexp.h
    branches/experimental/regexp2000/src/string-stream.cc
    branches/experimental/regexp2000/test/cctest/test-regexp.cc

Log:
Added rudimentary analysis phase.  Still lots of work to do but now at
least some basics are there.


Modified: branches/experimental/regexp2000/src/globals.h
==============================================================================
--- branches/experimental/regexp2000/src/globals.h      (original)
+++ branches/experimental/regexp2000/src/globals.h      Tue Nov 11 00:50:37 2008
@@ -178,6 +178,7 @@
  class MapSpace;
  class MarkCompactCollector;
  class NewSpace;
+class NodeVisitor;
  class Object;
  class OldSpace;
  class Property;

Modified: branches/experimental/regexp2000/src/jsregexp-inl.h
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp-inl.h (original)
+++ branches/experimental/regexp2000/src/jsregexp-inl.h Tue Nov 11 00:50:37  
2008
@@ -244,6 +244,15 @@
  }


+template <typename Node, class Callback>
+static void DoForEach(Node* node, Callback callback) {
+  if (node == NULL) return;
+  DoForEach<Node, Callback>(node->left(), callback);
+  callback.Call(node->key(), node->value());
+  DoForEach<Node, Callback>(node->right(), callback);
+}
+
+
  OutSet::OutSet(unsigned value)
    : first_(0),
      remaining_(NULL) {

Modified: branches/experimental/regexp2000/src/jsregexp.cc
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp.cc    (original)
+++ branches/experimental/regexp2000/src/jsregexp.cc    Tue Nov 11 00:50:37  
2008
@@ -51,6 +51,7 @@
  #include "third_party/jscre/pcre.h"
  #endif

+
  namespace v8 { namespace internal {


@@ -634,19 +635,6 @@
  class ExecutionState;


-class DotPrinter {
- public:
-  DotPrinter() : stream_(&alloc_) { }
-  void PrintNode(const char* label, RegExpNode* node);
-  void Visit(RegExpNode* node);
-  StringStream* stream() { return &stream_; }
- private:
-  HeapStringAllocator alloc_;
-  StringStream stream_;
-  std::set<RegExpNode*> seen_;
-};
-
-
  class RegExpCompiler {
   public:
    explicit RegExpCompiler(int capture_count)
@@ -654,9 +642,7 @@

    RegExpNode* Compile(RegExpTree* tree,
                        RegExpNode* on_success,
-                      RegExpNode* on_failure) {
-    return tree->ToNode(this, on_success, on_failure);
-  }
+                      RegExpNode* on_failure);

    int AllocateRegister() { return next_register_++; }

@@ -665,10 +651,19 @@
  };


+#define FOR_EACH_NODE_TYPE(VISIT)                                    \
+  VISIT(End)                                                         \
+  VISIT(Atom)                                                        \
+  VISIT(Action)                                                      \
+  VISIT(Choice)                                                      \
+  VISIT(Backreference)                                               \
+  VISIT(CharacterClass)
+
+
  class RegExpNode: public ZoneObject {
   public:
    virtual ~RegExpNode() { }
-  virtual void EmitDot(DotPrinter* out);
+  virtual void Accept(NodeVisitor* visitor) = 0;
  };


@@ -685,7 +680,7 @@
  class EndNode: public RegExpNode {
   public:
    enum Action { ACCEPT, BACKTRACK };
-  virtual void EmitDot(DotPrinter* out);
+  virtual void Accept(NodeVisitor* visitor);
    static EndNode* GetAccept() { return &kAccept; }
    static EndNode* GetBacktrack() { return &kBacktrack; }
   private:
@@ -708,7 +703,7 @@
      : SeqRegExpNode(on_success),
        on_failure_(on_failure),
        data_(data) { }
-  virtual void EmitDot(DotPrinter* out);
+  virtual void Accept(NodeVisitor* visitor);
    Vector<const uc16> data() { return data_; }
    RegExpNode* on_failure() { return on_failure_; }
   private:
@@ -727,7 +722,7 @@
        on_failure_(on_failure),
        start_reg_(start_reg),
        end_reg_(end_reg) { }
-  virtual void EmitDot(DotPrinter* out);
+  virtual void Accept(NodeVisitor* visitor);
    RegExpNode* on_failure() { return on_failure_; }
    int start_register() { return start_reg_; }
    int end_register() { return end_reg_; }
@@ -746,7 +741,7 @@
      : SeqRegExpNode(on_success),
        on_failure_(on_failure),
        ranges_(ranges) { }
-  virtual void EmitDot(DotPrinter* out);
+  virtual void Accept(NodeVisitor* visitor);
    ZoneList<CharacterRange>* ranges() { return ranges_; }
    RegExpNode* on_failure() { return on_failure_; }
   private:
@@ -795,16 +790,20 @@
   public:
    explicit ChoiceNode(int expected_size, RegExpNode* on_failure)
      : on_failure_(on_failure),
-      choices_(new ZoneList<GuardedAlternative>(expected_size)) { }
-  virtual void EmitDot(DotPrinter* out);
+      choices_(new ZoneList<GuardedAlternative>(expected_size)),
+      visited_(false) { }
+  virtual void Accept(NodeVisitor* visitor);
    void AddChild(GuardedAlternative node) { choices()->Add(node); }
    ZoneList<GuardedAlternative>* choices() { return choices_; }
    DispatchTable* table() { return &table_; }
    RegExpNode* on_failure() { return on_failure_; }
+  bool visited() { return visited_; }
+  void set_visited(bool value) { visited_ = value; }
   private:
    RegExpNode* on_failure_;
    ZoneList<GuardedAlternative>* choices_;
    DispatchTable table_;
+  bool visited_;
  };


@@ -819,61 +818,120 @@
      ESCAPE_SUBMATCH,
      END_SUBMATCH
    };
-  static ActionNode* StoreRegister(int reg, int val, RegExpNode*  
on_success) {
-    ActionNode* result = new ActionNode(STORE_REGISTER, on_success);
-    result->data_.u_store_register.reg_ = reg;
-    result->data_.u_store_register.value_ = val;
-    return result;
-  }
-  static ActionNode* IncrementRegister(int reg, RegExpNode* on_success) {
-    ActionNode* result = new ActionNode(INCREMENT_REGISTER, on_success);
-    result->data_.u_increment_register.reg_ = reg;
-    return result;
-  }
-  static ActionNode* StorePosition(int reg, RegExpNode* on_success) {
-    ActionNode* result = new ActionNode(STORE_POSITION, on_success);
-    result->data_.u_position_register.reg_ = reg;
-    return result;
-  }
-  static ActionNode* RestorePosition(int reg, RegExpNode* on_success) {
-    ActionNode* result = new ActionNode(RESTORE_POSITION, on_success);
-    result->data_.u_position_register.reg_ = reg;
-    return result;
-  }
-  static ActionNode* BeginSubmatch(RegExpNode* on_success) {
-    return new ActionNode(BEGIN_SUBMATCH, on_success);
-  }
-  static ActionNode* EscapeSubmatch(RegExpNode* on_success) {
-    return new ActionNode(ESCAPE_SUBMATCH, on_success);
-  }
-  static ActionNode* EndSubmatch(RegExpNode* on_success) {
-    return new ActionNode(END_SUBMATCH, on_success);
-  }
-  virtual void EmitDot(DotPrinter* out);
-  Type type() { return type_; }
- private:
-  ActionNode(Type type, RegExpNode* on_success)
-    : SeqRegExpNode(on_success),
-      type_(type) { }
-  Type type_;
+  static ActionNode* StoreRegister(int reg, int val, RegExpNode*  
on_success);
+  static ActionNode* IncrementRegister(int reg, RegExpNode* on_success);
+  static ActionNode* StorePosition(int reg, RegExpNode* on_success);
+  static ActionNode* RestorePosition(int reg, RegExpNode* on_success);
+  static ActionNode* BeginSubmatch(RegExpNode* on_success);
+  static ActionNode* EscapeSubmatch(RegExpNode* on_success);
+  static ActionNode* EndSubmatch(RegExpNode* on_success);
+  virtual void Accept(NodeVisitor* visitor);
+  Type type;
    union {
      struct {
-      int reg_;
-      int value_;
+      int reg;
+      int value;
      } u_store_register;
      struct {
-      int reg_;
+      int reg;
      } u_increment_register;
      struct {
-      int reg_;
+      int reg;
      } u_position_register;
-  } data_;
+  } data;
+ private:
+  ActionNode(Type _type, RegExpNode* on_success)
+    : SeqRegExpNode(on_success),
+      type(_type) { }
  };


+ActionNode* ActionNode::StoreRegister(int reg,
+                                      int val,
+                                      RegExpNode* on_success) {
+  ActionNode* result = new ActionNode(STORE_REGISTER, on_success);
+  result->data.u_store_register.reg = reg;
+  result->data.u_store_register.value = val;
+  return result;
+}
+
+
+ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success)  
{
+  ActionNode* result = new ActionNode(INCREMENT_REGISTER, on_success);
+  result->data.u_increment_register.reg = reg;
+  return result;
+}
+
+
+ActionNode* ActionNode::StorePosition(int reg, RegExpNode* on_success) {
+  ActionNode* result = new ActionNode(STORE_POSITION, on_success);
+  result->data.u_position_register.reg = reg;
+  return result;
+}
+
+
+ActionNode* ActionNode::RestorePosition(int reg, RegExpNode* on_success) {
+  ActionNode* result = new ActionNode(RESTORE_POSITION, on_success);
+  result->data.u_position_register.reg = reg;
+  return result;
+}
+
+
+ActionNode* ActionNode::BeginSubmatch(RegExpNode* on_success) {
+  return new ActionNode(BEGIN_SUBMATCH, on_success);
+}
+
+
+ActionNode* ActionNode::EscapeSubmatch(RegExpNode* on_success) {
+  return new ActionNode(ESCAPE_SUBMATCH, on_success);
+}
+
+
+ActionNode* ActionNode::EndSubmatch(RegExpNode* on_success) {
+  return new ActionNode(END_SUBMATCH, on_success);
+}
+
+
+class NodeVisitor {
+ public:
+  virtual ~NodeVisitor() { }
+#define DECLARE_VISIT(Type)                                          \
+  virtual void Visit##Type(Type##Node* that) = 0;
+FOR_EACH_NODE_TYPE(DECLARE_VISIT)
+#undef DECLARE_VISIT
+};
+
+
+#define DEFINE_ACCEPT(Type)                                          \
+  void Type##Node::Accept(NodeVisitor* visitor) {                    \
+    visitor->Visit##Type(this);                                      \
+  }
+FOR_EACH_NODE_TYPE(DEFINE_ACCEPT)
+#undef DEFINE_ACCEPT
+
+
  // -------------------------------------------------------------------
  // Dot/dotty output

+
+class DotPrinter: public NodeVisitor {
+ public:
+  DotPrinter() : stream_(&alloc_) { }
+  void PrintNode(const char* label, RegExpNode* node);
+  void Visit(RegExpNode* node);
+  void PrintOnFailure(RegExpNode* from, RegExpNode* on_failure);
+  StringStream* stream() { return &stream_; }
+#define DECLARE_VISIT(Type)                                          \
+  virtual void Visit##Type(Type##Node* that);
+FOR_EACH_NODE_TYPE(DECLARE_VISIT)
+#undef DECLARE_VISIT
+ private:
+  HeapStringAllocator alloc_;
+  StringStream stream_;
+  std::set<RegExpNode*> seen_;
+};
+
+
  void DotPrinter::PrintNode(const char* label, RegExpNode* node) {
    stream()->Add("digraph G {\n  graph [label=\"");
    for (int i = 0; label[i]; i++) {
@@ -900,125 +958,126 @@
    if (seen_.find(node) != seen_.end())
      return;
    seen_.insert(node);
-  node->EmitDot(this);
+  node->Accept(this);
  }


-void RegExpNode::EmitDot(DotPrinter* out) {
-  UNIMPLEMENTED();
-}
+#ifdef DEBUG


-static void PrintOnFailure(DotPrinter* out,
-                           RegExpNode* from,
-                           RegExpNode* on_failure) {
+void DotPrinter::PrintOnFailure(RegExpNode* from, RegExpNode* on_failure) {
    if (on_failure == EndNode::GetBacktrack()) return;
-  out->stream()->Add("  n%p -> n%p [style=dotted];\n", from, on_failure);
-  out->Visit(on_failure);
+  stream()->Add("  n%p -> n%p [style=dotted];\n", from, on_failure);
+  Visit(on_failure);
  }


-void ChoiceNode::EmitDot(DotPrinter* out) {
-  out->stream()->Add("  n%p [label=\"?\", shape=circle];\n", this);
-  PrintOnFailure(out, this, this->on_failure());
-  for (int i = 0; i < choices()->length(); i++) {
-    GuardedAlternative alt = choices()->at(i);
-    out->stream()->Add("  n%p -> n%p [label=\"%i",
-                       this,
+void DotPrinter::VisitChoice(ChoiceNode* that) {
+  stream()->Add("  n%p [label=\"? (%p)\"];\n", that, that);
+  PrintOnFailure(that, that->on_failure());
+  for (int i = 0; i < that->choices()->length(); i++) {
+    GuardedAlternative alt = that->choices()->at(i);
+    stream()->Add("  n%p -> n%p [label=\"%i",
+                       that,
                         alt.node(),
                         i);
      if (alt.guards() != NULL) {
-      out->stream()->Add(" [");
+      stream()->Add(" [");
        for (int j = 0; j < alt.guards()->length(); j++) {
-        if (j > 0) out->stream()->Add(" ");
+        if (j > 0) stream()->Add(" ");
          Guard* guard = alt.guards()->at(j);
          switch (guard->op()) {
            case Guard::GEQ:
-            out->stream()->Add("$%i &#8805; %i", guard->reg(),  
guard->value());
+            stream()->Add("$%i &#8805; %i", guard->reg(), guard->value());
              break;
            case Guard::LT:
-            out->stream()->Add("$%i < %i", guard->reg(), guard->value());
+            stream()->Add("$%i < %i", guard->reg(), guard->value());
              break;
          }
        }
-      out->stream()->Add("]");
+      stream()->Add("]");
      }
-    out->stream()->Add("\"];\n");
-    out->Visit(choices()->at(i).node());
+    stream()->Add("\"];\n");
+    that->choices()->at(i).node()->Accept(this);
    }
+  OS::PrintError("--- %p ---\n", static_cast<void*>(this));
+  that->table()->Dump();
  }


-void AtomNode::EmitDot(DotPrinter* out) {
-  out->stream()->Add("  n%p [label=\"'%w'\", shape=doubleoctagon];\n",
-                     this,
-                     data());
-  out->stream()->Add("  n%p -> n%p;\n", this, this->on_success());
-  out->Visit(this->on_success());
-  PrintOnFailure(out, this, this->on_failure());
+void DotPrinter::VisitAtom(AtomNode* that) {
+  stream()->Add("  n%p [label=\"'%w'\", shape=doubleoctagon];\n",
+                that,
+                that->data());
+  stream()->Add("  n%p -> n%p;\n", that, that->on_success());
+  Visit(that->on_success());
+  PrintOnFailure(that, that->on_failure());
  }


-void BackreferenceNode::EmitDot(DotPrinter* out) {
-  out->stream()->Add("  n%p [label=\"$%i..$%i\", shape=doubleoctagon];\n",
-                     this,
-                     start_register(),
-                     end_register());
-  out->stream()->Add("  n%p -> n%p;\n", this, this->on_success());
-  out->Visit(this->on_success());
-  PrintOnFailure(out, this, this->on_failure());
+void DotPrinter::VisitBackreference(BackreferenceNode* that) {
+  stream()->Add("  n%p [label=\"$%i..$%i\", shape=doubleoctagon];\n",
+                that,
+                that->start_register(),
+                that->end_register());
+  stream()->Add("  n%p -> n%p;\n", that, that->on_success());
+  Visit(that->on_success());
+  PrintOnFailure(that, that->on_failure());
  }


-void EndNode::EmitDot(DotPrinter* out) {
-  out->stream()->Add("  n%p [style=bold, shape=point];\n", this);
+void DotPrinter::VisitEnd(EndNode* that) {
+  stream()->Add("  n%p [style=bold, shape=point];\n", that);
  }


-void CharacterClassNode::EmitDot(DotPrinter* out) {
-  out->stream()->Add("  n%p [label=\"[...]\"];\n", this);
-  out->stream()->Add("  n%p -> n%p;\n", this, this->on_success());
-  out->Visit(this->on_success());
-  PrintOnFailure(out, this, this->on_failure());
+void DotPrinter::VisitCharacterClass(CharacterClassNode* that) {
+  stream()->Add("  n%p [label=\"[...]\"];\n", that);
+  stream()->Add("  n%p -> n%p;\n", that, that->on_success());
+  Visit(that->on_success());
+  PrintOnFailure(that, that->on_failure());
  }


-void ActionNode::EmitDot(DotPrinter* out) {
-  out->stream()->Add("  n%p [", this);
-  switch (type()) {
-    case STORE_REGISTER:
-      out->stream()->Add("label=\"$%i:=%i\", shape=box",
-                         data_.u_store_register.reg_,
-                         data_.u_store_register.value_);
+void DotPrinter::VisitAction(ActionNode* that) {
+  stream()->Add("  n%p [", that);
+  switch (that->type) {
+    case ActionNode::STORE_REGISTER:
+      stream()->Add("label=\"$%i:=%i\", shape=box",
+                    that->data.u_store_register.reg,
+                    that->data.u_store_register.value);
        break;
-    case INCREMENT_REGISTER:
-      out->stream()->Add("label=\"$%i++\", shape=box",
-                         data_.u_increment_register.reg_);
+    case ActionNode::INCREMENT_REGISTER:
+      stream()->Add("label=\"$%i++\", shape=box",
+                    that->data.u_increment_register.reg);
        break;
-    case STORE_POSITION:
-      out->stream()->Add("label=\"$%i:=$pos\", shape=box",
-                         data_.u_position_register.reg_);
+    case ActionNode::STORE_POSITION:
+      stream()->Add("label=\"$%i:=$pos\", shape=box",
+                    that->data.u_position_register.reg);
        break;
-    case RESTORE_POSITION:
-      out->stream()->Add("label=\"$pos:=$%i\", shape=box",
-                         data_.u_position_register.reg_);
+    case ActionNode::RESTORE_POSITION:
+      stream()->Add("label=\"$pos:=$%i\", shape=box",
+                    that->data.u_position_register.reg);
        break;
-    case BEGIN_SUBMATCH:
-      out->stream()->Add("label=\"begin\", shape=septagon");
+    case ActionNode::BEGIN_SUBMATCH:
+      stream()->Add("label=\"begin\", shape=septagon");
        break;
-    case ESCAPE_SUBMATCH:
-      out->stream()->Add("label=\"escape\", shape=septagon");
+    case ActionNode::ESCAPE_SUBMATCH:
+      stream()->Add("label=\"escape\", shape=septagon");
        break;
-    case END_SUBMATCH:
-      out->stream()->Add("label=\"end\", shape=septagon");
+    case ActionNode::END_SUBMATCH:
+      stream()->Add("label=\"end\", shape=septagon");
        break;
    }
-  out->stream()->Add("];\n");
-  out->stream()->Add("  n%p -> n%p;\n", this, this->on_success());
-  out->Visit(this->on_success());
+  stream()->Add("];\n");
+  stream()->Add("  n%p -> n%p;\n", that, that->on_success());
+  Visit(that->on_success());
  }


+#endif // DEBUG
+
+
  // -------------------------------------------------------------------
  // Tree to graph conversion

@@ -1392,6 +1451,45 @@
  }


+#ifdef DEBUG
+
+
+class DispatchTableDumper {
+ public:
+  DispatchTableDumper(StringStream* stream) : stream_(stream) { }
+  void Call(uc16 key, DispatchTable::Entry entry);
+  StringStream* stream() { return stream_; }
+ private:
+  StringStream* stream_;
+};
+
+
+void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) {
+  stream()->Add("[%k-%k]: {", key, entry.to());
+  OutSet set = entry.out_set();
+  bool first = true;
+  for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
+    if (set.Get(i)) {
+      if (first) first = false;
+      else stream()->Add(", ");
+      stream()->Add("%i", i);
+    }
+  }
+  stream()->Add("}\n");
+}
+
+
+void DispatchTable::Dump() {
+  HeapStringAllocator alloc;
+  StringStream stream(&alloc);
+  tree()->ForEach(DispatchTableDumper(&stream));
+  OS::PrintError("%s", *stream.ToCString());
+}
+
+
+#endif
+
+
  OutSet DispatchTable::Get(uc16 value) {
    ZoneSplayTree<Config>::Locator loc;
    if (!tree()->FindGreatestLessThan(value, &loc))
@@ -1401,6 +1499,109 @@
      return entry->out_set();
    else
      return OutSet::empty();
+}
+
+
+// -------------------------------------------------------------------
+// Analysis
+
+
+class Analysis: public NodeVisitor {
+ public:
+  Analysis(RegExpCompiler* compiler)
+    : compiler_(compiler),
+      table_(NULL),
+      choice_index_(-1) { }
+  DispatchTable* table() { return table_; }
+  RegExpCompiler* compiler() { return compiler_; }
+  int choice_index() { return choice_index_; }
+  void Analyze(RegExpNode* node) { node->Accept(this); }
+#define DECLARE_VISIT(Type)                                          \
+  virtual void Visit##Type(Type##Node* that);
+FOR_EACH_NODE_TYPE(DECLARE_VISIT)
+#undef DECLARE_VISIT
+ protected:
+  Analysis(Analysis* prev) { *this = *prev; }
+  RegExpCompiler* compiler_;
+  DispatchTable *table_;
+  int choice_index_;
+};
+
+
+// A subclass of analysis data that allows fields to be set.  Anyone
+// who needs to create new analysis data creates an instance of this
+// class, configures it, and then passes it on as an AnalysisData
+// which doesn't allow its fields to be changed.
+class AnalysisBuilder: public Analysis {
+ public:
+  AnalysisBuilder(Analysis* prev) : Analysis(prev) { }
+  void set_table(DispatchTable* value) { table_ = value; }
+  void set_choice_index(int value) { choice_index_ = value; }
+};
+
+
+void Analysis::VisitEnd(EndNode* that) {
+  // nothing to do
+}
+
+
+void Analysis::VisitChoice(ChoiceNode* node) {
+  if (node->visited()) return;
+  node->set_visited(true);
+  ZoneList<GuardedAlternative>* choices = node->choices();
+  AnalysisBuilder data(this);
+  data.set_table(node->table());
+  for (int i = 0; i < choices->length(); i++) {
+    data.set_choice_index(i);
+    data.Analyze(choices->at(i).node());
+  }
+  node->set_visited(false);
+}
+
+
+void Analysis::VisitBackreference(BackreferenceNode* that) {
+  UNIMPLEMENTED();
+}
+
+
+void Analysis::VisitCharacterClass(CharacterClassNode* that) {
+  if (table() != NULL) {
+    int index = choice_index();
+    ZoneList<CharacterRange>* ranges = that->ranges();
+    for (int i = 0; i < ranges->length(); i++) {
+      CharacterRange range = ranges->at(i);
+      table()->AddRange(range, index);
+    }
+  }
+  AnalysisBuilder outgoing(this);
+  outgoing.set_table(NULL);
+  outgoing.Analyze(that->on_success());
+}
+
+
+void Analysis::VisitAtom(AtomNode* that) {
+  if (table() != NULL) {
+    uc16 c = that->data()[0];
+    table()->AddRange(CharacterRange(c, c), choice_index());
+  }
+  AnalysisBuilder outgoing(this);
+  outgoing.set_table(NULL);
+  outgoing.Analyze(that->on_success());
+}
+
+
+void Analysis::VisitAction(ActionNode* that) {
+  Analyze(that->on_success());
+}
+
+
+RegExpNode* RegExpCompiler::Compile(RegExpTree* tree,
+                                    RegExpNode* on_success,
+                                    RegExpNode* on_failure) {
+  RegExpNode* node = tree->ToNode(this, on_success, on_failure);
+  Analysis analysis(this);
+  analysis.Analyze(node);
+  return node;
  }



Modified: branches/experimental/regexp2000/src/jsregexp.h
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp.h     (original)
+++ branches/experimental/regexp2000/src/jsregexp.h     Tue Nov 11 00:50:37 2008
@@ -164,6 +164,10 @@
  };


+template <typename Node, class Callback>
+static void DoForEach(Node* node, Callback callback);
+
+
  // A zone splay tree.  The config type parameter encapsulates the
  // different configurations of a concrete splay tree:
  //
@@ -225,6 +229,10 @@
          value_(value),
          left_(NULL),
          right_(NULL) { }
+     Key key() { return key_; }
+     Value value() { return value_; }
+     Node* left() { return left_; }
+     Node* right() { return right_; }
     private:
      friend class ZoneSplayTree;
      friend class Locator;
@@ -238,6 +246,7 @@
    // exposing the node.
    class Locator {
     public:
+    Locator(Node* node) : node_(node) { }
      Locator() : node_(NULL) { }
      const Key& key() { return node_->key_; }
      Value& value() { return node_->value_; }
@@ -247,6 +256,11 @@
      Node* node_;
    };

+  template <class Callback>
+  void ForEach(Callback c) {
+    DoForEach<typename ZoneSplayTree<Config>::Node, Callback>(root_, c);
+  }
+
   private:
    Node* root_;
  };
@@ -262,10 +276,10 @@
    void Set(unsigned value);
    bool Get(unsigned value);
    OutSet Clone();
+  static const unsigned kFirstLimit = 32;
   private:
    OutSet(uint32_t first, ZoneList<unsigned>* remaining)
      : first_(first), remaining_(remaining) { }
-  static const unsigned kFirstLimit = 32;
    uint32_t first_;
    ZoneList<unsigned>* remaining_;
  };
@@ -309,6 +323,7 @@
    };
    void AddRange(CharacterRange range, int value);
    OutSet Get(uc16 value);
+  void Dump();
   private:
    ZoneSplayTree<Config>* tree() { return &tree_; }
    ZoneSplayTree<Config> tree_;

Modified: branches/experimental/regexp2000/src/string-stream.cc
==============================================================================
--- branches/experimental/regexp2000/src/string-stream.cc       (original)
+++ branches/experimental/regexp2000/src/string-stream.cc       Tue Nov 11  
00:50:37 2008
@@ -140,7 +140,17 @@
        PrintObject(obj);
        break;
      }
-    case 'i': case 'd': case 'u': case 'x': case 'c': case 'p': {
+    case 'k': {
+      ASSERT_EQ(FmtElm::INT, current.type_);
+      int value = current.data_.u_int_;
+      if (0x20 <= value && value <= 0xFF) {
+        Put(value);
+      } else {
+        Add("\\x%X", value);
+      }
+      break;
+    }
+    case 'i': case 'd': case 'u': case 'x': case 'c': case 'p': case 'X': {
        int value = current.data_.u_int_;
        EmbeddedVector<char, 24> formatted;
        int length = OS::SNPrintF(formatted, temp.start(), value);

Modified: branches/experimental/regexp2000/test/cctest/test-regexp.cc
==============================================================================
--- branches/experimental/regexp2000/test/cctest/test-regexp.cc (original)
+++ branches/experimental/regexp2000/test/cctest/test-regexp.cc Tue Nov 11  
00:50:37 2008
@@ -604,3 +604,8 @@
        Factory::NewStringFromAscii(CStrVector("walking\nbarefoot"));
    CHECK(!Re2kInterpreter::Match(*array, *f5, captures, 0));
  }
+
+
+TEST(Graph) {
+  Execute("(a|b|c|\\w|\\s)", "", true);
+}

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to