diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2025-04-06 17:09:42 +0200 |
---|---|---|
committer | P-E-P <32375388+P-E-P@users.noreply.github.com> | 2025-04-24 16:53:44 +0000 |
commit | ca4175b0e5c86d864d973875f7bb793bdcd2c7dd (patch) | |
tree | 3a6497d97fe070347618e58ea4a07e048db1e0d8 /gcc | |
parent | 22c008cc523fcc12fe03a244a61d327e06df35bf (diff) | |
download | gcc-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.h | 81 |
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 { |