dsl: give! and take! macros
Some checks are pending
/ build (push) Waiting to run

This commit is contained in:
🪞👃🪞 2025-05-24 00:29:50 +03:00
parent cbd28a5934
commit 5a2177cc77
4 changed files with 131 additions and 94 deletions

View file

@ -17,13 +17,6 @@ pub trait Give<Type> {
}
}
}
impl<'n, T: Take<'n, U>, U> Give<T> for U {
fn give <'source> (&self, words: &mut TokenIter<'source>) -> Perhaps<T> {
T::take(self, words)
}
}
/// [Give]s instances of [Self] given [TokenIter].
pub trait Take<'n, State>: Sized + 'n {
fn take <'source> (state: &State, words: &mut TokenIter<'source>) -> Perhaps<Self>;
@ -39,6 +32,68 @@ pub trait Take<'n, State>: Sized + 'n {
}
}
#[macro_export] macro_rules! take {
() => {
impl<'n, Type: 'n, State: Give<Type> + 'n> Take<'n, State> for Type {
fn take <'source> (state: &State, words: &mut TokenIter<'source>) -> Perhaps<Self> {
state.give(words)
}
}
};
(box) => {
impl<'n, T, State: Give<Box<T>> + 'n> Take<'n, State> for Box<T> {
fn take <'source> (state: &State, words: &mut TokenIter<'source>) -> Perhaps<Self> {
state.give(words)
}
}
};
($Type:ty:$State:ty) => {
impl<'n> Take<'n, $State> for $Type {
fn take <'source> (state: &$State, words: &mut TokenIter<'source>) -> Perhaps<Self> {
state.give(words)
}
}
};
($Type:path$(,$Arg:ident)*|$state:ident:$State:path,$words:ident|$expr:expr) => {
impl<'n, State: $State + 'n $(, $Arg: 'n)*> Take<'n, State> for $Type {
fn take <'source> ($state: &State, $words: &mut TokenIter<'source>) -> Perhaps<Self> {
$expr
}
}
};
}
#[macro_export] macro_rules! give {
() => {
impl<'n, Type: Take<'n, State>, State> Give<Type> for State {
fn give <'source> (&self, words: &mut TokenIter<'source>) -> Perhaps<Type> {
Type::take(self, words)
}
}
};
(box) => {
//impl<'n, T, Type: Take<'n, Box<T>>> Give<Box<T>> for Box<Type> {
//fn give <'source> (&self, words: &mut TokenIter<'source>) -> Perhaps<Box<Type>> {
//Type::take(self, words)
//}
//}
};
($Type:ty: $State:ty) => {
impl<'n, $Type: Take<'n, $State>> Give<$Type> for $State {
fn give <'source> (&self, words: &mut TokenIter<'source>) -> Perhaps<$Type> {
$Type::take(self, words)
}
}
};
($Type:ty|$state:ident:$State:ident,$words:ident|$expr:expr) => {
impl Give<$Type> for $State {
fn give <'source> (&self, $words: &mut TokenIter<'source>) -> Perhaps<$Type> {
let $state = self;
$expr
}
}
};
}
/// Implement the [Give] trait, which boils down to
/// specifying two types and providing an expression.
#[macro_export] macro_rules! from_dsl {