just/src/variables.rs
Casey Rodarmor 19f7ad09a7
Add conditional expressions (#714)
Add conditional expressions of the form:

   foo := if lhs == rhs { then } else { otherwise }

`lhs`, `rhs`, `then`, and `otherwise` are all arbitrary expressions, and
can recursively include other conditionals. Conditionals short-circuit,
so the branch not taken isn't evaluated.

It is also possible to test for inequality with `==`.
2020-10-26 18:16:42 -07:00

48 lines
1.2 KiB
Rust

use crate::common::*;
pub(crate) struct Variables<'expression, 'src> {
stack: Vec<&'expression Expression<'src>>,
}
impl<'expression, 'src> Variables<'expression, 'src> {
pub(crate) fn new(root: &'expression Expression<'src>) -> Variables<'expression, 'src> {
Variables { stack: vec![root] }
}
}
impl<'expression, 'src> Iterator for Variables<'expression, 'src> {
type Item = Token<'src>;
fn next(&mut self) -> Option<Token<'src>> {
match self.stack.pop() {
None
| Some(Expression::StringLiteral { .. })
| Some(Expression::Backtick { .. })
| Some(Expression::Call { .. }) => None,
Some(Expression::Conditional {
lhs,
rhs,
then,
otherwise,
..
}) => {
self.stack.push(lhs);
self.stack.push(rhs);
self.stack.push(then);
self.stack.push(otherwise);
self.next()
},
Some(Expression::Variable { name, .. }) => Some(name.token()),
Some(Expression::Concatination { lhs, rhs }) => {
self.stack.push(lhs);
self.stack.push(rhs);
self.next()
},
Some(Expression::Group { contents }) => {
self.stack.push(contents);
self.next()
},
}
}
}