feat: add ExprRef sumtype with better expression iteration

This commit is contained in:
Anand Balakrishnan 2023-03-20 10:28:26 -07:00
parent 79384d436d
commit 0359029741
No known key found for this signature in database
5 changed files with 93 additions and 19 deletions

View 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)
}
}

View file

@ -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 {