diff --git a/dsl/src/dsl.rs b/dsl/src/dsl.rs index e9d108b..cb2ee5c 100644 --- a/dsl/src/dsl.rs +++ b/dsl/src/dsl.rs @@ -81,7 +81,7 @@ pub const fn peek_tail (src: &str) -> DslPerhaps<&str> { Ok(None) => Ok(None), Ok(Some((start, length))) => { let tail = str_range(src, start + length, src.len()); - for_each!((i, c) in char_indices(tail) => if !is_space(c) { return Ok(Some(tail)) }); + for_each!((_i, c) in char_indices(tail) => if !is_space(c) { return Ok(Some(tail)) }); Ok(None) }, } diff --git a/dsl/src/dsl_conv.rs b/dsl/src/dsl_conv.rs index ae214dd..033e6eb 100644 --- a/dsl/src/dsl_conv.rs +++ b/dsl/src/dsl_conv.rs @@ -1,5 +1,43 @@ use crate::*; +/// Namespace. Currently linearly searched. +pub struct DslNs<'t, T: 't>(pub &'t [(&'t str, T)]); + +/// Namespace where keys are symbols. +pub trait DslSymNs<'t, T: 't>: 't { + const SYMS: DslNs<'t, fn (&'t Self)->T>; + fn from_sym (&'t self, dsl: D) -> Usually { + if let Some(dsl) = dsl.sym()? { + for (sym, get) in Self::SYMS.0 { + if dsl == *sym { + return Ok(get(self)) + } + } + } + return Err(format!("not found: sym: {dsl:?}").into()) + } +} + +#[macro_export] macro_rules! dsl_sym ( + (|$state:ident:$State:ty| -> $type:ty {$($lit:literal => $exp:expr),* $(,)?})=>{ + impl<'t> DslSymNs<'t, $type> for $State { + const SYMS: DslNs<'t, fn (&'t $State)->$type> = + DslNs(&[$(($lit, |$state: &$State|$exp)),*]); } }); + +pub trait DslExpNs<'t, T: 't>: 't { + const EXPS: DslNs<'t, fn (&'t Self, &str)->T>; +} + +#[macro_export] macro_rules! dsl_exp ( + (|$state:ident:$State:ty|->$type:ty { $( + [$key:literal $(/ $sub:ident: $Sub:ty)? $(, $arg:ident $(?)? :$argtype:ty)*] => $body:expr + ),* $(,)? }) => { + impl<'t> DslExpNs<'t, $type> for $State { + const EXPS: DslNs<'t, fn (&'t $State, &str)->$type> = + DslNs(&[]); } }); + +// TODO DEPRECATE: + /// `T` + [Dsl] -> `Self`. pub trait FromDsl: Sized { fn from_dsl (state: &T, dsl: &impl Dsl) -> Perhaps;