1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use binder::Binder;
use bound::{BoundPattern, ScopeState};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Nest<P> {
pub unsafe_patterns: Vec<P>,
}
impl<P> Nest<P> {
pub fn new<N>(patterns: Vec<P>) -> Nest<P>
where
N: Clone,
P: BoundPattern<N>,
{
let mut rebound_patterns = Vec::<P>::with_capacity(patterns.len());
for mut pattern in patterns {
let mut state = ScopeState::new();
for rebound_pattern in &rebound_patterns {
state = state.incr();
pattern.close_pattern(state, &rebound_pattern.binders());
}
rebound_patterns.push(pattern);
}
Nest {
unsafe_patterns: rebound_patterns,
}
}
pub fn unnest<N>(self) -> Vec<P>
where
N: Clone,
P: BoundPattern<N>,
{
let mut unrebound_patterns = Vec::<P>::with_capacity(self.unsafe_patterns.len());
for mut pattern in self.unsafe_patterns {
let mut state = ScopeState::new();
for bound_pattern in &unrebound_patterns {
state = state.incr();
pattern.open_pattern(state, &bound_pattern.binders());
}
unrebound_patterns.push(pattern);
}
unrebound_patterns
}
}
impl<N, P> BoundPattern<N> for Nest<P>
where
N: Clone,
P: BoundPattern<N>,
{
fn pattern_eq(&self, other: &Nest<P>) -> bool {
<[P]>::pattern_eq(&self.unsafe_patterns, &other.unsafe_patterns)
}
fn close_pattern(&mut self, mut state: ScopeState, binders: &[Binder<N>]) {
for elem in &mut self.unsafe_patterns {
elem.close_pattern(state, binders);
state = state.incr();
}
}
fn open_pattern(&mut self, mut state: ScopeState, binders: &[Binder<N>]) {
for elem in &mut self.unsafe_patterns {
elem.close_pattern(state, binders);
state = state.incr();
}
}
fn visit_binders(&self, on_binder: &mut impl FnMut(&Binder<N>)) {
<[P]>::visit_binders(&self.unsafe_patterns, on_binder);
}
fn visit_mut_binders(&mut self, on_binder: &mut impl FnMut(&mut Binder<N>)) {
<[P]>::visit_mut_binders(&mut self.unsafe_patterns, on_binder);
}
}