weresocool_ast 1.0.43

AST for WereSoCool
Documentation
use crate::operations::{helpers::handle_id_error, NormalForm, Normalize, Substitute};
use crate::substitute_operations;
use crate::{ListOp, Term};
use scop::Defs;
use weresocool_error::Error;

impl Substitute<Term> for ListOp {
    fn substitute(
        &self,
        normal_form: &mut NormalForm,
        defs: &mut Defs<Term>,
    ) -> Result<Term, Error> {
        match self {
            ListOp::Const { terms } => Ok(Term::Lop(ListOp::Const {
                terms: substitute_operations(terms.to_vec(), normal_form, defs)?,
            })),
            ListOp::Named { name } => {
                let term = handle_id_error(name, defs)?;

                match term {
                    Term::Lop(lop) => lop.substitute(normal_form, defs),
                    _ => Err(Error::with_msg("List.substitute() on called non-list")),
                }
            }
            ListOp::ListOpIndexed { .. } => Ok(Term::Lop(ListOp::Const {
                terms: self
                    .term_vectors(defs)?
                    .iter_mut()
                    .map(|term_vector| {
                        let mut nf = normal_form.clone();

                        term_vector.term.apply_to_normal_form(&mut nf, defs)?;
                        term_vector.index_terms.iter().try_for_each(|index_term| {
                            index_term.apply_to_normal_form(&mut nf, defs)
                        })?;

                        Ok(Term::Nf(nf))
                    })
                    .collect::<Result<Vec<Term>, Error>>()?,
            })),
            ListOp::Concat { listops } => {
                let mut result = vec![];
                for list in listops {
                    result.push(list.substitute(normal_form, defs)?)
                }

                Ok(Term::Lop(ListOp::Const { terms: result }))
            }
            ListOp::GenOp { gen, .. } => gen.substitute(normal_form, defs),
        }
    }
}