mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 11:46:42 +01:00
dsl: simplify trait further
This commit is contained in:
parent
ad2d7c38b1
commit
c57117df9c
9 changed files with 395 additions and 312 deletions
70
dsl/src/dsl_expr.rs
Normal file
70
dsl/src/dsl_expr.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use crate::*;
|
||||
|
||||
pub type GetDslExpr<'a, S, T> = for<'b> fn(&'a S, &'b str)->Perhaps<T>;
|
||||
|
||||
pub type DslExprs<'a, S, T> = &'a [(&'a str, GetDslExpr<'a, S, T>)];
|
||||
|
||||
dsl_type!(DslExpr {
|
||||
fn expr (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(expr_peek_inner_only))}
|
||||
fn head (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(peek))}
|
||||
fn tail (&self) -> DslPerhaps<&str> {ok_flat(self.src()?.map(peek_tail))}
|
||||
/// my other car is a cdr :<
|
||||
fn each (&self, mut cb: impl FnMut(&str)->Usually<()>) -> Usually<()> {
|
||||
Ok(if let Some(head) = self.head()? {
|
||||
cb(head)?;
|
||||
if let Some(tail) = self.tail()? {
|
||||
tail.each(cb)?;
|
||||
}
|
||||
})
|
||||
}
|
||||
} {
|
||||
pub const fn expr_peek [generated];
|
||||
pub const fn expr_peek_only [generated];
|
||||
pub const fn expr_seek [generated];
|
||||
pub const fn expr_seek_start (src) {
|
||||
for_each!((i, c) in char_indices(src) =>
|
||||
if is_expr_start(c) { return Ok(Some(i)) } else
|
||||
if !is_space(c) { return Err(Unexpected(c, Some(i), Some("expected expression start"))) });
|
||||
Ok(None)
|
||||
}
|
||||
pub const fn expr_seek_length (src) {
|
||||
let mut depth = 0;
|
||||
for_each!((i, c) in char_indices(src) =>
|
||||
if is_expr_start(c) { depth += 1; } else
|
||||
if is_expr_end(c) {
|
||||
if depth == 0 {
|
||||
return Err(Unexpected(c, Some(i), Some("expected expression end")))
|
||||
} else if depth == 1 {
|
||||
return Ok(Some(i + 1))
|
||||
} else {
|
||||
depth -= 1;
|
||||
}
|
||||
});
|
||||
Err(Incomplete)
|
||||
}
|
||||
});
|
||||
|
||||
#[macro_export] macro_rules!dsl_exprs(($l:lifetime |$state:ident|->$Type:ty$({
|
||||
$($name:literal ($($arg:ident:$ty:ty),* $(,)?) => $body:expr),* $(,)?
|
||||
})?)=>{
|
||||
const EXPRS: DslExprs<$l, Self, $Type> = &[$( $({
|
||||
let get: GetDslExpr<$l, Self, $Type> = |$state: &$l Self, tail_base|{
|
||||
let tail = tail_base;
|
||||
$(
|
||||
let head = tail.head()?.unwrap_or_default();
|
||||
let tail = tail.tail()?.unwrap_or_default();
|
||||
let $arg: $ty = if let Some(arg) = $state.from(&head)? {
|
||||
arg
|
||||
} else {
|
||||
return Err(format!("{}: arg \"{}\" ({}) got: {head} {tail}",
|
||||
$name,
|
||||
stringify!($arg),
|
||||
stringify!($ty),
|
||||
).into())
|
||||
};
|
||||
)*
|
||||
Ok(Some($body as $Type))
|
||||
};
|
||||
($name, get)
|
||||
}),* )? ];
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue