pub mod convert;
pub mod pointer;
pub mod projection;
pub use projection::{AstChildList, AstNode, AstProjection, PostOrderVisitor};
pub trait AstVisitor {
fn visit_variable(
&mut self,
_idx: usize,
_sym_id: crate::dag::symbol::SymbolId,
_dag_id: crate::dag::node::DagNodeId,
) {
}
fn visit_constant(&mut self, _idx: usize, _val: f64, _dag_id: crate::dag::node::DagNodeId) {}
fn visit_operator(
&mut self,
_idx: usize,
_op: crate::dag::symbol::OpKind,
_children: &AstChildList,
_dag_id: crate::dag::node::DagNodeId,
) {
}
fn visit_function(
&mut self,
_idx: usize,
_fn_id: crate::dag::symbol::FnId,
_children: &AstChildList,
_dag_id: crate::dag::node::DagNodeId,
) {
}
}
pub fn walk_projection<V: AstVisitor>(proj: &AstProjection, visitor: &mut V) {
for (idx, node) in proj.nodes.iter().enumerate() {
match node.kind {
crate::dag::symbol::SymbolKind::Variable(sym_id) => {
visitor.visit_variable(idx, sym_id, node.dag_id);
}
crate::dag::symbol::SymbolKind::Constant(val) => {
visitor.visit_constant(idx, val, node.dag_id);
}
crate::dag::symbol::SymbolKind::Operator(op) => {
visitor.visit_operator(idx, op, &node.children, node.dag_id);
}
crate::dag::symbol::SymbolKind::Function(fn_id) => {
visitor.visit_function(idx, fn_id, &node.children, node.dag_id);
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::convert::dag_to_ast;
use crate::dag::builder::DagBuilder;
#[test]
fn walk_counts_node_kinds() {
let mut b = DagBuilder::new();
let x = b.variable("x");
let c = b.constant(2.0);
let expr = b.mul(x, c);
let proj = dag_to_ast(b.arena(), expr);
struct Counter {
vars: usize,
consts: usize,
ops: usize,
}
impl AstVisitor for Counter {
fn visit_variable(
&mut self,
_idx: usize,
_sym_id: crate::dag::symbol::SymbolId,
_dag_id: crate::dag::node::DagNodeId,
) {
self.vars += 1;
}
fn visit_constant(
&mut self,
_idx: usize,
_val: f64,
_dag_id: crate::dag::node::DagNodeId,
) {
self.consts += 1;
}
fn visit_operator(
&mut self,
_idx: usize,
_op: crate::dag::symbol::OpKind,
_children: &AstChildList,
_dag_id: crate::dag::node::DagNodeId,
) {
self.ops += 1;
}
}
let mut counter = Counter {
vars: 0,
consts: 0,
ops: 0,
};
walk_projection(&proj, &mut counter);
assert_eq!(counter.vars, 1);
assert_eq!(counter.consts, 1);
assert_eq!(counter.ops, 1);
}
}