fix(input): sorting out event map

This commit is contained in:
🪞👃🪞 2025-07-19 19:53:02 +03:00
parent 238ac2e888
commit d72a3b5b8f
5 changed files with 155 additions and 316 deletions

View file

@ -18,7 +18,7 @@ pub(crate) use self::DslError::*;
#[macro_export] macro_rules! dsl_read_advance (($exp:ident, $pat:pat => $val:expr)=>{{
let (head, tail) = $exp.advance(); $exp = tail; match head {
Some($pat) => $val, _ => Err(format!("(e4) unexpected {head:?}").into()) }}});
Some($pat) => Ok($val), _ => Err(format!("(e4) unexpected {head:?}").into()) }}});
/// Coerce to [Val] for predefined [Self::Str] and [Self::Exp].
pub trait Dsl: Clone + Debug {
@ -28,49 +28,41 @@ pub trait Dsl: Clone + Debug {
type Exp: DslExp;
/// Request the top-level DSL [Val]ue.
/// May perform cloning or parsing.
fn val (&self) -> Val<Self::Str, Self::Exp>;
fn err (&self) -> Option<DslError> {self.val().err()}
fn nil (&self) -> bool {self.val().nil()}
fn num (&self) -> Option<usize> {self.val().num()}
fn sym (&self) -> Option<Self::Str> {self.val().sym()}
fn key (&self) -> Option<Self::Str> {self.val().key()}
fn str (&self) -> Option<Self::Str> {self.val().str()}
fn exp (&self) -> Option<Self::Exp> {self.val().exp()}
fn exp_depth (&self) -> Option<isize> {self.val().exp_depth()}
fn exp_head (&self) -> Val<Self::Str, Self::Exp> {self.val().exp_head()}
fn exp_tail (&self) -> Self::Exp {self.val().exp_tail()}
fn exp_each (&self, f: impl Fn(&Self) -> Usually<()>) -> Usually<()> {
todo!()
}
fn advance (&self) -> (Val<Self::Str, Self::Exp>, Self::Exp) {
(self.exp_head(), self.exp_tail())
}
fn val (&self) -> Val<Self::Str, Self::Exp>;
fn err (&self) -> Option<DslError> {self.val().err()}
fn nil (&self) -> bool {self.val().nil()}
fn num (&self) -> Option<usize> {self.val().num()}
fn sym (&self) -> Option<Self::Str> {self.val().sym()}
fn key (&self) -> Option<Self::Str> {self.val().key()}
fn str (&self) -> Option<Self::Str> {self.val().str()}
fn exp (&self) -> Option<Self::Exp> {self.val().exp()}
fn depth (&self) -> Option<isize> {self.val().depth()}
fn head (&self) -> Val<Self::Str, Self::Exp> {self.val().head()}
fn tail (&self) -> Self::Exp {self.val().tail()}
fn advance (&self) -> (Val<Self::Str, Self::Exp>, Self::Exp) { (self.head(), self.tail()) }
fn each (&self, f: impl Fn(&Self) -> Usually<()>) -> Usually<()> { todo!() }
fn exp_next (&mut self) -> Option<Val<Self::Str, Self::Exp>> { todo!() }
}
impl<'s> Dsl for &'s str {
type Str = &'s str;
type Exp = &'s str;
fn val (&self) -> Val<Self::Str, Self::Exp> { Val::Exp(0, self) }
}
impl<'s> Dsl for Cst<'s> {
type Str = &'s str;
type Exp = Cst<'s>;
fn val (&self) -> Val<Self::Str, Self::Exp> { Val::Exp(0, *self) }
}
impl Dsl for Ast {
type Str = Arc<str>;
type Exp = Ast;
fn val (&self) -> Val<Self::Str, Ast> { Val::Exp(0, self.clone()) }
}
impl<Str: DslStr, Exp: DslExp> Dsl for Token<Str, Exp> {
type Str = Str;
type Exp = Exp;
fn val (&self) -> Val<Str, Exp> { self.value.clone() }
}
impl<Str: DslStr, Exp: DslExp> Dsl for Val<Str, Exp> {
type Str = Str;
type Exp = Exp;
@ -134,7 +126,7 @@ impl<Str: DslStr, Exp: DslExp + Dsl<Str=Str>> Val<Str, Exp> {
pub const fn key (&self) -> Option<&Str> {match self{Val::Key(k)=>Some(k), _=>None}}
pub const fn str (&self) -> Option<&Str> {match self{Val::Str(s)=>Some(s), _=>None}}
pub const fn exp (&self) -> Option<&Exp> {match self{Val::Exp(_, x)=>Some(x),_=>None}}
pub const fn exp_depth (&self) -> Option<isize> {match self{Val::Exp(d, _)=>Some(*d), _=>None}}
pub const fn depth (&self) -> Option<isize> {match self{Val::Exp(d, _)=>Some(*d), _=>None}}
}
/// Parsed substring with range and value.
#[derive(Debug, Clone, Default, PartialEq)]
@ -363,10 +355,10 @@ pub const fn peek <'s> (mut value: CstVal<'s>, source: &'s str) -> CstToken<'s>
}
start = i;
length = 1;
value = if is_exp_start(c) { Exp(1, str_range(source, i, i+1)) }
else if is_str_start(c) { Str(str_range(source, i, i+1)) }
else if is_sym_start(c) { Sym(str_range(source, i, i+1)) }
else if is_key_start(c) { Key(str_range(source, i, i+1)) }
value = if is_exp_start(c) { Exp(1, str_range(source, i, i+1)) }
else if is_str_start(c) { Str(str_range(source, i, i+1)) }
else if is_sym_start(c) { Sym(str_range(source, i, i+1)) }
else if is_key_start(c) { Key(str_range(source, i, i+1)) }
else if is_digit(c) { match to_digit(c) { Ok(c) => Num(c), Err(e) => Error(e) } }
else { value = Error(Unexpected(c)); break }
} else if matches!(value, Str(_)) {
@ -451,33 +443,6 @@ pub const fn to_digit (c: char) -> Result<usize, DslError> {
})
}
/// Implement type conversions.
macro_rules! from(($($Struct:ty { $(
$(<$($l:lifetime),* $($T:ident$(:$U:ident)?),*>)? ($source:ident: $From:ty) $expr:expr
);+ $(;)? })*) => { $(
$(impl $(<$($l),* $($T$(:$U)?),*>)? From<$From> for $Struct {
fn from ($source: $From) -> Self { $expr }
})+
)* });
//from! {
////Vec<Token<'s>> { <'s> (val: CstIter<'s>) val.collect(); }
//CstConstIter<'s> {
//<'s> (src: &'s str) Self(src);
//<'s> (iter: CstIter<'s>) iter.0; }
//CstIter<'s> {
//<'s> (src: &'s str) Self(CstConstIter(src));
//<'s> (iter: CstConstIter<'s>) Self(iter); }
//Cst<'s> { <'s> (src: &'s str) Self(CstIter(CstConstIter(src))); }
//Vec<Ast> { <'s> (val: CstIter<'s>) val.map(Into::into).collect(); }
//Token<Cst<'s>> { <'s> (token: Token<Cst<'s>>) Self { value: token.value.into(), span: token.span.into() } }
//Ast {
//<'s> (src: &'s str) Ast::from(CstIter(CstConstIter(src)));
//<'s> (cst: Cst<'s>) Ast(VecDeque::from([dsl_val(cst.val())]).into());
//<'s> (iter: CstIter<'s>) Ast(iter.map(|x|x.value.into()).collect::<VecDeque<_>>().into());
//<D: Dsl> (token: Token<D>) Ast(VecDeque::from([dsl_val(token.val())]).into()); }
//}
/// `T` + [Dsl] -> `Self`.
pub trait FromDsl<T>: Sized {
fn from_dsl (state: &T, dsl: &impl Dsl) -> Perhaps<Self>;
@ -489,19 +454,19 @@ pub trait FromDsl<T>: Sized {
}
}
impl<T: FromDsl<U>, U> DslInto<T> for U {
impl<'s, T: FromDsl<U>, U> DslInto<'s, T> for U {
fn dsl_into (&self, dsl: &impl Dsl) -> Perhaps<T> {
T::from_dsl(self, dsl)
}
}
/// `self` + [Dsl] -> `T`
pub trait DslInto<T> {
fn dsl_into (&self, dsl: &impl Dsl) -> Perhaps<T>;
fn dsl_into_or (&self, dsl: &impl Dsl, err: Box<dyn Error>) -> Usually<T> {
pub trait DslInto<'s, T> {
fn dsl_into (&'s self, dsl: &impl Dsl) -> Perhaps<T>;
fn dsl_into_or (&'s self, dsl: &impl Dsl, err: Box<dyn Error>) -> Usually<T> {
self.dsl_into(dsl)?.ok_or(err)
}
fn dsl_into_or_else (&self, dsl: &impl Dsl, err: impl Fn()->Box<dyn Error>) -> Usually<T> {
fn dsl_into_or_else (&'s self, dsl: &impl Dsl, err: impl Fn()->Box<dyn Error>) -> Usually<T> {
self.dsl_into(dsl)?.ok_or_else(err)
}
}