mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 11:46:42 +01:00
dsl: add sexpr syntaces; prefix modules
This commit is contained in:
parent
844681d6ad
commit
3d01f5558c
7 changed files with 234 additions and 178 deletions
179
dsl/src/lib.rs
179
dsl/src/lib.rs
|
|
@ -1,91 +1,18 @@
|
|||
#![feature(adt_const_params)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(impl_trait_in_fn_trait_return)]
|
||||
mod error; pub use self::error::*;
|
||||
mod token; pub use self::token::*;
|
||||
mod iter; pub use self::iter::*;
|
||||
mod context; pub use self::context::*;
|
||||
|
||||
pub(crate) use self::Value::*;
|
||||
pub(crate) use self::ParseError::*;
|
||||
pub(crate) use konst::iter::{ConstIntoIter, IsIteratorKind};
|
||||
pub(crate) use konst::string::{split_at, str_range, char_indices};
|
||||
pub(crate) use std::fmt::Debug;
|
||||
|
||||
/// Static iteration helper.
|
||||
#[macro_export] macro_rules! iterate {
|
||||
($expr:expr => $arg: pat => $body:expr) => {
|
||||
let mut iter = $expr;
|
||||
while let Some(($arg, next)) = iter.next() {
|
||||
$body;
|
||||
iter = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement the const iterator pattern.
|
||||
#[macro_export] macro_rules! const_iter {
|
||||
($(<$l:lifetime>)?|$self:ident: $Struct:ty| => $Item:ty => $expr:expr) => {
|
||||
impl$(<$l>)? Iterator for $Struct {
|
||||
type Item = $Item;
|
||||
fn next (&mut $self) -> Option<$Item> { $expr }
|
||||
}
|
||||
impl$(<$l>)? ConstIntoIter for $Struct {
|
||||
type Kind = IsIteratorKind;
|
||||
type Item = $Item;
|
||||
type IntoIter = Self;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! expose {
|
||||
($([$self:ident:$State:ty] { $([$($Type:tt)*] => { $($pat:pat => $expr:expr),* $(,)? })* })*) => {
|
||||
$(expose!(@impl [$self: $State] { $([$($Type)*] => { $($pat => $expr),* })* });)*
|
||||
};
|
||||
(@impl [$self:ident:$State:ty] { $([$($Type:tt)*] => { $($pat:pat => $expr:expr),* $(,)? })* }) => {
|
||||
$(expose!(@type [$($Type)*] [$self: $State] => { $($pat => $expr),* });)*
|
||||
};
|
||||
(@type [bool] [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide_bool!(bool: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
(@type [u16] [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide_num!(u16: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
(@type [usize] [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide_num!(usize: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
(@type [isize] [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide_num!(isize: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
(@type [$Type:ty] [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide!($Type: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! impose {
|
||||
([$self:ident:$Struct:ty] { $($Command:ty => $variants:tt)* }) => {
|
||||
$(atom_command!($Command: |$self: $Struct| $variants);)*
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! get_value {
|
||||
($state:expr => $token:expr) => {
|
||||
if let Some(value) = $state.get(&$token.value) {
|
||||
value
|
||||
} else {
|
||||
panic!("no value corresponding to {:?}", &$token.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! get_content {
|
||||
($state:expr => $token:expr) => {
|
||||
if let Some(content) = $state.get_content(&$token.value) {
|
||||
content
|
||||
} else {
|
||||
panic!("no content corresponding to {:?}", &$token.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
mod dsl_error; pub use self::dsl_error::*;
|
||||
mod dsl_token; pub use self::dsl_token::*;
|
||||
mod dsl_iter; pub use self::dsl_iter::*;
|
||||
mod dsl_context; pub use self::dsl_context::*;
|
||||
mod dsl_macros; pub use self::dsl_macros::*;
|
||||
|
||||
//#[cfg(test)] #[test] fn test_examples () -> Result<(), ParseError> {
|
||||
//// Let's pretend to render some view.
|
||||
|
|
@ -111,3 +38,97 @@ pub(crate) use std::fmt::Debug;
|
|||
////}
|
||||
//Ok(())
|
||||
//}
|
||||
|
||||
#[cfg(test)] mod test_token_iter {
|
||||
use crate::*;
|
||||
//use proptest::prelude::*;
|
||||
#[test] fn test_iters () {
|
||||
let mut iter = crate::SourceIter::new(&":foo :bar");
|
||||
let _ = iter.next();
|
||||
let mut iter = crate::TokenIter::new(&":foo :bar");
|
||||
let _ = iter.next();
|
||||
}
|
||||
#[test] const fn test_const_iters () {
|
||||
let mut iter = crate::SourceIter::new(&":foo :bar");
|
||||
let _ = iter.next();
|
||||
}
|
||||
#[test] fn test_num () {
|
||||
let digit = to_digit('0');
|
||||
let digit = to_digit('x');
|
||||
let number = to_number(&"123");
|
||||
let number = to_number(&"12asdf3");
|
||||
}
|
||||
//proptest! {
|
||||
//#[test] fn proptest_source_iter (
|
||||
//source in "\\PC*"
|
||||
//) {
|
||||
//let mut iter = crate::SourceIter::new(&source);
|
||||
////let _ = iter.next();
|
||||
//}
|
||||
//#[test] fn proptest_token_iter (
|
||||
//source in "\\PC*"
|
||||
//) {
|
||||
//let mut iter = crate::TokenIter::new(&source);
|
||||
////let _ = iter.next();
|
||||
//}
|
||||
//}
|
||||
}
|
||||
|
||||
#[cfg(test)] mod test_token_prop {
|
||||
use proptest::prelude::*;
|
||||
proptest! {
|
||||
#[test] fn test_token_prop (
|
||||
source in "\\PC*",
|
||||
start in usize::MIN..usize::MAX,
|
||||
length in usize::MIN..usize::MAX,
|
||||
) {
|
||||
let token = crate::Token {
|
||||
source: &source,
|
||||
start,
|
||||
length,
|
||||
value: crate::Value::Nil
|
||||
};
|
||||
let _ = token.slice();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)] #[test] fn test_token () -> Result<(), Box<dyn std::error::Error>> {
|
||||
let source = ":f00";
|
||||
let mut token = Token { source, start: 0, length: 1, value: Sym(":") };
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 2, value: Sym(":f") });
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 3, value: Sym(":f0") });
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 4, value: Sym(":f00") });
|
||||
|
||||
let src = "";
|
||||
assert_eq!(None, SourceIter(src).next());
|
||||
|
||||
let src = " \n \r \t ";
|
||||
assert_eq!(None, SourceIter(src).next());
|
||||
|
||||
let src = "7";
|
||||
assert_eq!(Num(7), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " 100 ";
|
||||
assert_eq!(Num(100), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " 9a ";
|
||||
assert_eq!(Err(Unexpected('a')), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " :123foo ";
|
||||
assert_eq!(Sym(":123foo"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " \r\r\r\n\n\n@bar456\t\t\t\t\t\t";
|
||||
assert_eq!(Sym("@bar456"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = "foo123";
|
||||
assert_eq!(Key("foo123"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = "foo/bar";
|
||||
assert_eq!(Key("foo/bar"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue