From e1452227b8bd9ad3805480f8a5a66a75fb8370dd Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Fri, 8 Jan 2021 18:00:11 +0000 Subject: Do more restructuring. --- src/chomp/check/substitute.rs | 77 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/chomp/check/substitute.rs (limited to 'src/chomp/check/substitute.rs') diff --git a/src/chomp/check/substitute.rs b/src/chomp/check/substitute.rs new file mode 100644 index 0000000..32595b1 --- /dev/null +++ b/src/chomp/check/substitute.rs @@ -0,0 +1,77 @@ +use super::{ + super::{ + ast::{Alt, Call, Cat, Epsilon, Expression, Fix, Literal, Parameter, Variable}, + error::SubstituteError, + visit::{Folder, Visitable}, + }, + DeepenVars, ShallowVars, +}; + +#[derive(Clone, Debug)] +pub struct SubstituteParams { + params: Vec, +} + +impl SubstituteParams { + pub fn new(params: Vec) -> Self { + Self { params } + } +} + +impl Folder for SubstituteParams { + type Out = Result; + + fn fold_epsilon(&mut self, eps: Epsilon) -> Self::Out { + Ok(eps.into()) + } + + fn fold_literal(&mut self, lit: Literal) -> Self::Out { + Ok(lit.into()) + } + + fn fold_cat(&mut self, mut cat: Cat) -> Self::Out { + cat.fst = Box::new(cat.fst.fold(self)?); + cat.snd = Box::new(cat.snd.fold(self)?); + Ok(cat.into()) + } + + fn fold_alt(&mut self, mut alt: Alt) -> Self::Out { + alt.left = Box::new(alt.left.fold(self)?); + alt.right = Box::new(alt.right.fold(self)?); + Ok(alt.into()) + } + + fn fold_fix(&mut self, mut fix: Fix) -> Self::Out { + for param in &mut self.params { + param.map(&mut DeepenVars::default()); + } + + fix.inner = Box::new(fix.inner.fold(self)?); + + for param in &mut self.params { + param.map(&mut ShallowVars::default()); + } + + Ok(fix.into()) + } + + fn fold_variable(&mut self, var: Variable) -> Self::Out { + Ok(Expression::Variable(var)) + } + + fn fold_call(&mut self, mut call: Call) -> Self::Out { + call.args = call + .args + .into_iter() + .map(|arg| arg.fold(self)) + .collect::>()?; + Ok(call.into()) + } + + fn fold_parameter(&mut self, param: Parameter) -> Self::Out { + self.params + .get(param.index()) + .cloned() + .ok_or(SubstituteError::FreeParameter(param)) + } +} -- cgit v1.2.3