diff options
author | Greg Brown <gmb60@cam.ac.uk> | 2021-01-21 09:42:02 +0000 |
---|---|---|
committer | Greg Brown <gmb60@cam.ac.uk> | 2021-01-21 17:45:02 +0000 |
commit | 1a93b1f82bc8c21d24e67031c5eca96830e928c7 (patch) | |
tree | 4c3fbfac9f0fbbc31defee03cd460e0400278d30 /src/nibble | |
parent | faa3f30deb32d0a1fd7cb196559762635b22ecfd (diff) |
Fix many warnings.
Diffstat (limited to 'src/nibble')
-rw-r--r-- | src/nibble/convert.rs | 115 | ||||
-rw-r--r-- | src/nibble/cst.rs | 103 |
2 files changed, 157 insertions, 61 deletions
diff --git a/src/nibble/convert.rs b/src/nibble/convert.rs index 3310b2a..bfa0be2 100644 --- a/src/nibble/convert.rs +++ b/src/nibble/convert.rs @@ -1,7 +1,7 @@ -use std::{collections::HashMap, fmt}; +use std::{collections::HashMap, fmt, mem}; use proc_macro2::Span; -use syn::punctuated::Pair; +use syn::{punctuated::Pair, Token}; use crate::chomp::{ ast::{self, NamedExpression}, @@ -41,7 +41,9 @@ impl Context { // we make variable binding cheaper by inserting wrong and pulling right. match self.names.get(&name.to_string()).copied() { Some(Binding::Variable(index)) => Some(Binding::Variable(self.vars - index - 1)), - x => x, + Some(Binding::Parameter(index)) => Some(Binding::Parameter(index)), + Some(Binding::Global) => Some(Binding::Global), + None => None, } } @@ -68,7 +70,9 @@ impl Context { #[derive(Clone, Debug)] pub enum ConvertError { - UndeclaredName(Name), + UndeclaredName(Box<Name>), + EmptyCat(Option<Span>), + EmptyAlt(Option<Span>), } impl From<ConvertError> for syn::Error { @@ -76,6 +80,7 @@ impl From<ConvertError> for syn::Error { let msg = e.to_string(); let span = match e { ConvertError::UndeclaredName(name) => name.span(), + ConvertError::EmptyCat(span) | ConvertError::EmptyAlt(span) => span, }; Self::new(span.unwrap_or_else(Span::call_site), msg) @@ -88,6 +93,12 @@ impl fmt::Display for ConvertError { Self::UndeclaredName(name) => { write!(f, "undeclared name: `{}`", name) } + Self::EmptyCat(_) => { + write!(f, "concatenation has no elements") + } + Self::EmptyAlt(_) => { + write!(f, "alternation has no elements") + } } } } @@ -105,7 +116,7 @@ impl Convert for Ident { let binding = context .lookup(&name) - .ok_or_else(|| ConvertError::UndeclaredName(name.clone()))?; + .ok_or_else(|| ConvertError::UndeclaredName(Box::new(name.clone())))?; Ok(match binding { Binding::Variable(index) => NamedExpression { @@ -198,42 +209,37 @@ impl Convert for Term { impl Convert for Cat { fn convert(self, context: &mut Context) -> Result<NamedExpression, ConvertError> { + fn convert_pair( + pair: Pair<Term, Token![.]>, + context: &mut Context, + ) -> Result<(NamedExpression, Option<Span>), ConvertError> { + match pair { + Pair::Punctuated(t, p) => t.convert(context).map(|expr| (expr, Some(p.span))), + Pair::End(t) => t.convert(context).map(|expr| (expr, None)), + } + } + + let span = self.span(); let mut iter = self.0.into_pairs(); - let (first, punct) = match iter.next().unwrap() { - Pair::Punctuated(t, p) => (t.convert(context)?, Some(p.span)), - Pair::End(t) => (t.convert(context)?, None), - }; + let (first, mut punct) = iter + .next() + .ok_or(ConvertError::EmptyCat(span)) + .and_then(|pair| convert_pair(pair, context))?; - let mut rest = Vec::new(); - let (span, _) = iter.try_fold( - ( - first.span.and_then(|s| punct.and_then(|p| s.join(p))), - punct, - ), - |(span, punct), pair| { - let (snd, p) = match pair { - Pair::Punctuated(t, p) => (t.convert(context)?, Some(p.span)), - Pair::End(t) => (t.convert(context)?, None), - }; - - let span = span - .and_then(|s| snd.span.and_then(|t| s.join(t))) - .and_then(|s| p.and_then(|p| s.join(p))); - rest.push((punct, snd)); - Ok((span, p)) - }, - )?; + let mut rest = iter.map(|pair| { + convert_pair(pair, context).map(|(snd, p)| (mem::replace(&mut punct, p), snd)) + }); - let mut iter = rest.into_iter(); - if let Some((punct, second)) = iter.next() { + if let Some(res) = rest.next() { + let (punct, second) = res?; Ok(NamedExpression { name: None, expr: ast::Cat { first: Box::new(first), punct, second: Box::new(second), - rest: iter.collect(), + rest: rest.collect::<Result<_, _>>()?, } .into(), span, @@ -260,42 +266,37 @@ impl Convert for Labelled { impl Convert for Alt { fn convert(self, context: &mut Context) -> Result<NamedExpression, ConvertError> { +fn convert_pair( + pair: Pair<Labelled, Token![|]>, + context: &mut Context, + ) -> Result<(NamedExpression, Option<Span>), ConvertError> { + match pair { + Pair::Punctuated(t, p) => t.convert(context).map(|expr| (expr, Some(p.span))), + Pair::End(t) => t.convert(context).map(|expr| (expr, None)), + } + } + + let span = self.span(); let mut iter = self.0.into_pairs(); - let (first, punct) = match iter.next().unwrap() { - Pair::Punctuated(t, p) => (t.convert(context)?, Some(p.span)), - Pair::End(t) => (t.convert(context)?, None), - }; + let (first, mut punct) = iter + .next() + .ok_or(ConvertError::EmptyAlt(span)) + .and_then(|pair| convert_pair(pair, context))?; - let mut rest = Vec::new(); - let (span, _) = iter.try_fold( - ( - first.span.and_then(|s| punct.and_then(|p| s.join(p))), - punct, - ), - |(span, punct), pair| { - let (snd, p) = match pair { - Pair::Punctuated(t, p) => (t.convert(context)?, Some(p.span)), - Pair::End(t) => (t.convert(context)?, None), - }; - - let span = span - .and_then(|s| snd.span.and_then(|t| s.join(t))) - .and_then(|s| p.and_then(|p| s.join(p))); - rest.push((punct, snd)); - Ok((span, p)) - }, - )?; + let mut rest = iter.map(|pair| { + convert_pair(pair, context).map(|(snd, p)| (mem::replace(&mut punct, p), snd)) + }); - let mut iter = rest.into_iter(); - if let Some((punct, second)) = iter.next() { + if let Some(res) = rest.next() { + let (punct, second) = res?; Ok(NamedExpression { name: None, expr: ast::Alt { first: Box::new(first), punct, second: Box::new(second), - rest: iter.collect(), + rest: rest.collect::<Result<_, _>>()?, } .into(), span, diff --git a/src/nibble/cst.rs b/src/nibble/cst.rs index fc698e8..d8b71b7 100644 --- a/src/nibble/cst.rs +++ b/src/nibble/cst.rs @@ -1,3 +1,5 @@ +use std::fmt; + use proc_macro2::Span; use syn::{ bracketed, @@ -58,7 +60,14 @@ impl<T: Parse> Parse for ArgList<T> { } } -#[derive(Clone)] +impl<T: fmt::Debug> fmt::Debug for ArgList<T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ArgList")?; + f.debug_list().entries(self.args.iter()).finish() + } +} + +#[derive(Clone, Debug)] pub struct Call { pub name: Ident, pub args: ArgList<Expression>, @@ -109,6 +118,15 @@ impl Parse for Fix { } } +impl fmt::Debug for Fix { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Fix") + .field("arg", &self.arg) + .field("expr", &self.expr) + .finish() + } +} + #[derive(Clone)] pub struct ParenExpression { paren_token: Paren, @@ -124,6 +142,14 @@ impl Parse for ParenExpression { } } +impl fmt::Debug for ParenExpression { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ParenExpression") + .field("expr", &self.expr) + .finish() + } +} + #[derive(Clone)] pub enum Term { Epsilon(Epsilon), @@ -173,6 +199,19 @@ impl Parse for Term { } } +impl fmt::Debug for Term { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Term::Epsilon(_) => write!(f, "Term::Epsilon"), + Term::Ident(i) => write!(f, "Term::Ident({:?})", i), + Term::Literal(l) => write!(f, "Term::Literal({:?})", l.value()), + Term::Call(c) => write!(f, "Term::Call({:?})", c), + Term::Fix(x) => write!(f, "Term::Fix({:?})", x), + Term::Parens(p) => write!(f, "Term::Parens({:?})", p), + } + } +} + #[derive(Clone)] pub struct Cat(pub Punctuated<Term, Token![.]>); @@ -200,6 +239,13 @@ impl Cat { } } +impl fmt::Debug for Cat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Cat")?; + f.debug_list().entries(self.0.iter()).finish() + } +} + #[derive(Clone)] pub struct Label { colon_tok: Token![:], @@ -220,7 +266,13 @@ impl Parse for Label { } } -#[derive(Clone)] +impl fmt::Debug for Label { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Label").field("label", &self.label).finish() + } +} + +#[derive(Clone, Debug)] pub struct Labelled { pub cat: Cat, pub label: Option<Label>, @@ -251,12 +303,37 @@ impl Parse for Labelled { #[derive(Clone)] pub struct Alt(pub Punctuated<Labelled, Token![|]>); +impl Alt { + pub fn span(&self) -> Option<Span> { + let mut iter = self.0.pairs(); + let span = match iter.next()? { + Pair::Punctuated(t, p) => t.span().and_then(|s| s.join(p.span)), + Pair::End(t) => t.span(), + }?; + + iter.try_fold(span, |span, pair| match pair { + Pair::Punctuated(t, p) => t + .span() + .and_then(|s| span.join(s)) + .and_then(|s| s.join(p.span)), + Pair::End(t) => t.span().and_then(|s| span.join(s)), + }) + } +} + impl Parse for Alt { fn parse(input: ParseStream<'_>) -> syn::Result<Self> { input.call(Punctuated::parse_separated_nonempty).map(Self) } } +impl fmt::Debug for Alt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Alt")?; + f.debug_list().entries(self.0.iter()).finish() + } +} + pub type Expression = Alt; #[derive(Clone)] @@ -299,6 +376,16 @@ impl Parse for LetStatement { } } +impl fmt::Debug for LetStatement { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("LetStatement") + .field("name", &self.name) + .field("args", &self.args) + .field("expr", &self.expr) + .finish() + } +} + #[derive(Clone)] pub struct GoalStatement { match_token: Token![match], @@ -320,7 +407,15 @@ impl Parse for GoalStatement { } } -#[derive(Clone)] +impl fmt::Debug for GoalStatement { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("GoalStatement") + .field("expr", &self.expr) + .finish() + } +} + +#[derive(Clone, Debug)] pub struct File { lets: Vec<LetStatement>, goal: GoalStatement, @@ -336,7 +431,7 @@ impl File { let params = stmt .args .into_iter() - .flat_map(|args| args.into_iter()) + .flat_map(ArgList::into_iter) .map(Name::from); let mut context = Context::new(&names, params.clone()); let mut expr = stmt.expr.convert(&mut context)?; |