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/chomp | |
parent | faa3f30deb32d0a1fd7cb196559762635b22ecfd (diff) |
Fix many warnings.
Diffstat (limited to 'src/chomp')
-rw-r--r-- | src/chomp/ast/error.rs | 12 | ||||
-rw-r--r-- | src/chomp/ast/substitute.rs | 14 | ||||
-rw-r--r-- | src/chomp/typed/context.rs | 35 | ||||
-rw-r--r-- | src/chomp/typed/error.rs | 96 | ||||
-rw-r--r-- | src/chomp/typed/infer.rs | 37 | ||||
-rw-r--r-- | src/chomp/typed/mod.rs | 30 |
6 files changed, 120 insertions, 104 deletions
diff --git a/src/chomp/ast/error.rs b/src/chomp/ast/error.rs index 12d7b90..9e4282b 100644 --- a/src/chomp/ast/error.rs +++ b/src/chomp/ast/error.rs @@ -27,8 +27,8 @@ impl From<SubstituteError> for syn::Error { fn from(e: SubstituteError) -> Self { let msg = e.to_string(); let span = match e { - SubstituteError::FreeParameter { span, .. } => span, - SubstituteError::WrongArgCount { span, .. } => span, + SubstituteError::FreeParameter { span, .. } + | SubstituteError::WrongArgCount { span, .. } => span, }; Self::new(span.unwrap_or_else(Span::call_site), msg) @@ -38,18 +38,14 @@ impl From<SubstituteError> for syn::Error { impl Display for SubstituteError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::FreeParameter { param, span, name } => { + Self::FreeParameter { param, name, .. } => { if let Some(name) = name { write!(f, "unbound parameter: `{}`", name) } else { write!(f, "unbound parameter: '{}", param.index) } } - Self::WrongArgCount { - call, - expected, - span, - } => { + Self::WrongArgCount { call, expected, .. } => { if call.args.len() == 1 { write!( f, diff --git a/src/chomp/ast/substitute.rs b/src/chomp/ast/substitute.rs index 1a622e1..c7cc03f 100644 --- a/src/chomp/ast/substitute.rs +++ b/src/chomp/ast/substitute.rs @@ -418,13 +418,7 @@ impl Folder for InlineCalls { expr: call.into(), span, }) - } else if call.args.len() != self.function.params.len() { - Err(SubstituteError::WrongArgCount { - call, - expected: self.function.params.len(), - span, - }) - } else { + } else if call.args.len() == self.function.params.len() { let mut expr = self .function .expr @@ -434,6 +428,12 @@ impl Folder for InlineCalls { expr.span = expr.span.or(span); Ok(expr) + } else { + Err(SubstituteError::WrongArgCount { + call, + expected: self.function.params.len(), + span, + }) } } } 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<bool> { - 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<F: FnOnce(&mut Self) -> 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<F: FnOnce(&mut Self) -> 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<Name>, } -impl PartialEq for VariableError { - fn eq(&self, other: &Self) -> bool { - todo!() - } -} - -impl Eq for VariableError {} - impl From<VariableError> 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<Span>), - /// The flast set of the first term intersects the first set of the second. - FirstFlastOverlap(Vec<TypedExpression>, Option<Span>, TypedExpression), + FirstNullable { + expr: TypedExpression, + punct: Option<Span>, + }, + FirstFlastOverlap { + first: Vec<TypedExpression>, + punct: Option<Span>, + next: TypedExpression, + }, } -impl PartialEq for CatError { - fn eq(&self, other: &Self) -> bool { - todo!() - } -} - -impl Eq for CatError {} - impl From<CatError> 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<TypedExpression>, Option<Span>, TypedExpression), - /// The first sets of the two terms intersect. - FirstOverlap(Vec<TypedExpression>, Option<Span>, TypedExpression), -} - -impl PartialEq for AltError { - fn eq(&self, other: &Self) -> bool { - todo!() - } + BothNullable { + left: Vec<TypedExpression>, + punct: Option<Span>, + right: TypedExpression, + }, + FirstOverlap { + left: Vec<TypedExpression>, + punct: Option<Span>, + right: TypedExpression, + }, } -impl Eq for AltError {} - impl From<AltError> 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<Name>, span: Option<Span>, 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::<Result<Vec<_>, _>>()?; let punct = alt.punct; - self.context - .with_unguard(|context| -> Result<TypedExpression, TypeError> { - 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::<Result<Vec<_>, _>>()?; - 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<Name>, span: Option<Span>, fix: Fix) -> Self::Out { @@ -111,7 +104,7 @@ impl Folder for TypeInfer<'_> { span: Option<Span>, 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<Span>, _param: Parameter, ) -> Self::Out { - todo!() + unimplemented!() } - fn fold_call(&mut self, _name: Option<Name>,_span: Option<Span>, _call: Call) -> Self::Out { - todo!() + fn fold_call(&mut self, _name: Option<Name>, _span: Option<Span>, _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<Self, CatError> { 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, + }) } }, ) |