formality_core/fixed_point/
stack.rs1use super::Value;
2
3pub struct FixedPointStack<Input, Output> {
4 entries: Vec<StackEntry<Input, Output>>,
5}
6
7impl<Input, Output> Default for FixedPointStack<Input, Output> {
8 fn default() -> Self {
9 Self {
10 entries: Default::default(),
11 }
12 }
13}
14
15struct StackEntry<Input, Output> {
16 input: Input,
18
19 output: Output,
21
22 has_dependents: bool,
25}
26
27impl<Input, Output> FixedPointStack<Input, Output>
28where
29 Input: Value,
30 Output: Value,
31{
32 fn top_frame(&mut self, input: &Input) -> &mut StackEntry<Input, Output> {
34 let top = self.entries.last_mut().unwrap();
35 assert_eq!(top.input, *input);
36 top
37 }
38
39 pub fn search(&mut self, input: &Input) -> Option<Output> {
49 for entry in &mut self.entries {
50 if entry.input == *input {
51 entry.has_dependents = true;
52 return Some(entry.output.clone());
53 }
54 }
55
56 None
57 }
58
59 pub fn push(&mut self, input: &Input, output: Output) {
62 assert!(self.search(input).is_none());
63
64 self.entries.push(StackEntry {
65 input: input.clone(),
66 output,
67 has_dependents: false,
68 });
69 }
70
71 pub fn update_output(&mut self, input: &Input, output: Output) -> bool {
74 let top = self.top_frame(input);
75 if top.output == output {
76 return false;
77 }
78
79 top.output = output;
80 top.has_dependents
81 }
82
83 pub fn pop(&mut self, input: &Input) -> Output {
85 let top = self.entries.pop().unwrap();
86 assert_eq!(top.input, *input);
87 top.output
88 }
89}