summaryrefslogtreecommitdiff
path: root/src/chomp/check/substitute.rs
diff options
context:
space:
mode:
authorGreg Brown <gmb60@cam.ac.uk>2021-01-08 18:00:11 +0000
committerGreg Brown <gmb60@cam.ac.uk>2021-01-08 18:00:11 +0000
commite1452227b8bd9ad3805480f8a5a66a75fb8370dd (patch)
treeb02c9dfdc157d753e3f1c8a09bbd2ffb0bbfcc36 /src/chomp/check/substitute.rs
parentfe2eac31d9dbec772796c3ea75be32e9cd01b810 (diff)
Do more restructuring.
Diffstat (limited to 'src/chomp/check/substitute.rs')
-rw-r--r--src/chomp/check/substitute.rs77
1 files changed, 77 insertions, 0 deletions
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<Expression>,
+}
+
+impl SubstituteParams {
+ pub fn new(params: Vec<Expression>) -> Self {
+ Self { params }
+ }
+}
+
+impl Folder for SubstituteParams {
+ type Out = Result<Expression, SubstituteError>;
+
+ 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::<Result<_, _>>()?;
+ Ok(call.into())
+ }
+
+ fn fold_parameter(&mut self, param: Parameter) -> Self::Out {
+ self.params
+ .get(param.index())
+ .cloned()
+ .ok_or(SubstituteError::FreeParameter(param))
+ }
+}