mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
halp, i cant write a recursive iterator :3
This commit is contained in:
parent
f3fd88a199
commit
140fd22223
10 changed files with 107 additions and 99 deletions
|
|
@ -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) =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue