feat: add ExprRef sumtype with better expression iteration
This commit is contained in:
parent
79384d436d
commit
0359029741
5 changed files with 93 additions and 19 deletions
42
argus-core/src/expr/iter.rs
Normal file
42
argus-core/src/expr/iter.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use super::{Expr, ExprRef};
|
||||
|
||||
/// Iterator that starts from some root [`Expr`] and travels down to it's leaf
|
||||
/// expressions.
|
||||
///
|
||||
/// This essentially implements breadth-first search over the expression tree rooted at
|
||||
/// the given [`Expr`].
|
||||
pub struct AstIter<'a> {
|
||||
queue: VecDeque<ExprRef<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> AstIter<'a> {
|
||||
/// Create an iterator that traverses an [`Expr`] from root to leaf.
|
||||
pub fn new(root: ExprRef<'a>) -> Self {
|
||||
let mut queue = VecDeque::new();
|
||||
queue.push_back(root);
|
||||
Self { queue }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for AstIter<'a> {
|
||||
type Item = ExprRef<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let expr_ref = self.queue.pop_front()?;
|
||||
|
||||
let expr: &dyn Expr = match expr_ref {
|
||||
ExprRef::Bool(expr) => expr,
|
||||
ExprRef::Num(expr) => expr,
|
||||
};
|
||||
|
||||
// We need to get all the arguments of the current expression (not including
|
||||
// any intervals), and push them into the queue.
|
||||
for arg in expr.args().into_iter() {
|
||||
self.queue.push_back(arg);
|
||||
}
|
||||
// 4. Give the user their expr
|
||||
Some(expr_ref)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,17 @@
|
|||
use std::any::Any;
|
||||
|
||||
use super::iter::AstIter;
|
||||
use super::{iter::AstIter, ExprRef};
|
||||
|
||||
/// A trait representing expressions
|
||||
pub trait Expr {
|
||||
fn args(&self) -> Vec<&dyn Expr>;
|
||||
fn is_numeric(&self) -> bool;
|
||||
fn is_boolean(&self) -> bool;
|
||||
|
||||
fn args(&self) -> Vec<ExprRef<'_>>;
|
||||
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
fn iter(&self) -> AstIter<'_>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
AstIter::new(self)
|
||||
}
|
||||
fn iter(&self) -> AstIter<'_>;
|
||||
}
|
||||
|
||||
impl dyn Expr {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue