mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
Utility to collect symbols bound by a pattern
This commit is contained in:
parent
fe9be63787
commit
393250db92
1 changed files with 56 additions and 0 deletions
|
@ -9491,6 +9491,62 @@ impl<'a> Pattern<'a> {
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: vast majority of the time, the patterns will be singleton or empty.
|
||||||
|
// We should introduce a smallvec optimized for the singleton case.
|
||||||
|
pub fn collect_symbols(&self, layout: InLayout<'a>) -> std::vec::Vec<(Symbol, InLayout<'a>)> {
|
||||||
|
let mut stack = vec![(self, layout)];
|
||||||
|
let mut collected = std::vec::Vec::with_capacity(1);
|
||||||
|
|
||||||
|
while let Some((pattern, layout)) = stack.pop() {
|
||||||
|
match pattern {
|
||||||
|
Pattern::Identifier(symbol) => {
|
||||||
|
collected.push((*symbol, layout));
|
||||||
|
}
|
||||||
|
Pattern::Underscore => {}
|
||||||
|
Pattern::As(subpattern, symbol) => {
|
||||||
|
collected.push((*symbol, layout));
|
||||||
|
stack.push((subpattern, layout));
|
||||||
|
}
|
||||||
|
Pattern::IntLiteral(_, _)
|
||||||
|
| Pattern::FloatLiteral(_, _)
|
||||||
|
| Pattern::DecimalLiteral(_)
|
||||||
|
| Pattern::BitLiteral { .. }
|
||||||
|
| Pattern::EnumLiteral { .. }
|
||||||
|
| Pattern::StrLiteral(_) => {}
|
||||||
|
Pattern::RecordDestructure(destructs, _) => {
|
||||||
|
for destruct in destructs {
|
||||||
|
match &destruct.typ {
|
||||||
|
DestructType::Required(symbol) => {
|
||||||
|
collected.push((*symbol, destruct.layout));
|
||||||
|
}
|
||||||
|
DestructType::Guard(pattern) => {
|
||||||
|
stack.push((pattern, destruct.layout));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Pattern::TupleDestructure(destructs, _) => {
|
||||||
|
for destruct in destructs {
|
||||||
|
stack.push((&destruct.pat, destruct.layout));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Pattern::NewtypeDestructure { arguments, .. } => {
|
||||||
|
stack.extend(arguments.iter().map(|(t, l)| (t, *l)))
|
||||||
|
}
|
||||||
|
Pattern::Voided { .. } => {}
|
||||||
|
Pattern::AppliedTag { arguments, .. } => {
|
||||||
|
stack.extend(arguments.iter().map(|(t, l)| (t, *l)))
|
||||||
|
}
|
||||||
|
Pattern::OpaqueUnwrap { argument, .. } => stack.push((&argument.0, argument.1)),
|
||||||
|
Pattern::List { elements, .. } => {
|
||||||
|
stack.extend(elements.iter().map(|t| (t, layout)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collected
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue