From 1a93b1f82bc8c21d24e67031c5eca96830e928c7 Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Thu, 21 Jan 2021 09:42:02 +0000 Subject: Fix many warnings. --- src/chomp/typed/context.rs | 35 +++++++++-------- src/chomp/typed/error.rs | 96 ++++++++++++++++++++++++++-------------------- src/chomp/typed/infer.rs | 37 ++++++++---------- src/chomp/typed/mod.rs | 30 ++++++++++----- 4 files changed, 109 insertions(+), 89 deletions(-) (limited to 'src/chomp/typed') diff --git a/src/chomp/typed/context.rs b/src/chomp/typed/context.rs index 5c8d398..f3263ce 100644 --- a/src/chomp/typed/context.rs +++ b/src/chomp/typed/context.rs @@ -17,16 +17,6 @@ impl Context { self.vars.len() } - pub fn is_unguarded(&self, var: &Variable) -> Option { - if self.vars.len() <= var.index { - None - } else if self.unguard_points.is_empty() { - Some(false) - } else { - Some(self.unguard_points[self.unguard_points.len() - 1] + var.index >= self.vars.len()) - } - } - pub fn with_unguard R, R>(&mut self, f: F) -> R { self.unguard_points.push(self.vars.len()); let res = f(self); @@ -34,12 +24,23 @@ impl Context { res } - pub fn get_variable_type(&self, var: &Variable) -> Result<&Type, GetVariableError> { - match self.is_unguarded(var) { - None => Err(GetVariableError::FreeVariable), - Some(false) => Err(GetVariableError::GuardedVariable), - Some(true) => Ok(&self.vars[self.vars.len() - var.index - 1]), - } + pub fn get_variable_type(&self, var: Variable) -> Result<&Type, GetVariableError> { + self.vars + .iter() + .nth_back(var.index) + .ok_or(GetVariableError::FreeVariable) + .and_then(|ty| { + self.unguard_points + .last() + .and_then(|point| { + if point + var.index >= self.vars.len() { + Some(ty) + } else { + None + } + }) + .ok_or(GetVariableError::GuardedVariable) + }) } pub fn with_variable_type R, R>(&mut self, ty: Type, f: F) -> R { @@ -50,7 +51,7 @@ impl Context { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum GetVariableError { FreeVariable, GuardedVariable, diff --git a/src/chomp/typed/error.rs b/src/chomp/typed/error.rs index bb807fc..5c1e21e 100644 --- a/src/chomp/typed/error.rs +++ b/src/chomp/typed/error.rs @@ -18,91 +18,105 @@ pub struct VariableError { pub name: Option, } -impl PartialEq for VariableError { - fn eq(&self, other: &Self) -> bool { - todo!() - } -} - -impl Eq for VariableError {} - impl From for syn::Error { fn from(other: VariableError) -> Self { - todo!() + let msg = other.to_string(); + let span = other.span; + Self::new(span.unwrap_or_else(Span::call_site), msg) } } impl Display for VariableError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - todo!() + match &self.inner { + GetVariableError::FreeVariable => write!(f, "unbound variable: "), + GetVariableError::GuardedVariable => write!(f, "usage of guarded variable: "), + }?; + + if let Some(name) = &self.name { + write!(f, "`{}`", name) + } else { + write!(f, "'{}", self.var.index) + } } } impl Error for VariableError {} -/// A type error when concatenating two terms. #[derive(Debug)] pub enum CatError { - /// The first term was unexpectedly nullable. - FirstNullable(TypedExpression, Option), - /// The flast set of the first term intersects the first set of the second. - FirstFlastOverlap(Vec, Option, TypedExpression), + FirstNullable { + expr: TypedExpression, + punct: Option, + }, + FirstFlastOverlap { + first: Vec, + punct: Option, + next: TypedExpression, + }, } -impl PartialEq for CatError { - fn eq(&self, other: &Self) -> bool { - todo!() - } -} - -impl Eq for CatError {} - impl From for syn::Error { fn from(other: CatError) -> Self { - todo!() + let msg = other.to_string(); + let span = match other { + CatError::FirstNullable { punct, .. } | CatError::FirstFlastOverlap { punct, .. } => { + punct + } + }; + Self::new(span.unwrap_or_else(Span::call_site), msg) } } impl Display for CatError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - todo!() + match self { + Self::FirstNullable { .. } => write!(f, "first part of concatenation is nullable"), + Self::FirstFlastOverlap { .. } => { + write!(f, "first set overlaps with preceding flast set") + } + } } } impl Error for CatError {} -/// A type error when alternating two terms. #[derive(Debug)] pub enum AltError { - /// Both terms are nullable. - BothNullable(Vec, Option, TypedExpression), - /// The first sets of the two terms intersect. - FirstOverlap(Vec, Option, TypedExpression), -} - -impl PartialEq for AltError { - fn eq(&self, other: &Self) -> bool { - todo!() - } + BothNullable { + left: Vec, + punct: Option, + right: TypedExpression, + }, + FirstOverlap { + left: Vec, + punct: Option, + right: TypedExpression, + }, } -impl Eq for AltError {} - impl From for syn::Error { fn from(other: AltError) -> Self { - todo!() + let msg = other.to_string(); + let span = match other { + AltError::BothNullable { punct, .. } | AltError::FirstOverlap { punct, .. } => punct, + }; + Self::new(span.unwrap_or_else(Span::call_site), msg) } } impl Display for AltError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - todo!() + match self { + Self::BothNullable { .. } => write!(f, "both branches are nullable"), + Self::FirstOverlap { .. } => write!(f, "first sets of both branches overlap"), + } } } impl Error for AltError {} -#[derive(Debug, Eq, PartialEq)] +#[derive(Debug)] pub enum TypeError { Cat(CatError), Alt(AltError), diff --git a/src/chomp/typed/infer.rs b/src/chomp/typed/infer.rs index 8095103..44ea654 100644 --- a/src/chomp/typed/infer.rs +++ b/src/chomp/typed/infer.rs @@ -61,25 +61,18 @@ impl Folder for TypeInfer<'_> { fn fold_alt(&mut self, name: Option, span: Option, alt: Alt) -> Self::Out { let first = alt.first.fold(self)?; - let second = alt.second; - let rest = alt.rest; + let second = alt.second.fold(self)?; + let rest = alt + .rest + .into_iter() + .map(|(punct, term)| -> Result<_, TypeError> { Ok((punct, term.fold(self)?)) }) + .collect::, _>>()?; let punct = alt.punct; - self.context - .with_unguard(|context| -> Result { - let mut infer = TypeInfer { context }; - let second = second.fold(&mut infer)?; - let rest = rest - .into_iter() - .map(|(punct, term)| -> Result<_, TypeError> { - Ok((punct, term.fold(&mut infer)?)) - }) - .collect::, _>>()?; - Ok(TypedExpression { - inner: super::Alt::new(first, punct, second, rest)?.into(), - name, - span, - }) - }) + Ok(TypedExpression { + inner: super::Alt::new(first, punct, second, rest)?.into(), + name, + span, + }) } fn fold_fix(&mut self, name: Option, span: Option, fix: Fix) -> Self::Out { @@ -111,7 +104,7 @@ impl Folder for TypeInfer<'_> { span: Option, var: Variable, ) -> Self::Out { - let ty = match self.context.get_variable_type(&var) { + let ty = match self.context.get_variable_type(var) { Ok(ty) => ty.clone(), Err(inner) => { return Err(VariableError { @@ -136,10 +129,10 @@ impl Folder for TypeInfer<'_> { _span: Option, _param: Parameter, ) -> Self::Out { - todo!() + unimplemented!() } - fn fold_call(&mut self, _name: Option,_span: Option, _call: Call) -> Self::Out { - todo!() + fn fold_call(&mut self, _name: Option, _span: Option, _call: Call) -> Self::Out { + unimplemented!() } } diff --git a/src/chomp/typed/mod.rs b/src/chomp/typed/mod.rs index e9aed79..2a9e365 100644 --- a/src/chomp/typed/mod.rs +++ b/src/chomp/typed/mod.rs @@ -14,8 +14,8 @@ pub mod lower; mod infer; -pub use self::infer::TypeInfer; use self::error::{AltError, CatError}; +pub use self::infer::TypeInfer; #[derive(Debug, Default, Clone, Eq, Hash, PartialEq)] pub struct Type { @@ -130,7 +130,7 @@ impl Cat { rest: I, ) -> Result { if first.get_type().nullable() { - return Err(CatError::FirstNullable(first, punct)); + return Err(CatError::FirstNullable { expr: first, punct }); } iter::once((punct, second)) @@ -138,16 +138,20 @@ impl Cat { .try_fold( (first.get_type().clone(), vec![first]), |(ty, mut terms), (punct, right)| { - if !ty + if ty .flast_set() .intersect_first(right.get_type().first_set()) .is_empty() { - Err(CatError::FirstFlastOverlap(terms, punct, right)) - } else { let ty = ty.cat(right.get_type().clone()); terms.push(right); Ok((ty, terms)) + } else { + Err(CatError::FirstFlastOverlap { + first: terms, + punct, + next: right, + }) } }, ) @@ -184,17 +188,25 @@ impl Alt { (first.get_type().clone(), vec![first]), |(ty, mut terms), (punct, right)| { if ty.nullable() && right.get_type().nullable() { - Err(AltError::BothNullable(terms, punct, right)) - } else if !ty + Err(AltError::BothNullable { + left: terms, + punct, + right, + }) + } else if ty .first_set() .intersect(right.get_type().first_set()) .is_empty() { - Err(AltError::FirstOverlap(terms, punct, right)) - } else { let ty = ty.alt(right.get_type().clone()); terms.push(right); Ok((ty, terms)) + } else { + Err(AltError::FirstOverlap { + left: terms, + punct, + right, + }) } }, ) -- cgit v1.2.3