aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2025-04-06 17:09:42 +0200
committerP-E-P <32375388+P-E-P@users.noreply.github.com>2025-04-24 16:53:44 +0000
commitca4175b0e5c86d864d973875f7bb793bdcd2c7dd (patch)
tree3a6497d97fe070347618e58ea4a07e048db1e0d8 /gcc
parent22c008cc523fcc12fe03a244a61d327e06df35bf (diff)
downloadgcc-ca4175b0e5c86d864d973875f7bb793bdcd2c7dd.zip
gcc-ca4175b0e5c86d864d973875f7bb793bdcd2c7dd.tar.gz
gcc-ca4175b0e5c86d864d973875f7bb793bdcd2c7dd.tar.bz2
Add binding context class
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>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index 3ba93bd..cb2df64 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -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
{