From 31e84bf5b3a44fb0b51f853f135109ea184ace84 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 25 May 2025 11:43:35 +0300 Subject: [PATCH] proc: builtims --- dsl/src/dsl_provide.rs | 59 +++++++++++++++-------------------------- proc/src/proc_expose.rs | 8 ------ proc/src/proc_view.rs | 56 +++++++++++++++++++++++--------------- 3 files changed, 55 insertions(+), 68 deletions(-) diff --git a/dsl/src/dsl_provide.rs b/dsl/src/dsl_provide.rs index d63426e..34dabd6 100644 --- a/dsl/src/dsl_provide.rs +++ b/dsl/src/dsl_provide.rs @@ -1,10 +1,17 @@ use crate::*; -// maybe their names should be switched around? +///// Implement the [Give] trait, which boils down to +///// specifying two types and providing an expression. +#[macro_export] macro_rules! from_dsl { + ($Type:ty: |$state:ident:$State:ty, $words:ident|$expr:expr) => { + take! { $Type|$state:$State,$words|$expr } + }; +} /// [Take]s instances of [Type] given [TokenIter]. pub trait Give<'state, Type> { /// Implement this to be able to [Give] [Type] from the [TokenIter]. + /// Advance the stream if returning `Ok>`. fn give <'source: 'state> (&self, words: TokenIter<'source>) -> Perhaps; /// Return custom error on [None]. fn give_or_fail <'source: 'state, E: Into>, F: Fn()->E> ( @@ -59,6 +66,8 @@ pub trait Give<'state, Type> { } /// [Give]s instances of [Self] given [TokenIter]. pub trait Take<'state, State>: Sized { + /// Implement this to be able to [Take] [Self] from the [TokenIter]. + /// Advance the stream if returning `Ok>`. fn take <'source: 'state> (state: &State, words: TokenIter<'source>) -> Perhaps; /// Return custom error on [None]. fn take_or_fail <'source: 'state, E: Into>, F: Fn()->E> ( @@ -113,40 +122,6 @@ pub trait Take<'state, State>: Sized { }; } -#[cfg(feature="dsl")] -impl<'state, E: 'state, State: Give<'state, Box + 'state>>> -Take<'state, State> for Box + 'state> { - fn take <'source: 'state> (state: &State, words: TokenIter<'source>) -> Perhaps { - state.give(words) - } -} - -/// Implement the [Give] trait, which boils down to -/// specifying two types and providing an expression. -#[macro_export] macro_rules! from_dsl { - (@a: $T:ty: |$state:ident, $words:ident|$expr:expr) => { - impl<'state, State, A: Take<'state, State>> Take<'state, State> for $T { - fn take <'source: 'state> ($state: &State, mut $words:TokenIter<'source>) -> Perhaps<$T> { - $expr - } - } - }; - (@ab: $T:ty: |$state:ident, $words:ident|$expr:expr) => { - impl<'state, State, A: Take<'state, State>, B: Take<'state, State>> Take<'state, State> for $T { - fn take <'source: 'state> ($state: &State, mut $words:TokenIter<'source>) -> Perhaps<$T> { - $expr - } - } - }; - ($T:ty: |$state:ident:$S:ty, $words:ident|$expr:expr) => { - impl<'state> Take<'state, $S> for $T { - fn take <'source: 'state> ($state: &$S, mut $words:TokenIter<'source>) -> Perhaps<$T> { - $expr - } - } - }; -} - // auto impl graveyard: //impl<'state, State: Give, Type: 'state> Take<'state, State> for Type { @@ -157,8 +132,16 @@ Take<'state, State> for Box + 'state> { //} //} -//impl<'state, Type: Take<'state, State>, State> Give for State { - //fn take <'state> (&self, mut words:TokenIter<'source>) -> Perhaps { - //Type::take(self, words) +//#[cfg(feature="dsl")] +//impl<'state, E: 'state, State: Give<'state, Box + 'state>>> +//Take<'state, State> for Box + 'state> { + //fn take <'source: 'state> (state: &State, words: TokenIter<'source>) -> Perhaps { + //state.give(words) //} //} + +impl<'state, Type: Take<'state, State>, State> Give<'state, Type> for State { + fn give <'source: 'state> (&self, words: TokenIter<'source>) -> Perhaps { + Type::take(self, words) + } +} diff --git a/proc/src/proc_expose.rs b/proc/src/proc_expose.rs index 4d0b928..f345e43 100644 --- a/proc/src/proc_expose.rs +++ b/proc/src/proc_expose.rs @@ -84,14 +84,6 @@ impl ToTokens for ExposeImpl { quote! { Some(::tengri::dsl::Value::Sym(#key)) => state.#value(), } }); write_quote_to(out, quote! { - /// Generated by [tengri_proc::expose]. - impl<'n> ::tengri::dsl::Give<'n, #t> for #state { - fn give <'source: 'n> ( - &self, words: ::tengri::dsl::TokenIter<'source> - ) -> Perhaps<#t> { - Take::take(self, words) - } - } /// Generated by [tengri_proc::expose]. impl<'n> ::tengri::dsl::Take<'n, #state> for #t { fn take <'source: 'n> ( diff --git a/proc/src/proc_view.rs b/proc/src/proc_view.rs index f16852f..578bbbf 100644 --- a/proc/src/proc_view.rs +++ b/proc/src/proc_view.rs @@ -43,7 +43,7 @@ impl ToTokens for ViewDef { let self_ty = &block.self_ty; // Expressions are handled by built-in functions // that operate over constants and symbols. - let builtin = builtins_with_types().map(|ty|write_quote(quote! { #ty })); + let builtin = builtins_with_boxes_output(quote! { #output }); // Symbols are handled by user-taked functions // that take no parameters but `&self`. let exposed = exposed.iter().map(|(key, value)|write_quote(quote! { @@ -52,18 +52,18 @@ impl ToTokens for ViewDef { write_quote_to(out, quote! { /// Generated by [tengri_proc]. /// - /// Gives [#self_ty] the ability to construct the [Render]able - /// which might corresponds to a given [TokenStream], + /// Makes [#self_ty] able to construct the [Render]able + /// which might correspond to a given [TokenStream], /// while taking [#self_ty]'s state into consideration. - impl<'state> Give<'state, Box + 'state>> for #self_ty { - fn give <'source: 'state> (&self, mut words: TokenIter<'source>) + impl<'state: 'static> Take<'state, #self_ty> for Box + 'state> { + fn take <'source: 'state> (state: &#self_ty, mut words: TokenIter<'source>) -> Perhaps + 'state>> { - let state = self; + //let state = self; Ok(if let Some(::tengri::dsl::Token { value, .. }) = words.peek() { match value { #(::tengri::dsl::Value::Exp(_, expr) => { - #builtin::take(state, expr)?.map(|value|value.boxed()) + Give::<'state, #builtin>::give(state, expr)?.map(|value|value.boxed()) },)* #( #exposed, @@ -91,21 +91,33 @@ impl ToTokens for ViewDef { } } -fn builtins_with_types () -> impl Iterator { +fn builtins_with_holes () -> impl Iterator { + builtins_with(quote! { _ }, quote! { _ }) +} + +fn builtins_with_boxes () -> impl Iterator { + builtins_with(quote! { _ }, quote! { Box+'state> }) +} + +fn builtins_with_boxes_output (o: TokenStream2) -> impl Iterator { + builtins_with(quote! { _ }, quote! { Box+'state> }) +} + +fn builtins_with (n: TokenStream2, c: TokenStream2) -> impl Iterator { [ - quote! { When::< Box> > }, - quote! { Either::< Box>, Box>> }, - quote! { Align::< Box> > }, - quote! { Bsp::< Box>, Box>> }, - quote! { Fill::< Box> > }, - quote! { Fixed::<_, Box> > }, - quote! { Min::<_, Box> > }, - quote! { Max::<_, Box> > }, - quote! { Shrink::<_, Box> > }, - quote! { Expand::<_, Box> > }, - quote! { Push::<_, Box> > }, - quote! { Pull::<_, Box> > }, - quote! { Margin::<_, Box> > }, - quote! { Padding::<_, Box> > }, + quote! { When::< #c > }, + quote! { Either::< #c, #c> }, + quote! { Align::< #c > }, + quote! { Bsp::< #c, #c> }, + quote! { Fill::< #c > }, + quote! { Fixed::<#n, #c > }, + quote! { Min::<#n, #c > }, + quote! { Max::<#n, #c > }, + quote! { Shrink::<#n, #c > }, + quote! { Expand::<#n, #c > }, + quote! { Push::<#n, #c > }, + quote! { Pull::<#n, #c > }, + quote! { Margin::<#n, #c > }, + quote! { Padding::<#n, #c > }, ].into_iter() }