halp, i cant write a recursive iterator :3

This commit is contained in:
🪞👃🪞 2025-01-05 03:29:27 +01:00
parent f3fd88a199
commit 140fd22223
10 changed files with 107 additions and 99 deletions

View file

@ -1,37 +1,5 @@
use crate::*;
fn number (digits: &str) -> usize {
let mut value = 0;
for c in digits.chars() {
value = 10 * value + digit(c);
}
value
}
const fn digit (c: char) -> usize {
match c { '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4,
'5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, _ => unreachable!() }
}
#[derive(Debug)]
pub enum ParseError {
Unknown(u8),
Empty,
Incomplete,
Unexpected(char),
}
impl std::fmt::Display for ParseError {
fn fmt (&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Empty => write!(f, "empty"),
Self::Incomplete => write!(f, "incomplete"),
Self::Unexpected(c) => write!(f, "unexpected '{c}'"),
Self::Unknown(i) => write!(f, "unknown #{i}"),
}
}
}
impl std::error::Error for ParseError {}
pub enum EdnItem<T> {
Nil,
Num(usize),
@ -44,7 +12,6 @@ impl<T> Default for EdnItem<T> {
Self::Nil
}
}
impl<T: AsRef<str> + PartialEq + Default + Clone + std::fmt::Debug> EdnItem<T> {
pub fn to_ref (&self) -> EdnItem<&str> {
match self {
@ -58,8 +25,52 @@ impl<T: AsRef<str> + PartialEq + Default + Clone + std::fmt::Debug> EdnItem<T> {
_ => todo!()
}
}
pub fn symbols <'a> (&'a self) -> SymIterator<'a, T> {
SymIterator::new(&self)
}
}
enum SymIterator<'a, T> {
Nil,
Sym(&'a T),
Exp(&'a [EdnItem<T>])
}
impl<'a, T: AsRef<str>> SymIterator<'a, T> {
fn new (item: &'a EdnItem<T>) -> Self {
use EdnItem::*;
match item {
Sym(t) => Self::Sym(t),
Exp(i) => Self::Exp(i.as_slice()),
_ => Self::Nil,
}
}
}
impl<'a, T: AsRef<str>> Iterator for SymIterator<'a, T> {
type Item = &'a str;
fn next (&mut self) -> Option<Self::Item> {
use SymIterator::*;
match self {
Sym(t) => {
*self = Nil;
Some(t.as_ref())
},
Exp([a, b @ ..]) => match a {
EdnItem::Sym(t) => {
*self = Exp(b);
Some(t.as_ref())
}
EdnItem::Exp(_) => todo!(),
_ => {
*self = Nil;
None
}
},
_ => {
*self = Nil;
None
}
}
}
}
impl EdnItem<String> {
fn from (other: EdnItem<impl AsRef<str>>) -> EdnItem<String> {
use EdnItem::*;
@ -70,7 +81,6 @@ impl EdnItem<String> {
}
}
}
impl<'a> TryFrom<Token<'a>> for EdnItem<String> {
type Error = ParseError;
fn try_from (token: Token<'a>) -> Result<Self, Self::Error> {
@ -78,7 +88,7 @@ impl<'a> TryFrom<Token<'a>> for EdnItem<String> {
Ok(match token {
Nil => Self::Nil,
Num(chars, index, length) =>
Self::Num(number(&chars[index..index+length])),
Self::Num(Token::number(&chars[index..index+length])),
Sym(chars, index, length) =>
Self::Sym(String::from(&chars[index..index+length])),
Key(chars, index, length) =>
@ -97,7 +107,7 @@ impl<'a> TryFrom<Token<'a>> for EdnItem<&'a str> {
Ok(match token {
Nil => EdnItem::Nil,
Num(chars, index, length) =>
Self::Num(number(&chars[index..index+length])),
Self::Num(Token::number(&chars[index..index+length])),
Sym(chars, index, length) =>
Self::Sym(&chars[index..index+length]),
Key(chars, index, length) =>
@ -136,7 +146,7 @@ impl<'a, T: std::fmt::Debug + Clone + Default + PartialEq + From<&'a str>> EdnIt
Ok(match token {
Nil => EdnItem::Nil,
Num(chars, index, length) =>
Self::Num(number(&chars[index..index+length])),
Self::Num(Token::number(&chars[index..index+length])),
Sym(chars, index, length) =>
Self::Sym(T::from(&chars[index..index+length])),
Key(chars, index, length) =>