From aac3549a72663c523a456b2f5d7c3b77f509cdd6 Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Thu, 14 Jan 2021 11:42:55 +0000 Subject: Add labelled expressions. Restructure project (again). Convert `Cat` and `Alt` from binary to n+2-ary. --- src/chomp/visit.rs | 219 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 125 insertions(+), 94 deletions(-) (limited to 'src/chomp/visit.rs') diff --git a/src/chomp/visit.rs b/src/chomp/visit.rs index 4113b64..bdef30e 100644 --- a/src/chomp/visit.rs +++ b/src/chomp/visit.rs @@ -1,62 +1,120 @@ -use super::ast::{Alt, Call, Cat, Epsilon, Expression, Fix, Literal, Parameter, Variable}; +use proc_macro2::Span; + +use super::{ + ast::{ + Alt, Call, Cat, Epsilon, Expression, Fix, Literal, NamedExpression, Parameter, Variable, + }, + Name, +}; pub trait Visitor { type Out; - fn visit_epsilon(&mut self, eps: &Epsilon) -> Self::Out; - - fn visit_literal(&mut self, lit: &Literal) -> Self::Out; - - fn visit_cat(&mut self, cat: &Cat) -> Self::Out; - - fn visit_alt(&mut self, alt: &Alt) -> Self::Out; - - fn visit_fix(&mut self, fix: &Fix) -> Self::Out; - - fn visit_variable(&mut self, var: &Variable) -> Self::Out; - - fn visit_parameter(&mut self, param: &Parameter) -> Self::Out; - - fn visit_call(&mut self, call: &Call) -> Self::Out; + fn visit_epsilon( + &mut self, + name: Option<&Name>, + span: Option, + eps: &Epsilon, + ) -> Self::Out; + + fn visit_literal( + &mut self, + name: Option<&Name>, + span: Option, + lit: &Literal, + ) -> Self::Out; + + fn visit_cat(&mut self, name: Option<&Name>, span: Option, cat: &Cat) -> Self::Out; + + fn visit_alt(&mut self, name: Option<&Name>, span: Option, alt: &Alt) -> Self::Out; + + fn visit_fix(&mut self, name: Option<&Name>, span: Option, fix: &Fix) -> Self::Out; + + fn visit_variable( + &mut self, + name: Option<&Name>, + span: Option, + var: &Variable, + ) -> Self::Out; + + fn visit_parameter( + &mut self, + name: Option<&Name>, + span: Option, + param: &Parameter, + ) -> Self::Out; + + fn visit_call(&mut self, name: Option<&Name>, span: Option, call: &Call) -> Self::Out; } pub trait Mapper { type Out; - fn map_epsilon(&mut self, eps: &mut Epsilon) -> Self::Out; - - fn map_literal(&mut self, lit: &mut Literal) -> Self::Out; - - fn map_cat(&mut self, cat: &mut Cat) -> Self::Out; - - fn map_alt(&mut self, alt: &mut Alt) -> Self::Out; - - fn map_fix(&mut self, fix: &mut Fix) -> Self::Out; - - fn map_variable(&mut self, var: &mut Variable) -> Self::Out; - - fn map_parameter(&mut self, param: &mut Parameter) -> Self::Out; - - fn map_call(&mut self, call: &mut Call) -> Self::Out; + fn map_epsilon( + &mut self, + name: &mut Option, + span: Option, + eps: &mut Epsilon, + ) -> Self::Out; + + fn map_literal( + &mut self, + name: &mut Option, + span: Option, + lit: &mut Literal, + ) -> Self::Out; + + fn map_cat(&mut self, name: &mut Option, span: Option, cat: &mut Cat) -> Self::Out; + + fn map_alt(&mut self, name: &mut Option, span: Option, alt: &mut Alt) -> Self::Out; + + fn map_fix(&mut self, name: &mut Option, span: Option, fix: &mut Fix) -> Self::Out; + + fn map_variable( + &mut self, + name: &mut Option, + span: Option, + var: &mut Variable, + ) -> Self::Out; + + fn map_parameter( + &mut self, + name: &mut Option, + span: Option, + param: &mut Parameter, + ) -> Self::Out; + + fn map_call( + &mut self, + name: &mut Option, + span: Option, + call: &mut Call, + ) -> Self::Out; } pub trait Folder { type Out; - fn fold_epsilon(&mut self, eps: Epsilon) -> Self::Out; + fn fold_epsilon(&mut self, name: Option, span: Option, eps: Epsilon) -> Self::Out; - fn fold_literal(&mut self, lit: Literal) -> Self::Out; + fn fold_literal(&mut self, name: Option, span: Option, lit: Literal) -> Self::Out; - fn fold_cat(&mut self, cat: Cat) -> Self::Out; + fn fold_cat(&mut self, name: Option, span: Option, cat: Cat) -> Self::Out; - fn fold_alt(&mut self, alt: Alt) -> Self::Out; + fn fold_alt(&mut self, name: Option, span: Option, alt: Alt) -> Self::Out; - fn fold_fix(&mut self, fix: Fix) -> Self::Out; + fn fold_fix(&mut self, name: Option, span: Option, fix: Fix) -> Self::Out; - fn fold_variable(&mut self, var: Variable) -> Self::Out; + fn fold_variable(&mut self, name: Option, span: Option, var: Variable) + -> Self::Out; - fn fold_parameter(&mut self, param: Parameter) -> Self::Out; + fn fold_parameter( + &mut self, + name: Option, + span: Option, + param: Parameter, + ) -> Self::Out; - fn fold_call(&mut self, call: Call) -> Self::Out; + fn fold_call(&mut self, name: Option, span: Option, call: Call) -> Self::Out; } pub trait Visitable { @@ -67,70 +125,43 @@ pub trait Visitable { fn fold(self, folder: &mut F) -> ::Out; } -macro_rules! visitable_leaf { - ($ty:ty, $visit:ident, $map:ident, $fold:ident) => { - impl Visitable for $ty { - fn visit(&self, visitor: &mut V) -> ::Out { - visitor.$visit(self) - } - - fn map(&mut self, mapper: &mut M) -> ::Out { - mapper.$map(self) - } - - fn fold(self, folder: &mut F) -> ::Out { - folder.$fold(self) - } - } - }; -} - -visitable_leaf!(Epsilon, visit_epsilon, map_epsilon, fold_epsilon); -visitable_leaf!(Literal, visit_literal, map_literal, fold_literal); -visitable_leaf!(Cat, visit_cat, map_cat, fold_cat); -visitable_leaf!(Alt, visit_alt, map_alt, fold_alt); -visitable_leaf!(Fix, visit_fix, map_fix, fold_fix); -visitable_leaf!(Variable, visit_variable, map_variable, fold_variable); -visitable_leaf!(Parameter, visit_parameter, map_parameter, fold_parameter); -visitable_leaf!(Call, visit_call, map_call, fold_call); - -impl Visitable for Expression { +impl Visitable for NamedExpression { fn visit(&self, visitor: &mut V) -> ::Out { - match self { - Self::Epsilon(e) => visitor.visit_epsilon(e), - Self::Literal(l) => visitor.visit_literal(l), - Self::Cat(c) => visitor.visit_cat(c), - Self::Alt(a) => visitor.visit_alt(a), - Self::Fix(f) => visitor.visit_fix(f), - Self::Variable(v) => visitor.visit_variable(v), - Self::Parameter(p) => visitor.visit_parameter(p), - Self::Call(c) => visitor.visit_call(c), + match &self.expr { + Expression::Epsilon(e) => visitor.visit_epsilon(self.name.as_ref(), self.span, e), + Expression::Literal(l) => visitor.visit_literal(self.name.as_ref(), self.span, l), + Expression::Cat(c) => visitor.visit_cat(self.name.as_ref(), self.span, c), + Expression::Alt(a) => visitor.visit_alt(self.name.as_ref(), self.span, a), + Expression::Fix(f) => visitor.visit_fix(self.name.as_ref(), self.span, f), + Expression::Variable(v) => visitor.visit_variable(self.name.as_ref(), self.span, v), + Expression::Parameter(p) => visitor.visit_parameter(self.name.as_ref(), self.span, p), + Expression::Call(c) => visitor.visit_call(self.name.as_ref(), self.span, c), } } fn map(&mut self, mapper: &mut M) -> ::Out { - match self { - Self::Epsilon(e) => mapper.map_epsilon(e), - Self::Literal(l) => mapper.map_literal(l), - Self::Cat(c) => mapper.map_cat(c), - Self::Alt(a) => mapper.map_alt(a), - Self::Fix(f) => mapper.map_fix(f), - Self::Variable(v) => mapper.map_variable(v), - Self::Parameter(p) => mapper.map_parameter(p), - Self::Call(c) => mapper.map_call(c), + match &mut self.expr { + Expression::Epsilon(e) => mapper.map_epsilon(&mut self.name, self.span, e), + Expression::Literal(l) => mapper.map_literal(&mut self.name, self.span, l), + Expression::Cat(c) => mapper.map_cat(&mut self.name, self.span, c), + Expression::Alt(a) => mapper.map_alt(&mut self.name, self.span, a), + Expression::Fix(f) => mapper.map_fix(&mut self.name, self.span, f), + Expression::Variable(v) => mapper.map_variable(&mut self.name, self.span, v), + Expression::Parameter(p) => mapper.map_parameter(&mut self.name, self.span, p), + Expression::Call(c) => mapper.map_call(&mut self.name, self.span, c), } } fn fold(self, folder: &mut F) -> ::Out { - match self { - Self::Epsilon(e) => folder.fold_epsilon(e), - Self::Literal(l) => folder.fold_literal(l), - Self::Cat(c) => folder.fold_cat(c), - Self::Alt(a) => folder.fold_alt(a), - Self::Fix(f) => folder.fold_fix(f), - Self::Variable(v) => folder.fold_variable(v), - Self::Parameter(p) => folder.fold_parameter(p), - Self::Call(c) => folder.fold_call(c), + match self.expr { + Expression::Epsilon(e) => folder.fold_epsilon(self.name, self.span, e), + Expression::Literal(l) => folder.fold_literal(self.name, self.span, l), + Expression::Cat(c) => folder.fold_cat(self.name, self.span, c), + Expression::Alt(a) => folder.fold_alt(self.name, self.span, a), + Expression::Fix(f) => folder.fold_fix(self.name, self.span, f), + Expression::Variable(v) => folder.fold_variable(self.name, self.span, v), + Expression::Parameter(p) => folder.fold_parameter(self.name, self.span, p), + Expression::Call(c) => folder.fold_call(self.name, self.span, c), } } } -- cgit v1.2.3