TokenIter -> SourceIter, reuse logic in operators, and now it renders correctly!

This commit is contained in:
🪞👃🪞 2025-01-19 01:46:06 +01:00
parent 266f59085e
commit b8726de78f
13 changed files with 203 additions and 154 deletions

View file

@ -1,12 +1,10 @@
use crate::*;
pub trait TryFromAtom<'a, T>: Sized {
fn try_from_expr (_state: &'a T, _iter: TokenIter<'a>) -> Option<Self> { None }
fn try_from_atom (state: &'a T, value: Value<'a>) -> Option<Self> {
if let Exp(0, iter) = value { return Self::try_from_expr(state, iter) }
None
}
fn try_from_expr (_state: &'a T, _iter: TokenIter<'a>) -> Option<Self> {
None
}
}
pub trait TryIntoAtom<T>: Sized {
fn try_into_atom (&self) -> Option<Value>;

View file

@ -1,8 +1,19 @@
use crate::*;
#[derive(Copy, Clone, Debug, Default, PartialEq)] pub struct TokenIter<'a>(pub &'a str);
const_iter!(<'a>|self: TokenIter<'a>| => Token<'a> => self.next_mut().map(|(result, _)|result));
impl<'a> From<&'a str> for TokenIter<'a> {fn from (source: &'a str) -> Self{Self::new(source)}}
#[derive(Copy, Clone, Debug, Default, PartialEq)] pub struct TokenIter<'a>(pub SourceIter<'a>);
impl<'a> TokenIter<'a> {
pub const fn new (source: &'a str) -> Self { Self(SourceIter::new(source)) }
pub const fn peek (&self) -> Option<Token<'a>> { self.0.peek() }
}
impl<'a> Iterator for TokenIter<'a> {
type Item = Token<'a>;
fn next (&mut self) -> Option<Token<'a>> {
self.0.next().map(|(item, rest)|{self.0 = rest; item})
}
}
#[derive(Copy, Clone, Debug, Default, PartialEq)] pub struct SourceIter<'a>(pub &'a str);
const_iter!(<'a>|self: SourceIter<'a>| => Token<'a> => self.next_mut().map(|(result, _)|result));
impl<'a> From<&'a str> for SourceIter<'a> {fn from (source: &'a str) -> Self{Self::new(source)}}
impl<'a> SourceIter<'a> {
pub const fn new (source: &'a str) -> Self { Self(source) }
pub const fn chomp (&self, index: usize) -> Self { Self(split_at(self.0, index).1) }
pub const fn next (mut self) -> Option<(Token<'a>, Self)> { Self::next_mut(&mut self) }
@ -22,7 +33,7 @@ pub const fn peek_src <'a> (source: &'a str) -> Option<Token<'a>> {
' '|'\n'|'\r'|'\t' =>
token.grow(),
'(' =>
Token::new(source, start, 1, Exp(1, TokenIter(str_range(source, start, start + 1)))),
Token::new(source, start, 1, Exp(1, TokenIter::new(str_range(source, start, start + 1)))),
':'|'@' =>
Token::new(source, start, 1, Sym(str_range(source, start, start + 1))),
'/'|'a'..='z' =>

View file

@ -53,37 +53,37 @@ pub(crate) use std::fmt::{Debug, Display, Formatter, Result as FormatResult, Err
assert_eq!(token, Token { source, start: 0, length: 4, value: Sym(":f00") });
let src = "";
assert_eq!(None, TokenIter(src).next());
assert_eq!(None, SourceIter(src).next());
let src = " \n \r \t ";
assert_eq!(None, TokenIter(src).next());
assert_eq!(None, SourceIter(src).next());
let src = "7";
assert_eq!(Num(7), TokenIter(src).next().unwrap().0.value);
assert_eq!(Num(7), SourceIter(src).next().unwrap().0.value);
let src = " 100 ";
assert_eq!(Num(100), TokenIter(src).next().unwrap().0.value);
assert_eq!(Num(100), SourceIter(src).next().unwrap().0.value);
let src = " 9a ";
assert_eq!(Err(Unexpected('a')), TokenIter(src).next().unwrap().0.value);
assert_eq!(Err(Unexpected('a')), SourceIter(src).next().unwrap().0.value);
let src = " :123foo ";
assert_eq!(Sym(":123foo"), TokenIter(src).next().unwrap().0.value);
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"), TokenIter(src).next().unwrap().0.value);
assert_eq!(Sym("@bar456"), SourceIter(src).next().unwrap().0.value);
let src = "foo123";
assert_eq!(Key("foo123"), TokenIter(src).next().unwrap().0.value);
assert_eq!(Key("foo123"), SourceIter(src).next().unwrap().0.value);
let src = "foo/bar";
assert_eq!(Key("foo/bar"), TokenIter(src).next().unwrap().0.value);
assert_eq!(Key("foo/bar"), SourceIter(src).next().unwrap().0.value);
Ok(())
}
#[cfg(test)] #[test] fn test_examples () -> Result<(), ParseError> {
let src = include_str!("../../tek/src/view_arranger.edn");
let mut view = TokenIter(src);
let mut view = SourceIter(src);
assert_eq!(view.0, src);
let mut expr = view.peek();
assert_eq!(view.0, src);
@ -91,7 +91,7 @@ pub(crate) use std::fmt::{Debug, Display, Formatter, Result as FormatResult, Err
source: src,
start: 0,
length: src.len(),
value: Exp(0, TokenIter(&src[1..]))
value: Exp(0, SourceIter(&src[1..]))
}));
//panic!("{view:?}");
//panic!("{:#?}", expr);

View file

@ -59,7 +59,7 @@ impl<'a> Token<'a> {
pub const fn grow_exp (self) -> Self {
let mut token = self.grow();
if let Exp(depth, _) = token.value {
token.value = Exp(depth, TokenIter(token.slice_source_exp(self.source)));
token.value = Exp(depth, TokenIter::new(token.slice_source_exp(self.source)));
} else {
unreachable!()
}