From f77139c8fdda9dcff048ed2613db74ac3156c154 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Mon, 26 May 2025 23:21:38 +0300 Subject: [PATCH] wip: wee --- dsl/src/dsl_ast.rs | 24 ++++++++--------- dsl/src/dsl_cst.rs | 10 +++----- dsl/src/dsl_display.rs | 13 ++-------- dsl/src/dsl_iter.rs | 58 +++++++++++++++++++++++++++--------------- dsl/src/dsl_token.rs | 22 ++++++++++------ 5 files changed, 68 insertions(+), 59 deletions(-) diff --git a/dsl/src/dsl_ast.rs b/dsl/src/dsl_ast.rs index 010d3f6..0936cde 100644 --- a/dsl/src/dsl_ast.rs +++ b/dsl/src/dsl_ast.rs @@ -3,12 +3,13 @@ use std::sync::Arc; use std::borrow::Cow; /// Owns its values, and has no metadata. -pub type AstToken = Token; +#[derive(PartialEq, Clone, Default, Debug)] +pub struct AstToken(pub AstValue, pub AstMeta); #[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct AstMeta; -pub type AstValue = Value, AstExp>; +pub type AstValue = Value, Vec>; impl<'source> From> for AstValue { fn from (value: CstValue<'source>) -> Self { use Value::*; @@ -19,18 +20,15 @@ impl<'source> From> for AstValue { Sym(s) => Sym(s.into()), Key(s) => Key(s.into()), Str(s) => Str(s.into()), - Exp(x) => Exp(x.into()), + Exp(d, x) => Exp(d, x.into()), } } } -#[derive(Clone, Default, PartialEq)] -pub struct AstExp(pub Vec); -impl<'source> From> for AstExp { - fn from (exp: CstExp<'source>) -> AstExp { - AstExp(exp.words.map(|token|Token( - AstValue::from(token.value()), - AstMeta, - )).collect()) - } -} +pub trait AstIter: DslIter {} + +//impl<'source> From> for AstExp { + //fn from (exp: CstExp<'source>) -> AstExp { + //AstExp(exp.words.map(|token|Token(AstValue::from(token.value()), AstMeta,)).collect()) + //} +//} diff --git a/dsl/src/dsl_cst.rs b/dsl/src/dsl_cst.rs index 61b9352..1c896b5 100644 --- a/dsl/src/dsl_cst.rs +++ b/dsl/src/dsl_cst.rs @@ -1,7 +1,8 @@ use crate::*; /// Keeps the reference to the source slice. -pub type CstToken<'source> = Token, CstMeta<'source>>; +#[derive(Debug, Copy, Clone, Default, PartialEq)] +pub struct CstToken<'source>(pub CstValue<'source>, pub CstMeta<'source>); #[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct CstMeta<'source> { pub source: &'source str, @@ -9,9 +10,4 @@ pub type CstToken<'source> = Token, CstMeta<'source>>; pub length: usize, } -pub type CstValue<'source> = Value<&'source str, CstExp<'source>>; - -#[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct CstExp<'source> { - pub depth: usize, - pub words: SourceIter<'source> -} +pub type CstValue<'source> = Value<&'source str, SourceIter<'source>>; diff --git a/dsl/src/dsl_display.rs b/dsl/src/dsl_display.rs index a986664..8a10193 100644 --- a/dsl/src/dsl_display.rs +++ b/dsl/src/dsl_display.rs @@ -1,7 +1,5 @@ use crate::*; - use std::fmt::{Debug, Display, Formatter, Error as FormatError}; - impl Display for AstValue { fn fmt (&self, out: &mut Formatter) -> Result<(), FormatError> { use Value::*; @@ -12,17 +10,10 @@ impl Display for AstValue { Sym(s) => format!("{s}"), Key(s) => format!("{s}"), Str(s) => format!("{s}"), - Exp(e) => format!("{e:?}"), + Exp(_, e) => format!("{e:?}"), }) } } - -impl Debug for AstExp { - fn fmt (&self, out: &mut Formatter) -> Result<(), FormatError> { - todo!() - } -} - impl<'source> Display for CstValue<'source> { fn fmt (&self, out: &mut Formatter) -> Result<(), FormatError> { use Value::*; @@ -33,7 +24,7 @@ impl<'source> Display for CstValue<'source> { Sym(s) => format!("{s}"), Key(s) => format!("{s}"), Str(s) => format!("{s}"), - Exp(e) => format!("{e:?}"), + Exp(_, e) => format!("{e:?}"), }) } } diff --git a/dsl/src/dsl_iter.rs b/dsl/src/dsl_iter.rs index 9b5cc24..6b12682 100644 --- a/dsl/src/dsl_iter.rs +++ b/dsl/src/dsl_iter.rs @@ -13,30 +13,48 @@ pub trait DslIter { /// [Cst::next] returns just the [CstToken] and mutates `self`, /// instead of returning an updated version of the struct as [SourceConstIter::next] does. #[derive(Copy, Clone, Debug, Default, PartialEq)] -pub struct SourceIter<'a>(pub SourceConstIter<'a>); +pub struct SourceIter<'source>(pub SourceConstIter<'source>); -impl<'a> SourceIter<'a> { - pub const fn new (source: &'a str) -> Self { +impl<'source> SourceIter<'source> { + pub const fn new (source: &'source str) -> Self { Self(SourceConstIter::new(source)) } - pub const fn peek (&self) -> Option> { + pub const fn peek (&self) -> Option> { self.0.peek() } } -impl<'a> Iterator for SourceIter<'a> { - type Item = CstToken<'a>; - fn next (&mut self) -> Option> { +impl<'source> Iterator for SourceIter<'source> { + type Item = CstToken<'source>; + fn next (&mut self) -> Option> { self.0.next().map(|(item, rest)|{self.0 = rest; item}) } } -impl<'a> From<&'a str> for SourceIter<'a> { - fn from (source: &'a str) -> Self{ +impl<'source> From<&'source str> for SourceIter<'source> { + fn from (source: &'source str) -> Self{ Self(SourceConstIter(source)) } } +impl<'source> Into>> for SourceIter<'source> { + fn into (self) -> Vec> { + self.collect() + } +} + +impl<'source> Into> for SourceIter<'source> { + fn into (self) -> Vec { + self.map(Into::into).collect() + } +} + +impl<'source> From> for AstToken { + fn from (value: CstToken<'source>) -> Self { + Self(value.0.into(), AstMeta) + } +} + /// Implement the const iterator pattern. #[macro_export] macro_rules! const_iter { ($(<$l:lifetime>)?|$self:ident: $Struct:ty| => $Item:ty => $expr:expr) => { @@ -58,34 +76,34 @@ impl<'a> From<&'a str> for SourceIter<'a> { /// * the source text remaining /// * [ ] TODO: maybe [SourceConstIter::next] should wrap the remaining source in `Self` ? #[derive(Copy, Clone, Debug, Default, PartialEq)] -pub struct SourceConstIter<'a>(pub &'a str); +pub struct SourceConstIter<'source>(pub &'source str); -impl<'a> From> for SourceIter<'a> { - fn from (source: SourceConstIter<'a>) -> Self{ +impl<'source> From> for SourceIter<'source> { + fn from (source: SourceConstIter<'source>) -> Self{ Self(source) } } -impl<'a> From<&'a str> for SourceConstIter<'a> { - fn from (source: &'a str) -> Self{ +impl<'source> From<&'source str> for SourceConstIter<'source> { + fn from (source: &'source str) -> Self{ Self::new(source) } } -impl<'a> SourceConstIter<'a> { - pub const fn new (source: &'a str) -> Self { +impl<'source> SourceConstIter<'source> { + pub const fn new (source: &'source str) -> Self { Self(source) } pub const fn chomp (&self, index: usize) -> Self { Self(split_at(self.0, index).1) } - pub const fn next (mut self) -> Option<(CstToken<'a>, Self)> { + pub const fn next (mut self) -> Option<(CstToken<'source>, Self)> { Self::next_mut(&mut self) } - pub const fn peek (&self) -> Option> { + pub const fn peek (&self) -> Option> { peek_src(self.0) } - pub const fn next_mut (&mut self) -> Option<(CstToken<'a>, Self)> { + pub const fn next_mut (&mut self) -> Option<(CstToken<'source>, Self)> { match self.peek() { Some(token) => Some((token, self.chomp(token.end()))), None => None @@ -93,4 +111,4 @@ impl<'a> SourceConstIter<'a> { } } -const_iter!(<'a>|self: SourceConstIter<'a>| => CstToken<'a> => self.next_mut().map(|(result, _)|result)); +const_iter!(<'source>|self: SourceConstIter<'source>| => CstToken<'source> => self.next_mut().map(|(result, _)|result)); diff --git a/dsl/src/dsl_token.rs b/dsl/src/dsl_token.rs index 6a132a9..71d1997 100644 --- a/dsl/src/dsl_token.rs +++ b/dsl/src/dsl_token.rs @@ -5,9 +5,14 @@ pub enum Value< S: PartialEq + Clone + Default + Debug, X: PartialEq + Clone + Default + Debug, > { - #[default] Nil, Err(DslError), Num(usize), Sym(S), Key(S), Str(S), Exp(X), + #[default] Nil, Err(DslError), Num(usize), Sym(S), Key(S), Str(S), Exp(usize, X), } +impl< + S: Copy + PartialEq + Clone + Default + Debug, + X: Copy + PartialEq + Clone + Default + Debug, +> Copy for Value {} + pub trait DslValue: PartialEq + Clone + Default + Debug { type Err: PartialEq + Clone + Debug; type Num: PartialEq + Copy + Clone + Default + Debug; @@ -20,8 +25,9 @@ pub trait DslValue: PartialEq + Clone + Default + Debug { fn key (&self) -> Option<&Self::Str>; fn str (&self) -> Option<&Self::Str>; fn exp (&self) -> Option<&Self::Exp>; - fn exp_head (&self) -> Option<&Self> { None } // TODO - fn exp_tail (&self) -> Option<&[Self]> { None } // TODO + fn exp_depth (&self) -> Option { None } // TODO + fn exp_head (&self) -> Option<&Self> { None } // TODO + fn exp_tail (&self) -> Option<&[Self]> { None } // TODO } impl< @@ -51,7 +57,7 @@ impl< if let Self::Str(s) = self { Some(s) } else { None } } fn exp (&self) -> Option<&Exp> { - if let Self::Exp(x) = self { Some(x) } else { None } + if let Self::Exp(_, x) = self { Some(x) } else { None } } } @@ -136,14 +142,14 @@ impl<'source> CstToken<'source> { use Value::*; let token = self.grow(); if let Exp(depth, _) = token.value() { - token.with_value(Exp(depth, Cst::new(token.slice_source_exp(self.source)))) + token.with_value(Exp(depth, SourceIter::new(token.slice_source_exp(self.1.source)))) } else { unreachable!() } } pub const fn grow_in (self) -> Self { let token = self.grow_exp(); - if let Value::Exp(depth, source) = token.value { + if let Value::Exp(depth, source) = token.value() { token.with_value(Value::Exp(depth.saturating_add(1), source)) } else { unreachable!() @@ -151,7 +157,7 @@ impl<'source> CstToken<'source> { } pub const fn grow_out (self) -> Self { let token = self.grow_exp(); - if let Value::Exp(depth, source) = token.value { + if let Value::Exp(depth, source) = token.value() { if depth > 0 { token.with_value(Value::Exp(depth - 1, source)) } else { @@ -200,7 +206,7 @@ pub const fn peek_src <'a> (source: &'a str) -> Option> { ' '|'\n'|'\r'|'\t' => token.grow(), '(' => - CstToken::new(source, start, 1, Exp(1, Cst::new(str_range(source, start, start + 1)))), + CstToken::new(source, start, 1, Exp(1, SourceIter::new(str_range(source, start, start + 1)))), '"' => CstToken::new(source, start, 1, Str(str_range(source, start, start + 1))), ':'|'@' =>