pub_just/
variables.rs

1use super::*;
2
3pub struct Variables<'expression, 'src> {
4  stack: Vec<&'expression Expression<'src>>,
5}
6
7impl<'expression, 'src> Variables<'expression, 'src> {
8  pub fn new(root: &'expression Expression<'src>) -> Self {
9    Self { stack: vec![root] }
10  }
11}
12
13impl<'expression, 'src> Iterator for Variables<'expression, 'src> {
14  type Item = Token<'src>;
15
16  fn next(&mut self) -> Option<Token<'src>> {
17    loop {
18      match self.stack.pop()? {
19        Expression::And { lhs, rhs } | Expression::Or { lhs, rhs } => {
20          self.stack.push(lhs);
21          self.stack.push(rhs);
22        }
23        Expression::Assert {
24          condition:
25            Condition {
26              lhs,
27              rhs,
28              operator: _,
29            },
30          error,
31        } => {
32          self.stack.push(error);
33          self.stack.push(rhs);
34          self.stack.push(lhs);
35        }
36        Expression::Backtick { .. } | Expression::StringLiteral { .. } => {}
37        Expression::Call { thunk } => match thunk {
38          Thunk::Nullary { .. } => {}
39          Thunk::Unary { arg, .. } => self.stack.push(arg),
40          Thunk::UnaryOpt {
41            args: (a, opt_b), ..
42          } => {
43            self.stack.push(a);
44            if let Some(b) = opt_b.as_ref() {
45              self.stack.push(b);
46            }
47          }
48          Thunk::UnaryPlus {
49            args: (a, rest), ..
50          } => {
51            let first: &[&Expression] = &[a];
52            for arg in first.iter().copied().chain(rest).rev() {
53              self.stack.push(arg);
54            }
55          }
56          Thunk::Binary { args, .. } => {
57            for arg in args.iter().rev() {
58              self.stack.push(arg);
59            }
60          }
61          Thunk::BinaryPlus {
62            args: ([a, b], rest),
63            ..
64          } => {
65            let first: &[&Expression] = &[a, b];
66            for arg in first.iter().copied().chain(rest).rev() {
67              self.stack.push(arg);
68            }
69          }
70          Thunk::Ternary { args, .. } => {
71            for arg in args.iter().rev() {
72              self.stack.push(arg);
73            }
74          }
75        },
76        Expression::Concatenation { lhs, rhs } => {
77          self.stack.push(rhs);
78          self.stack.push(lhs);
79        }
80        Expression::Conditional {
81          condition:
82            Condition {
83              lhs,
84              rhs,
85              operator: _,
86            },
87          then,
88          otherwise,
89        } => {
90          self.stack.push(otherwise);
91          self.stack.push(then);
92          self.stack.push(rhs);
93          self.stack.push(lhs);
94        }
95        Expression::Group { contents } => {
96          self.stack.push(contents);
97        }
98        Expression::Join { lhs, rhs } => {
99          self.stack.push(rhs);
100          if let Some(lhs) = lhs {
101            self.stack.push(lhs);
102          }
103        }
104        Expression::Variable { name, .. } => return Some(name.token),
105      }
106    }
107  }
108}