mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 03:36:42 +01:00
core, input: add flex_trait
This commit is contained in:
parent
360b404b69
commit
8cbd7dd8e8
7 changed files with 201 additions and 98 deletions
|
|
@ -1,5 +1,6 @@
|
|||
//#![feature(adt_const_params)]
|
||||
//#![feature(type_alias_impl_trait)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(impl_trait_in_fn_trait_return)]
|
||||
#![feature(const_precise_live_drops)]
|
||||
extern crate const_panic;
|
||||
|
|
@ -31,10 +32,6 @@ impl Dsl for std::sync::Arc<str> {
|
|||
fn src (&self) -> &str { self.as_ref() }
|
||||
}
|
||||
|
||||
impl<D: Dsl> Dsl for Option<D> {
|
||||
fn src (&self) -> &str { if let Some(dsl) = self { dsl.src() } else { "" } }
|
||||
}
|
||||
|
||||
impl<D: Dsl> Dsl for &D {
|
||||
fn src (&self) -> &str { (*self).src() }
|
||||
}
|
||||
|
|
@ -43,6 +40,14 @@ impl<D: Dsl> Dsl for &mut D {
|
|||
fn src (&self) -> &str { (**self).src() }
|
||||
}
|
||||
|
||||
impl<D: Dsl> Dsl for std::sync::Arc<D> {
|
||||
fn src (&self) -> &str { (*self).src() }
|
||||
}
|
||||
|
||||
impl<D: Dsl> Dsl for Option<D> {
|
||||
fn src (&self) -> &str { if let Some(dsl) = self { dsl.src() } else { "" } }
|
||||
}
|
||||
|
||||
/// DSL-specific result type.
|
||||
pub type DslResult<T> = Result<T, DslError>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
use crate::*;
|
||||
|
||||
macro_rules! iter_chars(($source:expr => |$i:ident, $c:ident|$val:expr)=>{
|
||||
while let Some((($i, $c), next)) = char_indices($source).next() {
|
||||
$source = next.as_str(); $val } });
|
||||
|
||||
macro_rules! def_peek_seek(($peek:ident, $seek:ident, $seek_start:ident, $seek_length:ident)=>{
|
||||
/// Find a slice corrensponding to a syntax token.
|
||||
const fn $peek (source: &str) -> DslPerhaps<&str> {
|
||||
|
|
@ -22,27 +20,56 @@ macro_rules! def_peek_seek(($peek:ident, $seek:ident, $seek_start:ident, $seek_l
|
|||
Ok(None) => Ok(None),
|
||||
Err(e) => Err(e) } } });
|
||||
|
||||
const fn is_whitespace (c: char) -> bool { matches!(c, ' '|'\n'|'\r'|'\t') }
|
||||
pub const fn peek (mut src: &str) -> DslPerhaps<&str> {
|
||||
Ok(Some(match () {
|
||||
_ if let Ok(Some(exp)) = exp_peek(src) => exp,
|
||||
_ if let Ok(Some(sym)) = sym_peek(src) => sym,
|
||||
_ if let Ok(Some(key)) = key_peek(src) => key,
|
||||
_ if let Ok(Some(num)) = num_peek(src) => num,
|
||||
_ if let Ok(Some(text)) = text_peek(src) => text,
|
||||
_ => {
|
||||
iter_chars!(src => |_i, c| if !is_whitespace(c) {
|
||||
return Err(Unexpected(c))
|
||||
});
|
||||
return Ok(None)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
pub trait DslExp: Dsl {
|
||||
fn exp (&self) -> DslPerhaps<impl DslExp> {
|
||||
todo!();
|
||||
Ok(Some(self))
|
||||
pub const fn seek (mut src: &str) -> DslPerhaps<(usize, usize)> {
|
||||
Ok(Some(match () {
|
||||
_ if let Ok(Some(exp)) = exp_seek(src) => exp,
|
||||
_ if let Ok(Some(sym)) = sym_seek(src) => sym,
|
||||
_ if let Ok(Some(key)) = key_seek(src) => key,
|
||||
_ if let Ok(Some(num)) = num_seek(src) => num,
|
||||
_ if let Ok(Some(text)) = text_seek(src) => text,
|
||||
_ => {
|
||||
iter_chars!(src => |_i, c| if !is_whitespace(c) {
|
||||
return Err(Unexpected(c))
|
||||
});
|
||||
return Ok(None)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
const fn is_whitespace (c: char) -> bool { matches!(c, ' '|'\n'|'\r'|'\t') }
|
||||
pub trait DslExp<'s>: Dsl + From<&'s str> {
|
||||
fn exp (&'s self) -> DslPerhaps<Self> {
|
||||
Ok(exp_peek(self.src())?.map(Into::into))
|
||||
}
|
||||
fn exp_head (&self) -> DslPerhaps<impl Dsl> {
|
||||
todo!();
|
||||
Ok(Some(self))
|
||||
fn head (&'s self) -> DslPerhaps<Self> {
|
||||
Ok(peek(&self.src()[1..])?.map(Into::into))
|
||||
}
|
||||
fn exp_tail (&self) -> DslPerhaps<impl DslExp> {
|
||||
todo!();
|
||||
Ok(Some(self))
|
||||
}
|
||||
fn exp_next (&mut self) -> DslPerhaps<impl Dsl> {
|
||||
todo!();
|
||||
Ok(Some(self))
|
||||
fn tail (&'s self) -> DslPerhaps<Self> {
|
||||
Ok(if let Some((head_start, head_len)) = seek(&self.src()[1..])? {
|
||||
peek(&self.src()[(1+head_start+head_len)..])?.map(Into::into)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
}
|
||||
}
|
||||
impl<D: Dsl> DslExp for D {}
|
||||
//impl<'s, D: DslExp<'s>> DslExp<'s> for Option<D> {}
|
||||
impl<'s, D: Dsl + From<&'s str>> DslExp<'s> for D {}
|
||||
def_peek_seek!(exp_peek, exp_seek, exp_seek_start, exp_seek_length);
|
||||
const fn is_exp_start (c: char) -> bool { matches!(c, '(') }
|
||||
const fn is_exp_end (c: char) -> bool { matches!(c, ')') }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue