summaryrefslogtreecommitdiff
path: root/src/chomp/visit.rs
diff options
context:
space:
mode:
authorGreg Brown <gmb60@cam.ac.uk>2021-05-06 19:40:59 +0100
committerGreg Brown <gmb60@cam.ac.uk>2021-05-06 19:40:59 +0100
commitdfc08ff2c6580bbeb3951b223e0332546ba3b0d9 (patch)
tree60597dd9492b9c2dfa10ea610289f143dd3e41b7 /src/chomp/visit.rs
parentef485d6f3e4df6e1a424ba3797388fa0bba6eb2e (diff)
Introduce lambda expressions.
Diffstat (limited to 'src/chomp/visit.rs')
-rw-r--r--src/chomp/visit.rs119
1 files changed, 52 insertions, 67 deletions
diff --git a/src/chomp/visit.rs b/src/chomp/visit.rs
index 7e716d3..b37909d 100644
--- a/src/chomp/visit.rs
+++ b/src/chomp/visit.rs
@@ -1,113 +1,81 @@
use proc_macro2::Span;
use super::{
- ast::{Alt, Call, Cat, Epsilon, Expression, Fix, Lambda, Literal, NamedExpression, Variable},
- Name,
+ ast::{
+ Alt, Call, Cat, Epsilon, Expression, Fix, Lambda, Let, Literal, NamedExpression, Variable,
+ },
+ name::Name,
};
pub trait Visitor {
type Out;
- fn visit_epsilon(
- &mut self,
- name: Option<&Name>,
- span: Option<Span>,
- eps: &Epsilon,
- ) -> Self::Out;
+ fn visit_epsilon(&mut self, name: Option<&Name>, span: Span, eps: &Epsilon) -> Self::Out;
- fn visit_literal(
- &mut self,
- name: Option<&Name>,
- span: Option<Span>,
- lit: &Literal,
- ) -> Self::Out;
+ fn visit_literal(&mut self, name: Option<&Name>, span: Span, lit: &Literal) -> Self::Out;
- fn visit_cat(&mut self, name: Option<&Name>, span: Option<Span>, cat: &Cat) -> Self::Out;
+ fn visit_cat(&mut self, name: Option<&Name>, span: Span, cat: &Cat) -> Self::Out;
- fn visit_alt(&mut self, name: Option<&Name>, span: Option<Span>, alt: &Alt) -> Self::Out;
+ fn visit_alt(&mut self, name: Option<&Name>, span: Span, alt: &Alt) -> Self::Out;
- fn visit_fix(&mut self, name: Option<&Name>, span: Option<Span>, fix: &Fix) -> Self::Out;
+ fn visit_fix(&mut self, name: Option<&Name>, span: Span, fix: &Fix) -> Self::Out;
- fn visit_variable(
- &mut self,
- name: Option<&Name>,
- span: Option<Span>,
- var: &Variable,
- ) -> Self::Out;
+ fn visit_variable(&mut self, name: Option<&Name>, span: Span, var: &Variable) -> Self::Out;
- fn visit_call(&mut self, name: Option<&Name>, span: Option<Span>, call: &Call) -> Self::Out;
+ fn visit_call(&mut self, name: Option<&Name>, span: Span, call: &Call) -> Self::Out;
- fn visit_lambda(
- &mut self,
- name: Option<&Name>,
- span: Option<Span>,
- lambda: &Lambda,
- ) -> Self::Out;
+ fn visit_lambda(&mut self, name: Option<&Name>, span: Span, lambda: &Lambda) -> Self::Out;
+
+ fn visit_let(&mut self, name: Option<&Name>, span: Span, stmt: &Let) -> Self::Out;
}
pub trait Mapper {
type Out;
- fn map_epsilon(
- &mut self,
- name: &mut Option<Name>,
- span: Option<Span>,
- eps: &mut Epsilon,
- ) -> Self::Out;
+ fn map_epsilon(&mut self, name: &mut Option<Name>, span: Span, eps: &mut Epsilon) -> Self::Out;
- fn map_literal(
- &mut self,
- name: &mut Option<Name>,
- span: Option<Span>,
- lit: &mut Literal,
- ) -> Self::Out;
+ fn map_literal(&mut self, name: &mut Option<Name>, span: Span, lit: &mut Literal) -> Self::Out;
- fn map_cat(&mut self, name: &mut Option<Name>, span: Option<Span>, cat: &mut Cat) -> Self::Out;
+ fn map_cat(&mut self, name: &mut Option<Name>, span: Span, cat: &mut Cat) -> Self::Out;
- fn map_alt(&mut self, name: &mut Option<Name>, span: Option<Span>, alt: &mut Alt) -> Self::Out;
+ fn map_alt(&mut self, name: &mut Option<Name>, span: Span, alt: &mut Alt) -> Self::Out;
- fn map_fix(&mut self, name: &mut Option<Name>, span: Option<Span>, fix: &mut Fix) -> Self::Out;
+ fn map_fix(&mut self, name: &mut Option<Name>, span: Span, fix: &mut Fix) -> Self::Out;
fn map_variable(
&mut self,
name: &mut Option<Name>,
- span: Option<Span>,
+ span: Span,
var: &mut Variable,
) -> Self::Out;
- fn map_call(
- &mut self,
- name: &mut Option<Name>,
- span: Option<Span>,
- call: &mut Call,
- ) -> Self::Out;
+ fn map_call(&mut self, name: &mut Option<Name>, span: Span, call: &mut Call) -> Self::Out;
- fn map_lambda(
- &mut self,
- name: &mut Option<Name>,
- span: Option<Span>,
- lambda: &mut Lambda,
- ) -> Self::Out;
+ fn map_lambda(&mut self, name: &mut Option<Name>, span: Span, lambda: &mut Lambda)
+ -> Self::Out;
+
+ fn map_let(&mut self, name: &mut Option<Name>, span: Span, stmt: &mut Let) -> Self::Out;
}
pub trait Folder {
type Out;
- fn fold_epsilon(&mut self, name: Option<Name>, span: Option<Span>, eps: Epsilon) -> Self::Out;
+ fn fold_epsilon(&mut self, name: Option<Name>, span: Span, eps: Epsilon) -> Self::Out;
- fn fold_literal(&mut self, name: Option<Name>, span: Option<Span>, lit: Literal) -> Self::Out;
+ fn fold_literal(&mut self, name: Option<Name>, span: Span, lit: Literal) -> Self::Out;
- fn fold_cat(&mut self, name: Option<Name>, span: Option<Span>, cat: Cat) -> Self::Out;
+ fn fold_cat(&mut self, name: Option<Name>, span: Span, cat: Cat) -> Self::Out;
- fn fold_alt(&mut self, name: Option<Name>, span: Option<Span>, alt: Alt) -> Self::Out;
+ fn fold_alt(&mut self, name: Option<Name>, span: Span, alt: Alt) -> Self::Out;
- fn fold_fix(&mut self, name: Option<Name>, span: Option<Span>, fix: Fix) -> Self::Out;
+ fn fold_fix(&mut self, name: Option<Name>, span: Span, fix: Fix) -> Self::Out;
- fn fold_variable(&mut self, name: Option<Name>, span: Option<Span>, var: Variable)
- -> Self::Out;
+ fn fold_variable(&mut self, name: Option<Name>, span: Span, var: Variable) -> Self::Out;
+
+ fn fold_call(&mut self, name: Option<Name>, span: Span, call: Call) -> Self::Out;
- fn fold_call(&mut self, name: Option<Name>, span: Option<Span>, call: Call) -> Self::Out;
+ fn fold_lambda(&mut self, name: Option<Name>, span: Span, lambda: Lambda) -> Self::Out;
- fn fold_lambda(&mut self, name: Option<Name>, span: Option<Span>, lambda: Lambda) -> Self::Out;
+ fn fold_let(&mut self, name: Option<Name>, span: Span, stmt: Let) -> Self::Out;
}
pub trait Visitable {
@@ -118,6 +86,20 @@ pub trait Visitable {
fn fold<F: Folder>(self, folder: &mut F) -> <F as Folder>::Out;
}
+impl<T: Visitable> Visitable for Box<T> {
+ fn visit<V: Visitor>(&self, visitor: &mut V) -> <V as Visitor>::Out {
+ self.as_ref().visit(visitor)
+ }
+
+ fn map<M: Mapper>(&mut self, mapper: &mut M) -> <M as Mapper>::Out {
+ self.as_mut().map(mapper)
+ }
+
+ fn fold<F: Folder>(self, folder: &mut F) -> <F as Folder>::Out {
+ (*self).fold(folder)
+ }
+}
+
impl Visitable for NamedExpression {
fn visit<V: Visitor>(&self, visitor: &mut V) -> <V as Visitor>::Out {
match &self.expr {
@@ -129,6 +111,7 @@ impl Visitable for NamedExpression {
Expression::Variable(v) => visitor.visit_variable(self.name.as_ref(), self.span, v),
Expression::Call(c) => visitor.visit_call(self.name.as_ref(), self.span, c),
Expression::Lambda(l) => visitor.visit_lambda(self.name.as_ref(), self.span, l),
+ Expression::Let(l) => visitor.visit_let(self.name.as_ref(), self.span, l),
}
}
@@ -142,6 +125,7 @@ impl Visitable for NamedExpression {
Expression::Variable(v) => mapper.map_variable(&mut self.name, self.span, v),
Expression::Call(c) => mapper.map_call(&mut self.name, self.span, c),
Expression::Lambda(l) => mapper.map_lambda(&mut self.name, self.span, l),
+ Expression::Let(l) => mapper.map_let(&mut self.name, self.span, l),
}
}
@@ -155,6 +139,7 @@ impl Visitable for NamedExpression {
Expression::Variable(v) => folder.fold_variable(self.name, self.span, v),
Expression::Call(c) => folder.fold_call(self.name, self.span, c),
Expression::Lambda(l) => folder.fold_lambda(self.name, self.span, l),
+ Expression::Let(l) => folder.fold_let(self.name, self.span, l),
}
}
}