2019-04-11 15:23:14 -07:00
|
|
|
use crate::common::*;
|
2017-11-16 23:30:08 -08:00
|
|
|
|
|
|
|
#[derive(PartialEq, Debug)]
|
|
|
|
pub enum Expression<'a> {
|
2018-12-08 14:29:41 -08:00
|
|
|
Backtick {
|
|
|
|
raw: &'a str,
|
|
|
|
token: Token<'a>,
|
|
|
|
},
|
|
|
|
Call {
|
|
|
|
name: &'a str,
|
|
|
|
token: Token<'a>,
|
|
|
|
arguments: Vec<Expression<'a>>,
|
|
|
|
},
|
|
|
|
Concatination {
|
|
|
|
lhs: Box<Expression<'a>>,
|
|
|
|
rhs: Box<Expression<'a>>,
|
|
|
|
},
|
|
|
|
String {
|
|
|
|
cooked_string: CookedString<'a>,
|
|
|
|
},
|
|
|
|
Variable {
|
|
|
|
name: &'a str,
|
|
|
|
token: Token<'a>,
|
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Expression<'a> {
|
|
|
|
pub fn variables(&'a self) -> Variables<'a> {
|
2018-12-08 14:29:41 -08:00
|
|
|
Variables { stack: vec![self] }
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
2017-12-02 05:37:10 -08:00
|
|
|
|
|
|
|
pub fn functions(&'a self) -> Functions<'a> {
|
2018-12-08 14:29:41 -08:00
|
|
|
Functions { stack: vec![self] }
|
2017-12-02 05:37:10 -08:00
|
|
|
}
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Display for Expression<'a> {
|
2019-04-11 15:23:14 -07:00
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
2017-11-16 23:30:08 -08:00
|
|
|
match *self {
|
2018-12-08 14:29:41 -08:00
|
|
|
Expression::Backtick { raw, .. } => write!(f, "`{}`", raw)?,
|
|
|
|
Expression::Concatination { ref lhs, ref rhs } => write!(f, "{} + {}", lhs, rhs)?,
|
|
|
|
Expression::String { ref cooked_string } => write!(f, "\"{}\"", cooked_string.raw)?,
|
|
|
|
Expression::Variable { name, .. } => write!(f, "{}", name)?,
|
|
|
|
Expression::Call {
|
|
|
|
name,
|
|
|
|
ref arguments,
|
|
|
|
..
|
|
|
|
} => {
|
2017-12-02 14:59:07 -08:00
|
|
|
write!(f, "{}(", name)?;
|
|
|
|
for (i, argument) in arguments.iter().enumerate() {
|
|
|
|
if i > 0 {
|
|
|
|
write!(f, ", {}", argument)?;
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", argument)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
write!(f, ")")?;
|
|
|
|
}
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Variables<'a> {
|
|
|
|
stack: Vec<&'a Expression<'a>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Iterator for Variables<'a> {
|
|
|
|
type Item = &'a Token<'a>;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<&'a Token<'a>> {
|
|
|
|
match self.stack.pop() {
|
2017-12-02 05:37:10 -08:00
|
|
|
None
|
2018-12-08 14:29:41 -08:00
|
|
|
| Some(&Expression::String { .. })
|
|
|
|
| Some(&Expression::Backtick { .. })
|
|
|
|
| Some(&Expression::Call { .. }) => None,
|
|
|
|
Some(&Expression::Variable { ref token, .. }) => Some(token),
|
|
|
|
Some(&Expression::Concatination { ref lhs, ref rhs }) => {
|
2017-12-02 05:37:10 -08:00
|
|
|
self.stack.push(lhs);
|
|
|
|
self.stack.push(rhs);
|
|
|
|
self.next()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Functions<'a> {
|
|
|
|
stack: Vec<&'a Expression<'a>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Iterator for Functions<'a> {
|
2017-12-02 14:59:07 -08:00
|
|
|
type Item = (&'a Token<'a>, usize);
|
2017-12-02 05:37:10 -08:00
|
|
|
|
2017-12-02 14:59:07 -08:00
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
2017-12-02 05:37:10 -08:00
|
|
|
match self.stack.pop() {
|
|
|
|
None
|
2018-12-08 14:29:41 -08:00
|
|
|
| Some(&Expression::String { .. })
|
|
|
|
| Some(&Expression::Backtick { .. })
|
|
|
|
| Some(&Expression::Variable { .. }) => None,
|
|
|
|
Some(&Expression::Call {
|
|
|
|
ref token,
|
|
|
|
ref arguments,
|
|
|
|
..
|
|
|
|
}) => Some((token, arguments.len())),
|
|
|
|
Some(&Expression::Concatination { ref lhs, ref rhs }) => {
|
2017-11-16 23:30:08 -08:00
|
|
|
self.stack.push(lhs);
|
|
|
|
self.stack.push(rhs);
|
|
|
|
self.next()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|