From d7884f6289ac6c7a88f806f4453fb7c246c87f0b Mon Sep 17 00:00:00 2001 From: unspeaker Date: Fri, 15 Aug 2025 21:24:13 +0300 Subject: [PATCH] dsl: some ns progress --- dsl/src/dsl_ns.rs | 96 ++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/dsl/src/dsl_ns.rs b/dsl/src/dsl_ns.rs index a0b2c9c..bb59abf 100644 --- a/dsl/src/dsl_ns.rs +++ b/dsl/src/dsl_ns.rs @@ -1,64 +1,68 @@ use crate::*; +/// Namespace where keys are symbols. +pub trait DslSymNs<'t, T: 't>: 't { + /// Known symbold. + const SYMS: DslNs<'t, fn (&'t Self)->Perhaps> = DslNs(&[]); + /// Resolve a symbol if known. + fn from_sym (&'t self, dsl: D) -> Perhaps { + if let Some(dsl) = dsl.sym()? { + for (sym, get) in Self::SYMS.0 { if dsl == *sym { return get(self) } } + } + return Ok(None) + } +} + /// Define a symbol namespace. #[macro_export] macro_rules! dsl_sym_ns ( - (|$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)),* + (|$state:ident:$State:ty| -> $Type:ty {$($lit:literal => $exp:expr),* $(,)?})=>{ + impl<'t> DslSymNs<'t, $Type> for $State { + const SYMS: DslNs<'t, fn (&'t $State)->Perhaps<$Type>> = DslNs(&[ + $(($lit, |$state: &$State|Ok(Some($exp)))),* ]); } }); -/// Define an expression namespace. -#[macro_export] macro_rules! dsl_exp_ns ( - (|$state:ident:$State:ty|->$type:ty { $( ( - $key:literal - $(/ $sub:ident : $Sub:ty)? - $(, $arg:ident $(?)? : $argtype:ty)* - $(, ..$tail:ident)? - ) => $body:expr),* $(,)? }) => { - impl<'t> DslExpNs<'t, fn (&'t $State, &str)->$type> for $State { - const EXPS: DslNs<'t, fn (&'t $State, &str)->$type> = DslNs(&[ $( - ($key, |$state: &$State, mut tail: &str|{ - $(let $arg = dsl_next(&mut tail)?;)* - $(let $tail = tail;)? - $body - }) - ),* ]); - } - }); - -/// Namespace where keys are symbols. -pub trait DslSymNs<'t, T: 't>: 't { - const SYMS: DslNs<'t, fn (&'t Self)->T> = DslNs(&[]); - fn from_sym (&'t self, dsl: D) -> Perhaps { - if let Some(dsl) = dsl.sym()? { - for (sym, get) in Self::SYMS.0 { - if dsl == *sym { - return Ok(Some(get(self))) - } +/// Namespace where the keys are heads of expressions. +pub trait DslExpNs<'t, T: 't>: 't { + /// Known expressions. + const EXPS: DslNs<'t, fn (&'t Self, &str)->Perhaps> = DslNs(&[]); + /// Resolve an expression if known. + fn from_exp (&'t self, dsl: D) -> Perhaps { + if let Some(exp) = dsl.exp()? { + //panic!("exp\n{:?}\n{:?}\n{:?}\n{:?}", + //exp.src(), exp.head(), exp.head().src(), Self::EXPS.0); + for (key, value) in Self::EXPS.0.iter() { + println!("{key} {:?}", exp.head()); + if exp.head() == Ok(Some(key)) { return value(self, exp.tail()?.unwrap_or("")) } } } return Ok(None) } } -/// Namespace where the keys are heads of expressions. -pub trait DslExpNs<'t, T: 't>: 't { - const EXPS: DslNs<'t, fn (&'t Self, &str)->T> = DslNs(&[]); - fn from_exp (&'t self, dsl: D) -> Perhaps { - if let Some(exp) = dsl.exp()? { - panic!("exp\n{:?}\n{:?}\n{:?}\n{:?}", exp.src(), exp.head(), exp.head().src(), Self::EXPS.0); - for (key, value) in Self::EXPS.0.iter() { - println!("{key} {:?}", exp.head()); - if exp.head() == Ok(Some(key)) { - return Ok(Some(value(self, exp.tail()?.unwrap_or("")))) - } - } +/// Define an expression namespace. +#[macro_export] macro_rules! dsl_exp_ns ( + (|$state:ident:$State:ty|->$Type:ty { $( ( + $key:literal $(/ $sub:ident : $Sub:ty)? $(, $arg:ident:$ty:ty)* $(, ..$tail:ident)? + ) => $body:expr),* $(,)? }) => { + impl<'t> DslExpNs<'t, $Type> for $State { + const EXPS: DslNs<'t, fn (&'t $State, &str)->Perhaps<$Type>> = DslNs(&[ $( + ($key, |$state: &$State, mut tail: &str|{ + $(let $arg: $ty = if let Some(val) = dsl_next(&mut tail)? { + val + } else { + return Err(format!("missing arg: {}", stringify!($arg)).into()) + };)* + $(let $tail = tail;)? + Ok(Some($body)) + }) + ),* ]); } - return Ok(None) - } + }); + +pub fn dsl_next (dsl: &mut impl Dsl) -> DslPerhaps { + todo!() } /// Namespace.