mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: still trying to write the iterator
This commit is contained in:
parent
140fd22223
commit
433e4df0f2
7 changed files with 114 additions and 66 deletions
14
edn/Cargo.lock
generated
14
edn/Cargo.lock
generated
|
|
@ -279,6 +279,15 @@ dependencies = [
|
|||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.14"
|
||||
|
|
@ -468,7 +477,7 @@ dependencies = [
|
|||
"crossterm",
|
||||
"indoc",
|
||||
"instability",
|
||||
"itertools",
|
||||
"itertools 0.13.0",
|
||||
"lru",
|
||||
"paste",
|
||||
"strum",
|
||||
|
|
@ -609,6 +618,7 @@ name = "tek_edn"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clojure-reader",
|
||||
"itertools 0.14.0",
|
||||
"konst",
|
||||
"tek_layout",
|
||||
]
|
||||
|
|
@ -662,7 +672,7 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"itertools 0.13.0",
|
||||
"unicode-segmentation",
|
||||
"unicode-width 0.1.14",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ version = "0.1.0"
|
|||
[dependencies]
|
||||
clojure-reader = "0.3.0"
|
||||
konst = "0.3.16"
|
||||
itertools = "0.14.0"
|
||||
tek_layout = { optional = true, path = "../layout" }
|
||||
|
||||
[features]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,19 @@ impl<T> Default for EdnItem<T> {
|
|||
Self::Nil
|
||||
}
|
||||
}
|
||||
impl<T: Debug> Debug for EdnItem<T> {
|
||||
fn fmt (&self, f: &mut Formatter<'_>) -> Result<(), FormatError> {
|
||||
match self {
|
||||
Self::Nil => write!(f, "Nil"),
|
||||
Self::Num(u) => write!(f, "Num({u})"),
|
||||
Self::Sym(u) => write!(f, "Sym({u:?})"),
|
||||
Self::Key(u) => write!(f, "Key({u:?})"),
|
||||
Self::Exp(e) => write!(f, "Exp({})", itertools::join(
|
||||
e.iter().map(|i|format!("{:?}", i)), ","
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: AsRef<str> + PartialEq + Default + Clone + std::fmt::Debug> EdnItem<T> {
|
||||
pub fn to_ref (&self) -> EdnItem<&str> {
|
||||
match self {
|
||||
|
|
@ -25,40 +38,42 @@ 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)
|
||||
pub fn symbols <'a> (&'a self) -> EdnIterator<'a, T> {
|
||||
EdnIterator::new(&self)
|
||||
}
|
||||
}
|
||||
enum SymIterator<'a, T> {
|
||||
enum EdnIterator<'a, T>{
|
||||
Nil,
|
||||
Sym(&'a T),
|
||||
Exp(&'a [EdnItem<T>])
|
||||
Exp(Vec<EdnIterator<'a, T>>)
|
||||
}
|
||||
impl<'a, T: AsRef<str>> SymIterator<'a, T> {
|
||||
impl<'a, T: AsRef<str>> EdnIterator<'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()),
|
||||
Exp(i) => Self::Exp(i.iter().map(EdnIterator::new).collect()),
|
||||
_ => Self::Nil,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a, T: AsRef<str>> Iterator for SymIterator<'a, T> {
|
||||
type Item = &'a str;
|
||||
impl<'a, T: AsRef<str>> Iterator for EdnIterator<'a, T> {
|
||||
type Item = &'a T;
|
||||
fn next (&mut self) -> Option<Self::Item> {
|
||||
use SymIterator::*;
|
||||
use EdnIterator::*;
|
||||
match self {
|
||||
Sym(t) => {
|
||||
let t = *t;
|
||||
*self = Nil;
|
||||
Some(t.as_ref())
|
||||
Some(t)
|
||||
},
|
||||
Exp([a, b @ ..]) => match a {
|
||||
EdnItem::Sym(t) => {
|
||||
*self = Exp(b);
|
||||
Some(t.as_ref())
|
||||
}
|
||||
EdnItem::Exp(_) => todo!(),
|
||||
Exp(v) => match v.as_mut_slice() {
|
||||
[a] => if let Some(next) = a.next() {
|
||||
Some(next)
|
||||
} else {
|
||||
*self = Exp(v.split_off(1));
|
||||
self.next()
|
||||
},
|
||||
_ => {
|
||||
*self = Nil;
|
||||
None
|
||||
|
|
|
|||
|
|
@ -13,43 +13,8 @@ pub type EdnRenderCallback<'a, Engine, State> =
|
|||
Box<EdnCallback<'a, Engine, State>>;
|
||||
|
||||
pub trait EdnLayout<'a, E: Engine + 'a> where Self: 'a {
|
||||
fn get_bool (&self, _: &EdnItem<&str>) -> bool { false }
|
||||
fn get_unit (&self, _: &EdnItem<&str>) -> E::Unit { 0.into() }
|
||||
fn get_usize (&self, _: &EdnItem<&str>) -> usize { 0 }
|
||||
fn get_content (&'a self, _: &EdnItem<&str>) -> Box<EdnRender<'a, E>> { Box::new(()) }
|
||||
fn parse (items: &'a [EdnItem<String>]) -> EdnRenderCallback<'a, E, Self> {
|
||||
if let (Some(first), rest) = (items.get(0).map(EdnItem::to_str), &items[1..]) {
|
||||
match (first, rest) {
|
||||
("when", [c, a, ..]) => Box::new(move|state|Box::new(
|
||||
When(state.get_bool(&c.to_ref()), state.get_content(&a.to_ref())))),
|
||||
_ => Box::new(|_|Box::new(()))
|
||||
}
|
||||
} else {
|
||||
Box::new(|_|Box::new(()))
|
||||
}
|
||||
}
|
||||
//Box::new(match [items.get(0).map(|x|x.to_str()), items[1..]] {
|
||||
//["when", [c, a, ..]] => When(state.get_bool(c), state.get_content(a)),
|
||||
//["either", [c, a, b, ..]] => Either(state.get_bool(c), state.get_content(a), state.get_content(b)),
|
||||
//["fill", [a, ..]] => Fill::xy(state.get_content(a)),
|
||||
//["fill/x", [a, ..]] => Fill::x(state.get_content(a)),
|
||||
//["fill/y", [a, ..]] => Fill::y(state.get_content(a)),
|
||||
//["fixed", [x, y, a, ..]] => Fixed::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["fixed/x", [x, a, ..]] => Fixed::x(state.get_unit(x), state.get_content(a)),
|
||||
//["fixed/y", [y, a, ..]] => Fixed::y(state.get_unit(y), state.get_content(a)),
|
||||
//["shrink", [x, y, a, ..]] => Shrink::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["shrink/x", [x, a, ..]] => Shrink::x(state.get_unit(x), state.get_content(a)),
|
||||
//["shrink/y", [y, a, ..]] => Shrink::y(state.get_unit(y), state.get_content(a)),
|
||||
//["expand", [x, y, a, ..]] => Expand::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["expand/x", [x, a, ..]] => Expand::x(state.get_unit(x), state.get_content(a)),
|
||||
//["expand/y", [y, a, ..]] => Expand::y(state.get_unit(y), state.get_content(a)),
|
||||
//["push", [x, y, a, ..]] => Push::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["push/x", [x, a, ..]] => Push::x(state.get_unit(x), state.get_content(a)),
|
||||
//["push/y", [y, a, ..]] => Push::y(state.get_unit(y), state.get_content(a)),
|
||||
//["pull", [x, y, a, ..]] => Pull::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["pull/x", [x, a, ..]] => Pull::x(state.get_unit(x), state.get_content(a)),
|
||||
//["pull/y", [y, a, ..]] => Pull::y(state.get_unit(y), state.get_content(a)),
|
||||
//_ => Box::
|
||||
//})
|
||||
//}
|
||||
fn get_bool (&self, _sym: &str) -> bool { false }
|
||||
fn get_unit (&self, _sym: &str) -> E::Unit { 0.into() }
|
||||
fn get_usize (&self, _sym: &str) -> usize { 0 }
|
||||
fn get_content (&'a self, _sym: &str) -> Box<EdnRender<'a, E>> { Box::new(()) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
use crate::*;
|
||||
use std::marker::PhantomData;
|
||||
use EdnItem::*;
|
||||
|
||||
use EdnItem::*;
|
||||
|
||||
/// Renders from EDN source and context.
|
||||
pub struct EdnView<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> {
|
||||
|
|
@ -15,9 +12,53 @@ pub struct EdnView<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> {
|
|||
impl<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> EdnView<'a, E, T> {
|
||||
pub fn new (context: T, source: &'a str) -> Usually<Self> {
|
||||
let layout = EdnItem::read_one(&source)?.0;
|
||||
for symbol in layout.symbols() {
|
||||
context.import(symbol)
|
||||
}
|
||||
Ok(Self { _engine: Default::default(), context, layout, })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: Engine + 'a, T: EdnLayout<'a, E> + Send + Sync + 'a> Content<E> for EdnView<'a, E, T> {
|
||||
fn content (&self) -> impl Render<E> {
|
||||
use EdnItem::*;
|
||||
match &self.layout {
|
||||
Nil => None,
|
||||
Sym(t) => Some(self.context.get_content(t.as_str())),
|
||||
Key(t) => panic!("todo: add error handling to content() chain. unexpected key {t}"),
|
||||
Num(n) => panic!("todo: add error handling to content() chain. unexpected num {n}"),
|
||||
Exp(e) => todo!("exp {e:?}"),
|
||||
}
|
||||
//let items = &self.layout;
|
||||
//if let (Some(first), rest) = (items.get(0).map(EdnItem::to_str), &items[1..]) {
|
||||
//match (first, rest) {
|
||||
//("when", [c, a, ..]) => Box::new(move|state|Box::new(
|
||||
//When(state.get_bool(&c.to_ref()), state.get_content(&a.to_ref())))),
|
||||
//_ => Box::new(|_|Box::new(()))
|
||||
//}
|
||||
//} else {
|
||||
//Box::new(|_|Box::new(()))
|
||||
//}
|
||||
}
|
||||
//Box::new(match [items.get(0).map(|x|x.to_str()), items[1..]] {
|
||||
//["when", [c, a, ..]] => When(state.get_bool(c), state.get_content(a)),
|
||||
//["either", [c, a, b, ..]] => Either(state.get_bool(c), state.get_content(a), state.get_content(b)),
|
||||
//["fill", [a, ..]] => Fill::xy(state.get_content(a)),
|
||||
//["fill/x", [a, ..]] => Fill::x(state.get_content(a)),
|
||||
//["fill/y", [a, ..]] => Fill::y(state.get_content(a)),
|
||||
//["fixed", [x, y, a, ..]] => Fixed::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["fixed/x", [x, a, ..]] => Fixed::x(state.get_unit(x), state.get_content(a)),
|
||||
//["fixed/y", [y, a, ..]] => Fixed::y(state.get_unit(y), state.get_content(a)),
|
||||
//["shrink", [x, y, a, ..]] => Shrink::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["shrink/x", [x, a, ..]] => Shrink::x(state.get_unit(x), state.get_content(a)),
|
||||
//["shrink/y", [y, a, ..]] => Shrink::y(state.get_unit(y), state.get_content(a)),
|
||||
//["expand", [x, y, a, ..]] => Expand::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["expand/x", [x, a, ..]] => Expand::x(state.get_unit(x), state.get_content(a)),
|
||||
//["expand/y", [y, a, ..]] => Expand::y(state.get_unit(y), state.get_content(a)),
|
||||
//["push", [x, y, a, ..]] => Push::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["push/x", [x, a, ..]] => Push::x(state.get_unit(x), state.get_content(a)),
|
||||
//["push/y", [y, a, ..]] => Push::y(state.get_unit(y), state.get_content(a)),
|
||||
//["pull", [x, y, a, ..]] => Pull::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
//["pull/x", [x, a, ..]] => Pull::x(state.get_unit(x), state.get_content(a)),
|
||||
//["pull/y", [y, a, ..]] => Pull::y(state.get_unit(y), state.get_content(a)),
|
||||
//_ => Box::
|
||||
//})
|
||||
//}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(impl_trait_in_fn_trait_return)]
|
||||
|
||||
pub(crate) use ::tek_layout::{*, tek_engine::{Usually, Content, Render, Engine, Thunk}};
|
||||
pub(crate) use std::{
|
||||
fmt::{Debug, Formatter, Error as FormatError}
|
||||
};
|
||||
pub(crate) use ::tek_layout::{
|
||||
*,
|
||||
tek_engine::{Usually, Content, Render, Engine, Thunk}
|
||||
};
|
||||
|
||||
mod edn_error; pub use self::edn_error::*;
|
||||
mod edn_item; pub use self::edn_item::*;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue