From e68b9ec9889b0c5af5e442310d274da0f087a263 Mon Sep 17 00:00:00 2001 From: Will Sturgeon Date: Fri, 3 Nov 2023 13:44:56 -0400 Subject: [PATCH 1/2] Implement `fmt::Display` for `IllFormed<..>` --- automata/src/action.rs | 10 ++++++ automata/src/check.rs | 78 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/automata/src/action.rs b/automata/src/action.rs index 46d1552..9052643 100644 --- a/automata/src/action.rs +++ b/automata/src/action.rs @@ -70,4 +70,14 @@ impl Action { } Some(()) } + + /// Write this as a verb in natural language. + #[inline] + pub fn in_english(&self) -> String { + match *self { + Self::Local => "do nothing to".to_owned(), + Self::Push(ref s) => format!("push `{}` onto", s.to_src()), + Self::Pop => "pop from".to_owned(), + } + } } diff --git a/automata/src/check.rs b/automata/src/check.rs index 6c4b708..a32c2f5 100644 --- a/automata/src/check.rs +++ b/automata/src/check.rs @@ -7,9 +7,10 @@ //! Check well-formedness. use crate::{ - Action, Ctrl, CurryInput, CurryStack, Input, Range, RangeMap, Stack, State, Transition, Update, + Action, Ctrl, CurryInput, CurryStack, Input, Range, RangeMap, Stack, State, ToSrc, Transition, + Update, }; -use core::{mem, num::NonZeroUsize}; +use core::{fmt, mem, num::NonZeroUsize}; use std::collections::BTreeSet; /// Maximum size we're willing to tolerate in an `Err` variant (for performance reasons). @@ -92,6 +93,79 @@ impl IllFormed { } } +impl> fmt::Display for IllFormed { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + Self::OutOfBounds(i) => write!(f, "State index out of bounds: {i}"), + Self::ProlongingDeath => write!( + f, + "Transition to a state that will never accept. \ + Try removing the state along with any transitions to it.", + ), + Self::InvertedRange(ref a, ref b) => { + write!( + f, + "Range with endpoints flipped: {:?}..={:?}", + a.to_src(), + b.to_src(), + ) + } + Self::RangeMapOverlap(ref r) => { + write!(f, "Multiple ranges would accept {}", r.to_src()) + } + Self::WildcardMask { + ref arg_stack, + ref arg_token, + ref possibility_1, + ref possibility_2, + } => { + write!( + f, + "When the stack top is {} and the token is {}, \ + a wildcard match succeeds ({}), \ + but so does a specific match ({}).", + arg_stack.to_src(), + arg_token.to_src(), + possibility_1.to_src(), + possibility_2.to_src(), + ) + } + Self::Superposition(a, b) => write!( + f, + "Tried to visit two different deterministic states \ + ({a} and {b}) at the same time.", + ), + Self::IncompatibleStackActions(ref a, ref b) => { + write!( + f, + "Can't {} and {} the stack at the same time.", + a.in_english(), + b.in_english(), + ) + } + Self::IncompatibleCallbacks(ref a, ref b) => { + write!( + f, + "Tried to call both `{}` and `{}` at the same time.", + a.src, b.src, + ) + } + Self::DuplicateState(ref s) => write!(f, "Duplicate state: {}", s.to_src()), + Self::TagDNE(ref tag) => write!( + f, + "Requested a transition to a tag that does not exist: \"{tag}\"", + ), + Self::InitialNotUnit(ref s) => write!( + f, + "Initial state needs to take a unit-type input (`()`) but takes `{s}` instead.", + ), + Self::TypeMismatch(ref a, ref b) => write!(f, "Type mismatch: `{a}` =/= `{b}`."), + Self::WrongReturnType(ref a, ref b) => write!(f, "Wrong output type: `{a}` =/= `{b}`"), + } + } +} + /// Check well-formedness. pub trait Check> { /// Check well-formedness. From fa5035025d39eafbfd764c5127cdb146b289b559 Mon Sep 17 00:00:00 2001 From: Will Sturgeon Date: Fri, 3 Nov 2023 13:52:20 -0400 Subject: [PATCH 2/2] Typo --- automata/src/check.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automata/src/check.rs b/automata/src/check.rs index a32c2f5..fb6ac38 100644 --- a/automata/src/check.rs +++ b/automata/src/check.rs @@ -106,7 +106,7 @@ impl> fmt::Display for IllFormed { Self::InvertedRange(ref a, ref b) => { write!( f, - "Range with endpoints flipped: {:?}..={:?}", + "Range with endpoints flipped: {}..={}", a.to_src(), b.to_src(), )