2022-06-18 21:56:31 -07:00
|
|
|
use super::*;
|
2019-04-15 22:40:02 -07:00
|
|
|
|
2019-11-07 10:55:15 -08:00
|
|
|
pub(crate) struct Variables<'expression, 'src> {
|
|
|
|
stack: Vec<&'expression Expression<'src>>,
|
2019-04-15 22:40:02 -07:00
|
|
|
}
|
|
|
|
|
2019-11-07 10:55:15 -08:00
|
|
|
impl<'expression, 'src> Variables<'expression, 'src> {
|
|
|
|
pub(crate) fn new(root: &'expression Expression<'src>) -> Variables<'expression, 'src> {
|
2019-04-15 22:40:02 -07:00
|
|
|
Variables { stack: vec![root] }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 10:55:15 -08:00
|
|
|
impl<'expression, 'src> Iterator for Variables<'expression, 'src> {
|
|
|
|
type Item = Token<'src>;
|
2019-04-15 22:40:02 -07:00
|
|
|
|
2019-11-07 10:55:15 -08:00
|
|
|
fn next(&mut self) -> Option<Token<'src>> {
|
2021-10-08 22:04:13 -07:00
|
|
|
loop {
|
|
|
|
match self.stack.pop()? {
|
|
|
|
Expression::StringLiteral { .. } | Expression::Backtick { .. } => {}
|
|
|
|
Expression::Call { thunk } => match thunk {
|
|
|
|
Thunk::Nullary { .. } => {}
|
|
|
|
Thunk::Unary { arg, .. } => self.stack.push(arg),
|
2023-06-13 05:49:46 -07:00
|
|
|
Thunk::UnaryOpt {
|
|
|
|
args: (a, opt_b), ..
|
|
|
|
} => {
|
|
|
|
self.stack.push(a);
|
|
|
|
if let Some(b) = opt_b.as_ref() {
|
|
|
|
self.stack.push(b);
|
|
|
|
}
|
|
|
|
}
|
2021-10-08 22:04:13 -07:00
|
|
|
Thunk::Binary { args, .. } => {
|
|
|
|
for arg in args.iter().rev() {
|
|
|
|
self.stack.push(arg);
|
|
|
|
}
|
|
|
|
}
|
2021-10-14 17:00:58 -07:00
|
|
|
Thunk::BinaryPlus {
|
|
|
|
args: ([a, b], rest),
|
|
|
|
..
|
|
|
|
} => {
|
|
|
|
let first: &[&Expression] = &[a, b];
|
|
|
|
for arg in first.iter().copied().chain(rest).rev() {
|
|
|
|
self.stack.push(arg);
|
|
|
|
}
|
|
|
|
}
|
2021-10-08 22:04:13 -07:00
|
|
|
Thunk::Ternary { args, .. } => {
|
|
|
|
for arg in args.iter().rev() {
|
|
|
|
self.stack.push(arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Expression::Conditional {
|
|
|
|
lhs,
|
|
|
|
rhs,
|
|
|
|
then,
|
|
|
|
otherwise,
|
|
|
|
..
|
|
|
|
} => {
|
|
|
|
self.stack.push(otherwise);
|
|
|
|
self.stack.push(then);
|
|
|
|
self.stack.push(rhs);
|
|
|
|
self.stack.push(lhs);
|
|
|
|
}
|
2024-01-08 13:26:33 -08:00
|
|
|
Expression::Variable { name, .. } => return Some(name.token),
|
2022-09-11 00:48:02 -07:00
|
|
|
Expression::Concatenation { lhs, rhs } => {
|
2021-10-08 22:04:13 -07:00
|
|
|
self.stack.push(rhs);
|
|
|
|
self.stack.push(lhs);
|
|
|
|
}
|
2022-09-11 00:48:02 -07:00
|
|
|
Expression::Join { lhs, rhs } => {
|
|
|
|
self.stack.push(rhs);
|
|
|
|
if let Some(lhs) = lhs {
|
|
|
|
self.stack.push(lhs);
|
|
|
|
}
|
|
|
|
}
|
2021-10-08 22:04:13 -07:00
|
|
|
Expression::Group { contents } => {
|
|
|
|
self.stack.push(contents);
|
|
|
|
}
|
2021-09-16 06:44:40 -07:00
|
|
|
}
|
2019-04-15 22:40:02 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|