mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +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
Cargo.lock
generated
14
Cargo.lock
generated
|
|
@ -524,6 +524,15 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
|
@ -982,7 +991,7 @@ dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"indoc",
|
"indoc",
|
||||||
"instability",
|
"instability",
|
||||||
"itertools",
|
"itertools 0.13.0",
|
||||||
"lru",
|
"lru",
|
||||||
"paste",
|
"paste",
|
||||||
"strum",
|
"strum",
|
||||||
|
|
@ -1422,6 +1431,7 @@ name = "tek_edn"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clojure-reader",
|
"clojure-reader",
|
||||||
|
"itertools 0.14.0",
|
||||||
"konst",
|
"konst",
|
||||||
"tek_layout",
|
"tek_layout",
|
||||||
]
|
]
|
||||||
|
|
@ -1529,7 +1539,7 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
|
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools 0.13.0",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-width 0.1.14",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
14
edn/Cargo.lock
generated
14
edn/Cargo.lock
generated
|
|
@ -279,6 +279,15 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
|
@ -468,7 +477,7 @@ dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"indoc",
|
"indoc",
|
||||||
"instability",
|
"instability",
|
||||||
"itertools",
|
"itertools 0.13.0",
|
||||||
"lru",
|
"lru",
|
||||||
"paste",
|
"paste",
|
||||||
"strum",
|
"strum",
|
||||||
|
|
@ -609,6 +618,7 @@ name = "tek_edn"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clojure-reader",
|
"clojure-reader",
|
||||||
|
"itertools 0.14.0",
|
||||||
"konst",
|
"konst",
|
||||||
"tek_layout",
|
"tek_layout",
|
||||||
]
|
]
|
||||||
|
|
@ -662,7 +672,7 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
|
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools 0.13.0",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-width 0.1.14",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clojure-reader = "0.3.0"
|
clojure-reader = "0.3.0"
|
||||||
konst = "0.3.16"
|
konst = "0.3.16"
|
||||||
|
itertools = "0.14.0"
|
||||||
tek_layout = { optional = true, path = "../layout" }
|
tek_layout = { optional = true, path = "../layout" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,19 @@ impl<T> Default for EdnItem<T> {
|
||||||
Self::Nil
|
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> {
|
impl<T: AsRef<str> + PartialEq + Default + Clone + std::fmt::Debug> EdnItem<T> {
|
||||||
pub fn to_ref (&self) -> EdnItem<&str> {
|
pub fn to_ref (&self) -> EdnItem<&str> {
|
||||||
match self {
|
match self {
|
||||||
|
|
@ -25,40 +38,42 @@ impl<T: AsRef<str> + PartialEq + Default + Clone + std::fmt::Debug> EdnItem<T> {
|
||||||
_ => todo!()
|
_ => todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn symbols <'a> (&'a self) -> SymIterator<'a, T> {
|
pub fn symbols <'a> (&'a self) -> EdnIterator<'a, T> {
|
||||||
SymIterator::new(&self)
|
EdnIterator::new(&self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enum SymIterator<'a, T> {
|
enum EdnIterator<'a, T>{
|
||||||
Nil,
|
Nil,
|
||||||
Sym(&'a T),
|
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 {
|
fn new (item: &'a EdnItem<T>) -> Self {
|
||||||
use EdnItem::*;
|
use EdnItem::*;
|
||||||
match item {
|
match item {
|
||||||
Sym(t) => Self::Sym(t),
|
Sym(t) => Self::Sym(t),
|
||||||
Exp(i) => Self::Exp(i.as_slice()),
|
Exp(i) => Self::Exp(i.iter().map(EdnIterator::new).collect()),
|
||||||
_ => Self::Nil,
|
_ => Self::Nil,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, T: AsRef<str>> Iterator for SymIterator<'a, T> {
|
impl<'a, T: AsRef<str>> Iterator for EdnIterator<'a, T> {
|
||||||
type Item = &'a str;
|
type Item = &'a T;
|
||||||
fn next (&mut self) -> Option<Self::Item> {
|
fn next (&mut self) -> Option<Self::Item> {
|
||||||
use SymIterator::*;
|
use EdnIterator::*;
|
||||||
match self {
|
match self {
|
||||||
Sym(t) => {
|
Sym(t) => {
|
||||||
|
let t = *t;
|
||||||
*self = Nil;
|
*self = Nil;
|
||||||
Some(t.as_ref())
|
Some(t)
|
||||||
},
|
},
|
||||||
Exp([a, b @ ..]) => match a {
|
Exp(v) => match v.as_mut_slice() {
|
||||||
EdnItem::Sym(t) => {
|
[a] => if let Some(next) = a.next() {
|
||||||
*self = Exp(b);
|
Some(next)
|
||||||
Some(t.as_ref())
|
} else {
|
||||||
}
|
*self = Exp(v.split_off(1));
|
||||||
EdnItem::Exp(_) => todo!(),
|
self.next()
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
*self = Nil;
|
*self = Nil;
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -13,43 +13,8 @@ pub type EdnRenderCallback<'a, Engine, State> =
|
||||||
Box<EdnCallback<'a, Engine, State>>;
|
Box<EdnCallback<'a, Engine, State>>;
|
||||||
|
|
||||||
pub trait EdnLayout<'a, E: Engine + 'a> where Self: 'a {
|
pub trait EdnLayout<'a, E: Engine + 'a> where Self: 'a {
|
||||||
fn get_bool (&self, _: &EdnItem<&str>) -> bool { false }
|
fn get_bool (&self, _sym: &str) -> bool { false }
|
||||||
fn get_unit (&self, _: &EdnItem<&str>) -> E::Unit { 0.into() }
|
fn get_unit (&self, _sym: &str) -> E::Unit { 0.into() }
|
||||||
fn get_usize (&self, _: &EdnItem<&str>) -> usize { 0 }
|
fn get_usize (&self, _sym: &str) -> usize { 0 }
|
||||||
fn get_content (&'a self, _: &EdnItem<&str>) -> Box<EdnRender<'a, E>> { Box::new(()) }
|
fn get_content (&'a self, _sym: &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::
|
|
||||||
//})
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use EdnItem::*;
|
|
||||||
|
|
||||||
use EdnItem::*;
|
|
||||||
|
|
||||||
/// Renders from EDN source and context.
|
/// Renders from EDN source and context.
|
||||||
pub struct EdnView<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> {
|
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> {
|
impl<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> EdnView<'a, E, T> {
|
||||||
pub fn new (context: T, source: &'a str) -> Usually<Self> {
|
pub fn new (context: T, source: &'a str) -> Usually<Self> {
|
||||||
let layout = EdnItem::read_one(&source)?.0;
|
let layout = EdnItem::read_one(&source)?.0;
|
||||||
for symbol in layout.symbols() {
|
|
||||||
context.import(symbol)
|
|
||||||
}
|
|
||||||
Ok(Self { _engine: Default::default(), context, layout, })
|
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(type_alias_impl_trait)]
|
||||||
#![feature(impl_trait_in_fn_trait_return)]
|
#![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_error; pub use self::edn_error::*;
|
||||||
mod edn_item; pub use self::edn_item::*;
|
mod edn_item; pub use self::edn_item::*;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue