]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add binding context class
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Sun, 6 Apr 2025 15:09:42 +0000 (17:09 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 28 Apr 2025 14:18:56 +0000 (16:18 +0200)
We need to differentiate bindings types, so the same binding cannot be
reused multiple time in a product binding.

gcc/rust/ChangeLog:

* resolve/rust-name-resolution-context.h (struct Binding): Add Binding
struct to differentiate Or and Product bindings in patterns.
(enum class): Add Binding kind.
(class BindingContext): Add binding context with Binding stack.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/resolve/rust-name-resolution-context.h

index 51c08efe3df65bd04e9f45e060fe0ccb10fcea17..d0736bcd1baa20c2bc8580b5316f4bf7182ca7d4 100644 (file)
@@ -156,6 +156,87 @@ public:
   NodeId id;
 };
 
+struct Binding
+{
+  enum class Kind
+  {
+    Product,
+    Or,
+  } kind;
+
+  std::unordered_set<Identifier> set;
+
+  Binding (Binding::Kind kind) : kind (kind) {}
+};
+
+enum class BindingSource
+{
+  Match,
+  Let,
+  For,
+  Param
+};
+
+class BindingContext
+{
+  // FIXME: Use std::vector<std::vector<Binding>> to handle nested patterns
+  std::vector<Binding> bindings;
+
+  BindingSource source;
+
+  bool bind_test (Identifier ident, Binding::Kind kind)
+  {
+    for (auto &bind : bindings)
+      {
+       if (bind.set.find (ident) != bind.set.cend () && bind.kind == kind)
+         {
+           return true;
+         }
+      }
+    return false;
+  }
+
+public:
+  bool and_binded (Identifier ident)
+  {
+    return bind_test (ident, Binding::Kind::Product);
+  }
+
+  bool or_binded (Identifier ident)
+  {
+    return bind_test (ident, Binding::Kind::Or);
+  }
+
+  void insert_ident (Identifier ident) { bindings.back ().set.insert (ident); }
+
+  void push (Binding::Kind kind) { bindings.push_back (Binding (kind)); }
+
+  void new_binding (BindingSource source)
+  {
+    rust_assert (bindings.size () == 0);
+    this->source = source;
+    push (Binding::Kind::Product);
+  }
+
+  void clear ()
+  {
+    rust_assert (bindings.size () == 1);
+    bindings.clear ();
+  }
+
+  void merge ()
+  {
+    auto last_binding = bindings.back ();
+    bindings.pop_back ();
+    for (auto &value : last_binding.set)
+      {
+       bindings.back ().set.insert (value);
+      }
+  }
+
+  BindingSource get_source () const { return source; }
+};
+
 // Now our resolver, which keeps track of all the `ForeverStack`s we could want
 class NameResolutionContext
 {