diff options
author | Greg Brown <gmb60@cam.ac.uk> | 2021-01-08 18:00:11 +0000 |
---|---|---|
committer | Greg Brown <gmb60@cam.ac.uk> | 2021-01-08 18:00:11 +0000 |
commit | e1452227b8bd9ad3805480f8a5a66a75fb8370dd (patch) | |
tree | b02c9dfdc157d753e3f1c8a09bbd2ffb0bbfcc36 /src/chomp/check/spanning.rs | |
parent | fe2eac31d9dbec772796c3ea75be32e9cd01b810 (diff) |
Do more restructuring.
Diffstat (limited to 'src/chomp/check/spanning.rs')
-rw-r--r-- | src/chomp/check/spanning.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/chomp/check/spanning.rs b/src/chomp/check/spanning.rs new file mode 100644 index 0000000..91e593b --- /dev/null +++ b/src/chomp/check/spanning.rs @@ -0,0 +1,59 @@ +use proc_macro2::{Ident, Span}; + +use super::super::{ + ast::{Alt, Call, Cat, Epsilon, Fix, Literal, Parameter, Variable}, + visit::{Visitable, Visitor}, +}; + +#[derive(Clone, Copy, Debug)] +pub struct Spanning; + +impl Visitor for Spanning { + type Out = Option<Span>; + + fn visit_epsilon(&mut self, eps: &Epsilon) -> Self::Out { + eps.map(|e| e.span) + } + + fn visit_literal(&mut self, lit: &Literal) -> Self::Out { + lit.span() + } + + fn visit_cat(&mut self, cat: &Cat) -> Self::Out { + let fst = cat.first().visit(self); + let snd = cat.second().visit(self); + + match (fst, snd) { + (None, snd) => snd, + (Some(fst), None) => Some(fst), + (Some(fst), Some(snd)) => fst.join(snd), + } + } + + fn visit_alt(&mut self, alt: &Alt) -> Self::Out { + let left = alt.left().visit(self); + let right = alt.right().visit(self); + + match (left, right) { + (None, right) => right, + (Some(left), None) => Some(left), + (Some(left), Some(right)) => left.join(right), + } + } + + fn visit_fix(&mut self, fix: &Fix) -> Self::Out { + fix.span() + } + + fn visit_variable(&mut self, var: &Variable) -> Self::Out { + var.name().span() + } + + fn visit_parameter(&mut self, param: &Parameter) -> Self::Out { + param.name().span() + } + + fn visit_call(&mut self, call: &Call) -> Self::Out { + call.span() + } +} |