mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 11:46:42 +01:00
This commit is contained in:
parent
21832453d9
commit
17506726cb
36 changed files with 280 additions and 271 deletions
|
|
@ -3,6 +3,10 @@ use crate::*;
|
|||
/// CST stores strings as source references and expressions as new [SourceIter] instances.
|
||||
pub type CstValue<'source> = Value<&'source str, SourceIter<'source>>;
|
||||
|
||||
/// Token sharing memory with source reference.
|
||||
#[derive(Debug, Copy, Clone, Default, PartialEq)]
|
||||
pub struct CstToken<'source>(pub CstValue<'source>, pub CstMeta<'source>);
|
||||
|
||||
/// Reference to the source slice.
|
||||
#[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct CstMeta<'source> {
|
||||
pub source: &'source str,
|
||||
|
|
@ -10,10 +14,6 @@ pub type CstValue<'source> = Value<&'source str, SourceIter<'source>>;
|
|||
pub length: usize,
|
||||
}
|
||||
|
||||
/// Token sharing memory with source reference.
|
||||
#[derive(Debug, Copy, Clone, Default, PartialEq)]
|
||||
pub struct CstToken<'source>(pub CstValue<'source>, pub CstMeta<'source>);
|
||||
|
||||
impl<'source> CstToken<'source> {
|
||||
pub const fn new (
|
||||
source: &'source str, start: usize, length: usize, value: CstValue<'source>
|
||||
|
|
|
|||
|
|
@ -7,25 +7,32 @@ pub trait DslIter {
|
|||
fn rest (self) -> Vec<Self::Token>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
pub struct AstIter(std::collections::VecDeque<Ast>);
|
||||
|
||||
impl DslIter for AstIter {
|
||||
type Token = Ast;
|
||||
fn peek (&self) -> Option<Ast> {
|
||||
self.0.get(0).cloned()
|
||||
}
|
||||
fn next (&mut self) -> Option<Ast> {
|
||||
self.0.pop_front()
|
||||
}
|
||||
fn rest (self) -> Vec<Ast> {
|
||||
self.0.into()
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'source> From<SourceIter<'source>> for AstIter {
|
||||
fn from (source: SourceIter<'source>) -> Self {
|
||||
Self(source.map(Into::into).collect())
|
||||
/// Owns a reference to the source text.
|
||||
/// [SourceConstIter::next] emits subsequent pairs of:
|
||||
/// * a [CstToken] and
|
||||
/// * the source text remaining
|
||||
/// * [ ] TODO: maybe [SourceConstIter::next] should wrap the remaining source in `Self` ?
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
pub struct SourceConstIter<'source>(pub &'source str);
|
||||
|
||||
impl<'source> From<SourceConstIter<'source>> for SourceIter<'source> {
|
||||
fn from (source: SourceConstIter<'source>) -> Self{
|
||||
Self(source)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,35 +78,6 @@ impl<'source> Into<Vec<Ast>> for SourceIter<'source> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Owns a reference to the source text.
|
||||
/// [SourceConstIter::next] emits subsequent pairs of:
|
||||
/// * a [CstToken] and
|
||||
/// * the source text remaining
|
||||
/// * [ ] TODO: maybe [SourceConstIter::next] should wrap the remaining source in `Self` ?
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
pub struct SourceConstIter<'source>(pub &'source str);
|
||||
|
||||
impl<'source> From<SourceConstIter<'source>> for SourceIter<'source> {
|
||||
fn from (source: SourceConstIter<'source>) -> Self{
|
||||
Self(source)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'source> From<&'source str> for SourceConstIter<'source> {
|
||||
fn from (source: &'source str) -> Self{
|
||||
Self::new(source)
|
||||
|
|
@ -128,3 +106,25 @@ impl<'source> SourceConstIter<'source> {
|
|||
}
|
||||
|
||||
const_iter!(<'source>|self: SourceConstIter<'source>| => CstToken<'source> => self.next_mut().map(|(result, _)|result));
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
pub struct AstIter(std::collections::VecDeque<Ast>);
|
||||
|
||||
impl DslIter for AstIter {
|
||||
type Token = Ast;
|
||||
fn peek (&self) -> Option<Ast> {
|
||||
self.0.get(0).cloned()
|
||||
}
|
||||
fn next (&mut self) -> Option<Ast> {
|
||||
self.0.pop_front()
|
||||
}
|
||||
fn rest (self) -> Vec<Ast> {
|
||||
self.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'source> From<SourceIter<'source>> for AstIter {
|
||||
fn from (source: SourceIter<'source>) -> Self {
|
||||
Self(source.map(Into::into).collect())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
use crate::*;
|
||||
|
||||
#[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 = crate::SourceConstIter::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");
|
||||
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 (
|
||||
|
|
@ -33,67 +33,54 @@
|
|||
//}
|
||||
}
|
||||
|
||||
#[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)] mod test_token_prop {
|
||||
//use crate::{CstToken, CstMeta, Value::*};
|
||||
//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 = CstToken(Nil, CstMeta { source: &source, start, length });
|
||||
//let _ = token.slice();
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
|
||||
#[cfg(test)] #[test] fn test_token () -> Result<(), Box<dyn std::error::Error>> {
|
||||
use crate::Value::*;
|
||||
let source = ":f00";
|
||||
let mut token = Token { source, start: 0, length: 1, value: Sym(":") };
|
||||
let mut token = CstToken(Sym(":"), CstMeta { source, start: 0, length: 1 });
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 2, value: Sym(":f") });
|
||||
assert_eq!(token, CstToken(Sym(":f"), CstMeta { source, start: 0, length: 2, }));
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 3, value: Sym(":f0") });
|
||||
assert_eq!(token, CstToken(Sym(":f0"), CstMeta { source, start: 0, length: 3, }));
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 4, value: Sym(":f00") });
|
||||
assert_eq!(token, CstToken(Sym(":f00"), CstMeta { source, start: 0, length: 4, }));
|
||||
|
||||
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);
|
||||
|
||||
let src = "\"foo/bar\"";
|
||||
assert_eq!(Str("foo/bar"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " \"foo/bar\" ";
|
||||
assert_eq!(Str("foo/bar"), SourceIter(src).next().unwrap().0.value);
|
||||
assert_eq!(None,
|
||||
SourceIter::new("").next());
|
||||
assert_eq!(None,
|
||||
SourceIter::new(" \n \r \t ").next());
|
||||
assert_eq!(&Num(7),
|
||||
SourceIter::new("7").next().unwrap().0.value());
|
||||
assert_eq!(&Num(100),
|
||||
SourceIter::new(" 100 ").next().unwrap().0.value());
|
||||
assert_eq!(&Err(Unexpected('a')),
|
||||
SourceIter::new(" 9a ").next().unwrap().0.value());
|
||||
assert_eq!(&Sym(":123foo"),
|
||||
SourceIter::new(" :123foo ").next().unwrap().0.value());
|
||||
assert_eq!(&Sym("@bar456"),
|
||||
SourceIter::new(" \r\r\r\n\n\n@bar456\t\t\t\t\t\t").next().unwrap().0.value());
|
||||
assert_eq!(&Key("foo123"),
|
||||
SourceIter::new("foo123").next().unwrap().0.value());
|
||||
assert_eq!(&Key("foo/bar"),
|
||||
SourceIter::new("foo/bar").next().unwrap().0.value());
|
||||
assert_eq!(&Str("foo/bar"),
|
||||
SourceIter::new("\"foo/bar\"").next().unwrap().0.value());
|
||||
assert_eq!(&Str("foo/bar"),
|
||||
SourceIter::new(" \"foo/bar\" ").next().unwrap().0.value());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -108,7 +95,7 @@
|
|||
//let mut expr = view.peek();
|
||||
//assert_eq!(view.0.0, source);
|
||||
//assert_eq!(expr, Some(Token {
|
||||
//source, start: 0, length: source.len() - 1, value: Exp(0, SourceIter(&source[1..]))
|
||||
//source, start: 0, length: source.len() - 1, value: Exp(0, SourceIter::new(&source[1..]))
|
||||
//}));
|
||||
////panic!("{view:?}");
|
||||
////panic!("{:#?}", expr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue