diff options
author | Greg Brown <gmb60@cam.ac.uk> | 2021-05-06 19:40:59 +0100 |
---|---|---|
committer | Greg Brown <gmb60@cam.ac.uk> | 2021-05-06 19:40:59 +0100 |
commit | dfc08ff2c6580bbeb3951b223e0332546ba3b0d9 (patch) | |
tree | 60597dd9492b9c2dfa10ea610289f143dd3e41b7 /src/chomp/visit.rs | |
parent | ef485d6f3e4df6e1a424ba3797388fa0bba6eb2e (diff) |
Introduce lambda expressions.
Diffstat (limited to 'src/chomp/visit.rs')
-rw-r--r-- | src/chomp/visit.rs | 119 |
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), } } } |