From 4bf03c356db5517a4132dc2439d7512bc3183eb5 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 24 Nov 2023 21:26:17 +0100 Subject: [PATCH 01/75] wip refactor crates --- Cargo.toml | 10 +- {nested => lib-nested-core}/Cargo.toml | 10 +- .../src/editors/char/mod.rs | 16 +- .../src/editors/integer/add.rs | 0 .../src/editors/integer/ctx.rs | 3 +- .../src/editors/integer/editor.rs | 19 +- .../src/editors/integer/mod.rs | 0 .../src/editors/integer/radix.rs | 0 .../src/editors/list/cmd.rs | 3 +- .../src/editors/list/ctx.rs | 6 +- .../src/editors/list/cursor.rs | 0 .../src/editors/list/editor.rs | 8 +- .../src/editors/list/mod.rs | 3 - .../src/editors/list/nav.rs | 0 .../src/editors/list/segment.rs | 38 +- .../src/editors/mod.rs | 9 + .../src/editors/product/editor.rs | 4 - .../src/editors/product/mod.rs | 0 .../src/editors/product/nav.rs | 0 .../src/editors/product/segment.rs | 0 .../src/editors/sum/editor.rs | 27 +- .../src/editors/sum/mod.rs | 0 .../src/editors/typeterm/cmd.rs | 3 +- .../src/editors/typeterm/ctx.rs | 9 +- .../src/editors/typeterm/mod.rs | 8 +- .../src/editors/typeterm/nav.rs | 0 lib-nested-core/src/lib.rs | 8 + {nested => lib-nested-core}/src/tree/addr.rs | 0 .../src/tree/cursor.rs | 0 lib-nested-core/src/tree/diagnostics.rs | 24 ++ {nested => lib-nested-core}/src/tree/mod.rs | 1 + {nested => lib-nested-core}/src/tree/nav.rs | 32 +- {nested => lib-nested-core}/src/tree/node.rs | 38 +- .../src/tree/treetype.rs | 0 .../src/type_system/context.rs | 0 .../src/type_system/mod.rs | 0 .../src/type_system/repr_tree.rs | 8 + .../src/utils/bimap.rs | 0 {nested => lib-nested-core}/src/utils/mod.rs | 1 - .../src/utils/modulo.rs | 0 .../ansi_parser => lib-nested-tty}/Cargo.toml | 15 +- .../src}/ansi_parser.rs | 2 +- .../terminal => lib-nested-tty/src}/atom.rs | 0 .../src/utils => lib-nested-tty/src}/color.rs | 0 .../src}/compositor.rs | 2 +- lib-nested-tty/src/cursor_widget.rs | 33 ++ {nested => lib-nested-tty}/src/diagnostics.rs | 24 -- .../mod.rs => lib-nested-tty/src/lib.rs | 31 +- .../src/list_editor.rs | 41 ++- .../terminal => lib-nested-tty/src}/style.rs | 0 lib-nested-tty/src/sum_editor.rs | 8 + .../src}/terminal.rs | 0 .../src}/widgets/ascii_box.rs | 0 .../src}/widgets/mod.rs | 0 .../src}/widgets/monstera.rs | 0 .../src}/widgets/plot.rs | 0 math/fib/Cargo.toml | 9 - math/fib/src/main.rs | 62 ---- math/int2str/Cargo.toml | 9 - math/int2str/src/main.rs | 36 -- math/radix_transform/Cargo.toml | 13 - math/radix_transform/src/main.rs | 137 -------- math/str2int/Cargo.toml | 9 - math/str2int/src/main.rs | 69 ---- nested/src/editors/mod.rs | 9 - nested/src/lib.rs | 34 -- terminal/ansi_parser/src/main.rs | 331 ------------------ terminal/display_server/Cargo.toml | 12 - terminal/display_server/src/main.rs | 67 ---- 69 files changed, 238 insertions(+), 1003 deletions(-) rename {nested => lib-nested-core}/Cargo.toml (69%) rename {nested => lib-nested-core}/src/editors/char/mod.rs (91%) rename {nested => lib-nested-core}/src/editors/integer/add.rs (100%) rename {nested => lib-nested-core}/src/editors/integer/ctx.rs (99%) rename {nested => lib-nested-core}/src/editors/integer/editor.rs (96%) rename {nested => lib-nested-core}/src/editors/integer/mod.rs (100%) rename {nested => lib-nested-core}/src/editors/integer/radix.rs (100%) rename {nested => lib-nested-core}/src/editors/list/cmd.rs (98%) rename {nested => lib-nested-core}/src/editors/list/ctx.rs (80%) rename {nested => lib-nested-core}/src/editors/list/cursor.rs (100%) rename {nested => lib-nested-core}/src/editors/list/editor.rs (98%) rename {nested => lib-nested-core}/src/editors/list/mod.rs (77%) rename {nested => lib-nested-core}/src/editors/list/nav.rs (100%) rename {nested => lib-nested-core}/src/editors/list/segment.rs (74%) rename nested/src/commander.rs => lib-nested-core/src/editors/mod.rs (75%) rename {nested => lib-nested-core}/src/editors/product/editor.rs (98%) rename {nested => lib-nested-core}/src/editors/product/mod.rs (100%) rename {nested => lib-nested-core}/src/editors/product/nav.rs (100%) rename {nested => lib-nested-core}/src/editors/product/segment.rs (100%) rename {nested => lib-nested-core}/src/editors/sum/editor.rs (87%) rename {nested => lib-nested-core}/src/editors/sum/mod.rs (100%) rename {nested => lib-nested-core}/src/editors/typeterm/cmd.rs (99%) rename {nested => lib-nested-core}/src/editors/typeterm/ctx.rs (97%) rename {nested => lib-nested-core}/src/editors/typeterm/mod.rs (99%) rename {nested => lib-nested-core}/src/editors/typeterm/nav.rs (100%) create mode 100644 lib-nested-core/src/lib.rs rename {nested => lib-nested-core}/src/tree/addr.rs (100%) rename {nested => lib-nested-core}/src/tree/cursor.rs (100%) create mode 100644 lib-nested-core/src/tree/diagnostics.rs rename {nested => lib-nested-core}/src/tree/mod.rs (91%) rename {nested => lib-nested-core}/src/tree/nav.rs (74%) rename {nested => lib-nested-core}/src/tree/node.rs (91%) rename {nested => lib-nested-core}/src/tree/treetype.rs (100%) rename {nested => lib-nested-core}/src/type_system/context.rs (100%) rename {nested => lib-nested-core}/src/type_system/mod.rs (100%) rename {nested => lib-nested-core}/src/type_system/repr_tree.rs (96%) rename {nested => lib-nested-core}/src/utils/bimap.rs (100%) rename {nested => lib-nested-core}/src/utils/mod.rs (83%) rename {nested => lib-nested-core}/src/utils/modulo.rs (100%) rename {terminal/ansi_parser => lib-nested-tty}/Cargo.toml (51%) rename {nested/src/terminal => lib-nested-tty/src}/ansi_parser.rs (99%) rename {nested/src/terminal => lib-nested-tty/src}/atom.rs (100%) rename {nested/src/utils => lib-nested-tty/src}/color.rs (100%) rename {nested/src/terminal => lib-nested-tty/src}/compositor.rs (97%) create mode 100644 lib-nested-tty/src/cursor_widget.rs rename {nested => lib-nested-tty}/src/diagnostics.rs (82%) rename nested/src/terminal/mod.rs => lib-nested-tty/src/lib.rs (82%) rename nested/src/editors/list/pty_editor.rs => lib-nested-tty/src/list_editor.rs (85%) rename {nested/src/terminal => lib-nested-tty/src}/style.rs (100%) create mode 100644 lib-nested-tty/src/sum_editor.rs rename {nested/src/terminal => lib-nested-tty/src}/terminal.rs (100%) rename {nested/src/terminal => lib-nested-tty/src}/widgets/ascii_box.rs (100%) rename {nested/src/terminal => lib-nested-tty/src}/widgets/mod.rs (100%) rename {nested/src/terminal => lib-nested-tty/src}/widgets/monstera.rs (100%) rename {nested/src/terminal => lib-nested-tty/src}/widgets/plot.rs (100%) delete mode 100644 math/fib/Cargo.toml delete mode 100644 math/fib/src/main.rs delete mode 100644 math/int2str/Cargo.toml delete mode 100644 math/int2str/src/main.rs delete mode 100644 math/radix_transform/Cargo.toml delete mode 100644 math/radix_transform/src/main.rs delete mode 100644 math/str2int/Cargo.toml delete mode 100644 math/str2int/src/main.rs delete mode 100644 nested/src/editors/mod.rs delete mode 100644 nested/src/lib.rs delete mode 100644 terminal/ansi_parser/src/main.rs delete mode 100644 terminal/display_server/Cargo.toml delete mode 100644 terminal/display_server/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 641b295..26d3208 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,6 @@ [workspace] members = [ - "nested", -# "terminal/display_server", -# "terminal/ansi_parser", -# "math/str2int", -# "math/int2str", -# "math/radix_transform", -# "math/fib" + "lib-nested-core", + "lib-nested-tty" ] + diff --git a/nested/Cargo.toml b/lib-nested-core/Cargo.toml similarity index 69% rename from nested/Cargo.toml rename to lib-nested-core/Cargo.toml index 8814165..984b580 100644 --- a/nested/Cargo.toml +++ b/lib-nested-core/Cargo.toml @@ -10,15 +10,7 @@ r3vi = { path = "../../lib-r3vi" } laddertypes = { path = "../../lib-laddertypes" } no_deadlocks = "*" cgmath = { version = "0.18.0", features = ["serde"] } -termion = "2.0.1" -vte = "0.10.1" -ansi_colours = "1.0" -signal-hook = "0.3.1" -signal-hook-async-std = "0.2.0" + serde = { version = "1.0", features = ["derive"] } bincode = "1.3.3" serde_json = "*" - -[dependencies.async-std] -version = "1.9.0" -features = ["unstable", "attributes"] diff --git a/nested/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs similarity index 91% rename from nested/src/editors/char/mod.rs rename to lib-nested-core/src/editors/char/mod.rs index 2521cb1..a42dcf3 100644 --- a/nested/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -9,9 +9,8 @@ use { laddertypes::{TypeTerm}, crate::{ type_system::{Context, ReprTree}, - terminal::{TerminalAtom}, tree::{NestedNode, TreeNavResult}, - commander::{ObjCommander} + editors::ObjCommander, }, std::sync::Arc, std::sync::RwLock @@ -49,7 +48,7 @@ impl ObjCommander for CharEditor { TreeNavResult::Exit } } else { - TreeNavResult::Exit + TreeNavResult::Exit } } } @@ -83,20 +82,15 @@ impl CharEditor { ), depth ) + /* todo: move to lib-nested-term .set_view(data .get_port() .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) .to_grid() ) + */ .set_cmd( editor.clone() ) .set_editor( editor.clone() ) } } -/* -use crate::StringGen; -impl StringGen for CharEditor { - fn get_string(&self) -> String { - String::from(self.get()) - } -} -*/ + diff --git a/nested/src/editors/integer/add.rs b/lib-nested-core/src/editors/integer/add.rs similarity index 100% rename from nested/src/editors/integer/add.rs rename to lib-nested-core/src/editors/integer/add.rs diff --git a/nested/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs similarity index 99% rename from nested/src/editors/integer/ctx.rs rename to lib-nested-core/src/editors/integer/ctx.rs index 99c9aa7..95b138d 100644 --- a/nested/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -62,6 +62,7 @@ pub fn init_ctx(ctx: &mut Context) { if args.len() > 1 { match args[1] { TypeTerm::Num(_radix) => { + /* FIXME PTYListController::for_node( &mut node, Some(','), @@ -72,7 +73,7 @@ pub fn init_ctx(ctx: &mut Context) { &mut node, ("0d", "", "") ); - +*/ Some(node) }, _ => None diff --git a/nested/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs similarity index 96% rename from nested/src/editors/integer/editor.rs rename to lib-nested-core/src/editors/integer/editor.rs index 3e11b34..73bd353 100644 --- a/nested/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -13,13 +13,8 @@ use { laddertypes::{TypeTerm}, crate::{ type_system::{Context, ReprTree}, - editors::list::{ListCmd, PTYListController, PTYListStyle}, - terminal::{ - TerminalAtom, TerminalStyle, make_label - }, - diagnostics::{Message}, - tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, - commander::ObjCommander + editors::{list::{ListCmd}, ObjCommander}, + tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}}, }, std::sync::Arc, std::sync::RwLock, @@ -56,6 +51,8 @@ impl ObjCommander for DigitEditor { add a message to the diagnostics view */ +/* + let message = IndexBuffer::from_iter(vec![ (Point2::new(1, 0), make_label("invalid digit '")), (Point2::new(2, 0), make_label(&format!("{}", c)) @@ -64,6 +61,8 @@ impl ObjCommander for DigitEditor { ]); self.msg.push(crate::diagnostics::make_error(message.get_port().flatten())); +*/ + self.data.set(Some(c)); } else { self.data.set(Some(c)); @@ -93,6 +92,7 @@ impl DigitEditor { NestedNode::new(ed.ctx.clone(), data, depth) .set_cmd(editor.clone()) + /* .set_view( ed.data .get_port() @@ -112,6 +112,7 @@ impl DigitEditor { .set_diag( ed.msg.get_port().to_sequence() ) + */ } pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> { @@ -159,7 +160,7 @@ impl PosIntEditor { TypeTerm::TypeID(ctx.read().unwrap().get_typeid("BigEndian").unwrap()) ] )); - +/* PTYListController::for_node( &mut node, Some(' '), None ); PTYListStyle::for_node( &mut node, ( @@ -174,7 +175,7 @@ impl PosIntEditor { "".into() ) ); - +*/ PosIntEditor { radix, digits: node diff --git a/nested/src/editors/integer/mod.rs b/lib-nested-core/src/editors/integer/mod.rs similarity index 100% rename from nested/src/editors/integer/mod.rs rename to lib-nested-core/src/editors/integer/mod.rs diff --git a/nested/src/editors/integer/radix.rs b/lib-nested-core/src/editors/integer/radix.rs similarity index 100% rename from nested/src/editors/integer/radix.rs rename to lib-nested-core/src/editors/integer/radix.rs diff --git a/nested/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs similarity index 98% rename from nested/src/editors/list/cmd.rs rename to lib-nested-core/src/editors/list/cmd.rs index 74c7fee..ffcb9f1 100644 --- a/nested/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -3,10 +3,9 @@ use { view::{singleton::*} }, crate::{ - editors::list::{ListEditor, ListCursor, ListCursorMode}, + editors::{list::{ListEditor, ListCursor, ListCursorMode}, ObjCommander}, type_system::{Context, ReprTree}, tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, - commander::{ObjCommander} }, std::sync::{Arc, RwLock} }; diff --git a/nested/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs similarity index 80% rename from nested/src/editors/list/ctx.rs rename to lib-nested-core/src/editors/list/ctx.rs index 91474f0..89376b7 100644 --- a/nested/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -3,7 +3,7 @@ use { laddertypes::{TypeTerm}, crate::{ type_system::{Context}, - editors::list::{ListEditor, PTYListController, PTYListStyle} + editors::list::{ListEditor}//, PTYListController, PTYListStyle} }, std::sync::{Arc, RwLock} }; @@ -24,8 +24,8 @@ pub fn init_ctx(ctx: &mut Context) { let mut node = ListEditor::new(ctx.clone(), typ).into_node(depth); - PTYListController::for_node( &mut node, Some(','), Some('}') ); - PTYListStyle::for_node( &mut node, ("{",", ","}") ); +// PTYListController::for_node( &mut node, Some(','), Some('}') ); +// PTYListStyle::for_node( &mut node, ("{",", ","}") ); Some(node) } else { diff --git a/nested/src/editors/list/cursor.rs b/lib-nested-core/src/editors/list/cursor.rs similarity index 100% rename from nested/src/editors/list/cursor.rs rename to lib-nested-core/src/editors/list/cursor.rs diff --git a/nested/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs similarity index 98% rename from nested/src/editors/list/editor.rs rename to lib-nested-core/src/editors/list/editor.rs index 31c1f1b..63b4644 100644 --- a/nested/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -1,15 +1,13 @@ use { r3vi::{ - view::{ViewPort, OuterViewPort, singleton::*, sequence::*}, + view::{OuterViewPort, singleton::*, sequence::*}, buffer::{singleton::*, vec::*} }, laddertypes::{TypeTerm}, crate::{ type_system::{Context, ReprTree}, - editors::list::{ListCursor, ListCursorMode, ListCmd}, - tree::{NestedNode, TreeNav, TreeCursor}, - diagnostics::Diagnostics, - commander::ObjCommander + editors::{list::{ListCursor, ListCursorMode, ListCmd}, ObjCommander}, + tree::{NestedNode, TreeNav, TreeCursor, diagnostics::Diagnostics}, }, std::sync::{Arc, RwLock} }; diff --git a/nested/src/editors/list/mod.rs b/lib-nested-core/src/editors/list/mod.rs similarity index 77% rename from nested/src/editors/list/mod.rs rename to lib-nested-core/src/editors/list/mod.rs index c929369..b788aae 100644 --- a/nested/src/editors/list/mod.rs +++ b/lib-nested-core/src/editors/list/mod.rs @@ -1,10 +1,8 @@ - pub mod cursor; pub mod editor; pub mod nav; pub mod segment; -pub mod pty_editor; pub mod cmd; pub mod ctx; @@ -12,7 +10,6 @@ pub use { cursor::{ListCursor, ListCursorMode}, editor::ListEditor, segment::{ListSegment, ListSegmentSequence}, - pty_editor::{PTYListStyle, PTYListController}, cmd::ListCmd, ctx::init_ctx }; diff --git a/nested/src/editors/list/nav.rs b/lib-nested-core/src/editors/list/nav.rs similarity index 100% rename from nested/src/editors/list/nav.rs rename to lib-nested-core/src/editors/list/nav.rs diff --git a/nested/src/editors/list/segment.rs b/lib-nested-core/src/editors/list/segment.rs similarity index 74% rename from nested/src/editors/list/segment.rs rename to lib-nested-core/src/editors/list/segment.rs index 4ae0368..5e8b611 100644 --- a/nested/src/editors/list/segment.rs +++ b/lib-nested-core/src/editors/list/segment.rs @@ -9,10 +9,7 @@ use { }, crate::{ editors::list::{ListCursor, ListCursorMode}, - terminal::{TerminalView, TerminalStyle, make_label}, - tree::{NestedNode, TreeNav}, - utils::color::{bg_style_from_depth, fg_style_from_depth}, - PtySegment + tree::{NestedNode} }, std::sync::Arc, std::sync::RwLock, @@ -26,39 +23,6 @@ pub enum ListSegment { } } -impl PtySegment for ListSegment { - fn pty_view(&self) -> OuterViewPort<dyn TerminalView> { - match self { - ListSegment::InsertCursor => { - make_label("|") - .map_item(move |_pt, atom| { - atom.add_style_front(TerminalStyle::fg_color((150,80,230))) - .add_style_front(TerminalStyle::bold(true)) - }) - } - ListSegment::Item{ editor, cur_dist } => { - let e = editor.clone(); - let cur_dist = *cur_dist; - editor.get_view().map_item(move |_pt, atom| { - let c = e.get_cursor(); - let cur_depth = c.tree_addr.len(); - let select = - if cur_dist == 0 { - cur_depth - } else { - usize::MAX - }; - - atom - .add_style_back(bg_style_from_depth(select)) - .add_style_back(TerminalStyle::bold(select==1)) - .add_style_back(fg_style_from_depth(e.depth.get_view().get())) - }) - } - } - } -} - pub struct ListSegmentSequence { data: Arc<dyn SequenceView<Item = NestedNode>>, cursor: Arc<dyn SingletonView<Item = ListCursor>>, diff --git a/nested/src/commander.rs b/lib-nested-core/src/editors/mod.rs similarity index 75% rename from nested/src/commander.rs rename to lib-nested-core/src/editors/mod.rs index fdbeaee..d48a5b3 100644 --- a/nested/src/commander.rs +++ b/lib-nested-core/src/editors/mod.rs @@ -1,4 +1,13 @@ +pub mod list; +//pub mod product; +pub mod sum; + +pub mod char; +pub mod integer; +pub mod typeterm; + + pub trait Commander { type Cmd; diff --git a/nested/src/editors/product/editor.rs b/lib-nested-core/src/editors/product/editor.rs similarity index 98% rename from nested/src/editors/product/editor.rs rename to lib-nested-core/src/editors/product/editor.rs index d3bdd9a..80acc24 100644 --- a/nested/src/editors/product/editor.rs +++ b/lib-nested-core/src/editors/product/editor.rs @@ -12,10 +12,6 @@ use { laddertypes::{TypeTerm}, crate::{ type_system::{Context}, - terminal::{ - TerminalEditor, TerminalEditorResult, - TerminalEvent, TerminalView - }, editors::{ list::ListCursorMode, product::{ diff --git a/nested/src/editors/product/mod.rs b/lib-nested-core/src/editors/product/mod.rs similarity index 100% rename from nested/src/editors/product/mod.rs rename to lib-nested-core/src/editors/product/mod.rs diff --git a/nested/src/editors/product/nav.rs b/lib-nested-core/src/editors/product/nav.rs similarity index 100% rename from nested/src/editors/product/nav.rs rename to lib-nested-core/src/editors/product/nav.rs diff --git a/nested/src/editors/product/segment.rs b/lib-nested-core/src/editors/product/segment.rs similarity index 100% rename from nested/src/editors/product/segment.rs rename to lib-nested-core/src/editors/product/segment.rs diff --git a/nested/src/editors/sum/editor.rs b/lib-nested-core/src/editors/sum/editor.rs similarity index 87% rename from nested/src/editors/sum/editor.rs rename to lib-nested-core/src/editors/sum/editor.rs index 14b7798..195c6b2 100644 --- a/nested/src/editors/sum/editor.rs +++ b/lib-nested-core/src/editors/sum/editor.rs @@ -8,14 +8,9 @@ use { }, laddertypes::{TypeTerm}, crate::{ - terminal::TerminalView, - editors::list::ListCursorMode, + editors::{list::ListCursorMode, ObjCommander}, type_system::{Context, ReprTree}, - tree::{TreeNav, TreeCursor, TreeNavResult}, - diagnostics::{Diagnostics, Message}, - tree::NestedNode, - commander::{ObjCommander}, - PtySegment + tree::{TreeNav, TreeCursor, TreeNavResult, diagnostics::{Diagnostics, Message}, NestedNode}, }, cgmath::{Vector2}, std::sync::{Arc, RwLock} @@ -28,7 +23,7 @@ pub struct SumEditor { addr_port: ViewPort< dyn SequenceView<Item = isize> >, mode_port: ViewPort< dyn SingletonView<Item = ListCursorMode> >, - port: ViewPort< dyn TerminalView >, +// port: ViewPort< dyn TerminalView >, diag_port: ViewPort< dyn SequenceView<Item = Message> > } @@ -36,12 +31,12 @@ impl SumEditor { pub fn new( editors: Vec< NestedNode > ) -> Self { - let port = ViewPort::new(); +// let port = ViewPort::new(); SumEditor { cur: 0, editors, - port, +// port, diag_port: ViewPort::new(), @@ -55,7 +50,7 @@ impl SumEditor { } pub fn into_node(self, ctx: Arc<RwLock<Context>>) -> NestedNode { - let view = self.pty_view(); +// let view = self.pty_view(); let editor = Arc::new(RwLock::new(self)); NestedNode::new( @@ -63,7 +58,7 @@ impl SumEditor { ReprTree::new_arc(TypeTerm::TypeID(ctx.read().unwrap().get_typeid("Sum").unwrap())), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() ) - .set_view(view) +// .set_view(view) .set_editor(editor.clone()) .set_cmd(editor.clone()) .set_nav(editor.clone()) @@ -76,6 +71,7 @@ impl SumEditor { pub fn select(&mut self, idx: usize) { self.cur = idx; +/* FIXME let tv = self.editors[ self.cur ].get_view(); tv.add_observer( self.port.get_cast() ); @@ -100,6 +96,7 @@ impl SumEditor { self.mode_port.update_hooks.write().unwrap().clear(); self.mode_port.add_update_hook( Arc::new(dv.0.clone()) ); self.mode_port.set_view( Some(dv.get_view_arc()) ); + */ } } @@ -129,12 +126,6 @@ impl TreeNav for SumEditor { } } -impl PtySegment for SumEditor { - fn pty_view(&self) -> OuterViewPort<dyn TerminalView> { - self.port.outer() - } -} - impl ObjCommander for SumEditor { fn send_cmd_obj(&mut self, obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { self.editors[ self.cur ].send_cmd_obj( obj ) diff --git a/nested/src/editors/sum/mod.rs b/lib-nested-core/src/editors/sum/mod.rs similarity index 100% rename from nested/src/editors/sum/mod.rs rename to lib-nested-core/src/editors/sum/mod.rs diff --git a/nested/src/editors/typeterm/cmd.rs b/lib-nested-core/src/editors/typeterm/cmd.rs similarity index 99% rename from nested/src/editors/typeterm/cmd.rs rename to lib-nested-core/src/editors/typeterm/cmd.rs index e219cc8..29ec6cb 100644 --- a/nested/src/editors/typeterm/cmd.rs +++ b/lib-nested-core/src/editors/typeterm/cmd.rs @@ -4,9 +4,8 @@ use { }, crate::{ type_system::{Context, ReprTree}, - editors::{list::{ListEditor, ListCmd, ListCursorMode}}, + editors::{list::{ListEditor, ListCmd, ListCursorMode}, ObjCommander}, tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, - commander::ObjCommander }, std::{sync::{Arc, RwLock}}, diff --git a/nested/src/editors/typeterm/ctx.rs b/lib-nested-core/src/editors/typeterm/ctx.rs similarity index 97% rename from nested/src/editors/typeterm/ctx.rs rename to lib-nested-core/src/editors/typeterm/ctx.rs index 4ad5b55..58a65e4 100644 --- a/nested/src/editors/typeterm/ctx.rs +++ b/lib-nested-core/src/editors/typeterm/ctx.rs @@ -5,12 +5,10 @@ use { laddertypes::{TypeTerm}, crate::{ type_system::{Context, MorphismTypePattern}, - terminal::{TerminalStyle, TerminalProjections}, editors::{ - list::{PTYListStyle, PTYListController, ListEditor, ListSegmentSequence}, + list::{ListEditor, ListSegmentSequence}, typeterm::{State, TypeTermEditor} - }, - PtySegment + } }, std::{sync::{Arc, RwLock}}, cgmath::{Point2} @@ -36,7 +34,7 @@ pub fn init_ctx(ctx: &mut Context) { let new_node = TypeTermEditor::with_node( ctx, node.clone(), State::Any ); Some(new_node) })); - +/* ctx.add_morphism( MorphismTypePattern { src_tyid: ctx.get_typeid("List"), dst_tyid: ctx.get_typeid("Type::Ladder").unwrap() }, Arc::new(|mut node, _dst_type: _| { @@ -140,5 +138,6 @@ pub fn init_ctx(ctx: &mut Context) { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { Some(TypeTermEditor::new_node(ctx, depth)) })); + */ } diff --git a/nested/src/editors/typeterm/mod.rs b/lib-nested-core/src/editors/typeterm/mod.rs similarity index 99% rename from nested/src/editors/typeterm/mod.rs rename to lib-nested-core/src/editors/typeterm/mod.rs index d15cbb4..a0c4c5c 100644 --- a/nested/src/editors/typeterm/mod.rs +++ b/lib-nested-core/src/editors/typeterm/mod.rs @@ -12,9 +12,8 @@ use { laddertypes::{TypeID, TypeTerm}, crate::{ type_system::{Context, ReprTree}, - editors::{list::{ListCursorMode, ListEditor, ListCmd}}, + editors::{list::{ListCursorMode, ListEditor, ListCmd}, ObjCommander}, tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, - commander::ObjCommander }, std::{sync::{Arc, RwLock}} }; @@ -207,7 +206,7 @@ impl TypeTermEditor { spillbuf: Arc::new(RwLock::new(Vec::new())), depth: cur_node.depth.clone() }; - +/* FIXME let view = editor.cur_node .get_port() .map(|node| { @@ -215,11 +214,12 @@ impl TypeTermEditor { }) .to_grid() .flatten(); + */ let _cc = editor.cur_node.get().close_char; let editor = Arc::new(RwLock::new(editor)); let mut super_node = NestedNode::new(ctx, data, cur_node.depth) - .set_view(view) +// .set_view(view) .set_nav(editor.clone()) .set_cmd(editor.clone()) .set_editor(editor.clone()); diff --git a/nested/src/editors/typeterm/nav.rs b/lib-nested-core/src/editors/typeterm/nav.rs similarity index 100% rename from nested/src/editors/typeterm/nav.rs rename to lib-nested-core/src/editors/typeterm/nav.rs diff --git a/lib-nested-core/src/lib.rs b/lib-nested-core/src/lib.rs new file mode 100644 index 0000000..285710c --- /dev/null +++ b/lib-nested-core/src/lib.rs @@ -0,0 +1,8 @@ +pub mod utils; +pub mod editors; +pub mod tree; +pub mod type_system; + +pub fn magic_header() { + eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>"); +} diff --git a/nested/src/tree/addr.rs b/lib-nested-core/src/tree/addr.rs similarity index 100% rename from nested/src/tree/addr.rs rename to lib-nested-core/src/tree/addr.rs diff --git a/nested/src/tree/cursor.rs b/lib-nested-core/src/tree/cursor.rs similarity index 100% rename from nested/src/tree/cursor.rs rename to lib-nested-core/src/tree/cursor.rs diff --git a/lib-nested-core/src/tree/diagnostics.rs b/lib-nested-core/src/tree/diagnostics.rs new file mode 100644 index 0000000..71fb079 --- /dev/null +++ b/lib-nested-core/src/tree/diagnostics.rs @@ -0,0 +1,24 @@ +use { + r3vi::{ + view::{OuterViewPort, sequence::*}, + buffer::{vec::*, index_hashmap::*} + }, + crate::{ + type_system::ReprTree + }, + std::sync::{Arc, RwLock}, + cgmath::Point2 +}; + +#[derive(Clone)] +pub struct Message { + pub addr: Vec<usize>, + pub disp: Arc<RwLock<ReprTree>> +} + +pub trait Diagnostics { + fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> { + VecBuffer::new().get_port().to_sequence() + } +} + diff --git a/nested/src/tree/mod.rs b/lib-nested-core/src/tree/mod.rs similarity index 91% rename from nested/src/tree/mod.rs rename to lib-nested-core/src/tree/mod.rs index 71e40c8..81251d0 100644 --- a/nested/src/tree/mod.rs +++ b/lib-nested-core/src/tree/mod.rs @@ -3,6 +3,7 @@ pub mod cursor; pub mod nav; pub mod node; pub mod treetype; +pub mod diagnostics; pub use { addr::TreeAddr, diff --git a/nested/src/tree/nav.rs b/lib-nested-core/src/tree/nav.rs similarity index 74% rename from nested/src/tree/nav.rs rename to lib-nested-core/src/tree/nav.rs index 9d85cdd..962834d 100644 --- a/nested/src/tree/nav.rs +++ b/lib-nested-core/src/tree/nav.rs @@ -15,8 +15,7 @@ use { }, crate::{ editors::list::ListCursorMode, - tree::TreeCursor, - terminal::{TerminalView, TerminalProjections, make_label} + tree::TreeCursor }, cgmath::Vector2, }; @@ -150,35 +149,6 @@ pub trait TreeNav { } } - fn get_cursor_widget(&self) -> OuterViewPort<dyn TerminalView> { - VecBuffer::with_data( - vec![ - make_label("@").with_fg_color((150, 80,230)), - self.get_addr_view() - .map(|i| - make_label(&format!("{}", i)).with_fg_color((0, 100, 20))) - .separate(make_label(".").with_fg_color((150, 80,230))) - .to_grid_horizontal() - .flatten(), - make_label(":").with_fg_color((150, 80,230)), - self.get_mode_view() - .map(|mode| { - make_label( - match mode { - ListCursorMode::Insert => "INSERT", - ListCursorMode::Select => "SELECT" - }) - .with_fg_color((200, 200, 20)) - }) - .to_grid() - .flatten(), - make_label(":").with_fg_color((150, 80,230)) - ] - ).get_port() - .to_sequence() - .to_grid_horizontal() - .flatten() - } } diff --git a/nested/src/tree/node.rs b/lib-nested-core/src/tree/node.rs similarity index 91% rename from nested/src/tree/node.rs rename to lib-nested-core/src/tree/node.rs index 1406c96..f0c9d16 100644 --- a/nested/src/tree/node.rs +++ b/lib-nested-core/src/tree/node.rs @@ -3,30 +3,28 @@ use { cgmath::{Vector2, Point2}, r3vi::{ view::{View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*}, - buffer::{singleton::*} + buffer::{singleton::*, vec::*} }, laddertypes::{TypeTerm}, crate::{ type_system::{ReprTree, Context}, - terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult, TerminalAtom}, - diagnostics::{Diagnostics, Message}, - tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp}, - editors::list::{ListCursorMode}, - commander::ObjCommander, + tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}}, + editors::{list::{ListCursorMode}, ObjCommander} } }; -/* TODO: refactoring proposal +//* TODO: refactoring proposal +/* struct NestedNodeDisplay { /// display view - pub view: Option< OuterViewPort<dyn TerminalView> >, + pub view: Option< Arc<RwLock<ReprTree>> >, /// diagnostics - pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >, + pub diag: Option< OuterViewPort<dyn SequenceView<Item = diagnostics::Message>> >, /// depth - pub depth: SingletonBuffer< usize >, + pub depth: SingletonBuffer< usize >, } struct NestedNodeEdit { @@ -40,7 +38,9 @@ struct NestedNodeEdit { /// commander & navigation pub cmd: SingletonBuffer< Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> > - >, + >, /// abstract data view + pub data: Arc<RwLock<ReprTree>>, + pub close_char: SingletonBuffer< Option< char > >, // could be replaced by cmd when TreeNav -CmdObjects are used @@ -62,7 +62,6 @@ pub struct NewNestedNode { /// editor & commander objects pub edit: NestedNodeEdit } - */ #[derive(Clone)] @@ -74,7 +73,7 @@ pub struct NestedNode { pub data: Arc<RwLock<ReprTree>>, /// display view - pub view: Option< OuterViewPort<dyn TerminalView> >, + pub view: Option< Arc<RwLock<ReprTree>> >, /// diagnostics pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >, @@ -129,7 +128,8 @@ impl NestedNode { buf.get_port().into() ), SingletonBuffer::new(0).get_port() - ) + ) + /* .set_view(buf.get_port() .map(|c| TerminalAtom::from(c)) .to_index() @@ -141,6 +141,7 @@ impl NestedNode { if *p == Point2::new(0,0) { Some(()) } else { None } }) ) + */ .set_editor(Arc::new(RwLock::new(buf))) } @@ -162,7 +163,7 @@ impl NestedNode { self } - pub fn set_view(mut self, view: OuterViewPort<dyn TerminalView>) -> Self { + pub fn set_view(mut self, view: Arc<RwLock<ReprTree>>) -> Self { self.view = Some(view); self } @@ -188,8 +189,8 @@ impl NestedNode { self.diag.clone().unwrap_or(ViewPort::new().into_outer()) } - pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> { - self.view.clone().unwrap_or(ViewPort::new().into_outer()) + pub fn get_view(&self) -> Option< Arc<RwLock<ReprTree>> > { + self.view.clone() } pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>> @@ -246,6 +247,7 @@ impl TreeType for NestedNode { /* TODO: remove that at some point */ +/* impl TerminalEditor for NestedNode { fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> { self.get_view() @@ -265,7 +267,7 @@ impl TerminalEditor for NestedNode { TerminalEditorResult::Continue } } - +*/ impl TreeNav for NestedNode { fn get_cursor(&self) -> TreeCursor { if let Some(tn) = self.tree_nav.get() { diff --git a/nested/src/tree/treetype.rs b/lib-nested-core/src/tree/treetype.rs similarity index 100% rename from nested/src/tree/treetype.rs rename to lib-nested-core/src/tree/treetype.rs diff --git a/nested/src/type_system/context.rs b/lib-nested-core/src/type_system/context.rs similarity index 100% rename from nested/src/type_system/context.rs rename to lib-nested-core/src/type_system/context.rs diff --git a/nested/src/type_system/mod.rs b/lib-nested-core/src/type_system/mod.rs similarity index 100% rename from nested/src/type_system/mod.rs rename to lib-nested-core/src/type_system/mod.rs diff --git a/nested/src/type_system/repr_tree.rs b/lib-nested-core/src/type_system/repr_tree.rs similarity index 96% rename from nested/src/type_system/repr_tree.rs rename to lib-nested-core/src/type_system/repr_tree.rs index 611565c..7e226f9 100644 --- a/nested/src/type_system/repr_tree.rs +++ b/lib-nested-core/src/type_system/repr_tree.rs @@ -56,6 +56,14 @@ impl ReprTree { ) } + pub fn from_u64(ctx: &Arc<RwLock<Context>>, v: u64) -> Arc<RwLock<Self>> { + let buf = r3vi::buffer::singleton::SingletonBuffer::<u64>::new(v); + ReprTree::new_leaf( + Context::parse(ctx, "<MachineInt 64>"), + buf.get_port().into() + ) + } + pub fn new_leaf(type_tag: impl Into<TypeTerm>, port: AnyOuterViewPort) -> Arc<RwLock<Self>> { let mut tree = ReprTree::new(type_tag.into()); tree.insert_leaf(vec![].into_iter(), port); diff --git a/nested/src/utils/bimap.rs b/lib-nested-core/src/utils/bimap.rs similarity index 100% rename from nested/src/utils/bimap.rs rename to lib-nested-core/src/utils/bimap.rs diff --git a/nested/src/utils/mod.rs b/lib-nested-core/src/utils/mod.rs similarity index 83% rename from nested/src/utils/mod.rs rename to lib-nested-core/src/utils/mod.rs index fe10469..8e8f5dd 100644 --- a/nested/src/utils/mod.rs +++ b/lib-nested-core/src/utils/mod.rs @@ -1,6 +1,5 @@ pub mod bimap; pub mod modulo; -pub mod color; pub use modulo::modulo; pub use bimap::Bimap; diff --git a/nested/src/utils/modulo.rs b/lib-nested-core/src/utils/modulo.rs similarity index 100% rename from nested/src/utils/modulo.rs rename to lib-nested-core/src/utils/modulo.rs diff --git a/terminal/ansi_parser/Cargo.toml b/lib-nested-tty/Cargo.toml similarity index 51% rename from terminal/ansi_parser/Cargo.toml rename to lib-nested-tty/Cargo.toml index 2b1ca1d..e85b2d9 100644 --- a/terminal/ansi_parser/Cargo.toml +++ b/lib-nested-tty/Cargo.toml @@ -1,13 +1,22 @@ [package] authors = ["Michael Sippel <micha@fragmental.art>"] -name = "ansi_parser" +name = "nested-tty" version = "0.1.0" edition = "2018" [dependencies] -nested = { path = "../../nested" } +r3vi = { path = "../../lib-r3vi" } +nested = { path = "../lib-nested-core" } cgmath = { version = "0.18.0", features = ["serde"] } serde = { version = "1.0", features = ["serde_derive"] } -bincode = "1.3.3" +termion = "2.0.3" vte = "0.10.1" ansi_colours = "1.0" +signal-hook = "*" +signal-hook-async-std = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] + + diff --git a/nested/src/terminal/ansi_parser.rs b/lib-nested-tty/src/ansi_parser.rs similarity index 99% rename from nested/src/terminal/ansi_parser.rs rename to lib-nested-tty/src/ansi_parser.rs index 669ee06..efd8a83 100644 --- a/nested/src/terminal/ansi_parser.rs +++ b/lib-nested-tty/src/ansi_parser.rs @@ -10,7 +10,7 @@ use { projection::projection_helper::ProjectionHelper, }, crate::{ - terminal::{TerminalAtom, TerminalStyle, TerminalView}, + TerminalAtom, TerminalStyle, TerminalView, }, cgmath::{Point2, Vector2}, std::io::Read, diff --git a/nested/src/terminal/atom.rs b/lib-nested-tty/src/atom.rs similarity index 100% rename from nested/src/terminal/atom.rs rename to lib-nested-tty/src/atom.rs diff --git a/nested/src/utils/color.rs b/lib-nested-tty/src/color.rs similarity index 100% rename from nested/src/utils/color.rs rename to lib-nested-tty/src/color.rs diff --git a/nested/src/terminal/compositor.rs b/lib-nested-tty/src/compositor.rs similarity index 97% rename from nested/src/terminal/compositor.rs rename to lib-nested-tty/src/compositor.rs index d8a53e4..e0774d6 100644 --- a/nested/src/terminal/compositor.rs +++ b/lib-nested-tty/src/compositor.rs @@ -6,7 +6,7 @@ use { }, projection::projection_helper::*, }, - crate::{terminal::{TerminalAtom, TerminalView}}, + crate::{TerminalAtom, TerminalView}, cgmath::Point2, std::sync::Arc, std::sync::RwLock, diff --git a/lib-nested-tty/src/cursor_widget.rs b/lib-nested-tty/src/cursor_widget.rs new file mode 100644 index 0000000..2504428 --- /dev/null +++ b/lib-nested-tty/src/cursor_widget.rs @@ -0,0 +1,33 @@ + +impl TreeNav { + fn get_cursor_widget(&self) -> OuterViewPort<dyn TerminalView> { + VecBuffer::with_data( + vec![ + make_label("@").with_fg_color((150, 80,230)), + self.get_addr_view() + .map(|i| + make_label(&format!("{}", i)).with_fg_color((0, 100, 20))) + .separate(make_label(".").with_fg_color((150, 80,230))) + .to_grid_horizontal() + .flatten(), + make_label(":").with_fg_color((150, 80,230)), + self.get_mode_view() + .map(|mode| { + make_label( + match mode { + ListCursorMode::Insert => "INSERT", + ListCursorMode::Select => "SELECT" + }) + .with_fg_color((200, 200, 20)) + }) + .to_grid() + .flatten(), + make_label(":").with_fg_color((150, 80,230)) + ] + ).get_port() + .to_sequence() + .to_grid_horizontal() + .flatten() + } +} + diff --git a/nested/src/diagnostics.rs b/lib-nested-tty/src/diagnostics.rs similarity index 82% rename from nested/src/diagnostics.rs rename to lib-nested-tty/src/diagnostics.rs index c1230c5..6ffad73 100644 --- a/nested/src/diagnostics.rs +++ b/lib-nested-tty/src/diagnostics.rs @@ -1,27 +1,3 @@ -use { - r3vi::{ - view::{OuterViewPort, sequence::*}, - buffer::{vec::*, index_hashmap::*} - }, - crate::{ - terminal::{ - TerminalView, TerminalStyle, make_label - } - }, - cgmath::Point2 -}; - -#[derive(Clone)] -pub struct Message { - pub addr: Vec<usize>, - pub port: OuterViewPort<dyn TerminalView> -} - -pub trait Diagnostics { - fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> { - VecBuffer::new().get_port().to_sequence() - } -} pub fn make_error(msg: OuterViewPort<dyn TerminalView>) -> Message { let mut mb = IndexBuffer::new(); diff --git a/nested/src/terminal/mod.rs b/lib-nested-tty/src/lib.rs similarity index 82% rename from nested/src/terminal/mod.rs rename to lib-nested-tty/src/lib.rs index 61e41b2..21e89e4 100644 --- a/nested/src/terminal/mod.rs +++ b/lib-nested-tty/src/lib.rs @@ -1,9 +1,20 @@ -pub mod ansi_parser; + +#![feature(trait_alias)] + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + pub mod atom; -pub mod compositor; pub mod style; + +pub mod compositor; +pub mod ansi_parser; + pub mod terminal; -pub mod widgets; + +//pub mod list_editor; +//pub mod widgets; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub use { atom::TerminalAtom, @@ -32,10 +43,17 @@ pub trait TerminalEditor { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +use r3vi::view::OuterViewPort; + +pub trait DisplaySegment { + fn display_view(&self) -> OuterViewPort<dyn TerminalView>; +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + use { r3vi::{ - view::{OuterViewPort}, - buffer::vec::*, + buffer::vec::*, }, cgmath::Point2, }; @@ -55,6 +73,8 @@ pub fn make_label(s: &str) -> OuterViewPort<dyn TerminalView> { v } +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + pub trait TerminalProjections { fn with_style(&self, style: TerminalStyle) -> OuterViewPort<dyn TerminalView>; fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView>; @@ -78,3 +98,4 @@ impl TerminalProjections for OuterViewPort<dyn TerminalView> { } } + diff --git a/nested/src/editors/list/pty_editor.rs b/lib-nested-tty/src/list_editor.rs similarity index 85% rename from nested/src/editors/list/pty_editor.rs rename to lib-nested-tty/src/list_editor.rs index 829aef4..663079d 100644 --- a/nested/src/editors/list/pty_editor.rs +++ b/lib-nested-tty/src/list_editor.rs @@ -3,20 +3,57 @@ use { view::{ViewPort, OuterViewPort, sequence::*}, projection::decorate_sequence::*, }, - crate::{ + nested::{ type_system::{Context, ReprTree}, editors::list::*, - terminal::{TerminalEvent, TerminalView, make_label}, tree::{TreeCursor, TreeNav, TreeNavResult}, tree::NestedNode, PtySegment }, + crate::{ + TerminalEvent, TerminalView, make_label + } std::sync::{Arc, RwLock}, termion::event::{Event, Key} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +impl PtySegment for ListSegment { + fn pty_view(&self) -> OuterViewPort<dyn TerminalView> { + match self { + ListSegment::InsertCursor => { + make_label("|") + .map_item(move |_pt, atom| { + atom.add_style_front(TerminalStyle::fg_color((150,80,230))) + .add_style_front(TerminalStyle::bold(true)) + }) + } + ListSegment::Item{ editor, cur_dist } => { + let e = editor.clone(); + let cur_dist = *cur_dist; + editor.get_view().map_item(move |_pt, atom| { + let c = e.get_cursor(); + let cur_depth = c.tree_addr.len(); + let select = + if cur_dist == 0 { + cur_depth + } else { + usize::MAX + }; + + atom + .add_style_back(bg_style_from_depth(select)) + .add_style_back(TerminalStyle::bold(select==1)) + .add_style_back(fg_style_from_depth(e.depth.get_view().get())) + }) + } + } + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + pub struct PTYListStyle { style: (String, String, String) } diff --git a/nested/src/terminal/style.rs b/lib-nested-tty/src/style.rs similarity index 100% rename from nested/src/terminal/style.rs rename to lib-nested-tty/src/style.rs diff --git a/lib-nested-tty/src/sum_editor.rs b/lib-nested-tty/src/sum_editor.rs new file mode 100644 index 0000000..626f249 --- /dev/null +++ b/lib-nested-tty/src/sum_editor.rs @@ -0,0 +1,8 @@ + + +impl PtySegment for SumEditor { + fn pty_view(&self) -> OuterViewPort<dyn TerminalView> { + self.port.outer() + } +} + diff --git a/nested/src/terminal/terminal.rs b/lib-nested-tty/src/terminal.rs similarity index 100% rename from nested/src/terminal/terminal.rs rename to lib-nested-tty/src/terminal.rs diff --git a/nested/src/terminal/widgets/ascii_box.rs b/lib-nested-tty/src/widgets/ascii_box.rs similarity index 100% rename from nested/src/terminal/widgets/ascii_box.rs rename to lib-nested-tty/src/widgets/ascii_box.rs diff --git a/nested/src/terminal/widgets/mod.rs b/lib-nested-tty/src/widgets/mod.rs similarity index 100% rename from nested/src/terminal/widgets/mod.rs rename to lib-nested-tty/src/widgets/mod.rs diff --git a/nested/src/terminal/widgets/monstera.rs b/lib-nested-tty/src/widgets/monstera.rs similarity index 100% rename from nested/src/terminal/widgets/monstera.rs rename to lib-nested-tty/src/widgets/monstera.rs diff --git a/nested/src/terminal/widgets/plot.rs b/lib-nested-tty/src/widgets/plot.rs similarity index 100% rename from nested/src/terminal/widgets/plot.rs rename to lib-nested-tty/src/widgets/plot.rs diff --git a/math/fib/Cargo.toml b/math/fib/Cargo.toml deleted file mode 100644 index 7f4efbb..0000000 --- a/math/fib/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "fib" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -nested = { path = "../../nested" } diff --git a/math/fib/src/main.rs b/math/fib/src/main.rs deleted file mode 100644 index b528448..0000000 --- a/math/fib/src/main.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::{ - fs::File, - io::{Read, Write}, - os::unix::io::FromRawFd, -}; - -fn fib(n: u64) -> u64 { - let mut y = 0; - let mut y1 = 1; - let mut y2 = 0; - - for _ in 0..n { - y = y1 + y2; - y2 = y1; - y1 = y; - } - - y -} - -fn main() { - nested::magic_header(); - - eprintln!(" Fibonacci Sequence"); - - nested::magic_header(); - - eprintln!( - " -interface (Sequence ℕ) 0 1" - ); - - let mut f0 = unsafe { File::from_raw_fd(0) }; - eprintln!( - " ->0: n - ( ℕ ) - ( MachineInt ) - ( MachineWord ) - ( Stream MachineSyllab ) -" - ); - - let mut f1 = unsafe { File::from_raw_fd(1) }; - eprintln!( - " -<1: n'th fibonacci number - ( ℕ ) - ( MachineInt ) - ( MachineWord ) - ( Stream MachineSyllab ) -" - ); - - nested::magic_header(); - - let mut bytes = [0 as u8; 8]; - f0.read_exact(&mut bytes).expect(""); - let n = u64::from_le_bytes(bytes); - bytes = fib(n).to_le_bytes(); - f1.write(&bytes).expect(""); -} diff --git a/math/int2str/Cargo.toml b/math/int2str/Cargo.toml deleted file mode 100644 index cdac039..0000000 --- a/math/int2str/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "int2str" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -nested = { path = "../../nested" } diff --git a/math/int2str/src/main.rs b/math/int2str/src/main.rs deleted file mode 100644 index 00cc669..0000000 --- a/math/int2str/src/main.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::{fs::File, io::Read, os::unix::io::FromRawFd}; - -fn main() { - nested::magic_header(); - eprintln!(" Human-readably Print MachineInt"); - nested::magic_header(); - - let mut f0 = unsafe { File::from_raw_fd(0) }; - eprintln!( - " ->0: - ( ℕ ) - ( MachineInt ) - ( MachineWord ) - ( Stream MachineSyllab ) -" - ); - - eprintln!( - " -<1: - ( ℕ ) - ( PositionalInt 10 BigEndian ) - ( Sequence ( Digit 10 ) ) - ( Sequence UTF-8-Char ) - ( Stream UTF-8-Char ) - ( Stream MachineSyllab ) -" - ); - - nested::magic_header(); - - let mut bytes = [0 as u8; 8]; - f0.read_exact(&mut bytes).expect(""); - println!("{}", u64::from_le_bytes(bytes)); -} diff --git a/math/radix_transform/Cargo.toml b/math/radix_transform/Cargo.toml deleted file mode 100644 index 678a012..0000000 --- a/math/radix_transform/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "radix_transform" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -nested = { path = "../../nested" } - -[dependencies.async-std] -version = "1.9.0" -features = ["unstable", "attributes"] diff --git a/math/radix_transform/src/main.rs b/math/radix_transform/src/main.rs deleted file mode 100644 index b1b48ff..0000000 --- a/math/radix_transform/src/main.rs +++ /dev/null @@ -1,137 +0,0 @@ -use nested::{ - core::{TypeDict, ViewPort}, - integer::RadixProjection, - vec::VecBuffer, -}; - -#[async_std::main] -async fn main() { - let mut td = TypeDict::new(); - for tn in vec![ - "MachineWord", - "MachineInt", - "MachineSyllab", - "Vec", - "Stream", - "Json", - "Sequence", - "UTF-8-Char", - "PositionalInt", - "Digit", - "LittleEndian", - "BigEndian", - "DiffStream", - "ℕ", - "$src_radix", - "$dst_radix", - ] { - td.add_typename(tn.into()); - } - - let radix_types = vec![ - td.type_term_from_str("( ℕ )").unwrap(), - td.type_term_from_str("( PositionalInt 10 LittleEndian )") - .unwrap(), - td.type_term_from_str("( Sequence ( Digit 10 ) )").unwrap(), - td.type_term_from_str("( Sequence UTF-8-Char )").unwrap(), - td.type_term_from_str("( Sequence MachineSyllab )").unwrap(), - ]; - - let src_types = vec![ - td.type_term_from_str("( ℕ )").unwrap(), - td.type_term_from_str("( PositionalInt $src_radix LittleEndian )") - .unwrap(), - td.type_term_from_str("( Sequence ( Digit $src_radix ) )") - .unwrap(), - td.type_term_from_str("( Sequence MachineInt )").unwrap(), - td.type_term_from_str("( DiffStream ( Vec MachineInt ) )") - .unwrap(), - td.type_term_from_str("( Json )").unwrap(), - td.type_term_from_str("( Stream UTF-8-Char )").unwrap(), - td.type_term_from_str("( Stream MachineSyllab )").unwrap(), - ]; - - let dst_types = vec![ - td.type_term_from_str("( ℕ )").unwrap(), - td.type_term_from_str("( PositionalInt $dst_radix LittleEndian )") - .unwrap(), - td.type_term_from_str("( Sequence ( Digit $dst_radix ) )") - .unwrap(), - td.type_term_from_str("( Sequence MachineInt )").unwrap(), - td.type_term_from_str("( DiffStream ( Vec MachineInt ) )") - .unwrap(), - td.type_term_from_str("( Json )").unwrap(), - td.type_term_from_str("( Stream UTF-8-Char )").unwrap(), - td.type_term_from_str("( Stream MachineSyllab )").unwrap(), - ]; - - nested::magic_header(); - eprintln!(" Convert Radix of Positional Integer"); - nested::magic_header(); - - eprintln!("\n$1: src_radix"); - for t in radix_types.iter() { - eprintln!(" {}", td.type_term_to_str(t)); - } - - eprintln!("\n$2: dst_radix"); - for t in radix_types.iter() { - eprintln!(" {}", td.type_term_to_str(t)); - } - - eprintln!("\n>0: n"); - for t in src_types.iter() { - eprintln!(" {}", td.type_term_to_str(t)); - } - - eprintln!("\n<1: n"); - for t in dst_types.iter() { - eprintln!(" {}", td.type_term_to_str(t)); - } - - nested::magic_header(); - - let mut args = std::env::args(); - args.next().expect("Arg $0 missing!"); - - let src_radix_str = args.next().expect("Arg $1 required!"); - let dst_radix_str = args.next().expect("Arg $2 required!"); - - let src_radix = usize::from_str_radix(&src_radix_str, 10).expect("could not parse src_radix"); - let dst_radix = usize::from_str_radix(&dst_radix_str, 10).expect("could not parse dst_radix"); - - assert!(src_radix > 1); - assert!(dst_radix > 1); - - let src_digits_port = ViewPort::new(); - let dst_digits_port = ViewPort::new(); - - let mut src_digits = VecBuffer::<usize>::new(src_digits_port.inner()); - - let _proj = RadixProjection::new( - src_radix, - dst_radix, - src_digits_port.outer().to_sequence(), - dst_digits_port.inner(), - ); - - // output dst digits - let writer = { - use std::os::unix::io::FromRawFd; - - dst_digits_port - .outer() - .serialize_json(unsafe { std::fs::File::from_raw_fd(1) }) - }; - - // start reading src digits - { - use async_std::os::unix::io::FromRawFd; - - src_digits - .from_json(unsafe { async_std::fs::File::from_raw_fd(0) }) - .await; - } - - drop(writer); -} diff --git a/math/str2int/Cargo.toml b/math/str2int/Cargo.toml deleted file mode 100644 index b85bed6..0000000 --- a/math/str2int/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "str2int" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -nested = { path = "../../nested" } diff --git a/math/str2int/src/main.rs b/math/str2int/src/main.rs deleted file mode 100644 index fa900b5..0000000 --- a/math/str2int/src/main.rs +++ /dev/null @@ -1,69 +0,0 @@ -use std::{ - fs::File, - io::{Read, Write}, - os::unix::io::FromRawFd, -}; - -fn main() { - nested::magic_header(); - eprintln!(" Parse MachineInt from String"); - nested::magic_header(); - - eprintln!( - " -$1: radix - ( ℕ ) - ( PositionalInt 10 BigEndian ) - ( Sequence ( Digit 10 ) ) - ( Sequence UTF-8-Char ) - ( Sequence MachineSyllab ) -" - ); - - eprintln!( - " ->0: n - ( ℕ ) - ( PositionalInt $radix BigEndian ) - ( Sequence ( Digit $radix ) ) - ( Sequence UTF-8-Char ) - ( Stream UTF-8-Char ) - ( Stream MachineSyllab ) -" - ); - - eprintln!( - " -<1: n - ( ℕ ) - ( MachineInt ) - ( MachineWord ) - ( Stream MachineSyllab ) -" - ); - - nested::magic_header(); - - let mut f0 = unsafe { File::from_raw_fd(0) }; - let mut f1 = unsafe { File::from_raw_fd(1) }; - - let mut args = std::env::args(); - args.next().expect("Arg $0 missing!"); - - let radix_str = args.next().expect("Arg $1 required!"); - - let radix = u32::from_str_radix(&radix_str, 10).expect("could not parse radix"); - if radix > 16 { - panic!("invalid radix! (radix<=16 required)"); - } - - let mut chars = Vec::new(); - f0.read_to_end(&mut chars).expect(""); - chars.retain(|c| (*c as char).is_alphanumeric()); - f1.write( - &u64::from_str_radix(&String::from_utf8_lossy(&chars), radix) - .unwrap() - .to_le_bytes(), - ) - .expect(""); -} diff --git a/nested/src/editors/mod.rs b/nested/src/editors/mod.rs deleted file mode 100644 index a93800c..0000000 --- a/nested/src/editors/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ - -pub mod list; -pub mod product; -pub mod sum; - -pub mod char; -pub mod integer; -pub mod typeterm; - diff --git a/nested/src/lib.rs b/nested/src/lib.rs deleted file mode 100644 index c81e77d..0000000 --- a/nested/src/lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![feature(trait_alias)] - -pub mod terminal; - -pub mod utils; -pub mod editors; -pub mod tree; -pub mod type_system; - -pub mod diagnostics; -pub mod commander; -//pub mod product; -//pub mod sum; -//pub mod list; - -pub fn magic_header() { - eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>"); -} - -/* -pub trait StringGen { - fn get_string(&self) -> String; -} - -use crate::{tree::{TreeNav}, diagnostics::Diagnostics, terminal::TerminalView, core::{OuterViewPort}}; - */ - -use r3vi::view::OuterViewPort; -use crate::terminal::TerminalView; - -pub trait PtySegment { - fn pty_view(&self) -> OuterViewPort<dyn TerminalView>; -} - diff --git a/terminal/ansi_parser/src/main.rs b/terminal/ansi_parser/src/main.rs deleted file mode 100644 index 0e4d532..0000000 --- a/terminal/ansi_parser/src/main.rs +++ /dev/null @@ -1,331 +0,0 @@ -#![feature(iter_advance_by)] - -use { - cgmath::Point2, - nested::terminal::{TerminalAtom, TerminalStyle}, - std::{ - fs::File, - io::{stdin, Read, Write}, - os::unix::io::FromRawFd, - }, - vte::{Params, Parser, Perform}, -}; - -struct ColorPalett { - black: (u8, u8, u8), - red: (u8, u8, u8), - green: (u8, u8, u8), - yellow: (u8, u8, u8), - blue: (u8, u8, u8), - magenta: (u8, u8, u8), - cyan: (u8, u8, u8), - white: (u8, u8, u8), -} - -struct PerfAtom { - colors: ColorPalett, - term_width: i16, - - cursor: Point2<i16>, - style: TerminalStyle, - - out: File, -} - -impl PerfAtom { - fn write_atom(&mut self, pos: Point2<i16>, atom: Option<TerminalAtom>) { - self.out - .write(&bincode::serialize(&(pos, atom)).unwrap()) - .expect(""); - } -} - -impl Perform for PerfAtom { - fn print(&mut self, c: char) { - //eprintln!("[print] {:?}", c); - self.write_atom(self.cursor, Some(TerminalAtom::new(c, self.style))); - - self.cursor.x += 1; - if self.cursor.x > self.term_width { - self.cursor.x = 0; - self.cursor.y += 1; - } - } - - fn execute(&mut self, byte: u8) { - //eprintln!("[execute] {:02x}", byte); - match byte { - b'\n' => { - self.cursor.x = 0; - self.cursor.y += 1; - } - _ => {} - } - } - - fn hook(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { - eprintln!( - "[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}", - params, intermediates, ignore, c - ); - } - - fn put(&mut self, byte: u8) { - eprintln!("[put] {:02x}", byte); - } - - fn unhook(&mut self) { - eprintln!("[unhook]"); - } - - fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) { - eprintln!( - "[osc_dispatch] params={:?} bell_terminated={}", - params, bell_terminated - ); - } - - fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { - eprintln!( - "[csi_dispatch] params={:#?}, intermediates={:?}, ignore={:?}, char={:?}", - params, intermediates, ignore, c - ); - - let mut piter = params.into_iter(); - - match c { - // Set SGR - 'm' => { - while let Some(n) = piter.next() { - match n[0] { - 0 => self.style = TerminalStyle::default(), - 1 => self.style = self.style.add(TerminalStyle::bold(true)), - 3 => self.style = self.style.add(TerminalStyle::italic(true)), - 4 => self.style = self.style.add(TerminalStyle::underline(true)), - - 30 => { - self.style = self.style.add(TerminalStyle::fg_color(self.colors.black)) - } - 40 => { - self.style = self.style.add(TerminalStyle::bg_color(self.colors.black)) - } - 31 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.red)), - 41 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.red)), - 32 => { - self.style = self.style.add(TerminalStyle::fg_color(self.colors.green)) - } - 42 => { - self.style = self.style.add(TerminalStyle::bg_color(self.colors.green)) - } - 33 => { - self.style = self.style.add(TerminalStyle::fg_color(self.colors.yellow)) - } - 43 => { - self.style = self.style.add(TerminalStyle::bg_color(self.colors.yellow)) - } - 34 => { - self.style = self.style.add(TerminalStyle::fg_color(self.colors.blue)) - } - 44 => { - self.style = self.style.add(TerminalStyle::bg_color(self.colors.blue)) - } - 35 => { - self.style = - self.style.add(TerminalStyle::fg_color(self.colors.magenta)) - } - 45 => { - self.style = - self.style.add(TerminalStyle::bg_color(self.colors.magenta)) - } - 36 => { - self.style = self.style.add(TerminalStyle::fg_color(self.colors.cyan)) - } - 46 => { - self.style = self.style.add(TerminalStyle::bg_color(self.colors.cyan)) - } - 37 => { - self.style = self.style.add(TerminalStyle::fg_color(self.colors.white)) - } - 47 => { - self.style = self.style.add(TerminalStyle::bg_color(self.colors.white)) - } - - 38 => { - let x = piter.next().unwrap(); - match x[0] { - 2 => { - let r = piter.next().unwrap(); - let g = piter.next().unwrap(); - let b = piter.next().unwrap(); - self.style = self.style.add(TerminalStyle::fg_color(( - r[0] as u8, - g[0] as u8, - b[30] as u8, - ))) - } - 5 => { - let v = piter.next().unwrap(); - self.style = self.style.add(TerminalStyle::fg_color( - ansi_colours::rgb_from_ansi256(v[0] as u8), - )) - } - _ => {} - } - } - - 48 => { - let x = piter.next().unwrap(); - match x[0] { - 2 => { - let r = piter.next().unwrap(); - let g = piter.next().unwrap(); - let b = piter.next().unwrap(); - self.style = self.style.add(TerminalStyle::bg_color(( - r[0] as u8, - g[0] as u8, - b[30] as u8, - ))) - } - 5 => { - let v = piter.next().unwrap(); - self.style = self.style.add(TerminalStyle::bg_color( - ansi_colours::rgb_from_ansi256(v[0] as u8), - )) - } - _ => {} - } - } - - _ => {} - } - } - } - - 'H' => { - if let Some(y) = piter.next() { - self.cursor.y = y[0] as i16 - 1 - }; - if let Some(x) = piter.next() { - self.cursor.x = x[0] as i16 - 1 - }; - - eprintln!("cursor at {:?}", self.cursor); - } - - 'A' => { - self.cursor.y -= piter.next().unwrap()[0] as i16; - } - 'B' => { - self.cursor.y += piter.next().unwrap()[0] as i16; - } - 'C' => { - self.cursor.x += piter.next().unwrap()[0] as i16; - } - 'D' => { - self.cursor.x -= piter.next().unwrap()[0] as i16; - } - 'E' => { - self.cursor.x = 0; - self.cursor.y += piter.next().unwrap()[0] as i16; - } - - 'J' => { - let x = piter.next().unwrap_or(&[0 as u16; 1]); - match x[0] { - 0 => {} - 1 => {} - 2 => { - for y in 0..100 { - for x in 0..self.term_width { - self.write_atom(Point2::new(x, y), None); - } - } - } - - // invalid - _ => {} - } - } - - 'K' => { - let x = piter.next().unwrap(); - match x[0] { - // clear cursor until end - 0 => { - for x in self.cursor.x..self.term_width { - self.write_atom(Point2::new(x, self.cursor.y), None); - } - } - - // clear start until cursor - 1 => { - for x in 0..self.cursor.x { - self.write_atom(Point2::new(x, self.cursor.y), None); - } - } - - // clear entire line - 2 => { - for x in 0..self.term_width { - self.write_atom(Point2::new(x, self.cursor.y), None); - } - } - - // invalid - _ => {} - } - } - - _ => {} - } - } - - fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) { - eprintln!( - "[esc_dispatch] intermediates={:?}, ignore={:?}, byte={:02x}", - intermediates, ignore, byte - ); - } -} - -fn main() { - let input = stdin(); - let mut handle = input.lock(); - - let mut statemachine = Parser::new(); - let mut performer = PerfAtom { - cursor: Point2::new(0, 0), - style: TerminalStyle::default(), - term_width: 200, - out: unsafe { File::from_raw_fd(1) }, - - colors: ColorPalett { - black: (1, 1, 1), - red: (222, 56, 43), - green: (0, 64, 0), - yellow: (255, 199, 6), - blue: (0, 111, 184), - magenta: (118, 38, 113), - cyan: (44, 181, 233), - white: (204, 204, 204), - }, - }; - - let mut buf = [0; 2048]; - - loop { - match handle.read(&mut buf) { - Ok(0) => break, - Ok(n) => { - for byte in &buf[..n] { - statemachine.advance(&mut performer, *byte); - performer.out.flush().unwrap(); - } - } - Err(err) => { - println!("err: {}", err); - break; - } - } - } -} diff --git a/terminal/display_server/Cargo.toml b/terminal/display_server/Cargo.toml deleted file mode 100644 index 4d933da..0000000 --- a/terminal/display_server/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -authors = ["Michael Sippel <micha@fragmental.art>"] -name = "display_server" -version = "0.1.0" -edition = "2018" - -[dependencies] -nested = { path = "../../nested" } -termion = "1.5.5" -cgmath = { version = "0.18.0", features = ["serde"] } -serde = { version = "1.0", features = ["serde_derive"] } -bincode = "1.3.3" diff --git a/terminal/display_server/src/main.rs b/terminal/display_server/src/main.rs deleted file mode 100644 index a3f52fc..0000000 --- a/terminal/display_server/src/main.rs +++ /dev/null @@ -1,67 +0,0 @@ -use { - cgmath::{Point2, Vector2}, - nested::terminal::{TerminalAtom, TerminalStyle}, - std::io::{stdout, Read, Write}, - termion::raw::IntoRawMode, -}; - -fn main() { - let mut out = stdout().into_raw_mode().unwrap(); - write!( - out, - "{}{}{}", - termion::cursor::Hide, - termion::cursor::Goto(1, 1), - termion::style::Reset - ) - .unwrap(); - - let mut cur_pos = Point2::<i16>::new(0, 0); - let mut cur_style = TerminalStyle::default(); - - let mut input = std::io::stdin(); - - loop { - match bincode::deserialize_from::<_, (Point2<i16>, Option<TerminalAtom>)>(input.by_ref()) { - Ok((pos, atom)) => { - if pos != cur_pos { - write!( - out, - "{}", - termion::cursor::Goto(pos.x as u16 + 1, pos.y as u16 + 1) - ) - .unwrap(); - } - - if let Some(atom) = atom { - if cur_style != atom.style { - cur_style = atom.style; - write!(out, "{}", atom.style).expect(""); - } - - write!(out, "{}", atom.c.unwrap_or(' ')).expect(""); - } else { - write!(out, "{} ", termion::style::Reset).expect(""); - cur_style = TerminalStyle::default(); - } - - cur_pos = pos + Vector2::new(1, 0); - - out.flush().unwrap(); - } - Err(err) => { - match *err { - bincode::ErrorKind::Io(_io_error) => break, - err => { - eprintln!("deserialization error\n{:?}", err); - } - } - break; - } - } - } - - // restore conventional terminal settings - write!(out, "{}", termion::cursor::Show).unwrap(); - out.flush().unwrap(); -} From f8e872acdac3d7122137f17b166680a6d6f79d7b Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 26 Nov 2023 22:08:43 +0100 Subject: [PATCH 02/75] Cargo.toml remove unneccesary dependencies --- lib-nested-core/Cargo.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib-nested-core/Cargo.toml b/lib-nested-core/Cargo.toml index 984b580..f7b1235 100644 --- a/lib-nested-core/Cargo.toml +++ b/lib-nested-core/Cargo.toml @@ -5,12 +5,7 @@ name = "nested" version = "0.1.0" [dependencies] -#r3vi = { git = "https://git.exobiont.de/senvas/lib-r3vi.git" } r3vi = { path = "../../lib-r3vi" } laddertypes = { path = "../../lib-laddertypes" } -no_deadlocks = "*" cgmath = { version = "0.18.0", features = ["serde"] } -serde = { version = "1.0", features = ["derive"] } -bincode = "1.3.3" -serde_json = "*" From ea38b0f9b062fc7474642569297732b321e199a4 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 26 Nov 2023 22:09:03 +0100 Subject: [PATCH 03/75] add hello world example --- Cargo.toml | 3 +- examples/tty-01-hello/Cargo.toml | 18 ++++++ examples/tty-01-hello/src/main.rs | 101 ++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 examples/tty-01-hello/Cargo.toml create mode 100644 examples/tty-01-hello/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 26d3208..707f44e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "lib-nested-core", - "lib-nested-tty" + "lib-nested-tty", + "examples/tty-01-hello" ] diff --git a/examples/tty-01-hello/Cargo.toml b/examples/tty-01-hello/Cargo.toml new file mode 100644 index 0000000..4582fd7 --- /dev/null +++ b/examples/tty-01-hello/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "tty-01-hello" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +r3vi = { path = "../../../lib-r3vi" } +nested = { path = "../../lib-nested-core" } +nested-tty = { path = "../../lib-nested-tty" } +termion = "*" +cgmath = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] + diff --git a/examples/tty-01-hello/src/main.rs b/examples/tty-01-hello/src/main.rs new file mode 100644 index 0000000..3dedd2b --- /dev/null +++ b/examples/tty-01-hello/src/main.rs @@ -0,0 +1,101 @@ +extern crate r3vi; +extern crate nested; +extern crate nested_tty; +extern crate termion; +extern crate cgmath; + +use { + r3vi::view::{ + ViewPort, + port::UpdateTask + }, + nested::{ + tree::{NestedNode}, + type_system::{Context, ReprTree} + }, + nested_tty::{ + Terminal, TerminalView, TerminalEvent, + TerminalStyle, + TerminalCompositor + }, + cgmath::Vector2, + termion::event::{Event, Key}, + std::sync::{Arc, RwLock} +}; + + +/* this task handles all terminal events (e.g. key press, resize) + */ +pub async fn event_loop( + mut term: Terminal, + term_port: ViewPort<dyn TerminalView>, + portmutex: Arc<RwLock<()>> +) { + loop { + let ev = term.next_event().await; + let _l = portmutex.write().unwrap(); + + if ev == TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) { + break; + } + term_port.update(); + } +} + +/* this task will continuously pull forward + * all notifications which are influencing + * the view in `term_port` + */ +pub async fn update_loop( + term_port: ViewPort<dyn TerminalView>, + portmutex: Arc<RwLock<()>> +) { + loop { + { + let _l = portmutex.write().unwrap(); + term_port.update(); + } + async_std::task::sleep(std::time::Duration::from_millis(500)).await; + } +} + +#[async_std::main] +async fn main() { + /* initialize our terminal + */ + let term_port = ViewPort::new(); + + let mut term = Terminal::new(term_port.outer()); + let term_writer = term.get_writer(); + + let portmutex = Arc::new(RwLock::new(())); + + /* spawn event-handling & updating tasks + */ + async_std::task::spawn( + update_loop(term_port.clone(), portmutex.clone())); + + async_std::task::spawn( + event_loop(term, term_port.clone(), portmutex.clone())); + + /* populate the view in `term_port` + */ + let compositor = TerminalCompositor::new(term_port.inner()); + + compositor.write().unwrap().push( + nested_tty::make_label("test") + .offset(Vector2::new(7,2))); + + compositor.write().unwrap().push( + nested_tty::make_label("Hello World") + .map_item(|p,a| + a.add_style_back( + TerminalStyle::fg_color(( (25*p.x%255) as u8, 200, 0 )) )) + .offset(Vector2::new(5, 3))); + + /* write the changes in the view of `term_port` to the terminal + */ + term_writer.show().await.expect("output error!"); +} + + From b1c17da75f01358b41538278435c10ce1446124a Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 26 Nov 2023 22:16:49 +0100 Subject: [PATCH 04/75] remove bimap (no longer needed since it is in lib-laddertypes now) --- lib-nested-core/src/utils/bimap.rs | 24 ------------------------ lib-nested-core/src/utils/mod.rs | 3 --- 2 files changed, 27 deletions(-) delete mode 100644 lib-nested-core/src/utils/bimap.rs diff --git a/lib-nested-core/src/utils/bimap.rs b/lib-nested-core/src/utils/bimap.rs deleted file mode 100644 index 8bd41b6..0000000 --- a/lib-nested-core/src/utils/bimap.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::{collections::HashMap, hash::Hash}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct Bimap<V: Eq + Hash, Λ: Eq + Hash> { - pub mλ: HashMap<V, Λ>, - pub my: HashMap<Λ, V>, -} - -impl<V: Eq + Hash + Clone, Λ: Eq + Hash + Clone> Bimap<V, Λ> { - pub fn new() -> Self { - Bimap { - mλ: HashMap::new(), - my: HashMap::new(), - } - } - - pub fn insert(&mut self, y: V, λ: Λ) { - self.mλ.insert(y.clone(), λ.clone()); - self.my.insert(λ, y); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/lib-nested-core/src/utils/mod.rs b/lib-nested-core/src/utils/mod.rs index 8e8f5dd..f97b6e5 100644 --- a/lib-nested-core/src/utils/mod.rs +++ b/lib-nested-core/src/utils/mod.rs @@ -1,5 +1,2 @@ -pub mod bimap; pub mod modulo; - pub use modulo::modulo; -pub use bimap::Bimap; From f3ad5c78d77d1b3d728063164a861c1092e57735 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 27 Nov 2023 04:18:46 +0100 Subject: [PATCH 05/75] rename submodules to reprTree & editTree --- examples/tty-01-hello/src/main.rs | 56 +++++++------------ lib-nested-core/Cargo.toml | 2 +- .../src/{tree => editTree}/addr.rs | 0 .../src/{tree => editTree}/cursor.rs | 0 .../src/{tree => editTree}/diagnostics.rs | 2 +- lib-nested-core/src/{tree => editTree}/mod.rs | 0 lib-nested-core/src/{tree => editTree}/nav.rs | 2 +- .../src/{tree => editTree}/node.rs | 4 +- .../src/{tree => editTree}/treetype.rs | 2 +- lib-nested-core/src/editors/char/mod.rs | 4 +- lib-nested-core/src/editors/integer/ctx.rs | 4 +- lib-nested-core/src/editors/integer/editor.rs | 4 +- lib-nested-core/src/editors/list/cmd.rs | 4 +- lib-nested-core/src/editors/list/ctx.rs | 2 +- lib-nested-core/src/editors/list/editor.rs | 10 ++-- lib-nested-core/src/editors/list/nav.rs | 2 +- lib-nested-core/src/editors/list/segment.rs | 2 +- lib-nested-core/src/editors/mod.rs | 4 +- lib-nested-core/src/editors/sum/editor.rs | 4 +- lib-nested-core/src/editors/typeterm/cmd.rs | 4 +- lib-nested-core/src/editors/typeterm/ctx.rs | 2 +- lib-nested-core/src/editors/typeterm/mod.rs | 4 +- lib-nested-core/src/editors/typeterm/nav.rs | 2 +- lib-nested-core/src/lib.rs | 7 +-- .../src/{type_system => reprTree}/context.rs | 4 +- .../repr_tree.rs => reprTree/mod.rs} | 9 ++- lib-nested-core/src/type_system/mod.rs | 8 --- 27 files changed, 61 insertions(+), 87 deletions(-) rename lib-nested-core/src/{tree => editTree}/addr.rs (100%) rename lib-nested-core/src/{tree => editTree}/cursor.rs (100%) rename lib-nested-core/src/{tree => editTree}/diagnostics.rs (93%) rename lib-nested-core/src/{tree => editTree}/mod.rs (100%) rename lib-nested-core/src/{tree => editTree}/nav.rs (99%) rename lib-nested-core/src/{tree => editTree}/node.rs (98%) rename lib-nested-core/src/{tree => editTree}/treetype.rs (85%) rename lib-nested-core/src/{type_system => reprTree}/context.rs (99%) rename lib-nested-core/src/{type_system/repr_tree.rs => reprTree/mod.rs} (98%) delete mode 100644 lib-nested-core/src/type_system/mod.rs diff --git a/examples/tty-01-hello/src/main.rs b/examples/tty-01-hello/src/main.rs index 3dedd2b..45aae38 100644 --- a/examples/tty-01-hello/src/main.rs +++ b/examples/tty-01-hello/src/main.rs @@ -1,35 +1,24 @@ -extern crate r3vi; +extern crate cgmath; extern crate nested; extern crate nested_tty; +extern crate r3vi; extern crate termion; -extern crate cgmath; use { - r3vi::view::{ - ViewPort, - port::UpdateTask - }, - nested::{ - tree::{NestedNode}, - type_system::{Context, ReprTree} - }, - nested_tty::{ - Terminal, TerminalView, TerminalEvent, - TerminalStyle, - TerminalCompositor - }, cgmath::Vector2, + nested::reprTree::Context, + nested_tty::{Terminal, TerminalCompositor, TerminalEvent, TerminalStyle, TerminalView}, + r3vi::view::{port::UpdateTask, ViewPort}, + std::sync::{Arc, RwLock}, termion::event::{Event, Key}, - std::sync::{Arc, RwLock} }; - /* this task handles all terminal events (e.g. key press, resize) */ pub async fn event_loop( mut term: Terminal, term_port: ViewPort<dyn TerminalView>, - portmutex: Arc<RwLock<()>> + portmutex: Arc<RwLock<()>>, ) { loop { let ev = term.next_event().await; @@ -46,10 +35,7 @@ pub async fn event_loop( * all notifications which are influencing * the view in `term_port` */ -pub async fn update_loop( - term_port: ViewPort<dyn TerminalView>, - portmutex: Arc<RwLock<()>> -) { +pub async fn update_loop(term_port: ViewPort<dyn TerminalView>, portmutex: Arc<RwLock<()>>) { loop { { let _l = portmutex.write().unwrap(); @@ -64,7 +50,7 @@ async fn main() { /* initialize our terminal */ let term_port = ViewPort::new(); - + let mut term = Terminal::new(term_port.outer()); let term_writer = term.get_writer(); @@ -72,30 +58,28 @@ async fn main() { /* spawn event-handling & updating tasks */ - async_std::task::spawn( - update_loop(term_port.clone(), portmutex.clone())); + async_std::task::spawn(update_loop(term_port.clone(), portmutex.clone())); - async_std::task::spawn( - event_loop(term, term_port.clone(), portmutex.clone())); + async_std::task::spawn(event_loop(term, term_port.clone(), portmutex.clone())); /* populate the view in `term_port` */ let compositor = TerminalCompositor::new(term_port.inner()); - compositor.write().unwrap().push( - nested_tty::make_label("test") - .offset(Vector2::new(7,2))); + compositor + .write() + .unwrap() + .push(nested_tty::make_label("test").offset(Vector2::new(7, 2))); compositor.write().unwrap().push( nested_tty::make_label("Hello World") - .map_item(|p,a| - a.add_style_back( - TerminalStyle::fg_color(( (25*p.x%255) as u8, 200, 0 )) )) - .offset(Vector2::new(5, 3))); + .map_item(|p, a| { + a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) + }) + .offset(Vector2::new(5, 3)), + ); /* write the changes in the view of `term_port` to the terminal */ term_writer.show().await.expect("output error!"); } - - diff --git a/lib-nested-core/Cargo.toml b/lib-nested-core/Cargo.toml index f7b1235..0805fce 100644 --- a/lib-nested-core/Cargo.toml +++ b/lib-nested-core/Cargo.toml @@ -7,5 +7,5 @@ version = "0.1.0" [dependencies] r3vi = { path = "../../lib-r3vi" } laddertypes = { path = "../../lib-laddertypes" } -cgmath = { version = "0.18.0", features = ["serde"] } +cgmath = { version = "0.18.0", features = ["serde"] } diff --git a/lib-nested-core/src/tree/addr.rs b/lib-nested-core/src/editTree/addr.rs similarity index 100% rename from lib-nested-core/src/tree/addr.rs rename to lib-nested-core/src/editTree/addr.rs diff --git a/lib-nested-core/src/tree/cursor.rs b/lib-nested-core/src/editTree/cursor.rs similarity index 100% rename from lib-nested-core/src/tree/cursor.rs rename to lib-nested-core/src/editTree/cursor.rs diff --git a/lib-nested-core/src/tree/diagnostics.rs b/lib-nested-core/src/editTree/diagnostics.rs similarity index 93% rename from lib-nested-core/src/tree/diagnostics.rs rename to lib-nested-core/src/editTree/diagnostics.rs index 71fb079..0983f5b 100644 --- a/lib-nested-core/src/tree/diagnostics.rs +++ b/lib-nested-core/src/editTree/diagnostics.rs @@ -4,7 +4,7 @@ use { buffer::{vec::*, index_hashmap::*} }, crate::{ - type_system::ReprTree + reprTree::ReprTree }, std::sync::{Arc, RwLock}, cgmath::Point2 diff --git a/lib-nested-core/src/tree/mod.rs b/lib-nested-core/src/editTree/mod.rs similarity index 100% rename from lib-nested-core/src/tree/mod.rs rename to lib-nested-core/src/editTree/mod.rs diff --git a/lib-nested-core/src/tree/nav.rs b/lib-nested-core/src/editTree/nav.rs similarity index 99% rename from lib-nested-core/src/tree/nav.rs rename to lib-nested-core/src/editTree/nav.rs index 962834d..c2aca14 100644 --- a/lib-nested-core/src/tree/nav.rs +++ b/lib-nested-core/src/editTree/nav.rs @@ -15,7 +15,7 @@ use { }, crate::{ editors::list::ListCursorMode, - tree::TreeCursor + editTree::TreeCursor }, cgmath::Vector2, }; diff --git a/lib-nested-core/src/tree/node.rs b/lib-nested-core/src/editTree/node.rs similarity index 98% rename from lib-nested-core/src/tree/node.rs rename to lib-nested-core/src/editTree/node.rs index f0c9d16..ad66127 100644 --- a/lib-nested-core/src/tree/node.rs +++ b/lib-nested-core/src/editTree/node.rs @@ -7,8 +7,8 @@ use { }, laddertypes::{TypeTerm}, crate::{ - type_system::{ReprTree, Context}, - tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}}, + reprTree::{ReprTree, Context}, + editTree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}}, editors::{list::{ListCursorMode}, ObjCommander} } }; diff --git a/lib-nested-core/src/tree/treetype.rs b/lib-nested-core/src/editTree/treetype.rs similarity index 85% rename from lib-nested-core/src/tree/treetype.rs rename to lib-nested-core/src/editTree/treetype.rs index 9f66849..4fed7a7 100644 --- a/lib-nested-core/src/tree/treetype.rs +++ b/lib-nested-core/src/editTree/treetype.rs @@ -2,7 +2,7 @@ use { laddertypes::{TypeTerm, TypeID}, crate::{ - tree::{TreeAddr} + editTree::{TreeAddr} } }; diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index a42dcf3..2fb66de 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -8,8 +8,8 @@ use { }, laddertypes::{TypeTerm}, crate::{ - type_system::{Context, ReprTree}, - tree::{NestedNode, TreeNavResult}, + reprTree::{Context, ReprTree}, + editTree::{NestedNode, TreeNavResult}, editors::ObjCommander, }, std::sync::Arc, diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 95b138d..5f5859a 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -5,12 +5,12 @@ use { }, laddertypes::{TypeTerm}, crate::{ - type_system::{Context}, + reprTree::{Context}, + reprTree::{MorphismTypePattern}, editors::{ list::*, integer::* }, - type_system::{MorphismTypePattern}, }, std::sync::{Arc, RwLock} }; diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index 73bd353..c58b984 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -12,9 +12,9 @@ use { }, laddertypes::{TypeTerm}, crate::{ - type_system::{Context, ReprTree}, editors::{list::{ListCmd}, ObjCommander}, - tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}}, + reprTree::{Context, ReprTree}, + editTree::{NestedNode, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}}, }, std::sync::Arc, std::sync::RwLock, diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs index ffcb9f1..59a28e7 100644 --- a/lib-nested-core/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -4,8 +4,8 @@ use { }, crate::{ editors::{list::{ListEditor, ListCursor, ListCursorMode}, ObjCommander}, - type_system::{Context, ReprTree}, - tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, + reprTree::{Context, ReprTree}, + editTree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, }, std::sync::{Arc, RwLock} }; diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 89376b7..67a73d1 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -2,7 +2,7 @@ use { r3vi::{view::{OuterViewPort, singleton::*}}, laddertypes::{TypeTerm}, crate::{ - type_system::{Context}, + reprTree::{Context}, editors::list::{ListEditor}//, PTYListController, PTYListStyle} }, std::sync::{Arc, RwLock} diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 63b4644..cc6e7f1 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -5,9 +5,9 @@ use { }, laddertypes::{TypeTerm}, crate::{ - type_system::{Context, ReprTree}, + reprTree::{Context, ReprTree}, + editTree::{NestedNode, TreeNav, TreeCursor, diagnostics::Diagnostics}, editors::{list::{ListCursor, ListCursorMode, ListCmd}, ObjCommander}, - tree::{NestedNode, TreeNav, TreeCursor, diagnostics::Diagnostics}, }, std::sync::{Arc, RwLock} }; @@ -117,8 +117,7 @@ impl ListEditor { .set_diag(e .get_data_port() .enumerate() - .map( - |(idx, item_editor)| { + .map(|(idx, item_editor)| { let idx = *idx; item_editor .get_msg_port() @@ -129,8 +128,7 @@ impl ListEditor { msg } ) - } - ) + }) .flatten() ); diff --git a/lib-nested-core/src/editors/list/nav.rs b/lib-nested-core/src/editors/list/nav.rs index 31d0cc2..2976074 100644 --- a/lib-nested-core/src/editors/list/nav.rs +++ b/lib-nested-core/src/editors/list/nav.rs @@ -11,7 +11,7 @@ use { ListCursor, ListCursorMode, editor::ListEditor }, - tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp} + editTree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp} }, cgmath::Vector2 }; diff --git a/lib-nested-core/src/editors/list/segment.rs b/lib-nested-core/src/editors/list/segment.rs index 5e8b611..8dcf003 100644 --- a/lib-nested-core/src/editors/list/segment.rs +++ b/lib-nested-core/src/editors/list/segment.rs @@ -9,7 +9,7 @@ use { }, crate::{ editors::list::{ListCursor, ListCursorMode}, - tree::{NestedNode} + editTree::{NestedNode} }, std::sync::Arc, std::sync::RwLock, diff --git a/lib-nested-core/src/editors/mod.rs b/lib-nested-core/src/editors/mod.rs index d48a5b3..849cb67 100644 --- a/lib-nested-core/src/editors/mod.rs +++ b/lib-nested-core/src/editors/mod.rs @@ -16,8 +16,8 @@ pub trait Commander { use std::sync::{Arc, RwLock}; use crate::{ - type_system::ReprTree, - tree::{nav::TreeNavResult} + reprTree::ReprTree, + editTree::nav::TreeNavResult }; pub trait ObjCommander { diff --git a/lib-nested-core/src/editors/sum/editor.rs b/lib-nested-core/src/editors/sum/editor.rs index 195c6b2..919dcb5 100644 --- a/lib-nested-core/src/editors/sum/editor.rs +++ b/lib-nested-core/src/editors/sum/editor.rs @@ -9,8 +9,8 @@ use { laddertypes::{TypeTerm}, crate::{ editors::{list::ListCursorMode, ObjCommander}, - type_system::{Context, ReprTree}, - tree::{TreeNav, TreeCursor, TreeNavResult, diagnostics::{Diagnostics, Message}, NestedNode}, + reprTree::{Context, ReprTree}, + editTree::{TreeNav, TreeCursor, TreeNavResult, diagnostics::{Diagnostics, Message}, NestedNode}, }, cgmath::{Vector2}, std::sync::{Arc, RwLock} diff --git a/lib-nested-core/src/editors/typeterm/cmd.rs b/lib-nested-core/src/editors/typeterm/cmd.rs index 29ec6cb..cf62d80 100644 --- a/lib-nested-core/src/editors/typeterm/cmd.rs +++ b/lib-nested-core/src/editors/typeterm/cmd.rs @@ -3,9 +3,9 @@ use { view::{singleton::*} }, crate::{ - type_system::{Context, ReprTree}, + reprTree::{Context, ReprTree}, + editTree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, editors::{list::{ListEditor, ListCmd, ListCursorMode}, ObjCommander}, - tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, }, std::{sync::{Arc, RwLock}}, diff --git a/lib-nested-core/src/editors/typeterm/ctx.rs b/lib-nested-core/src/editors/typeterm/ctx.rs index 58a65e4..cb9c1f9 100644 --- a/lib-nested-core/src/editors/typeterm/ctx.rs +++ b/lib-nested-core/src/editors/typeterm/ctx.rs @@ -4,7 +4,7 @@ use { }, laddertypes::{TypeTerm}, crate::{ - type_system::{Context, MorphismTypePattern}, + reprTree::{Context, MorphismTypePattern}, editors::{ list::{ListEditor, ListSegmentSequence}, typeterm::{State, TypeTermEditor} diff --git a/lib-nested-core/src/editors/typeterm/mod.rs b/lib-nested-core/src/editors/typeterm/mod.rs index a0c4c5c..2536c4e 100644 --- a/lib-nested-core/src/editors/typeterm/mod.rs +++ b/lib-nested-core/src/editors/typeterm/mod.rs @@ -11,9 +11,9 @@ use { }, laddertypes::{TypeID, TypeTerm}, crate::{ - type_system::{Context, ReprTree}, + reprTree::{Context, ReprTree}, + editTree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, editors::{list::{ListCursorMode, ListEditor, ListCmd}, ObjCommander}, - tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, }, std::{sync::{Arc, RwLock}} }; diff --git a/lib-nested-core/src/editors/typeterm/nav.rs b/lib-nested-core/src/editors/typeterm/nav.rs index 6fb7bf1..4439165 100644 --- a/lib-nested-core/src/editors/typeterm/nav.rs +++ b/lib-nested-core/src/editors/typeterm/nav.rs @@ -7,7 +7,7 @@ use { } }, crate::{ - tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp}, + editTree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp}, editors::{typeterm::TypeTermEditor, list::ListCursorMode} }, cgmath::Vector2 diff --git a/lib-nested-core/src/lib.rs b/lib-nested-core/src/lib.rs index 285710c..c0ef04d 100644 --- a/lib-nested-core/src/lib.rs +++ b/lib-nested-core/src/lib.rs @@ -1,8 +1,5 @@ pub mod utils; pub mod editors; -pub mod tree; -pub mod type_system; +pub mod editTree; +pub mod reprTree; -pub fn magic_header() { - eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>"); -} diff --git a/lib-nested-core/src/type_system/context.rs b/lib-nested-core/src/reprTree/context.rs similarity index 99% rename from lib-nested-core/src/type_system/context.rs rename to lib-nested-core/src/reprTree/context.rs index bf4f8c4..06af8c3 100644 --- a/lib-nested-core/src/type_system/context.rs +++ b/lib-nested-core/src/reprTree/context.rs @@ -2,8 +2,8 @@ use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ - type_system::{ReprTree}, - tree::NestedNode + reprTree::{ReprTree}, + editTree::NestedNode }, std::{ collections::HashMap, diff --git a/lib-nested-core/src/type_system/repr_tree.rs b/lib-nested-core/src/reprTree/mod.rs similarity index 98% rename from lib-nested-core/src/type_system/repr_tree.rs rename to lib-nested-core/src/reprTree/mod.rs index 7e226f9..758fea3 100644 --- a/lib-nested-core/src/type_system/repr_tree.rs +++ b/lib-nested-core/src/reprTree/mod.rs @@ -1,9 +1,12 @@ +pub mod context; + +pub use { + context::{Context, MorphismMode, MorphismType, MorphismTypePattern}, +}; + use { r3vi::view::{AnyOuterViewPort, OuterViewPort, View}, laddertypes::{TypeTerm}, - crate::{ - type_system::{Context} - }, std::{ collections::HashMap, sync::{Arc, RwLock}, diff --git a/lib-nested-core/src/type_system/mod.rs b/lib-nested-core/src/type_system/mod.rs deleted file mode 100644 index 6d52a5b..0000000 --- a/lib-nested-core/src/type_system/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub mod context; -pub mod repr_tree; - -pub use { - context::{Context, MorphismMode, MorphismType, MorphismTypePattern}, - repr_tree::ReprTree -}; - From 9b9ea77cb041a64ef9064b5062aeb673b3802649 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Tue, 28 Nov 2023 17:16:23 +0100 Subject: [PATCH 06/75] add lib-nested-tty::DisplaySegment trait for Node --- lib-nested-tty/src/lib.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index 21e89e4..85ded4d 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -31,24 +31,26 @@ pub trait TerminalView = GridView<Item = TerminalAtom>; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -pub enum TerminalEditorResult { - Continue, - Exit, -} - -pub trait TerminalEditor { - fn get_term_view(&self) -> OuterViewPort<dyn TerminalView>; - fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult; -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - use r3vi::view::OuterViewPort; pub trait DisplaySegment { fn display_view(&self) -> OuterViewPort<dyn TerminalView>; } + +use nested::reprTree::Context; +use std::sync::{Arc, RwLock}; + +impl DisplaySegment for nested::editTree::NestedNode { + fn display_view(&self) -> OuterViewPort<dyn TerminalView> { + self.view.as_ref().unwrap() + .read().unwrap() + .descend( Context::parse(&self.ctx, "TerminalView") ).expect("terminal backend not supported by view") + .read().unwrap() + .get_port::<dyn TerminalView>().unwrap() + } +} + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> use { From 57cb1ee3ffca4ecede0345c0d9af0e94a74d58a3 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Tue, 28 Nov 2023 17:16:51 +0100 Subject: [PATCH 07/75] add TTYApplication --- lib-nested-core/src/reprTree/context.rs | 2 +- lib-nested-tty/src/lib.rs | 2 + lib-nested-tty/src/terminal.rs | 2 +- lib-nested-tty/src/tty_application.rs | 71 +++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 lib-nested-tty/src/tty_application.rs diff --git a/lib-nested-core/src/reprTree/context.rs b/lib-nested-core/src/reprTree/context.rs index 06af8c3..9bfc9f9 100644 --- a/lib-nested-core/src/reprTree/context.rs +++ b/lib-nested-core/src/reprTree/context.rs @@ -1,4 +1,4 @@ -use { + use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index 85ded4d..4c1c7f6 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -10,6 +10,7 @@ pub mod compositor; pub mod ansi_parser; pub mod terminal; +pub mod tty_application; //pub mod list_editor; //pub mod widgets; @@ -21,6 +22,7 @@ pub use { compositor::TerminalCompositor, style::TerminalStyle, terminal::{Terminal, TerminalEvent}, + tty_application::TTYApplication }; use r3vi::view::grid::*; diff --git a/lib-nested-tty/src/terminal.rs b/lib-nested-tty/src/terminal.rs index c03e588..a7169c4 100644 --- a/lib-nested-tty/src/terminal.rs +++ b/lib-nested-tty/src/terminal.rs @@ -24,7 +24,7 @@ use { }, }; -#[derive(PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq, Clone, Debug)] pub enum TerminalEvent { Resize(Vector2<i16>), Input(termion::event::Event), diff --git a/lib-nested-tty/src/tty_application.rs b/lib-nested-tty/src/tty_application.rs new file mode 100644 index 0000000..aeb3fbb --- /dev/null +++ b/lib-nested-tty/src/tty_application.rs @@ -0,0 +1,71 @@ +use { + cgmath::Vector2, + nested::{ + editTree::NestedNode, + reprTree::{Context, ReprTree}, + }, + crate::{ + terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor, + TerminalEvent, TerminalStyle, TerminalView, + }, + r3vi::{ + buffer::singleton::*, + view::{port::UpdateTask, singleton::*, ViewPort}, + }, + std::sync::{Arc, Mutex, RwLock}, + termion::event::{Event, Key}, +}; + +pub struct TTYApplication { + pub port: ViewPort<dyn TerminalView>, + term_writer: Arc<TermOutWriter>, +} + +impl TTYApplication { + pub fn new(event_handler: impl Fn(TerminalEvent) + Send + Sync + 'static) -> Self { + let port = ViewPort::new(); + let portmutex = Mutex::new(()); + let term = Terminal::new(port.outer()); + let term_writer = term.get_writer(); + + async_std::task::spawn(TTYApplication::event_loop(term, port.clone(), Arc::new(event_handler))); + async_std::task::spawn(TTYApplication::update_loop(port.clone())); + + TTYApplication { + port, + term_writer, + } + } + + /* this task handles all terminal events (e.g. key press, resize) + */ + async fn event_loop(mut term: Terminal, port: ViewPort<dyn TerminalView>, event_handler: Arc<dyn Fn(TerminalEvent) + Send + Sync>) { + loop { + let ev = term.next_event().await; + if ev == TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) { + break; + } + + event_handler( ev ); + port.update(); + } + } + + /* this task will continuously pull forward + * all notifications which are influencing + * the view in `term_port` + */ + async fn update_loop(port: ViewPort<dyn TerminalView>) { + loop { + port.update(); + async_std::task::sleep(std::time::Duration::from_millis(500)).await; + } + } + + /* write the changes in the view of `term_port` to the terminal + */ + pub async fn show(&self) -> Result<(), std::io::Error> { + self.term_writer.show().await + } +} + From f151f9c5d228223a701f98dcaf2f87cbace24c50 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Tue, 28 Nov 2023 17:17:35 +0100 Subject: [PATCH 08/75] add second example with TTYApplication & Char-View --- Cargo.toml | 3 +- examples/tty-02-node/Cargo.toml | 18 +++++++ examples/tty-02-node/src/main.rs | 89 ++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 examples/tty-02-node/Cargo.toml create mode 100644 examples/tty-02-node/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 707f44e..ce6bd01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ members = [ "lib-nested-core", "lib-nested-tty", - "examples/tty-01-hello" + "examples/tty-01-hello", + "examples/tty-02-node" ] diff --git a/examples/tty-02-node/Cargo.toml b/examples/tty-02-node/Cargo.toml new file mode 100644 index 0000000..589ee96 --- /dev/null +++ b/examples/tty-02-node/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "tty-02-node" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +r3vi = { path = "../../../lib-r3vi" } +nested = { path = "../../lib-nested-core" } +nested-tty = { path = "../../lib-nested-tty" } +termion = "*" +cgmath = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] + diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs new file mode 100644 index 0000000..3d80c77 --- /dev/null +++ b/examples/tty-02-node/src/main.rs @@ -0,0 +1,89 @@ +extern crate cgmath; +extern crate nested; +extern crate nested_tty; +extern crate r3vi; +extern crate termion; + +use { + cgmath::Vector2, + nested::{ + editTree::NestedNode, + reprTree::{Context, ReprTree}, + }, + nested_tty::{ + terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor, + TerminalEvent, TerminalStyle, TerminalView, + TTYApplication + }, + r3vi::{ + buffer::singleton::*, + view::{port::UpdateTask, singleton::*, ViewPort}, + }, + std::sync::{Arc, Mutex, RwLock}, + termion::event::{Event, Key}, +}; + +#[async_std::main] +async fn main() { + let app = TTYApplication::new( |ev| { /* event handler */ } ); + let compositor = TerminalCompositor::new(app.port.inner()); + + /* setup context & create Editor-Tree + */ + let ctx = Arc::new(RwLock::new(Context::default())); + + // abstract data + let rt = ReprTree::from_char(&ctx, 'λ'); + + let mut node = Context::make_node( + &ctx, + // node type + Context::parse(&ctx, "Char"), + // depth + SingletonBuffer::new(0).get_port(), + ) + .unwrap(); + + /* add a display view to the node + */ + let char_view = rt + .read() + .unwrap() + .get_port::<dyn SingletonView<Item = char>>() + .expect("unable to get Char-view") + .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) + .to_grid(); + + let mut display_rt = ReprTree::new(Context::parse(&ctx, "Display")); + + display_rt.insert_branch(ReprTree::new_leaf( + Context::parse(&ctx, "TerminalView"), + char_view.into(), + )); + + node = node.set_view(Arc::new(RwLock::new(display_rt))); + + compositor.write().unwrap().push( + nested_tty::make_label("Hello World") + .map_item(|p, a| { + a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) + }) + .offset(Vector2::new(5, 0)), + ); + + compositor.write().unwrap() + .push(nested_tty::make_label("Char").offset(Vector2::new(0, 2))); + + compositor.write().unwrap() + .push(node.display_view().offset(Vector2::new(15, 2))); + + compositor.write().unwrap() + .push(nested_tty::make_label("<List Char>").offset(Vector2::new(0, 3))); + + compositor.write().unwrap() + .push(nested_tty::make_label("---").offset(Vector2::new(15, 3))); + + /* write the changes in the view of `term_port` to the terminal + */ + app.show().await.expect("output error!"); +} From 85b614a9bbec3dd0f203a460c2e36dc72fc1ad7e Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Tue, 28 Nov 2023 20:52:25 +0100 Subject: [PATCH 09/75] further restructuring --- examples/tty-01-hello/src/main.rs | 54 ++---------------- examples/tty-02-node/src/main.rs | 57 +++++++++++-------- .../src/{editTree => edit_tree}/addr.rs | 0 .../src/{editTree => edit_tree}/cursor.rs | 0 .../{editTree => edit_tree}/diagnostics.rs | 2 +- .../src/{editTree => edit_tree}/mod.rs | 0 .../src/{editTree => edit_tree}/nav.rs | 2 +- .../src/{editTree => edit_tree}/node.rs | 4 +- .../src/{editTree => edit_tree}/treetype.rs | 2 +- lib-nested-core/src/editors/char/mod.rs | 4 +- lib-nested-core/src/editors/integer/ctx.rs | 4 +- lib-nested-core/src/editors/integer/editor.rs | 4 +- lib-nested-core/src/editors/list/cmd.rs | 4 +- lib-nested-core/src/editors/list/ctx.rs | 2 +- lib-nested-core/src/editors/list/editor.rs | 4 +- lib-nested-core/src/editors/list/nav.rs | 2 +- lib-nested-core/src/editors/list/segment.rs | 2 +- lib-nested-core/src/editors/mod.rs | 4 +- lib-nested-core/src/editors/sum/editor.rs | 4 +- lib-nested-core/src/editors/typeterm/cmd.rs | 4 +- lib-nested-core/src/editors/typeterm/ctx.rs | 2 +- lib-nested-core/src/editors/typeterm/mod.rs | 4 +- lib-nested-core/src/editors/typeterm/nav.rs | 2 +- lib-nested-core/src/lib.rs | 9 +-- .../src/{reprTree => repr_tree}/context.rs | 4 +- .../src/{reprTree => repr_tree}/mod.rs | 0 lib-nested-tty/src/ansi_parser.rs | 3 +- lib-nested-tty/src/{atom.rs => atom/mod.rs} | 8 +-- lib-nested-tty/src/{ => atom}/style.rs | 0 lib-nested-tty/src/{ => edit-tree}/color.rs | 0 .../src/{ => edit-tree}/cursor_widget.rs | 0 .../src/{ => edit-tree}/diagnostics.rs | 0 lib-nested-tty/src/editors/char.rs | 0 .../src/{list_editor.rs => editors/list.rs} | 0 lib-nested-tty/src/editors/mod.rsr | 0 lib-nested-tty/src/editors/product.rs | 0 lib-nested-tty/src/editors/singleton.rs | 0 .../src/{sum_editor.rs => editors/sum.rs} | 0 lib-nested-tty/src/lib.rs | 22 ++++--- lib-nested-tty/src/terminal.rs | 3 +- lib-nested-tty/src/tty_application.rs | 4 +- 41 files changed, 95 insertions(+), 125 deletions(-) rename lib-nested-core/src/{editTree => edit_tree}/addr.rs (100%) rename lib-nested-core/src/{editTree => edit_tree}/cursor.rs (100%) rename lib-nested-core/src/{editTree => edit_tree}/diagnostics.rs (94%) rename lib-nested-core/src/{editTree => edit_tree}/mod.rs (100%) rename lib-nested-core/src/{editTree => edit_tree}/nav.rs (99%) rename lib-nested-core/src/{editTree => edit_tree}/node.rs (98%) rename lib-nested-core/src/{editTree => edit_tree}/treetype.rs (85%) rename lib-nested-core/src/{reprTree => repr_tree}/context.rs (99%) rename lib-nested-core/src/{reprTree => repr_tree}/mod.rs (100%) rename lib-nested-tty/src/{atom.rs => atom/mod.rs} (93%) rename lib-nested-tty/src/{ => atom}/style.rs (100%) rename lib-nested-tty/src/{ => edit-tree}/color.rs (100%) rename lib-nested-tty/src/{ => edit-tree}/cursor_widget.rs (100%) rename lib-nested-tty/src/{ => edit-tree}/diagnostics.rs (100%) create mode 100644 lib-nested-tty/src/editors/char.rs rename lib-nested-tty/src/{list_editor.rs => editors/list.rs} (100%) create mode 100644 lib-nested-tty/src/editors/mod.rsr create mode 100644 lib-nested-tty/src/editors/product.rs create mode 100644 lib-nested-tty/src/editors/singleton.rs rename lib-nested-tty/src/{sum_editor.rs => editors/sum.rs} (100%) diff --git a/examples/tty-01-hello/src/main.rs b/examples/tty-01-hello/src/main.rs index 45aae38..45856c0 100644 --- a/examples/tty-01-hello/src/main.rs +++ b/examples/tty-01-hello/src/main.rs @@ -6,65 +6,22 @@ extern crate termion; use { cgmath::Vector2, - nested::reprTree::Context, - nested_tty::{Terminal, TerminalCompositor, TerminalEvent, TerminalStyle, TerminalView}, + nested::repr_tree::Context, + nested_tty::{Terminal, TerminalCompositor, TTYApplication, TerminalEvent, TerminalStyle, TerminalView}, r3vi::view::{port::UpdateTask, ViewPort}, std::sync::{Arc, RwLock}, termion::event::{Event, Key}, }; -/* this task handles all terminal events (e.g. key press, resize) - */ -pub async fn event_loop( - mut term: Terminal, - term_port: ViewPort<dyn TerminalView>, - portmutex: Arc<RwLock<()>>, -) { - loop { - let ev = term.next_event().await; - let _l = portmutex.write().unwrap(); - - if ev == TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) { - break; - } - term_port.update(); - } -} - -/* this task will continuously pull forward - * all notifications which are influencing - * the view in `term_port` - */ -pub async fn update_loop(term_port: ViewPort<dyn TerminalView>, portmutex: Arc<RwLock<()>>) { - loop { - { - let _l = portmutex.write().unwrap(); - term_port.update(); - } - async_std::task::sleep(std::time::Duration::from_millis(500)).await; - } -} - #[async_std::main] async fn main() { /* initialize our terminal */ - let term_port = ViewPort::new(); - - let mut term = Terminal::new(term_port.outer()); - let term_writer = term.get_writer(); - - let portmutex = Arc::new(RwLock::new(())); - - /* spawn event-handling & updating tasks - */ - async_std::task::spawn(update_loop(term_port.clone(), portmutex.clone())); - - async_std::task::spawn(event_loop(term, term_port.clone(), portmutex.clone())); + let tty_app = TTYApplication::new(|event| { /* handle event */ }); /* populate the view in `term_port` */ - let compositor = TerminalCompositor::new(term_port.inner()); + let compositor = TerminalCompositor::new(tty_app.port.inner()); compositor .write() @@ -81,5 +38,6 @@ async fn main() { /* write the changes in the view of `term_port` to the terminal */ - term_writer.show().await.expect("output error!"); + tty_app.show().await.expect("output error!"); } + diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 3d80c77..fb5b1f8 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -7,8 +7,8 @@ extern crate termion; use { cgmath::Vector2, nested::{ - editTree::NestedNode, - reprTree::{Context, ReprTree}, + edit_tree::NestedNode, + repr_tree::{Context, ReprTree}, }, nested_tty::{ terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor, @@ -23,18 +23,37 @@ use { termion::event::{Event, Key}, }; +fn node_make_char_view( + node: NestedNode +) -> NestedNode { + let char_view = node.data + .read() + .unwrap() + .get_port::<dyn SingletonView<Item = char>>() + .expect("unable to get Char-view") + .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) + .to_grid(); + + let mut display_rt = ReprTree::new(Context::parse(&node.ctx, "Display")); + + display_rt.insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), + char_view.into(), + )); + + node.set_view( + Arc::new(RwLock::new(display_rt)) + ) +} + #[async_std::main] async fn main() { let app = TTYApplication::new( |ev| { /* event handler */ } ); - let compositor = TerminalCompositor::new(app.port.inner()); /* setup context & create Editor-Tree */ let ctx = Arc::new(RwLock::new(Context::default())); - // abstract data - let rt = ReprTree::from_char(&ctx, 'λ'); - let mut node = Context::make_node( &ctx, // node type @@ -44,25 +63,17 @@ async fn main() { ) .unwrap(); - /* add a display view to the node + // set abstract data + node.data = ReprTree::from_char(&ctx, 'Λ'); + + // add a display view to the node + node = node_make_char_view( node ); + + /* setup display view routed to `app.port` */ - let char_view = rt - .read() - .unwrap() - .get_port::<dyn SingletonView<Item = char>>() - .expect("unable to get Char-view") - .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) - .to_grid(); - - let mut display_rt = ReprTree::new(Context::parse(&ctx, "Display")); - - display_rt.insert_branch(ReprTree::new_leaf( - Context::parse(&ctx, "TerminalView"), - char_view.into(), - )); - - node = node.set_view(Arc::new(RwLock::new(display_rt))); + let compositor = TerminalCompositor::new(app.port.inner()); + // add some views to the display compositor compositor.write().unwrap().push( nested_tty::make_label("Hello World") .map_item(|p, a| { diff --git a/lib-nested-core/src/editTree/addr.rs b/lib-nested-core/src/edit_tree/addr.rs similarity index 100% rename from lib-nested-core/src/editTree/addr.rs rename to lib-nested-core/src/edit_tree/addr.rs diff --git a/lib-nested-core/src/editTree/cursor.rs b/lib-nested-core/src/edit_tree/cursor.rs similarity index 100% rename from lib-nested-core/src/editTree/cursor.rs rename to lib-nested-core/src/edit_tree/cursor.rs diff --git a/lib-nested-core/src/editTree/diagnostics.rs b/lib-nested-core/src/edit_tree/diagnostics.rs similarity index 94% rename from lib-nested-core/src/editTree/diagnostics.rs rename to lib-nested-core/src/edit_tree/diagnostics.rs index 0983f5b..4b39a1f 100644 --- a/lib-nested-core/src/editTree/diagnostics.rs +++ b/lib-nested-core/src/edit_tree/diagnostics.rs @@ -4,7 +4,7 @@ use { buffer::{vec::*, index_hashmap::*} }, crate::{ - reprTree::ReprTree + repr_tree::ReprTree }, std::sync::{Arc, RwLock}, cgmath::Point2 diff --git a/lib-nested-core/src/editTree/mod.rs b/lib-nested-core/src/edit_tree/mod.rs similarity index 100% rename from lib-nested-core/src/editTree/mod.rs rename to lib-nested-core/src/edit_tree/mod.rs diff --git a/lib-nested-core/src/editTree/nav.rs b/lib-nested-core/src/edit_tree/nav.rs similarity index 99% rename from lib-nested-core/src/editTree/nav.rs rename to lib-nested-core/src/edit_tree/nav.rs index c2aca14..3dae406 100644 --- a/lib-nested-core/src/editTree/nav.rs +++ b/lib-nested-core/src/edit_tree/nav.rs @@ -15,7 +15,7 @@ use { }, crate::{ editors::list::ListCursorMode, - editTree::TreeCursor + edit_tree::TreeCursor }, cgmath::Vector2, }; diff --git a/lib-nested-core/src/editTree/node.rs b/lib-nested-core/src/edit_tree/node.rs similarity index 98% rename from lib-nested-core/src/editTree/node.rs rename to lib-nested-core/src/edit_tree/node.rs index ad66127..b2a8fca 100644 --- a/lib-nested-core/src/editTree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -7,8 +7,8 @@ use { }, laddertypes::{TypeTerm}, crate::{ - reprTree::{ReprTree, Context}, - editTree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}}, + repr_tree::{ReprTree, Context}, + edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}}, editors::{list::{ListCursorMode}, ObjCommander} } }; diff --git a/lib-nested-core/src/editTree/treetype.rs b/lib-nested-core/src/edit_tree/treetype.rs similarity index 85% rename from lib-nested-core/src/editTree/treetype.rs rename to lib-nested-core/src/edit_tree/treetype.rs index 4fed7a7..c3ad118 100644 --- a/lib-nested-core/src/editTree/treetype.rs +++ b/lib-nested-core/src/edit_tree/treetype.rs @@ -2,7 +2,7 @@ use { laddertypes::{TypeTerm, TypeID}, crate::{ - editTree::{TreeAddr} + edit_tree::{TreeAddr} } }; diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 2fb66de..3262f2b 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -8,8 +8,8 @@ use { }, laddertypes::{TypeTerm}, crate::{ - reprTree::{Context, ReprTree}, - editTree::{NestedNode, TreeNavResult}, + repr_tree::{Context, ReprTree}, + edit_tree::{NestedNode, TreeNavResult}, editors::ObjCommander, }, std::sync::Arc, diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 5f5859a..214ef8c 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -5,8 +5,8 @@ use { }, laddertypes::{TypeTerm}, crate::{ - reprTree::{Context}, - reprTree::{MorphismTypePattern}, + repr_tree::{Context}, + repr_tree::{MorphismTypePattern}, editors::{ list::*, integer::* diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index c58b984..fa8593a 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -13,8 +13,8 @@ use { laddertypes::{TypeTerm}, crate::{ editors::{list::{ListCmd}, ObjCommander}, - reprTree::{Context, ReprTree}, - editTree::{NestedNode, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}}, + repr_tree::{Context, ReprTree}, + edit_tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}}, }, std::sync::Arc, std::sync::RwLock, diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs index 59a28e7..d1cec0d 100644 --- a/lib-nested-core/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -4,8 +4,8 @@ use { }, crate::{ editors::{list::{ListEditor, ListCursor, ListCursorMode}, ObjCommander}, - reprTree::{Context, ReprTree}, - editTree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, + repr_tree::{Context, ReprTree}, + edit_tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, }, std::sync::{Arc, RwLock} }; diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 67a73d1..2eefc7f 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -2,7 +2,7 @@ use { r3vi::{view::{OuterViewPort, singleton::*}}, laddertypes::{TypeTerm}, crate::{ - reprTree::{Context}, + repr_tree::{Context}, editors::list::{ListEditor}//, PTYListController, PTYListStyle} }, std::sync::{Arc, RwLock} diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index cc6e7f1..6776057 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -5,8 +5,8 @@ use { }, laddertypes::{TypeTerm}, crate::{ - reprTree::{Context, ReprTree}, - editTree::{NestedNode, TreeNav, TreeCursor, diagnostics::Diagnostics}, + repr_tree::{Context, ReprTree}, + edit_tree::{NestedNode, TreeNav, TreeCursor, diagnostics::Diagnostics}, editors::{list::{ListCursor, ListCursorMode, ListCmd}, ObjCommander}, }, std::sync::{Arc, RwLock} diff --git a/lib-nested-core/src/editors/list/nav.rs b/lib-nested-core/src/editors/list/nav.rs index 2976074..94b4731 100644 --- a/lib-nested-core/src/editors/list/nav.rs +++ b/lib-nested-core/src/editors/list/nav.rs @@ -11,7 +11,7 @@ use { ListCursor, ListCursorMode, editor::ListEditor }, - editTree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp} + edit_tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp} }, cgmath::Vector2 }; diff --git a/lib-nested-core/src/editors/list/segment.rs b/lib-nested-core/src/editors/list/segment.rs index 8dcf003..9e23550 100644 --- a/lib-nested-core/src/editors/list/segment.rs +++ b/lib-nested-core/src/editors/list/segment.rs @@ -9,7 +9,7 @@ use { }, crate::{ editors::list::{ListCursor, ListCursorMode}, - editTree::{NestedNode} + edit_tree::{NestedNode} }, std::sync::Arc, std::sync::RwLock, diff --git a/lib-nested-core/src/editors/mod.rs b/lib-nested-core/src/editors/mod.rs index 849cb67..669b5d8 100644 --- a/lib-nested-core/src/editors/mod.rs +++ b/lib-nested-core/src/editors/mod.rs @@ -16,8 +16,8 @@ pub trait Commander { use std::sync::{Arc, RwLock}; use crate::{ - reprTree::ReprTree, - editTree::nav::TreeNavResult + repr_tree::ReprTree, + edit_tree::nav::TreeNavResult }; pub trait ObjCommander { diff --git a/lib-nested-core/src/editors/sum/editor.rs b/lib-nested-core/src/editors/sum/editor.rs index 919dcb5..aa71f01 100644 --- a/lib-nested-core/src/editors/sum/editor.rs +++ b/lib-nested-core/src/editors/sum/editor.rs @@ -9,8 +9,8 @@ use { laddertypes::{TypeTerm}, crate::{ editors::{list::ListCursorMode, ObjCommander}, - reprTree::{Context, ReprTree}, - editTree::{TreeNav, TreeCursor, TreeNavResult, diagnostics::{Diagnostics, Message}, NestedNode}, + repr_tree::{Context, ReprTree}, + edit_tree::{TreeNav, TreeCursor, TreeNavResult, diagnostics::{Diagnostics, Message}, NestedNode}, }, cgmath::{Vector2}, std::sync::{Arc, RwLock} diff --git a/lib-nested-core/src/editors/typeterm/cmd.rs b/lib-nested-core/src/editors/typeterm/cmd.rs index cf62d80..4885ed1 100644 --- a/lib-nested-core/src/editors/typeterm/cmd.rs +++ b/lib-nested-core/src/editors/typeterm/cmd.rs @@ -3,8 +3,8 @@ use { view::{singleton::*} }, crate::{ - reprTree::{Context, ReprTree}, - editTree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, + repr_tree::{Context, ReprTree}, + edit_tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, editors::{list::{ListEditor, ListCmd, ListCursorMode}, ObjCommander}, }, std::{sync::{Arc, RwLock}}, diff --git a/lib-nested-core/src/editors/typeterm/ctx.rs b/lib-nested-core/src/editors/typeterm/ctx.rs index cb9c1f9..0039c8f 100644 --- a/lib-nested-core/src/editors/typeterm/ctx.rs +++ b/lib-nested-core/src/editors/typeterm/ctx.rs @@ -4,7 +4,7 @@ use { }, laddertypes::{TypeTerm}, crate::{ - reprTree::{Context, MorphismTypePattern}, + repr_tree::{Context, MorphismTypePattern}, editors::{ list::{ListEditor, ListSegmentSequence}, typeterm::{State, TypeTermEditor} diff --git a/lib-nested-core/src/editors/typeterm/mod.rs b/lib-nested-core/src/editors/typeterm/mod.rs index 2536c4e..2134be4 100644 --- a/lib-nested-core/src/editors/typeterm/mod.rs +++ b/lib-nested-core/src/editors/typeterm/mod.rs @@ -11,8 +11,8 @@ use { }, laddertypes::{TypeID, TypeTerm}, crate::{ - reprTree::{Context, ReprTree}, - editTree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, + repr_tree::{Context, ReprTree}, + edit_tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, editors::{list::{ListCursorMode, ListEditor, ListCmd}, ObjCommander}, }, std::{sync::{Arc, RwLock}} diff --git a/lib-nested-core/src/editors/typeterm/nav.rs b/lib-nested-core/src/editors/typeterm/nav.rs index 4439165..b4f2175 100644 --- a/lib-nested-core/src/editors/typeterm/nav.rs +++ b/lib-nested-core/src/editors/typeterm/nav.rs @@ -7,7 +7,7 @@ use { } }, crate::{ - editTree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp}, + edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp}, editors::{typeterm::TypeTermEditor, list::ListCursorMode} }, cgmath::Vector2 diff --git a/lib-nested-core/src/lib.rs b/lib-nested-core/src/lib.rs index c0ef04d..bca12dc 100644 --- a/lib-nested-core/src/lib.rs +++ b/lib-nested-core/src/lib.rs @@ -1,5 +1,6 @@ -pub mod utils; -pub mod editors; -pub mod editTree; -pub mod reprTree; + +pub mod repr_tree; +pub mod edit_tree; +pub mod editors; +pub mod utils; diff --git a/lib-nested-core/src/reprTree/context.rs b/lib-nested-core/src/repr_tree/context.rs similarity index 99% rename from lib-nested-core/src/reprTree/context.rs rename to lib-nested-core/src/repr_tree/context.rs index 9bfc9f9..3934246 100644 --- a/lib-nested-core/src/reprTree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -2,8 +2,8 @@ r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ - reprTree::{ReprTree}, - editTree::NestedNode + repr_tree::{ReprTree}, + edit_tree::NestedNode }, std::{ collections::HashMap, diff --git a/lib-nested-core/src/reprTree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs similarity index 100% rename from lib-nested-core/src/reprTree/mod.rs rename to lib-nested-core/src/repr_tree/mod.rs diff --git a/lib-nested-tty/src/ansi_parser.rs b/lib-nested-tty/src/ansi_parser.rs index efd8a83..399bf15 100644 --- a/lib-nested-tty/src/ansi_parser.rs +++ b/lib-nested-tty/src/ansi_parser.rs @@ -10,7 +10,8 @@ use { projection::projection_helper::ProjectionHelper, }, crate::{ - TerminalAtom, TerminalStyle, TerminalView, + atom::{TerminalAtom, TerminalStyle}, + TerminalView, }, cgmath::{Point2, Vector2}, std::io::Read, diff --git a/lib-nested-tty/src/atom.rs b/lib-nested-tty/src/atom/mod.rs similarity index 93% rename from lib-nested-tty/src/atom.rs rename to lib-nested-tty/src/atom/mod.rs index 2cd4d29..0bc55f1 100644 --- a/lib-nested-tty/src/atom.rs +++ b/lib-nested-tty/src/atom/mod.rs @@ -1,7 +1,7 @@ -use { - super::TerminalStyle, - serde::{Deserialize, Serialize}, -}; +pub mod style; +pub use style::TerminalStyle; + +use serde::{Deserialize, Serialize}; #[derive(Clone, Copy, Serialize, Deserialize, Debug)] pub struct TerminalAtom { diff --git a/lib-nested-tty/src/style.rs b/lib-nested-tty/src/atom/style.rs similarity index 100% rename from lib-nested-tty/src/style.rs rename to lib-nested-tty/src/atom/style.rs diff --git a/lib-nested-tty/src/color.rs b/lib-nested-tty/src/edit-tree/color.rs similarity index 100% rename from lib-nested-tty/src/color.rs rename to lib-nested-tty/src/edit-tree/color.rs diff --git a/lib-nested-tty/src/cursor_widget.rs b/lib-nested-tty/src/edit-tree/cursor_widget.rs similarity index 100% rename from lib-nested-tty/src/cursor_widget.rs rename to lib-nested-tty/src/edit-tree/cursor_widget.rs diff --git a/lib-nested-tty/src/diagnostics.rs b/lib-nested-tty/src/edit-tree/diagnostics.rs similarity index 100% rename from lib-nested-tty/src/diagnostics.rs rename to lib-nested-tty/src/edit-tree/diagnostics.rs diff --git a/lib-nested-tty/src/editors/char.rs b/lib-nested-tty/src/editors/char.rs new file mode 100644 index 0000000..e69de29 diff --git a/lib-nested-tty/src/list_editor.rs b/lib-nested-tty/src/editors/list.rs similarity index 100% rename from lib-nested-tty/src/list_editor.rs rename to lib-nested-tty/src/editors/list.rs diff --git a/lib-nested-tty/src/editors/mod.rsr b/lib-nested-tty/src/editors/mod.rsr new file mode 100644 index 0000000..e69de29 diff --git a/lib-nested-tty/src/editors/product.rs b/lib-nested-tty/src/editors/product.rs new file mode 100644 index 0000000..e69de29 diff --git a/lib-nested-tty/src/editors/singleton.rs b/lib-nested-tty/src/editors/singleton.rs new file mode 100644 index 0000000..e69de29 diff --git a/lib-nested-tty/src/sum_editor.rs b/lib-nested-tty/src/editors/sum.rs similarity index 100% rename from lib-nested-tty/src/sum_editor.rs rename to lib-nested-tty/src/editors/sum.rs diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index 4c1c7f6..687ceca 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -1,10 +1,9 @@ #![feature(trait_alias)] -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ pub mod atom; -pub mod style; pub mod compositor; pub mod ansi_parser; @@ -12,26 +11,25 @@ pub mod ansi_parser; pub mod terminal; pub mod tty_application; -//pub mod list_editor; +//pub mod edit_tree; //pub mod widgets; -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ pub use { - atom::TerminalAtom, - compositor::TerminalCompositor, - style::TerminalStyle, + atom::{TerminalAtom, TerminalStyle}, terminal::{Terminal, TerminalEvent}, - tty_application::TTYApplication + tty_application::TTYApplication, + compositor::TerminalCompositor, }; use r3vi::view::grid::*; -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ pub trait TerminalView = GridView<Item = TerminalAtom>; -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ use r3vi::view::OuterViewPort; @@ -40,10 +38,10 @@ pub trait DisplaySegment { } -use nested::reprTree::Context; +use nested::repr_tree::Context; use std::sync::{Arc, RwLock}; -impl DisplaySegment for nested::editTree::NestedNode { +impl DisplaySegment for nested::edit_tree::NestedNode { fn display_view(&self) -> OuterViewPort<dyn TerminalView> { self.view.as_ref().unwrap() .read().unwrap() diff --git a/lib-nested-tty/src/terminal.rs b/lib-nested-tty/src/terminal.rs index a7169c4..4cfa510 100644 --- a/lib-nested-tty/src/terminal.rs +++ b/lib-nested-tty/src/terminal.rs @@ -7,7 +7,8 @@ use { index::*, } }, - super::{TerminalStyle, TerminalView}, + crate::atom::{TerminalStyle}, + crate::{TerminalView}, async_std::{stream::StreamExt, task}, cgmath::{Point2, Vector2}, signal_hook, diff --git a/lib-nested-tty/src/tty_application.rs b/lib-nested-tty/src/tty_application.rs index aeb3fbb..fe4e48f 100644 --- a/lib-nested-tty/src/tty_application.rs +++ b/lib-nested-tty/src/tty_application.rs @@ -1,8 +1,8 @@ use { cgmath::Vector2, nested::{ - editTree::NestedNode, - reprTree::{Context, ReprTree}, + edit_tree::NestedNode, + repr_tree::{Context, ReprTree}, }, crate::{ terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor, From 25d8acdb72ef72d323a9ddc2657f35b2a81e48a6 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 29 Nov 2023 01:23:41 +0100 Subject: [PATCH 10/75] first steps in reactivating pty-list editor --- examples/tty-02-node/src/main.rs | 155 ++++++++++++++---- lib-nested-core/src/edit_tree/node.rs | 56 +------ lib-nested-core/src/editors/char/mod.rs | 7 - lib-nested-core/src/editors/list/editor.rs | 6 +- .../src/{edit-tree => edit_tree}/color.rs | 2 +- .../{edit-tree => edit_tree}/cursor_widget.rs | 0 .../{edit-tree => edit_tree}/diagnostics.rs | 0 lib-nested-tty/src/edit_tree/mod.rs | 3 + lib-nested-tty/src/editors/list.rs | 54 +++--- lib-nested-tty/src/editors/mod.rs | 3 + lib-nested-tty/src/editors/mod.rsr | 0 lib-nested-tty/src/lib.rs | 24 ++- 12 files changed, 191 insertions(+), 119 deletions(-) rename lib-nested-tty/src/{edit-tree => edit_tree}/color.rs (96%) rename lib-nested-tty/src/{edit-tree => edit_tree}/cursor_widget.rs (100%) rename lib-nested-tty/src/{edit-tree => edit_tree}/diagnostics.rs (100%) create mode 100644 lib-nested-tty/src/edit_tree/mod.rs create mode 100644 lib-nested-tty/src/editors/mod.rs delete mode 100644 lib-nested-tty/src/editors/mod.rsr diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index fb5b1f8..eb3515e 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -7,7 +7,7 @@ extern crate termion; use { cgmath::Vector2, nested::{ - edit_tree::NestedNode, + edit_tree::{NestedNode, TreeCursor, TreeNav}, repr_tree::{Context, ReprTree}, }, nested_tty::{ @@ -17,7 +17,8 @@ use { }, r3vi::{ buffer::singleton::*, - view::{port::UpdateTask, singleton::*, ViewPort}, + view::{port::UpdateTask, singleton::*, sequence::*, ViewPort}, + projection::decorate_sequence::* }, std::sync::{Arc, Mutex, RwLock}, termion::event::{Event, Key}, @@ -26,48 +27,134 @@ use { fn node_make_char_view( node: NestedNode ) -> NestedNode { - let char_view = node.data - .read() - .unwrap() - .get_port::<dyn SingletonView<Item = char>>() - .expect("unable to get Char-view") - .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) - .to_grid(); + node.display + .write().unwrap() + .insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), + node.data + .read() + .unwrap() + .get_port::<dyn SingletonView<Item = char>>() + .expect("unable to get Char-view") + .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) + .to_grid() + .into(), + )); - let mut display_rt = ReprTree::new(Context::parse(&node.ctx, "Display")); + node +} - display_rt.insert_branch(ReprTree::new_leaf( - Context::parse(&node.ctx, "TerminalView"), - char_view.into(), - )); +fn node_make_list_view( + mut node: NestedNode +) -> NestedNode { + eprintln!("add list display type"); + node.display + .write().unwrap() + .insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), - node.set_view( - Arc::new(RwLock::new(display_rt)) - ) + node.data + .read() + .unwrap() + .get_port::< dyn SequenceView<Item = NestedNode> >() + .expect("unable to get Seq-view") + .map(move |char_node| node_make_view(char_node.clone()).display_view() ) + .wrap(nested_tty::make_label("("), nested_tty::make_label(")")) + .to_grid_horizontal() + .flatten() + .into() + )); + +// nested_tty::editors::list::PTYListStyle::for_node( &mut node, ("(", ",", ")") ); + nested_tty::editors::list::PTYListController::for_node( &mut node, None, None ); + + node +} + +fn node_make_view( + node: NestedNode +) -> NestedNode { + if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { + node_make_char_view( node ) + } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") { + node_make_list_view( node ) +// node + } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") { + node_make_list_view( node ) + } else { + eprintln!("couldnt add view"); + node + } } #[async_std::main] async fn main() { - let app = TTYApplication::new( |ev| { /* event handler */ } ); - /* setup context & create Editor-Tree */ let ctx = Arc::new(RwLock::new(Context::default())); - let mut node = Context::make_node( + + /* Create a Char-Node with editor & view + */ + let mut n1 = Context::make_node( &ctx, // node type Context::parse(&ctx, "Char"), // depth SingletonBuffer::new(0).get_port(), - ) - .unwrap(); - - // set abstract data - node.data = ReprTree::from_char(&ctx, 'Λ'); + ).unwrap(); // add a display view to the node - node = node_make_char_view( node ); + n1 = node_make_view( n1 ); + + /* Create a <List Char>-Node with editor & view + */ + let mut node2 = Context::make_node( + &ctx, + // node type + Context::parse(&ctx, "<List Char>"), + // depth + SingletonBuffer::new(0).get_port(), + ).unwrap(); + + // add a display view to the node + node2 = node_make_view( node2 ); + + /* setup terminal + */ + let app = TTYApplication::new({ + /* event handler + */ + + let ctx = ctx.clone(); + let mut node = n1.clone(); + node.goto(TreeCursor::home()); + + + let node2 = node2.clone(); + move |ev| { + + if let Some(cmd) =node2.cmd.get() { + cmd.write().unwrap().send_cmd_obj( + ReprTree::new_leaf( + Context::parse(&ctx, "TerminalEvent"), + SingletonBuffer::new(ev.clone()).get_port().into() + ) + ); + } + + match ev { + TerminalEvent::Input(Event::Key(Key::Char(c))) => { + if let Some(cmd) = node.cmd.get() { + cmd.write().unwrap().send_cmd_obj( + ReprTree::from_char(&ctx, c) + ); + } + } + _ => {} + } + } + }); /* setup display view routed to `app.port` */ @@ -82,17 +169,21 @@ async fn main() { .offset(Vector2::new(5, 0)), ); + + let label = ctx.read().unwrap().type_term_to_str( &n1.get_type() ); compositor.write().unwrap() - .push(nested_tty::make_label("Char").offset(Vector2::new(0, 2))); + .push(nested_tty::make_label( &label ).offset(Vector2::new(0, 2))); compositor.write().unwrap() - .push(node.display_view().offset(Vector2::new(15, 2))); + .push(n1.display_view().offset(Vector2::new(15, 2))); + + + let label2 = ctx.read().unwrap().type_term_to_str( &node2.get_type() ); + compositor.write().unwrap() + .push(nested_tty::make_label( &label2 ).offset(Vector2::new(0, 3))); compositor.write().unwrap() - .push(nested_tty::make_label("<List Char>").offset(Vector2::new(0, 3))); - - compositor.write().unwrap() - .push(nested_tty::make_label("---").offset(Vector2::new(15, 3))); + .push(node2.display_view().offset(Vector2::new(15, 3))); /* write the changes in the view of `term_port` to the terminal */ diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index b2a8fca..61cd789 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -73,7 +73,7 @@ pub struct NestedNode { pub data: Arc<RwLock<ReprTree>>, /// display view - pub view: Option< Arc<RwLock<ReprTree>> >, + pub display: Arc<RwLock<ReprTree>>, /// diagnostics pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >, @@ -103,16 +103,17 @@ pub struct NestedNode { impl NestedNode { pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self { NestedNode { - ctx, data, - view: None, + display: Arc::new(RwLock::new(ReprTree::new(Context::parse(&ctx, "Display")))), diag: None, depth, editor: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())), cmd: SingletonBuffer::new(None), close_char: SingletonBuffer::new(None), - tree_nav: SingletonBuffer::new(None) + tree_nav: SingletonBuffer::new(None), + + ctx } } @@ -129,20 +130,7 @@ impl NestedNode { ), SingletonBuffer::new(0).get_port() ) - /* - .set_view(buf.get_port() - .map(|c| TerminalAtom::from(c)) - .to_index() - .map_key( - |_x| { - Point2::new(0, 0) - }, - |p| { - if *p == Point2::new(0,0) { Some(()) } else { None } - }) - ) - */ - .set_editor(Arc::new(RwLock::new(buf))) +// .set_editor(Arc::new(RwLock::new(buf))) } @@ -163,11 +151,6 @@ impl NestedNode { self } - pub fn set_view(mut self, view: Arc<RwLock<ReprTree>>) -> Self { - self.view = Some(view); - self - } - pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self { self.cmd.set(Some(cmd)); self @@ -189,10 +172,6 @@ impl NestedNode { self.diag.clone().unwrap_or(ViewPort::new().into_outer()) } - pub fn get_view(&self) -> Option< Arc<RwLock<ReprTree>> > { - self.view.clone() - } - pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>> where V::Msg: Clone { let ctx = self.ctx.clone(); @@ -245,29 +224,6 @@ impl TreeType for NestedNode { } */ -/* TODO: remove that at some point -*/ -/* -impl TerminalEditor for NestedNode { - fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> { - self.get_view() - } - - fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - let buf = SingletonBuffer::new(event.clone()); - - if let Some(cmd) = self.cmd.get() { - cmd.write().unwrap().send_cmd_obj( - ReprTree::new_leaf( - self.ctx.read().unwrap().type_term_from_str("TerminalEvent").unwrap(), - AnyOuterViewPort::from(buf.get_port()) - )); - } - - TerminalEditorResult::Continue - } -} -*/ impl TreeNav for NestedNode { fn get_cursor(&self) -> TreeCursor { if let Some(tn) = self.tree_nav.get() { diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 3262f2b..8294576 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -82,13 +82,6 @@ impl CharEditor { ), depth ) - /* todo: move to lib-nested-term - .set_view(data - .get_port() - .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) - .to_grid() - ) - */ .set_cmd( editor.clone() ) .set_editor( editor.clone() ) } diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 6776057..7006ac9 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -15,7 +15,7 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct ListEditor { - pub(super) cursor: SingletonBuffer<ListCursor>, + pub cursor: SingletonBuffer<ListCursor>, // todo: (?) remove RwLock<..> around NestedNode ?? pub data: VecBuffer< Arc<RwLock<NestedNode>> >, @@ -27,10 +27,10 @@ pub struct ListEditor { depth: OuterViewPort<dyn SingletonView<Item = usize>>, - pub(crate) ctx: Arc<RwLock<Context>>, + pub ctx: Arc<RwLock<Context>>, /// item type - pub(super) typ: TypeTerm, + pub typ: TypeTerm, } impl ListEditor { diff --git a/lib-nested-tty/src/edit-tree/color.rs b/lib-nested-tty/src/edit_tree/color.rs similarity index 96% rename from lib-nested-tty/src/edit-tree/color.rs rename to lib-nested-tty/src/edit_tree/color.rs index 532a7fe..42f36fc 100644 --- a/lib-nested-tty/src/edit-tree/color.rs +++ b/lib-nested-tty/src/edit_tree/color.rs @@ -1,5 +1,5 @@ use { - crate::terminal::TerminalStyle, + crate::atom::TerminalStyle, }; pub fn bg_style_from_depth(depth: usize) -> TerminalStyle { diff --git a/lib-nested-tty/src/edit-tree/cursor_widget.rs b/lib-nested-tty/src/edit_tree/cursor_widget.rs similarity index 100% rename from lib-nested-tty/src/edit-tree/cursor_widget.rs rename to lib-nested-tty/src/edit_tree/cursor_widget.rs diff --git a/lib-nested-tty/src/edit-tree/diagnostics.rs b/lib-nested-tty/src/edit_tree/diagnostics.rs similarity index 100% rename from lib-nested-tty/src/edit-tree/diagnostics.rs rename to lib-nested-tty/src/edit_tree/diagnostics.rs diff --git a/lib-nested-tty/src/edit_tree/mod.rs b/lib-nested-tty/src/edit_tree/mod.rs new file mode 100644 index 0000000..e5f34a1 --- /dev/null +++ b/lib-nested-tty/src/edit_tree/mod.rs @@ -0,0 +1,3 @@ + +pub mod color; + diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 663079d..f0f87e7 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -4,23 +4,24 @@ use { projection::decorate_sequence::*, }, nested::{ - type_system::{Context, ReprTree}, + repr_tree::{Context, ReprTree}, editors::list::*, - tree::{TreeCursor, TreeNav, TreeNavResult}, - tree::NestedNode, - PtySegment + edit_tree::{TreeCursor, TreeNav, TreeNavResult, NestedNode}, }, crate::{ - TerminalEvent, TerminalView, make_label - } + DisplaySegment, + TerminalStyle, + TerminalEvent, TerminalView, make_label, + edit_tree::color::{bg_style_from_depth, fg_style_from_depth} + }, std::sync::{Arc, RwLock}, termion::event::{Event, Key} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -impl PtySegment for ListSegment { - fn pty_view(&self) -> OuterViewPort<dyn TerminalView> { +impl DisplaySegment for ListSegment { + fn display_view(&self) -> OuterViewPort<dyn TerminalView> { match self { ListSegment::InsertCursor => { make_label("|") @@ -32,7 +33,7 @@ impl PtySegment for ListSegment { ListSegment::Item{ editor, cur_dist } => { let e = editor.clone(); let cur_dist = *cur_dist; - editor.get_view().map_item(move |_pt, atom| { + editor.display_view().map_item(move |_pt, atom| { let c = e.get_cursor(); let cur_depth = c.tree_addr.len(); let select = @@ -71,7 +72,7 @@ impl PTYListStyle { editor.get_data_port() ); let se = seg_seq.read().unwrap(); - se.get_view().map(move |segment| segment.pty_view()) + se.get_view().map(move |segment| segment.display_view()) } pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> { @@ -83,7 +84,7 @@ impl PTYListStyle { seg_seq .get_view() - .map(move |segment| segment.pty_view()) + .map(move |segment| segment.display_view()) .separate(make_label(&self.style.1)) .wrap(make_label(&self.style.0), make_label(&self.style.2)) .to_grid_horizontal() @@ -91,12 +92,15 @@ impl PTYListStyle { } pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) { - node.view = Some( - Self::new(style) - .pty_view( - &node.get_edit::<ListEditor>().unwrap().read().unwrap() - ) - ); + node.display + .write().unwrap() + .insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), + Self::new(style) + .pty_view( + &node.get_edit::<ListEditor>().unwrap().read().unwrap() + ).into() + )); } } @@ -166,15 +170,22 @@ impl PTYListController { self.editor.read().unwrap().get_item() } - pub fn handle_term_event(&mut self, event: &TerminalEvent, _cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { + pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { let mut e = self.editor.write().unwrap(); match event { TerminalEvent::Input(Event::Key(Key::Insert)) => { e.toggle_leaf_mode(); TreeNavResult::Continue } - _ => TreeNavResult::Continue - } + TerminalEvent::Input(Event::Key(Key::Char(c))) => { + let ctx = e.ctx.clone(); + drop(e); + self.handle_any_event( + ReprTree::from_char(&ctx, *c) + ) + } + _ => TreeNavResult::Continue + } } pub fn handle_meta_char(&mut self, c: char, child_close_char: Option<char>) -> TreeNavResult { @@ -201,6 +212,7 @@ impl PTYListController { } pub fn handle_any_event(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { + eprintln!("ANY EVENT"); let mut e = self.editor.write().unwrap(); let cur = e.cursor.get(); let ctx = e.ctx.clone(); @@ -255,7 +267,7 @@ impl PTYListController { } use r3vi::view::singleton::SingletonView; -use crate::commander::ObjCommander; +use nested::editors::ObjCommander; impl ObjCommander for PTYListController { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs new file mode 100644 index 0000000..dbaef38 --- /dev/null +++ b/lib-nested-tty/src/editors/mod.rs @@ -0,0 +1,3 @@ + +pub mod list; + diff --git a/lib-nested-tty/src/editors/mod.rsr b/lib-nested-tty/src/editors/mod.rsr deleted file mode 100644 index e69de29..0000000 diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index 687ceca..a95835e 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -11,7 +11,8 @@ pub mod ansi_parser; pub mod terminal; pub mod tty_application; -//pub mod edit_tree; +pub mod editors; +pub mod edit_tree; //pub mod widgets; // <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ @@ -43,11 +44,24 @@ use std::sync::{Arc, RwLock}; impl DisplaySegment for nested::edit_tree::NestedNode { fn display_view(&self) -> OuterViewPort<dyn TerminalView> { - self.view.as_ref().unwrap() + if let Some( tv_repr ) = self.display .read().unwrap() - .descend( Context::parse(&self.ctx, "TerminalView") ).expect("terminal backend not supported by view") - .read().unwrap() - .get_port::<dyn TerminalView>().unwrap() + .descend( Context::parse(&self.ctx, "TerminalView") ) + { + if let Some(port) = + tv_repr + .read().unwrap() + .get_port::<dyn TerminalView>() { + port + } + + else { + make_label("no TerminalView port found") + } + } else { + make_label("TTY Display not supported") + .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((220, 30, 30)))) + } } } From d15077aca077e2965d0b7f03018afb2285dc56e4 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 29 Nov 2023 02:22:44 +0100 Subject: [PATCH 11/75] add TreeNavCmd and keymap functions --- examples/tty-02-node/src/main.rs | 40 +++----- lib-nested-core/src/edit_tree/nav.rs | 14 +++ lib-nested-core/src/edit_tree/node.rs | 21 +++- lib-nested-core/src/editors/list/editor.rs | 2 - lib-nested-tty/src/edit_tree/keymap.rs | 109 +++++++++++++++++++++ lib-nested-tty/src/edit_tree/mod.rs | 1 + lib-nested-tty/src/editors/list.rs | 1 - 7 files changed, 155 insertions(+), 33 deletions(-) create mode 100644 lib-nested-tty/src/edit_tree/keymap.rs diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index eb3515e..4a027f5 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -9,6 +9,7 @@ use { nested::{ edit_tree::{NestedNode, TreeCursor, TreeNav}, repr_tree::{Context, ReprTree}, + editors::ObjCommander }, nested_tty::{ terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor, @@ -96,7 +97,7 @@ async fn main() { /* Create a Char-Node with editor & view */ - let mut n1 = Context::make_node( + let mut node1 = Context::make_node( &ctx, // node type Context::parse(&ctx, "Char"), @@ -105,7 +106,7 @@ async fn main() { ).unwrap(); // add a display view to the node - n1 = node_make_view( n1 ); + node1 = node_make_view( node1 ); /* Create a <List Char>-Node with editor & view */ @@ -127,32 +128,13 @@ async fn main() { */ let ctx = ctx.clone(); - let mut node = n1.clone(); - node.goto(TreeCursor::home()); - - - let node2 = node2.clone(); + let mut node1 = node1.clone(); + let mut node2 = node2.clone(); move |ev| { - - if let Some(cmd) =node2.cmd.get() { - cmd.write().unwrap().send_cmd_obj( - ReprTree::new_leaf( - Context::parse(&ctx, "TerminalEvent"), - SingletonBuffer::new(ev.clone()).get_port().into() - ) - ); - } - - match ev { - TerminalEvent::Input(Event::Key(Key::Char(c))) => { - if let Some(cmd) = node.cmd.get() { - cmd.write().unwrap().send_cmd_obj( - ReprTree::from_char(&ctx, c) - ); - } - } - _ => {} - } + let mut node1 = node1.clone(); + let mut node2 = node2.clone(); + node1.send_cmd_obj( ev.to_repr_tree(&ctx) ); + node2.send_cmd_obj( ev.to_repr_tree(&ctx) ); } }); @@ -170,12 +152,12 @@ async fn main() { ); - let label = ctx.read().unwrap().type_term_to_str( &n1.get_type() ); + let label = ctx.read().unwrap().type_term_to_str( &node1.get_type() ); compositor.write().unwrap() .push(nested_tty::make_label( &label ).offset(Vector2::new(0, 2))); compositor.write().unwrap() - .push(n1.display_view().offset(Vector2::new(15, 2))); + .push(node1.display_view().offset(Vector2::new(15, 2))); let label2 = ctx.read().unwrap().type_term_to_str( &node2.get_type() ); diff --git a/lib-nested-core/src/edit_tree/nav.rs b/lib-nested-core/src/edit_tree/nav.rs index 3dae406..f974c08 100644 --- a/lib-nested-core/src/edit_tree/nav.rs +++ b/lib-nested-core/src/edit_tree/nav.rs @@ -26,6 +26,20 @@ pub enum TreeNavResult { Continue, Exit } #[derive(Clone, Copy, Eq, PartialEq, Debug)] pub enum TreeHeightOp { P, Q, Max } +#[derive(Clone, Copy, Debug)] +pub enum TreeNavCmd { + pxev, nexd, up, dn, + qpxev, qnexd, dup, qdn, + + dn_pxev, + up_nexd, + pxev_dn_qnexd +} + +impl TreeNavCmd { + +} + pub trait TreeNav { /* CORE */ diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index 61cd789..2458766 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -282,9 +282,28 @@ impl TreeNav for NestedNode { } } +use crate::edit_tree::nav::TreeNavCmd; + impl ObjCommander for NestedNode { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { - if let Some(cmd) = self.cmd.get() { + + if cmd_obj.read().unwrap().get_type() == &Context::parse(&self.ctx, "TreeNavCmd") { + if let Some(cmd) = cmd_obj.read().unwrap().get_view::<dyn SingletonView<Item = TreeNavCmd>>() { + match cmd.get() { + TreeNavCmd::pxev => self.pxev(), + TreeNavCmd::nexd => self.nexd(), + TreeNavCmd::qpxev => self.qpxev(), + TreeNavCmd::qnexd => self.qnexd(), + + TreeNavCmd::up => self.up(), + TreeNavCmd::dn => self.dn(), + + _ => TreeNavResult::Continue + } + } else { + TreeNavResult::Exit + } + } else if let Some(cmd) = self.cmd.get() { // todo: filter out tree-nav cmds and send them to tree_nav cmd.write().unwrap().send_cmd_obj(cmd_obj) } else { diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 7006ac9..06b8bbb 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -230,8 +230,6 @@ impl ListEditor { /// insert a new element pub fn insert(&mut self, item: Arc<RwLock<NestedNode>>) { - eprintln!("list insert"); - item.read().unwrap().depth.0.set_view( self.depth.map(|d| d+1).get_view() ); diff --git a/lib-nested-tty/src/edit_tree/keymap.rs b/lib-nested-tty/src/edit_tree/keymap.rs new file mode 100644 index 0000000..54e4679 --- /dev/null +++ b/lib-nested-tty/src/edit_tree/keymap.rs @@ -0,0 +1,109 @@ +use { + termion::event::{Event, Key}, + r3vi::{ + buffer::singleton::* + }, + nested::{ + repr_tree::{Context, ReprTree}, + editors::list::ListCmd, + edit_tree::nav::TreeNavCmd + }, + crate::{ + TerminalEvent + }, + std::sync::{Arc, RwLock} +}; + +fn neo2_treenav_keymap( key: &Key ) -> Option<TreeNavCmd> { + match key { + Key::Ctrl(c) => { + match c { + + // left hand + 'l' => Some(TreeNavCmd::up), + 'i' => Some(TreeNavCmd::qnexd), + 'a' => Some(TreeNavCmd::dn), + 'e' => Some(TreeNavCmd::pxev), + + // right hand + 'n' => Some(TreeNavCmd::nexd), + 'r' => Some(TreeNavCmd::dn_pxev), + 't' => Some(TreeNavCmd::qnexd), + 'g' => Some(TreeNavCmd::up_nexd), + + _ => None + } + } + _ => None + } +} + +fn universal_treenav_keymap( key: &Key ) -> Option<TreeNavCmd> { + match key { + Key::Left => Some(TreeNavCmd::pxev), + Key::Right => Some(TreeNavCmd::nexd), + Key::Up => Some(TreeNavCmd::up), + Key::Down => Some(TreeNavCmd::dn), + Key::Home => Some(TreeNavCmd::qpxev), + Key::End => Some(TreeNavCmd::qnexd), + Key::PageUp => Some(TreeNavCmd::up_nexd), + Key::PageDown => Some(TreeNavCmd::pxev_dn_qnexd), + _ => None + } +} + +fn tty_list_keymap( key: &Key ) -> Option<ListCmd> { + match key { +// Key::Char('\t') => Some( ListCmd::ToggleLeafMode ), + + Key::Backspace => Some( ListCmd::DeletePxev ), + Key::Delete => Some( ListCmd::DeleteNexd ), + + _ => None + } +} + +impl TerminalEvent { + pub fn to_repr_tree( &self, ctx: &Arc<RwLock<Context>> ) -> Arc<RwLock<ReprTree>> { + match self { + TerminalEvent::Input(Event::Key(key)) => { + if let Some(tree_nav_cmd) = neo2_treenav_keymap(key) { + ReprTree::new_leaf( + Context::parse(&ctx, "TreeNavCmd"), + SingletonBuffer::new(tree_nav_cmd).get_port().into() + ) + } else if let Some(tree_nav_cmd) = universal_treenav_keymap(key) { + ReprTree::new_leaf( + Context::parse(&ctx, "TreeNavCmd"), + SingletonBuffer::new(tree_nav_cmd).get_port().into() + ) + } else { + if let Some(list_cmd) = tty_list_keymap(key) { + ReprTree::new_leaf( + Context::parse(&ctx, "ListCmd"), + SingletonBuffer::new(list_cmd).get_port().into() + ) + } else { + match key { + Key::Char(c) => { + ReprTree::from_char(&ctx, *c) + } + _ => { + ReprTree::new_leaf( + Context::parse(&ctx, "TerminalEvent"), + SingletonBuffer::new(self.clone()).get_port().into() + ) + } + } + } + } + } + _ => { + ReprTree::new_leaf( + Context::parse(&ctx, "TerminalEvent"), + SingletonBuffer::new(self.clone()).get_port().into() + ) + } + } + } +} diff --git a/lib-nested-tty/src/edit_tree/mod.rs b/lib-nested-tty/src/edit_tree/mod.rs index e5f34a1..fdf1de4 100644 --- a/lib-nested-tty/src/edit_tree/mod.rs +++ b/lib-nested-tty/src/edit_tree/mod.rs @@ -1,3 +1,4 @@ pub mod color; +pub mod keymap; diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index f0f87e7..0fff8ec 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -212,7 +212,6 @@ impl PTYListController { } pub fn handle_any_event(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { - eprintln!("ANY EVENT"); let mut e = self.editor.write().unwrap(); let cur = e.cursor.get(); let ctx = e.ctx.clone(); From 39fbae7740c1fe3382d9d97b41f28a557e0d5800 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 29 Nov 2023 17:37:47 +0100 Subject: [PATCH 12/75] remove debug prints --- lib-nested-core/src/editors/integer/editor.rs | 1 - lib-nested-core/src/editors/list/cmd.rs | 5 ----- lib-nested-core/src/editors/list/editor.rs | 6 ------ lib-nested-core/src/editors/list/nav.rs | 4 ---- lib-nested-core/src/editors/typeterm/cmd.rs | 1 - lib-nested-core/src/editors/typeterm/mod.rs | 3 --- lib-nested-core/src/repr_tree/context.rs | 1 - 7 files changed, 21 deletions(-) diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index fa8593a..67188ec 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -43,7 +43,6 @@ impl ObjCommander for DigitEditor { self.msg.clear(); if self.ctx.read().unwrap().meta_chars.contains(&c) { - eprintln!("digitedit: meta char"); return TreeNavResult::Exit; } else if c.to_digit(self.radix).is_none() { diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs index d1cec0d..a8a09c8 100644 --- a/lib-nested-core/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -57,7 +57,6 @@ impl ObjCommander for ListEditor { } else if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() { - eprintln!("pty-list-editor some list cmmd"); let cur = self.cursor.get(); drop(cmd_repr); @@ -76,7 +75,6 @@ impl ObjCommander for ListEditor { match cmd.get() { ListCmd::DeletePxev => { - eprintln!("SELECT: delete pxev"); if idx > 0 && item_cur.tree_addr.iter().fold( true, @@ -118,7 +116,6 @@ impl ObjCommander for ListEditor { } } } else { - eprintln!("ptylist: no item"); TreeNavResult::Exit } }, @@ -126,7 +123,6 @@ impl ObjCommander for ListEditor { ListCursorMode::Insert => { match cmd.get() { ListCmd::DeletePxev => { - eprintln!("INSERT: delete pxev"); self.delete_pxev(); TreeNavResult::Continue } @@ -149,7 +145,6 @@ impl ObjCommander for ListEditor { } } } else { - eprintln!("ptylist: cursor has no idx"); TreeNavResult::Exit } } diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 06b8bbb..85533ae 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -55,7 +55,6 @@ impl ListEditor { if idx >= 0 && idx < data.len() as isize { data.get(idx as usize).read().unwrap().get_mode_view() } else { - eprintln!("ListEditor::mode_port invalid cursor idx"); ip } } else { @@ -242,7 +241,6 @@ impl ListEditor { if self.is_listlist() { cur.mode = ListCursorMode::Select; } else { - eprintln!("list insert: is not a listlist ({:?})", self.typ); item.write().unwrap().goto(TreeCursor::none()); cur.idx = Some(idx + 1); } @@ -258,13 +256,11 @@ impl ListEditor { self.cursor.set(cur); } else { - //eprintln!("insert: no cursor"); } } /// split the list off at the current cursor position and return the second half pub fn split(&mut self) { - eprintln!("split"); let cur = self.cursor.get(); if let Some(idx) = cur.idx { let idx = idx as usize; @@ -299,7 +295,6 @@ impl ListEditor { } pub fn listlist_split(&mut self) { - eprintln!("listlist split"); let cur = self.get_cursor(); if let Some(mut item) = self.get_item().clone() { @@ -316,7 +311,6 @@ impl ListEditor { tail_node.goto(TreeCursor::home()); for node in b.iter() { - eprintln!("splid :send to tail node"); tail_node .send_cmd_obj( ReprTree::new_leaf( diff --git a/lib-nested-core/src/editors/list/nav.rs b/lib-nested-core/src/editors/list/nav.rs index 94b4731..b92cc8f 100644 --- a/lib-nested-core/src/editors/list/nav.rs +++ b/lib-nested-core/src/editors/list/nav.rs @@ -195,7 +195,6 @@ impl TreeNav for ListEditor { TreeNavResult::Exit } else if direction.y > 0 { // dn - eprintln!("dn: data.len() = {}", self.data.len()); self.cursor.set(ListCursor { mode: if self.data.len() > 0 { cur.leaf_mode } else { ListCursorMode::Insert }, idx: Some(0) @@ -367,7 +366,6 @@ impl TreeNav for ListEditor { depth as isize - 1 }; - eprintln!("<- LEFT CROSS: pxv_height = {}, cur_height = {}, dist_from_ground = {}, n_steps_down = {}", pxv_height, cur_height, dist_from_ground, n_steps_down); new_addr.push( cur.tree_addr[0] - 1 ); for _i in 0..n_steps_down { new_addr.push( -1 ); @@ -387,7 +385,6 @@ impl TreeNav for ListEditor { depth as isize - 1 }; - eprintln!("-> RIGHT CROSS: cur_height = {}, nxd_height = {}, dist_from_ground = {}, n_steps_down = {}", cur_height, nxd_height, dist_from_ground, n_steps_down); new_addr.push( cur.tree_addr[0] + 1 ); for _i in 0..n_steps_down { new_addr.push( 0 ); @@ -396,7 +393,6 @@ impl TreeNav for ListEditor { drop(cur_item); - eprintln!("CROSS: goto {:?}", new_addr); cur.tree_addr = new_addr; self.goto(cur) } else { diff --git a/lib-nested-core/src/editors/typeterm/cmd.rs b/lib-nested-core/src/editors/typeterm/cmd.rs index 4885ed1..4420115 100644 --- a/lib-nested-core/src/editors/typeterm/cmd.rs +++ b/lib-nested-core/src/editors/typeterm/cmd.rs @@ -240,7 +240,6 @@ impl ObjCommander for TypeTermEditor { self.set_state( State::Ladder ); } } else { - eprintln!("ERROR"); } } else { self.set_state( State::AnySymbol ); diff --git a/lib-nested-core/src/editors/typeterm/mod.rs b/lib-nested-core/src/editors/typeterm/mod.rs index 2134be4..0b8b3b6 100644 --- a/lib-nested-core/src/editors/typeterm/mod.rs +++ b/lib-nested-core/src/editors/typeterm/mod.rs @@ -285,7 +285,6 @@ impl TypeTermEditor { } pub fn normalize_empty(&mut self) { - eprintln!("normalize singleton"); let subladder_list_node = self.cur_node.get().clone(); let subladder_list_edit = subladder_list_node.get_edit::<ListEditor>().unwrap(); @@ -298,7 +297,6 @@ impl TypeTermEditor { /* unwrap a ladder if it only contains one element */ pub fn normalize_singleton(&mut self) { - eprintln!("normalize singleton"); if self.state == State::Ladder { let subladder_list_node = self.cur_node.get().clone(); @@ -362,7 +360,6 @@ impl TypeTermEditor { /* replace with new list-node (ladder/app) with self as first element */ pub(super) fn morph_to_list(&mut self, state: State) { - eprintln!("morph into ladder"); let mut old_node = self.cur_node.get().clone(); diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 3934246..6eaffd6 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -323,7 +323,6 @@ impl Context { node.clone() } } else { - eprintln!("could not find morphism {}", pattern.to_str(&node.ctx.read().unwrap())); node } } From 6a3afde29cbf3d25d590f1c0430bdfc6a837ac64 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 29 Nov 2023 17:38:30 +0100 Subject: [PATCH 13/75] tty application: set shorter update interval --- lib-nested-tty/src/tty_application.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib-nested-tty/src/tty_application.rs b/lib-nested-tty/src/tty_application.rs index fe4e48f..abcbf0b 100644 --- a/lib-nested-tty/src/tty_application.rs +++ b/lib-nested-tty/src/tty_application.rs @@ -58,7 +58,7 @@ impl TTYApplication { async fn update_loop(port: ViewPort<dyn TerminalView>) { loop { port.update(); - async_std::task::sleep(std::time::Duration::from_millis(500)).await; + async_std::task::sleep(std::time::Duration::from_millis(50)).await; } } From bee1b43ddc071b119e2e9edb04159a30279cfc27 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 29 Nov 2023 17:44:37 +0100 Subject: [PATCH 14/75] tty displaySegment: shorten error labels --- lib-nested-tty/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index a95835e..b8b780f 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -56,10 +56,10 @@ impl DisplaySegment for nested::edit_tree::NestedNode { } else { - make_label("no TerminalView port found") + make_label("?") } } else { - make_label("TTY Display not supported") + make_label("?") .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((220, 30, 30)))) } } From be3eefc3a5ab575553d4d1b56e4203a6b692473b Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 29 Nov 2023 18:12:04 +0100 Subject: [PATCH 15/75] edit tree: split node struct into sub structs --- examples/tty-02-node/src/main.rs | 23 ++-- lib-nested-core/src/edit_tree/nav.rs | 4 - lib-nested-core/src/edit_tree/node.rs | 110 +++++++------------- lib-nested-core/src/editors/list/editor.rs | 10 +- lib-nested-core/src/editors/typeterm/mod.rs | 18 ++-- lib-nested-core/src/repr_tree/context.rs | 2 +- lib-nested-tty/src/editors/list.rs | 12 +-- lib-nested-tty/src/lib.rs | 2 +- 8 files changed, 72 insertions(+), 109 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 4a027f5..d6199a8 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -28,7 +28,7 @@ use { fn node_make_char_view( node: NestedNode ) -> NestedNode { - node.display + node.disp.view .write().unwrap() .insert_branch(ReprTree::new_leaf( Context::parse(&node.ctx, "TerminalView"), @@ -45,15 +45,13 @@ fn node_make_char_view( node } -fn node_make_list_view( +fn node_make_seq_view( mut node: NestedNode ) -> NestedNode { - eprintln!("add list display type"); - node.display + node.disp.view .write().unwrap() .insert_branch(ReprTree::new_leaf( Context::parse(&node.ctx, "TerminalView"), - node.data .read() .unwrap() @@ -65,8 +63,13 @@ fn node_make_list_view( .flatten() .into() )); + node +} -// nested_tty::editors::list::PTYListStyle::for_node( &mut node, ("(", ",", ")") ); +fn node_make_list_edit( + mut node: NestedNode +) -> NestedNode { + nested_tty::editors::list::PTYListStyle::for_node( &mut node, ("(", ",", ")") ); nested_tty::editors::list::PTYListController::for_node( &mut node, None, None ); node @@ -78,10 +81,9 @@ fn node_make_view( if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { node_make_char_view( node ) } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") { - node_make_list_view( node ) -// node + node_make_seq_view( node ) } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") { - node_make_list_view( node ) + node_make_list_edit( node ) } else { eprintln!("couldnt add view"); node @@ -130,7 +132,7 @@ async fn main() { let ctx = ctx.clone(); let mut node1 = node1.clone(); let mut node2 = node2.clone(); - move |ev| { + move |ev| { let mut node1 = node1.clone(); let mut node2 = node2.clone(); node1.send_cmd_obj( ev.to_repr_tree(&ctx) ); @@ -151,7 +153,6 @@ async fn main() { .offset(Vector2::new(5, 0)), ); - let label = ctx.read().unwrap().type_term_to_str( &node1.get_type() ); compositor.write().unwrap() .push(nested_tty::make_label( &label ).offset(Vector2::new(0, 2))); diff --git a/lib-nested-core/src/edit_tree/nav.rs b/lib-nested-core/src/edit_tree/nav.rs index f974c08..a47204d 100644 --- a/lib-nested-core/src/edit_tree/nav.rs +++ b/lib-nested-core/src/edit_tree/nav.rs @@ -36,10 +36,6 @@ pub enum TreeNavCmd { pxev_dn_qnexd } -impl TreeNavCmd { - -} - pub trait TreeNav { /* CORE */ diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index 2458766..84d0412 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -13,33 +13,31 @@ use { } }; -//* TODO: refactoring proposal -/* - -struct NestedNodeDisplay { +#[derive(Clone)] +pub struct NestedNodeDisplay { /// display view - pub view: Option< Arc<RwLock<ReprTree>> >, + pub view: Arc<RwLock<ReprTree>>, /// diagnostics - pub diag: Option< OuterViewPort<dyn SequenceView<Item = diagnostics::Message>> >, + pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >, /// depth - pub depth: SingletonBuffer< usize >, + pub depth: OuterViewPort<dyn SingletonView<Item = usize>>, } -struct NestedNodeEdit { +#[derive(Clone)] +pub struct NestedNodeEdit { /// abstract editor pub editor: SingletonBuffer< Option< Arc<dyn Any + Send + Sync> > - >, + >, - pub spillbuf: VecBuffer< NestedNode >, + pub spillbuf: Arc<RwLock< Vec< Arc<RwLock< NestedNode >> > >>, /// commander & navigation pub cmd: SingletonBuffer< Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> > >, /// abstract data view - pub data: Arc<RwLock<ReprTree>>, pub close_char: SingletonBuffer< Option< char > >, @@ -49,7 +47,8 @@ struct NestedNodeEdit { >, } -pub struct NewNestedNode { +#[derive(Clone)] +pub struct NestedNode { /// context pub ctx: Arc<RwLock<Context>>, @@ -62,57 +61,23 @@ pub struct NewNestedNode { /// editor & commander objects pub edit: NestedNodeEdit } -*/ - -#[derive(Clone)] -pub struct NestedNode { - /// context - pub ctx: Arc<RwLock<Context>>, - - /// abstract data view - pub data: Arc<RwLock<ReprTree>>, - - /// display view - pub display: Arc<RwLock<ReprTree>>, - - /// diagnostics - pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >, - - /// depth - pub depth: OuterViewPort< dyn SingletonView<Item = usize> >, - - /// abstract editor - pub editor: SingletonBuffer< - Option< Arc<dyn Any + Send + Sync> > - >, - - pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>, - - /// commander & navigation - pub cmd: SingletonBuffer< - Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> > - >, - pub close_char: SingletonBuffer< - Option< char > - >, - pub tree_nav: SingletonBuffer< - Option< Arc<RwLock<dyn TreeNav + Send + Sync>> > - >, -} impl NestedNode { pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self { NestedNode { + disp: NestedNodeDisplay { + view: ReprTree::new_arc(Context::parse(&ctx, "Display")), + diag: None, + depth, + }, + edit: NestedNodeEdit { + editor: SingletonBuffer::new(None), + spillbuf: Arc::new(RwLock::new(Vec::new())), + cmd: SingletonBuffer::new(None), + close_char: SingletonBuffer::new(None), + tree_nav: SingletonBuffer::new(None), + }, data, - display: Arc::new(RwLock::new(ReprTree::new(Context::parse(&ctx, "Display")))), - diag: None, - depth, - editor: SingletonBuffer::new(None), - spillbuf: Arc::new(RwLock::new(Vec::new())), - cmd: SingletonBuffer::new(None), - close_char: SingletonBuffer::new(None), - tree_nav: SingletonBuffer::new(None), - ctx } } @@ -147,29 +112,29 @@ impl NestedNode { //\\//\\ pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self { - self.editor.set(Some(editor)); + self.edit.editor.set(Some(editor)); self } pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self { - self.cmd.set(Some(cmd)); + self.edit.cmd.set(Some(cmd)); self } pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self { - self.tree_nav.set(Some(nav)); + self.edit.tree_nav.set(Some(nav)); self } pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self { - self.diag = Some(diag); + self.disp.diag = Some(diag); self } //\\//\\ pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> { - self.diag.clone().unwrap_or(ViewPort::new().into_outer()) + self.disp.diag.clone().unwrap_or(ViewPort::new().into_outer()) } pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>> @@ -200,7 +165,7 @@ impl NestedNode { */ pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> { - if let Some(edit) = self.editor.get() { + if let Some(edit) = self.edit.editor.get() { if let Ok(edit) = edit.downcast::<RwLock<T>>() { Some(edit) } else { @@ -226,7 +191,7 @@ impl TreeType for NestedNode { impl TreeNav for NestedNode { fn get_cursor(&self) -> TreeCursor { - if let Some(tn) = self.tree_nav.get() { + if let Some(tn) = self.edit.tree_nav.get() { tn.read().unwrap().get_cursor() } else { TreeCursor::default() @@ -234,7 +199,7 @@ impl TreeNav for NestedNode { } fn get_addr_view(&self) -> OuterViewPort<dyn SequenceView<Item = isize>> { - if let Some(tn) = self.tree_nav.get() { + if let Some(tn) = self.edit.tree_nav.get() { tn.read().unwrap().get_addr_view() } else { OuterViewPort::default() @@ -242,7 +207,7 @@ impl TreeNav for NestedNode { } fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> { - if let Some(tn) = self.tree_nav.get() { + if let Some(tn) = self.edit.tree_nav.get() { tn.read().unwrap().get_mode_view() } else { OuterViewPort::default() @@ -250,7 +215,7 @@ impl TreeNav for NestedNode { } fn get_cursor_warp(&self) -> TreeCursor { - if let Some(tn) = self.tree_nav.get() { + if let Some(tn) = self.edit.tree_nav.get() { tn.read().unwrap().get_cursor_warp() } else { TreeCursor::default() @@ -258,7 +223,7 @@ impl TreeNav for NestedNode { } fn get_height(&self, op: &TreeHeightOp) -> usize { - if let Some(tn) = self.tree_nav.get() { + if let Some(tn) = self.edit.tree_nav.get() { tn.read().unwrap().get_height( op ) } else { 0 @@ -266,7 +231,7 @@ impl TreeNav for NestedNode { } fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult { - if let Some(tn) = self.tree_nav.get() { + if let Some(tn) = self.edit.tree_nav.get() { tn.write().unwrap().goby(direction) } else { TreeNavResult::Exit @@ -274,7 +239,7 @@ impl TreeNav for NestedNode { } fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult { - if let Some(tn) = self.tree_nav.get() { + if let Some(tn) = self.edit.tree_nav.get() { tn.write().unwrap().goto(new_cursor) } else { TreeNavResult::Exit @@ -303,7 +268,7 @@ impl ObjCommander for NestedNode { } else { TreeNavResult::Exit } - } else if let Some(cmd) = self.cmd.get() { + } else if let Some(cmd) = self.edit.cmd.get() { // todo: filter out tree-nav cmds and send them to tree_nav cmd.write().unwrap().send_cmd_obj(cmd_obj) } else { @@ -312,6 +277,7 @@ impl ObjCommander for NestedNode { } } + impl Diagnostics for NestedNode { fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> { self.get_diag() diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 85533ae..087861b 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -131,7 +131,7 @@ impl ListEditor { .flatten() ); - node.spillbuf = e.spillbuf.clone(); + node.edit.spillbuf = e.spillbuf.clone(); node } @@ -229,7 +229,7 @@ impl ListEditor { /// insert a new element pub fn insert(&mut self, item: Arc<RwLock<NestedNode>>) { - item.read().unwrap().depth.0.set_view( + item.read().unwrap().disp.depth.0.set_view( self.depth.map(|d| d+1).get_view() ); @@ -306,7 +306,7 @@ impl ListEditor { self.set_leaf_mode(ListCursorMode::Insert); self.nexd(); - let mut b = item.spillbuf.write().unwrap(); + let mut b = item.edit.spillbuf.write().unwrap(); let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap(); tail_node.goto(TreeCursor::home()); @@ -364,7 +364,7 @@ impl ListEditor { let old_cur = pxv_editor.get_cursor(); - let data = cur_editor.spillbuf.read().unwrap(); + let data = cur_editor.edit.spillbuf.read().unwrap(); for x in data.iter() { pxv_editor.send_cmd_obj( ReprTree::new_leaf( @@ -422,7 +422,7 @@ impl ListEditor { leaf_mode: ListCursorMode::Insert }); - let data = nxd_editor.spillbuf.read().unwrap(); + let data = nxd_editor.edit.spillbuf.read().unwrap(); for x in data.iter() { cur_editor.send_cmd_obj( diff --git a/lib-nested-core/src/editors/typeterm/mod.rs b/lib-nested-core/src/editors/typeterm/mod.rs index 0b8b3b6..abaaaab 100644 --- a/lib-nested-core/src/editors/typeterm/mod.rs +++ b/lib-nested-core/src/editors/typeterm/mod.rs @@ -168,8 +168,8 @@ impl TypeTermEditor { node.goto(TreeCursor::home()); - let _editor = node.editor.get(); - self.close_char.set(node.close_char.get()); + let _editor = node.edit.editor.get(); + self.close_char.set(node.edit.close_char.get()); self.cur_node.set(node); self.state = new_state; } @@ -204,7 +204,7 @@ impl TypeTermEditor { cur_node: SingletonBuffer::new(cur_node.clone()), close_char: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())), - depth: cur_node.depth.clone() + depth: cur_node.disp.depth.clone() }; /* FIXME let view = editor.cur_node @@ -215,24 +215,24 @@ impl TypeTermEditor { .to_grid() .flatten(); */ - let _cc = editor.cur_node.get().close_char; + let _cc = editor.cur_node.get().edit.close_char; let editor = Arc::new(RwLock::new(editor)); - let mut super_node = NestedNode::new(ctx, data, cur_node.depth) + let mut super_node = NestedNode::new(ctx, data, cur_node.disp.depth) // .set_view(view) .set_nav(editor.clone()) .set_cmd(editor.clone()) .set_editor(editor.clone()); - editor.write().unwrap().close_char = super_node.close_char.clone(); - super_node.spillbuf = editor.read().unwrap().spillbuf.clone(); + editor.write().unwrap().close_char = super_node.edit.close_char.clone(); + super_node.edit.spillbuf = editor.read().unwrap().spillbuf.clone(); super_node } fn forward_spill(&mut self) { let node = self.cur_node.get(); - let mut buf = node.spillbuf.write().unwrap(); + let mut buf = node.edit.spillbuf.write().unwrap(); for n in buf.iter() { self.spillbuf.write().unwrap().push(n.clone()); } @@ -371,7 +371,7 @@ impl TypeTermEditor { * that has same state & child-node as current node. */ let old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), SingletonBuffer::new(0).get_port() ); - old_node.depth.0.set_view( old_edit_node.depth.map(|x|x).get_view() ); + old_node.disp.depth.0.set_view( old_edit_node.disp.depth.map(|x|x).get_view() ); let old_edit_clone = old_edit_node.get_edit::<TypeTermEditor>().unwrap(); old_edit_clone.write().unwrap().set_state( self.state ); diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 6eaffd6..56d331d 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -260,7 +260,7 @@ impl Context { drop(dict); self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| { - mk_editor(node.ctx.clone(), dst_type, node.depth) + mk_editor(node.ctx.clone(), dst_type, node.disp.depth) })); } diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 0fff8ec..fb3f9a4 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -46,7 +46,7 @@ impl DisplaySegment for ListSegment { atom .add_style_back(bg_style_from_depth(select)) .add_style_back(TerminalStyle::bold(select==1)) - .add_style_back(fg_style_from_depth(e.depth.get_view().get())) + .add_style_back(fg_style_from_depth(e.disp.depth.get_view().get())) }) } } @@ -92,7 +92,7 @@ impl PTYListStyle { } pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) { - node.display + node.disp.view .write().unwrap() .insert_branch(ReprTree::new_leaf( Context::parse(&node.ctx, "TerminalView"), @@ -152,10 +152,10 @@ impl PTYListController { } let editor = node.get_edit::<ListEditor>().unwrap(); - let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.depth.clone() ))); + let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.disp.depth.clone() ))); - node.cmd.set(Some(controller.clone())); - node.close_char.set(close_char); + node.edit.cmd.set(Some(controller.clone())); + node.edit.close_char.set(close_char); } pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> { @@ -235,7 +235,7 @@ impl PTYListController { ListCursorMode::Select => { if let Some(item) = e.get_item_mut() { let res = item.write().unwrap().send_cmd_obj(cmd_obj.clone()); - let child_close_char = item.read().unwrap().close_char.get(); + let child_close_char = item.read().unwrap().edit.close_char.get(); match res { TreeNavResult::Continue => TreeNavResult::Continue, diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index b8b780f..e7c03a3 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -44,7 +44,7 @@ use std::sync::{Arc, RwLock}; impl DisplaySegment for nested::edit_tree::NestedNode { fn display_view(&self) -> OuterViewPort<dyn TerminalView> { - if let Some( tv_repr ) = self.display + if let Some( tv_repr ) = self.disp.view .read().unwrap() .descend( Context::parse(&self.ctx, "TerminalView") ) { From 834bb49b5e85821b7929836d7178a6becfd60156 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 18 Jan 2024 19:05:25 +0100 Subject: [PATCH 16/75] add tty/pty server as separate crates --- display-server-tty/Cargo.toml | 12 ++ display-server-tty/src/main.rs | 67 +++++++ pty-server/Cargo.toml | 13 ++ pty-server/src/main.rs | 331 +++++++++++++++++++++++++++++++++ 4 files changed, 423 insertions(+) create mode 100644 display-server-tty/Cargo.toml create mode 100644 display-server-tty/src/main.rs create mode 100644 pty-server/Cargo.toml create mode 100644 pty-server/src/main.rs diff --git a/display-server-tty/Cargo.toml b/display-server-tty/Cargo.toml new file mode 100644 index 0000000..4d933da --- /dev/null +++ b/display-server-tty/Cargo.toml @@ -0,0 +1,12 @@ +[package] +authors = ["Michael Sippel <micha@fragmental.art>"] +name = "display_server" +version = "0.1.0" +edition = "2018" + +[dependencies] +nested = { path = "../../nested" } +termion = "1.5.5" +cgmath = { version = "0.18.0", features = ["serde"] } +serde = { version = "1.0", features = ["serde_derive"] } +bincode = "1.3.3" diff --git a/display-server-tty/src/main.rs b/display-server-tty/src/main.rs new file mode 100644 index 0000000..a3f52fc --- /dev/null +++ b/display-server-tty/src/main.rs @@ -0,0 +1,67 @@ +use { + cgmath::{Point2, Vector2}, + nested::terminal::{TerminalAtom, TerminalStyle}, + std::io::{stdout, Read, Write}, + termion::raw::IntoRawMode, +}; + +fn main() { + let mut out = stdout().into_raw_mode().unwrap(); + write!( + out, + "{}{}{}", + termion::cursor::Hide, + termion::cursor::Goto(1, 1), + termion::style::Reset + ) + .unwrap(); + + let mut cur_pos = Point2::<i16>::new(0, 0); + let mut cur_style = TerminalStyle::default(); + + let mut input = std::io::stdin(); + + loop { + match bincode::deserialize_from::<_, (Point2<i16>, Option<TerminalAtom>)>(input.by_ref()) { + Ok((pos, atom)) => { + if pos != cur_pos { + write!( + out, + "{}", + termion::cursor::Goto(pos.x as u16 + 1, pos.y as u16 + 1) + ) + .unwrap(); + } + + if let Some(atom) = atom { + if cur_style != atom.style { + cur_style = atom.style; + write!(out, "{}", atom.style).expect(""); + } + + write!(out, "{}", atom.c.unwrap_or(' ')).expect(""); + } else { + write!(out, "{} ", termion::style::Reset).expect(""); + cur_style = TerminalStyle::default(); + } + + cur_pos = pos + Vector2::new(1, 0); + + out.flush().unwrap(); + } + Err(err) => { + match *err { + bincode::ErrorKind::Io(_io_error) => break, + err => { + eprintln!("deserialization error\n{:?}", err); + } + } + break; + } + } + } + + // restore conventional terminal settings + write!(out, "{}", termion::cursor::Show).unwrap(); + out.flush().unwrap(); +} diff --git a/pty-server/Cargo.toml b/pty-server/Cargo.toml new file mode 100644 index 0000000..2b1ca1d --- /dev/null +++ b/pty-server/Cargo.toml @@ -0,0 +1,13 @@ +[package] +authors = ["Michael Sippel <micha@fragmental.art>"] +name = "ansi_parser" +version = "0.1.0" +edition = "2018" + +[dependencies] +nested = { path = "../../nested" } +cgmath = { version = "0.18.0", features = ["serde"] } +serde = { version = "1.0", features = ["serde_derive"] } +bincode = "1.3.3" +vte = "0.10.1" +ansi_colours = "1.0" diff --git a/pty-server/src/main.rs b/pty-server/src/main.rs new file mode 100644 index 0000000..0e4d532 --- /dev/null +++ b/pty-server/src/main.rs @@ -0,0 +1,331 @@ +#![feature(iter_advance_by)] + +use { + cgmath::Point2, + nested::terminal::{TerminalAtom, TerminalStyle}, + std::{ + fs::File, + io::{stdin, Read, Write}, + os::unix::io::FromRawFd, + }, + vte::{Params, Parser, Perform}, +}; + +struct ColorPalett { + black: (u8, u8, u8), + red: (u8, u8, u8), + green: (u8, u8, u8), + yellow: (u8, u8, u8), + blue: (u8, u8, u8), + magenta: (u8, u8, u8), + cyan: (u8, u8, u8), + white: (u8, u8, u8), +} + +struct PerfAtom { + colors: ColorPalett, + term_width: i16, + + cursor: Point2<i16>, + style: TerminalStyle, + + out: File, +} + +impl PerfAtom { + fn write_atom(&mut self, pos: Point2<i16>, atom: Option<TerminalAtom>) { + self.out + .write(&bincode::serialize(&(pos, atom)).unwrap()) + .expect(""); + } +} + +impl Perform for PerfAtom { + fn print(&mut self, c: char) { + //eprintln!("[print] {:?}", c); + self.write_atom(self.cursor, Some(TerminalAtom::new(c, self.style))); + + self.cursor.x += 1; + if self.cursor.x > self.term_width { + self.cursor.x = 0; + self.cursor.y += 1; + } + } + + fn execute(&mut self, byte: u8) { + //eprintln!("[execute] {:02x}", byte); + match byte { + b'\n' => { + self.cursor.x = 0; + self.cursor.y += 1; + } + _ => {} + } + } + + fn hook(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { + eprintln!( + "[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}", + params, intermediates, ignore, c + ); + } + + fn put(&mut self, byte: u8) { + eprintln!("[put] {:02x}", byte); + } + + fn unhook(&mut self) { + eprintln!("[unhook]"); + } + + fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) { + eprintln!( + "[osc_dispatch] params={:?} bell_terminated={}", + params, bell_terminated + ); + } + + fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { + eprintln!( + "[csi_dispatch] params={:#?}, intermediates={:?}, ignore={:?}, char={:?}", + params, intermediates, ignore, c + ); + + let mut piter = params.into_iter(); + + match c { + // Set SGR + 'm' => { + while let Some(n) = piter.next() { + match n[0] { + 0 => self.style = TerminalStyle::default(), + 1 => self.style = self.style.add(TerminalStyle::bold(true)), + 3 => self.style = self.style.add(TerminalStyle::italic(true)), + 4 => self.style = self.style.add(TerminalStyle::underline(true)), + + 30 => { + self.style = self.style.add(TerminalStyle::fg_color(self.colors.black)) + } + 40 => { + self.style = self.style.add(TerminalStyle::bg_color(self.colors.black)) + } + 31 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.red)), + 41 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.red)), + 32 => { + self.style = self.style.add(TerminalStyle::fg_color(self.colors.green)) + } + 42 => { + self.style = self.style.add(TerminalStyle::bg_color(self.colors.green)) + } + 33 => { + self.style = self.style.add(TerminalStyle::fg_color(self.colors.yellow)) + } + 43 => { + self.style = self.style.add(TerminalStyle::bg_color(self.colors.yellow)) + } + 34 => { + self.style = self.style.add(TerminalStyle::fg_color(self.colors.blue)) + } + 44 => { + self.style = self.style.add(TerminalStyle::bg_color(self.colors.blue)) + } + 35 => { + self.style = + self.style.add(TerminalStyle::fg_color(self.colors.magenta)) + } + 45 => { + self.style = + self.style.add(TerminalStyle::bg_color(self.colors.magenta)) + } + 36 => { + self.style = self.style.add(TerminalStyle::fg_color(self.colors.cyan)) + } + 46 => { + self.style = self.style.add(TerminalStyle::bg_color(self.colors.cyan)) + } + 37 => { + self.style = self.style.add(TerminalStyle::fg_color(self.colors.white)) + } + 47 => { + self.style = self.style.add(TerminalStyle::bg_color(self.colors.white)) + } + + 38 => { + let x = piter.next().unwrap(); + match x[0] { + 2 => { + let r = piter.next().unwrap(); + let g = piter.next().unwrap(); + let b = piter.next().unwrap(); + self.style = self.style.add(TerminalStyle::fg_color(( + r[0] as u8, + g[0] as u8, + b[30] as u8, + ))) + } + 5 => { + let v = piter.next().unwrap(); + self.style = self.style.add(TerminalStyle::fg_color( + ansi_colours::rgb_from_ansi256(v[0] as u8), + )) + } + _ => {} + } + } + + 48 => { + let x = piter.next().unwrap(); + match x[0] { + 2 => { + let r = piter.next().unwrap(); + let g = piter.next().unwrap(); + let b = piter.next().unwrap(); + self.style = self.style.add(TerminalStyle::bg_color(( + r[0] as u8, + g[0] as u8, + b[30] as u8, + ))) + } + 5 => { + let v = piter.next().unwrap(); + self.style = self.style.add(TerminalStyle::bg_color( + ansi_colours::rgb_from_ansi256(v[0] as u8), + )) + } + _ => {} + } + } + + _ => {} + } + } + } + + 'H' => { + if let Some(y) = piter.next() { + self.cursor.y = y[0] as i16 - 1 + }; + if let Some(x) = piter.next() { + self.cursor.x = x[0] as i16 - 1 + }; + + eprintln!("cursor at {:?}", self.cursor); + } + + 'A' => { + self.cursor.y -= piter.next().unwrap()[0] as i16; + } + 'B' => { + self.cursor.y += piter.next().unwrap()[0] as i16; + } + 'C' => { + self.cursor.x += piter.next().unwrap()[0] as i16; + } + 'D' => { + self.cursor.x -= piter.next().unwrap()[0] as i16; + } + 'E' => { + self.cursor.x = 0; + self.cursor.y += piter.next().unwrap()[0] as i16; + } + + 'J' => { + let x = piter.next().unwrap_or(&[0 as u16; 1]); + match x[0] { + 0 => {} + 1 => {} + 2 => { + for y in 0..100 { + for x in 0..self.term_width { + self.write_atom(Point2::new(x, y), None); + } + } + } + + // invalid + _ => {} + } + } + + 'K' => { + let x = piter.next().unwrap(); + match x[0] { + // clear cursor until end + 0 => { + for x in self.cursor.x..self.term_width { + self.write_atom(Point2::new(x, self.cursor.y), None); + } + } + + // clear start until cursor + 1 => { + for x in 0..self.cursor.x { + self.write_atom(Point2::new(x, self.cursor.y), None); + } + } + + // clear entire line + 2 => { + for x in 0..self.term_width { + self.write_atom(Point2::new(x, self.cursor.y), None); + } + } + + // invalid + _ => {} + } + } + + _ => {} + } + } + + fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) { + eprintln!( + "[esc_dispatch] intermediates={:?}, ignore={:?}, byte={:02x}", + intermediates, ignore, byte + ); + } +} + +fn main() { + let input = stdin(); + let mut handle = input.lock(); + + let mut statemachine = Parser::new(); + let mut performer = PerfAtom { + cursor: Point2::new(0, 0), + style: TerminalStyle::default(), + term_width: 200, + out: unsafe { File::from_raw_fd(1) }, + + colors: ColorPalett { + black: (1, 1, 1), + red: (222, 56, 43), + green: (0, 64, 0), + yellow: (255, 199, 6), + blue: (0, 111, 184), + magenta: (118, 38, 113), + cyan: (44, 181, 233), + white: (204, 204, 204), + }, + }; + + let mut buf = [0; 2048]; + + loop { + match handle.read(&mut buf) { + Ok(0) => break, + Ok(n) => { + for byte in &buf[..n] { + statemachine.advance(&mut performer, *byte); + performer.out.flush().unwrap(); + } + } + Err(err) => { + println!("err: {}", err); + break; + } + } + } +} From 193b8c8cacc83bf20e6e8e8159ee77776ccdb576 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 18 Jan 2024 19:32:49 +0100 Subject: [PATCH 17/75] implement MorphismBase, remove `data` from NestedNode --- examples/tty-02-node/src/main.rs | 189 ++++++------- lib-nested-core/src/edit_tree/node.rs | 68 +---- lib-nested-core/src/editors/integer/ctx.rs | 5 +- lib-nested-core/src/editors/list/editor.rs | 3 +- lib-nested-core/src/editors/typeterm/ctx.rs | 4 +- lib-nested-core/src/repr_tree/context.rs | 287 +------------------- lib-nested-core/src/repr_tree/mod.rs | 113 +------- lib-nested-core/src/repr_tree/morphism.rs | 105 +++++++ lib-nested-tty/src/editors/mod.rs | 81 ++++++ 9 files changed, 309 insertions(+), 546 deletions(-) create mode 100644 lib-nested-core/src/repr_tree/morphism.rs diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index d6199a8..2fe3791 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -7,87 +7,36 @@ extern crate termion; use { cgmath::Vector2, nested::{ - edit_tree::{NestedNode, TreeCursor, TreeNav}, - repr_tree::{Context, ReprTree}, - editors::ObjCommander + editors::ObjCommander, + repr_tree::{Context}, }, nested_tty::{ - terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor, - TerminalEvent, TerminalStyle, TerminalView, - TTYApplication + DisplaySegment, TTYApplication, + TerminalCompositor, TerminalStyle, TerminalView, }, r3vi::{ buffer::singleton::*, - view::{port::UpdateTask, singleton::*, sequence::*, ViewPort}, - projection::decorate_sequence::* }, - std::sync::{Arc, Mutex, RwLock}, - termion::event::{Event, Key}, + std::sync::{Arc, RwLock}, }; -fn node_make_char_view( - node: NestedNode -) -> NestedNode { - node.disp.view - .write().unwrap() - .insert_branch(ReprTree::new_leaf( - Context::parse(&node.ctx, "TerminalView"), - node.data - .read() - .unwrap() - .get_port::<dyn SingletonView<Item = char>>() - .expect("unable to get Char-view") - .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) - .to_grid() - .into(), - )); - - node -} - -fn node_make_seq_view( - mut node: NestedNode -) -> NestedNode { - node.disp.view - .write().unwrap() - .insert_branch(ReprTree::new_leaf( - Context::parse(&node.ctx, "TerminalView"), - node.data - .read() - .unwrap() - .get_port::< dyn SequenceView<Item = NestedNode> >() - .expect("unable to get Seq-view") - .map(move |char_node| node_make_view(char_node.clone()).display_view() ) - .wrap(nested_tty::make_label("("), nested_tty::make_label(")")) - .to_grid_horizontal() - .flatten() - .into() - )); - node -} - -fn node_make_list_edit( - mut node: NestedNode -) -> NestedNode { - nested_tty::editors::list::PTYListStyle::for_node( &mut node, ("(", ",", ")") ); - nested_tty::editors::list::PTYListController::for_node( &mut node, None, None ); - - node -} - -fn node_make_view( - node: NestedNode -) -> NestedNode { - if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { - node_make_char_view( node ) - } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") { - node_make_seq_view( node ) - } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") { - node_make_list_edit( node ) - } else { - eprintln!("couldnt add view"); - node +struct ParseDigit { radix: u32 }; +impl Morphism for ParseDigit { + fn new( + ctx: &Arc<RwLock<Context>> + ) -> Self { + } + + fn setup_projection(&self, repr_tree: Arc<RwLock<ReprTree>>) { + if let Some( char_view ) = repr_tree.get_out(Context::parse(&ctx, "Char~")) { + + } + } +} + +get_morphism( ) -> Morphism { + } #[async_std::main] @@ -96,19 +45,36 @@ async fn main() { */ let ctx = Arc::new(RwLock::new(Context::default())); - /* Create a Char-Node with editor & view */ - let mut node1 = Context::make_node( + let mut char_obj = ReprTree::make_leaf( + Context::parse(&ctx, "Char"), + SingletonBuffer::new('X').get_port().into() + ); + + char_obj.insert_branch( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new( + + ) + ); + + let mut vec_obj = ReprTree::make_leaf( + Context::parse(&ctx, "<Vec Char>"), + VecBuffer::new(vec!['a', 'b', 'c']).get_port().into() + ); + + let mut char_edit = Context::new_edit_tree( &ctx, // node type Context::parse(&ctx, "Char"), // depth SingletonBuffer::new(0).get_port(), - ).unwrap(); + ) + .unwrap(); // add a display view to the node - node1 = node_make_view( node1 ); + node1 = nested_tty::editors::node_make_tty_view(node1); /* Create a <List Char>-Node with editor & view */ @@ -118,10 +84,25 @@ async fn main() { Context::parse(&ctx, "<List Char>"), // depth SingletonBuffer::new(0).get_port(), - ).unwrap(); + ) + .unwrap(); // add a display view to the node - node2 = node_make_view( node2 ); + node2 = nested_tty::editors::node_make_tty_view(node2); + + /* Create a <List Char>-Node with editor & view + */ + let mut node3 = Context::make_node( + &ctx, + // node type + Context::parse(&ctx, "<List <List Char>>"), + // depth + SingletonBuffer::new(0).get_port(), + ) + .unwrap(); + + // add a display view to the node + node3 = nested_tty::editors::node_make_tty_view(node3); /* setup terminal */ @@ -130,13 +111,16 @@ async fn main() { */ let ctx = ctx.clone(); - let mut node1 = node1.clone(); - let mut node2 = node2.clone(); - move |ev| { + let node1 = node1.clone(); + let node2 = node2.clone(); + let node3 = node3.clone(); + move |ev| { let mut node1 = node1.clone(); let mut node2 = node2.clone(); - node1.send_cmd_obj( ev.to_repr_tree(&ctx) ); - node2.send_cmd_obj( ev.to_repr_tree(&ctx) ); + let mut node3 = node3.clone(); + node1.send_cmd_obj(ev.to_repr_tree(&ctx)); + node2.send_cmd_obj(ev.to_repr_tree(&ctx)); + node3.send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -144,7 +128,7 @@ async fn main() { */ let compositor = TerminalCompositor::new(app.port.inner()); - // add some views to the display compositor + // add some views to the display compositor compositor.write().unwrap().push( nested_tty::make_label("Hello World") .map_item(|p, a| { @@ -153,21 +137,40 @@ async fn main() { .offset(Vector2::new(5, 0)), ); - let label = ctx.read().unwrap().type_term_to_str( &node1.get_type() ); - compositor.write().unwrap() - .push(nested_tty::make_label( &label ).offset(Vector2::new(0, 2))); + let label = ctx.read().unwrap().type_term_to_str(&node1.get_type()); + compositor + .write() + .unwrap() + .push(nested_tty::make_label(&label).offset(Vector2::new(0, 2))); - compositor.write().unwrap() + compositor + .write() + .unwrap() .push(node1.display_view().offset(Vector2::new(15, 2))); + let label2 = ctx.read().unwrap().type_term_to_str(&node2.get_type()); + compositor + .write() + .unwrap() + .push(nested_tty::make_label(&label2).offset(Vector2::new(0, 3))); - let label2 = ctx.read().unwrap().type_term_to_str( &node2.get_type() ); - compositor.write().unwrap() - .push(nested_tty::make_label( &label2 ).offset(Vector2::new(0, 3))); - - compositor.write().unwrap() + compositor + .write() + .unwrap() .push(node2.display_view().offset(Vector2::new(15, 3))); + + let label3 = ctx.read().unwrap().type_term_to_str(&node3.get_type()); + compositor + .write() + .unwrap() + .push(nested_tty::make_label(&label3).offset(Vector2::new(0, 4))); + + compositor + .write() + .unwrap() + .push(node3.display_view().offset(Vector2::new(25, 4))); + /* write the changes in the view of `term_port` to the terminal */ app.show().await.expect("output error!"); diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index 84d0412..b60326a 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -52,9 +52,6 @@ pub struct NestedNode { /// context pub ctx: Arc<RwLock<Context>>, - /// abstract data view - pub data: Arc<RwLock<ReprTree>>, - /// viewports for terminal display pub disp: NestedNodeDisplay, @@ -63,7 +60,7 @@ pub struct NestedNode { } impl NestedNode { - pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self { + pub fn new(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self { NestedNode { disp: NestedNodeDisplay { view: ReprTree::new_arc(Context::parse(&ctx, "Display")), @@ -74,43 +71,13 @@ impl NestedNode { editor: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())), cmd: SingletonBuffer::new(None), - close_char: SingletonBuffer::new(None), + close_char: SingletonBuffer::new(None), tree_nav: SingletonBuffer::new(None), }, - data, ctx } } - - /* TODO: move into separate file/module - */ - pub fn from_char(ctx: Arc<RwLock<Context>>, c: char) -> NestedNode { - let buf = r3vi::buffer::singleton::SingletonBuffer::<char>::new(c); - - NestedNode::new( - ctx.clone(), - ReprTree::new_leaf( - Context::parse(&ctx, "Char"), - buf.get_port().into() - ), - SingletonBuffer::new(0).get_port() - ) -// .set_editor(Arc::new(RwLock::new(buf))) - } - - - //\\//\\ - - pub fn morph(self, ty: TypeTerm) -> NestedNode { - Context::morph_node(self, ty) - } - - pub fn get_type(&self) -> TypeTerm { - self.data.read().unwrap().get_type().clone() - } - - //\\//\\ - + pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self { self.edit.editor.set(Some(editor)); self @@ -137,33 +104,6 @@ impl NestedNode { self.disp.diag.clone().unwrap_or(ViewPort::new().into_outer()) } - pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>> - where V::Msg: Clone { - let ctx = self.ctx.clone(); - let type_ladder = type_str.map(|s| Context::parse(&ctx, s)); - - let repr_tree = ReprTree::descend_ladder(&self.data, type_ladder)?; - repr_tree.clone().read().unwrap() - .get_port::<V>().clone() - } - - pub fn get_data_view<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<Arc<V>> - where V::Msg: Clone { - self.get_data_port::<V>(type_str)?.get_view() - } - - /* TODO - pub fn get_seq_view<'a, T: Clone>(&self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<dyn SingletonView<Item = T>>> { - self.get_data_view::<dyn SequenceView<Item = NestedNode>>(type_str) - .unwrap() - .map({ - move |node| { - node.get_data_view::<dyn SingletonView<Item = T>>().get() - } - }) - } - */ - pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> { if let Some(edit) = self.edit.editor.get() { if let Ok(edit) = edit.downcast::<RwLock<T>>() { @@ -187,7 +127,7 @@ impl TreeType for NestedNode { } } } - */ +*/ impl TreeNav for NestedNode { fn get_cursor(&self) -> TreeCursor { diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 214ef8c..86875d0 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -6,7 +6,7 @@ use { laddertypes::{TypeTerm}, crate::{ repr_tree::{Context}, - repr_tree::{MorphismTypePattern}, + repr_tree::{MorphismType}, editors::{ list::*, integer::* @@ -16,6 +16,7 @@ use { }; pub fn init_ctx(ctx: &mut Context) { + /* ctx.add_typename("MachineInt".into()); ctx.add_typename("u32".into()); ctx.add_typename("u64".into()); @@ -126,7 +127,7 @@ pub fn init_ctx(ctx: &mut Context) { } ) ); - +*/ ctx.add_typename("Date".into()); ctx.add_typename("ISO-8601".into()); ctx.add_typename("TimeSince".into()); diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 087861b..8619012 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -109,7 +109,7 @@ impl ListEditor { let e = editor.read().unwrap(); - let mut node = NestedNode::new(ctx, data, depth) + let mut node = NestedNode::new(ctx, depth) .set_editor(editor.clone()) .set_nav(editor.clone()) .set_cmd(editor.clone()) @@ -307,6 +307,7 @@ impl ListEditor { self.nexd(); let mut b = item.edit.spillbuf.write().unwrap(); + let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap(); tail_node.goto(TreeCursor::home()); diff --git a/lib-nested-core/src/editors/typeterm/ctx.rs b/lib-nested-core/src/editors/typeterm/ctx.rs index 0039c8f..984bb19 100644 --- a/lib-nested-core/src/editors/typeterm/ctx.rs +++ b/lib-nested-core/src/editors/typeterm/ctx.rs @@ -4,7 +4,7 @@ use { }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, MorphismTypePattern}, + repr_tree::{Context, MorphismType}, editors::{ list::{ListEditor, ListSegmentSequence}, typeterm::{State, TypeTermEditor} @@ -26,7 +26,7 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_list_typename("Type::Ladder".into()); // = T1~T2~... ctx.add_morphism( - MorphismTypePattern { src_tyid: ctx.get_typeid("List"), dst_tyid: ctx.get_typeid("Type").unwrap() }, + MorphismType { src_tyid: Context::parse(&ctx, "<List T>"), dst_tyid: Context::parse(&ctx, "Type") }, Arc::new(move |node, _dst_type:_| { let ctx : Arc<RwLock<Context>> = Arc::new(RwLock::new(Context::with_parent(Some(node.ctx.clone())))); ctx.write().unwrap().meta_chars.push('~'); diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 56d331d..264e3cc 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -1,8 +1,8 @@ - use { +use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ - repr_tree::{ReprTree}, + repr_tree::{ReprTree, MorphismType, GenericReprTreeMorphism, MorphismBase}, edit_tree::NestedNode }, std::{ @@ -13,129 +13,26 @@ //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -#[derive(Clone, Copy, Hash, PartialEq, Eq)] -pub enum MorphismMode { - /// Isomorphism - /// e.g. `( PositionalInteger 10 BigEndian ) <~> ( PositionalInteger 16 LittleEndian )` - Iso, - - /// Monomorphism, i.e. injective functions, - /// upcast-view, downcast-control, semantic gain - /// e.g. `( Sequence ( Digit 16 ) ) ~> ( PositionalInteger 16 LittleEndian )` - Mono, - - /// Epimorphsim, i.e. surjective functions, - /// upcast-control, downcast-view, possible loss of entropy - /// e.g. `( Ascii ) ~> ( Digit 16 )` - Epi, - - /// Any other function - Any, -} - -#[derive(Clone, Hash, PartialEq, Eq, Debug)] -pub struct MorphismType { -// pub mode: MorphismMode, - pub src_type: Option<TypeTerm>, - pub dst_type: TypeTerm, -} - -#[derive(Clone, Hash, Eq, PartialEq)] -pub struct MorphismTypePattern { - pub src_tyid: Option<TypeID>, - pub dst_tyid: TypeID -} - -impl MorphismType { - pub fn to_str(&self, ctx: &Context) -> String { - format!("{:?} -> {:?}", - if let Some(t) = self.src_type.as_ref() { - ctx.type_term_to_str(t) - } else { - "None".into() - }, - ctx.type_term_to_str(&self.dst_type)) - } -} - -impl MorphismTypePattern { - pub fn to_str(&self, ctx: &Context) -> String { - format!("{:?} -> {:?}", - if let Some(t) = self.src_tyid.as_ref() { - ctx.type_term_to_str(&TypeTerm::TypeID(t.clone())) - } else { - "None".into() - }, - ctx.type_term_to_str(&TypeTerm::TypeID(self.dst_tyid.clone()))) - } -} - -impl From<MorphismType> for MorphismTypePattern { - fn from(value: MorphismType) -> MorphismTypePattern { - fn strip( x: &TypeTerm ) -> TypeID { - match x { - TypeTerm::TypeID(id) => id.clone(), - TypeTerm::App(args) => strip(&args[0]), - TypeTerm::Ladder(args) => strip(&args[0]), - _ => unreachable!() - } - } - - MorphismTypePattern { - src_tyid: value.src_type.map(|x| strip(&x)), - dst_tyid: strip(&value.dst_type) - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - #[derive(Clone)] pub struct Context { /// assigns a name to every type pub type_dict: Arc<RwLock<TypeDict>>, + pub morphisms: MorphismBase, + /// named vertices of the graph - nodes: HashMap< String, NestedNode >, + nodes: HashMap< String, Arc<RwLock<ReprTree>> >, /// todo: beautify /// types that can be edited as lists + /// do we really need this? pub list_types: Vec< TypeID >, pub meta_chars: Vec< char >, - /// graph constructors - /// TODO: move into separate struct MorphismMap or something - morphisms: HashMap< - MorphismTypePattern, - Arc< - dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode> - + Send + Sync - > - >, - /// recursion parent: Option<Arc<RwLock<Context>>>, } -impl Default for Context { - fn default() -> Context { - let mut ctx = Context::new(); - - ctx.add_list_typename("Sequence"); - ctx.add_synonym("Seq", "Sequence"); - ctx.add_list_typename("SepSeq"); - ctx.add_typename("NestedNode"); - ctx.add_typename("TerminalEvent"); - - crate::editors::list::init_ctx( &mut ctx ); - crate::editors::char::init_ctx( &mut ctx ); - crate::editors::integer::init_ctx( &mut ctx ); - crate::editors::typeterm::init_ctx( &mut ctx ); - - ctx - } -} - impl Context { pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self { Context { @@ -143,7 +40,7 @@ impl Context { Some(p) => p.read().unwrap().type_dict.clone(), None => Arc::new(RwLock::new(TypeDict::new())) }, - morphisms: HashMap::new(), + morphisms: MorphismBase::new(), nodes: HashMap::new(), list_types: match parent.as_ref() { Some(p) => p.read().unwrap().list_types.clone(), @@ -240,105 +137,20 @@ impl Context { pub fn type_term_to_str(&self, t: &TypeTerm) -> String { self.type_dict.read().unwrap().unparse(&t) } - - pub fn add_node_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, OuterViewPort<dyn SingletonView<Item = usize>>) -> Option<NestedNode> + Send + Sync>) { - let dict = self.type_dict.clone(); - let mut dict = dict.write().unwrap(); - - let tyid = - if let Some(tyid) = dict.get_typeid(&tn.into()) { - tyid - } else { - dict.add_typename(tn.into()) - }; - - let morphism_pattern = MorphismTypePattern { - src_tyid: None, - dst_tyid: tyid - }; - - drop(dict); - - self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| { - mk_editor(node.ctx.clone(), dst_type, node.disp.depth) - })); - } - - pub fn add_morphism( - &mut self, - morph_type_pattern: MorphismTypePattern, - morph_fn: Arc< - dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode> - + Send + Sync - > - ) { - self.morphisms.insert(morph_type_pattern, morph_fn); - } - - pub fn get_morphism(&self, ty: MorphismType) -> Option<Arc<dyn Fn(NestedNode, TypeTerm) -> Option<NestedNode> + Send + Sync>> { - let pattern = MorphismTypePattern::from(ty.clone()); - - if let Some(morphism) = self.morphisms.get( &pattern ) { - Some(morphism.clone()) - } else { - self.parent.as_ref()? - .read().unwrap() - .get_morphism(ty) - } - } - - pub fn make_node(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Option<NestedNode> { - let mk_node = ctx.read().unwrap().get_morphism(MorphismType { - src_type: None, - dst_type: type_term.clone() - }).expect(&format!("morphism {}", ctx.read().unwrap().type_term_to_str(&type_term))); - - /* create new context per node ?? too heavy.. whats the reason? TODO */ - - let new_ctx = Arc::new(RwLock::new(Context::with_parent(Some(ctx.clone())))); - - mk_node( - NestedNode::new(new_ctx, ReprTree::new_arc(type_term.clone()), depth), - type_term - ) - } - - pub fn morph_node(mut node: NestedNode, dst_type: TypeTerm) -> NestedNode { - let src_type = node.data.read().unwrap().get_type().clone(); - let pattern = MorphismType { src_type: Some(src_type), dst_type: dst_type.clone() }; - - /* it is not univesally true to always use ascend. - */ - node.data = - ReprTree::ascend( - &node.data, - dst_type.clone() - ); - - let m = node.ctx.read().unwrap().get_morphism(pattern.clone()); - if let Some(transform) = m { - if let Some(new_node) = transform(node.clone(), dst_type) { - new_node - } else { - node.clone() - } - } else { - node - } - } - /// adds an object without any representations pub fn add_obj(ctx: Arc<RwLock<Context>>, name: String, typename: &str) { let type_tag = ctx.read().unwrap() .type_dict.write().unwrap() .parse(typename).unwrap(); +/* if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) { ctx.write().unwrap().nodes.insert(name, node); } +*/ } - pub fn get_obj(&self, name: &String) -> Option<NestedNode> { + pub fn get_obj(&self, name: &String) -> Option< Arc<RwLock<ReprTree>> > { if let Some(obj) = self.nodes.get(name) { Some(obj.clone()) } else if let Some(parent) = self.parent.as_ref() { @@ -347,85 +159,6 @@ impl Context { None } } - -/* - pub fn get_obj_port<'a, V: View + ?Sized + 'static>( - &self, - name: &str, - type_ladder: impl Iterator<Item = &'a str>, - ) -> Option<OuterViewPort<V>> - where - V::Msg: Clone, - { - self.get_obj(&name.into())? - .downcast_ladder(type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()))? - .get_port() - } - - pub fn insert_repr<'a>( - &mut self, - name: &str, - type_ladder: impl Iterator<Item = &'a str>, - port: AnyOuterViewPort, - ) { - self.get_obj(&name.to_string()) - .unwrap() - .repr - .write() - .unwrap() - .insert_leaf( - type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()), - port, - ); - } - - pub fn epi_cast(&mut self, name: &str, typename: &str) { - let dst_type = self.type_dict.type_term_from_str(typename).unwrap(); - let old_obj = self.objects.get(&name.to_string()).unwrap().clone(); - let new_obj = if let Some(ctor) = self.morphism_constructors.get(&MorphismType { - mode: MorphismMode::Epi, - src_type: old_obj.type_tag.clone(), - dst_type: dst_type.clone(), - }) { - ctor(old_obj.clone()) - } else { - Arc::new(RwLock::new(ReprTree::new(dst_type))) - }; - - new_obj - .repr - .write() - .unwrap() - .insert_branch(old_obj.type_tag, old_obj.repr); - - self.objects.insert(name.to_string(), new_obj); - } - - pub fn mono_view<'a, V: View + ?Sized + 'static>( - &mut self, - name: &str, - type_ladder: impl Iterator<Item = &'a str>, - ) -> Option<OuterViewPort<V>> - where - V::Msg: Clone, - { - if let Some(p) = self.get_obj_port(name, type_ladder) { - Some(p) - } else { - // todo : add repr with morphism constructor (if one exists) - /* - if let Some(ctor) = self.morphism_constructors.get( - &MorphismType { - mode: MorphismMode::Mono, - src_type: old_obj.type_tag.clone(), - dst_type: - } - ) - */ - None - } -} - */ } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 758fea3..dc6e7d9 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -1,7 +1,9 @@ pub mod context; +pub mod morphism; pub use { - context::{Context, MorphismMode, MorphismType, MorphismTypePattern}, + context::{Context}, + morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase} }; use { @@ -16,7 +18,7 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] -pub struct ReprTree { +pub struct ReprTree { type_tag: TypeTerm, port: Option<AnyOuterViewPort>, branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>, @@ -97,6 +99,8 @@ impl ReprTree { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone, @@ -137,110 +141,5 @@ impl ReprTree { n.insert_branch(rt.clone()); Arc::new(RwLock::new(n)) } - -/* - pub fn add_iso_repr( - &self, - type_ladder: impl Iterator<Item = TypeTerm>, - morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>, - ) { - let mut cur_repr = self.repr.clone(); - - for dst_type in type_ladder { - if let Some(next_repr) = self.repr.read().unwrap().branches.get(&dst_type) { - // go deeper - cur_repr = next_repr.clone(); - } else { - // search for morphism constructor and insert new repr - let mut obj = None; - - for src_type in cur_repr.read().unwrap().branches.keys() { - if let Some(ctor) = morphism_constructors.get(&MorphismType { - mode: MorphismMode::Iso, - src_type: src_type.clone(), - dst_type: dst_type.clone(), - }) { - let new_obj = ctor(Object { - type_tag: src_type.clone(), - repr: cur_repr - .read() - .unwrap() - .branches - .get(&src_type) - .unwrap() - .clone(), - }); - - assert!(new_obj.type_tag == dst_type); - - obj = Some(new_obj); - break; - } - } - - if let Some(obj) = obj { - cur_repr - .write() - .unwrap() - .insert_branch(obj.type_tag, obj.repr); - } else { - panic!("could not find matching isomorphism!"); - } - } - } - } - - pub fn add_mono_repr<'a>( - &self, - type_ladder: impl Iterator<Item = TypeTerm>, - morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>, - ) { - let mut cur_type = self.type_tag.clone(); - let mut cur_repr = self.repr.clone(); - - for dst_type in type_ladder { - if let Some(next_repr) = self.repr.read().unwrap().branches.get(&dst_type) { - // go deeper - cur_type = dst_type; - cur_repr = next_repr.clone(); - } else { - if let Some(constructor) = morphism_constructors.get(&MorphismType { - mode: MorphismMode::Mono, - src_type: cur_type.clone(), - dst_type: dst_type.clone(), - }) { - let new_obj = constructor(Object { - type_tag: cur_type.clone(), - repr: cur_repr - .read() - .unwrap() - .branches - .get(&cur_type) - .unwrap() - .clone(), - }); - - assert!(new_obj.type_tag == dst_type); - cur_repr - .write() - .unwrap() - .insert_branch(new_obj.type_tag.clone(), new_obj.repr.clone()); - - cur_type = new_obj.type_tag; - cur_repr = new_obj.repr; - } - } - } - } - - // replace with higher-level type in which self is a repr branch - pub fn epi_cast<'a>( - &self, - _type_ladder: impl Iterator<Item = TypeTerm>, - _morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>, - ) { - // todo -} - */ } diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs new file mode 100644 index 0000000..cc08e05 --- /dev/null +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -0,0 +1,105 @@ +use { + laddertypes::{TypeTerm, TypeID}, + crate::{ + repr_tree::{ReprTree}, + }, + std::{ + sync::{Arc, RwLock}, + collections::HashMap + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone, Hash, PartialEq, Eq, Debug)] +pub struct MorphismType { + pub src_type: TypeTerm, + pub dst_type: TypeTerm, +} + +#[derive(Clone)] +pub struct GenericReprTreeMorphism { + morph_type: MorphismType, + repr_tree_op: Arc< + dyn Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + + Send + Sync + > +} + +#[derive(Clone)] +pub struct MorphismBase { + morphisms: Vec< GenericReprTreeMorphism > +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl MorphismBase { + pub fn new() -> Self { + MorphismBase { + morphisms: Vec::new() + } + } + + pub fn add_morphism( + &mut self, + morph_type: MorphismType, + repr_tree_op: impl Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + Send + Sync + ) { + self.morphisms.push( + GenericReprTreeMorphism { + morph_type, + repr_tree_op: Arc::new(repr_tree_op) + } + ); + } + + pub fn find_morphism( + &self, + src_type: &TypeTerm, + dst_type: &TypeTerm + ) -> Option<(&GenericReprTreeMorphism, HashMap<TypeID, TypeTerm>)> { + for m in self.morphisms.iter() { + + let unification_problem = laddertypes::UnificationProblem::new( + vec![ + ( src_type.clone(), m.morph_type.src_type.clone() ), + ( dst_type.clone(), m.morph_type.dst_type.clone() ) + ] + ); + + if let Ok(σ) = unification_problem.solve() { + eprintln!("found matching morphism"); + return Some((m, σ)); + } + } + + None + } + + pub fn morph( + &self, + repr_tree: Arc<RwLock<ReprTree>>, + target_type: &TypeTerm + ) { + if let Some((m, σ)) = self.find_morphism( repr_tree.read().unwrap().get_type(), target_type ) { + (m.repr_tree_op)( repr_tree, &σ ); + } else { + eprintln!("could not find morphism"); + } + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +/* +impl MorphismType { + pub fn to_str(&self, ctx: &Context) -> String { + format!("{:?} -> {:?}", + if let Some(t) = self.src_type.as_ref() { + ctx.type_dict.read().unwrap().unparse(t) + } else { + "None".into() + }, + ctx.type_dict.read().unwrap().unparse(&self.dst_type)) + } +} +*/ diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index dbaef38..dfc07ee 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -1,3 +1,84 @@ pub mod list; +use { + nested::{ + edit_tree::{NestedNode}, + repr_tree::{ReprTree, Context} + }, + r3vi::{ + view::{singleton::*, sequence::*}, + projection::decorate_sequence::* + }, + crate::{ + make_label, + DisplaySegment, + atom::TerminalAtom + } +}; + +pub fn node_make_char_view( + node: NestedNode +) -> NestedNode { + node.disp.view + .write().unwrap() + .insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), + node.data + .read() + .unwrap() + .get_port::<dyn SingletonView<Item = char>>() + .expect("unable to get Char-view") + .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) + .to_grid() + .into(), + )); + + node +} + +pub fn node_make_seq_view( + mut node: NestedNode +) -> NestedNode { + node.disp.view + .write().unwrap() + .insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), + node.data + .read() + .unwrap() + .get_port::<dyn SequenceView<Item = NestedNode>>() + .expect("unable to get Seq-view") + .map(move |char_node| node_make_tty_view(char_node.clone()).display_view() ) + .wrap(make_label("("), make_label(")")) + .to_grid_horizontal() + .flatten() + .into() + )); + node +} + +pub fn node_make_list_edit( + mut node: NestedNode +) -> NestedNode { + list::PTYListStyle::for_node( &mut node, ("(", "", ")") ); + list::PTYListController::for_node( &mut node, None, None ); + + node +} + +pub fn node_make_tty_view( + node: NestedNode +) -> NestedNode { + if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { + node_make_char_view( node ) + } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") { + node_make_seq_view( node ) + } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") { + node_make_list_edit( node ) + } else { + eprintln!("couldnt add view"); + node + } +} + From 97a5b580dfd7454d87e8c699cf5c6033fa259b27 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 4 Jan 2024 15:39:39 +0100 Subject: [PATCH 18/75] wip: deactivate code to make it compileable --- examples/tty-02-node/src/main.rs | 59 +++++++++++-------- lib-nested-core/src/edit_tree/node.rs | 3 + lib-nested-core/src/editors/char/mod.rs | 4 ++ lib-nested-core/src/editors/integer/editor.rs | 9 ++- lib-nested-core/src/editors/list/ctx.rs | 3 +- lib-nested-core/src/editors/list/editor.rs | 5 +- lib-nested-core/src/editors/mod.rs | 6 +- lib-nested-core/src/editors/sum/editor.rs | 2 +- lib-nested-core/src/editors/typeterm/ctx.rs | 2 + lib-nested-core/src/repr_tree/context.rs | 6 ++ lib-nested-core/src/repr_tree/morphism.rs | 4 +- lib-nested-tty/src/editors/list.rs | 3 + lib-nested-tty/src/editors/mod.rs | 4 +- 13 files changed, 71 insertions(+), 39 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 2fe3791..d041723 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -8,19 +8,21 @@ use { cgmath::Vector2, nested::{ editors::ObjCommander, - repr_tree::{Context}, + repr_tree::{Context, ReprTree}, + edit_tree::{NestedNode} }, nested_tty::{ DisplaySegment, TTYApplication, TerminalCompositor, TerminalStyle, TerminalView, }, r3vi::{ - buffer::singleton::*, + buffer::{singleton::*, vec::*}, }, std::sync::{Arc, RwLock}, }; -struct ParseDigit { radix: u32 }; +/* +struct ParseDigit { radix: u32 } impl Morphism for ParseDigit { fn new( ctx: &Arc<RwLock<Context>> @@ -38,24 +40,25 @@ impl Morphism for ParseDigit { get_morphism( ) -> Morphism { } - +*/ #[async_std::main] async fn main() { /* setup context & create Editor-Tree */ - let ctx = Arc::new(RwLock::new(Context::default())); + let ctx = Arc::new(RwLock::new(Context::new())); /* Create a Char-Node with editor & view */ + let mut char_obj = ReprTree::make_leaf( Context::parse(&ctx, "Char"), SingletonBuffer::new('X').get_port().into() ); - +/* char_obj.insert_branch( Context::parse(&ctx, "EditTree"), SingletonBuffer::new( - + NestedNode::new() ) ); @@ -72,12 +75,14 @@ async fn main() { SingletonBuffer::new(0).get_port(), ) .unwrap(); - +*/ // add a display view to the node - node1 = nested_tty::editors::node_make_tty_view(node1); + //node1 = nested_tty::editors::node_make_tty_view(node1); /* Create a <List Char>-Node with editor & view */ + +/* let mut node2 = Context::make_node( &ctx, // node type @@ -86,12 +91,13 @@ async fn main() { SingletonBuffer::new(0).get_port(), ) .unwrap(); - +*/ // add a display view to the node - node2 = nested_tty::editors::node_make_tty_view(node2); + //node2 = nested_tty::editors::node_make_tty_view(node2); /* Create a <List Char>-Node with editor & view */ +/* let mut node3 = Context::make_node( &ctx, // node type @@ -100,10 +106,10 @@ async fn main() { SingletonBuffer::new(0).get_port(), ) .unwrap(); - +*/ // add a display view to the node - node3 = nested_tty::editors::node_make_tty_view(node3); - + //node3 = nested_tty::editors::node_make_tty_view(node3); + /* setup terminal */ let app = TTYApplication::new({ @@ -111,16 +117,16 @@ async fn main() { */ let ctx = ctx.clone(); - let node1 = node1.clone(); - let node2 = node2.clone(); - let node3 = node3.clone(); + // let node1 = node1.clone(); +// let node2 = node2.clone(); +// let node3 = node3.clone(); move |ev| { - let mut node1 = node1.clone(); - let mut node2 = node2.clone(); - let mut node3 = node3.clone(); - node1.send_cmd_obj(ev.to_repr_tree(&ctx)); - node2.send_cmd_obj(ev.to_repr_tree(&ctx)); - node3.send_cmd_obj(ev.to_repr_tree(&ctx)); +// let mut node1 = node1.clone(); +// let mut node2 = node2.clone(); +// let mut node3 = node3.clone(); +// node1.send_cmd_obj(ev.to_repr_tree(&ctx)); +// node2.send_cmd_obj(ev.to_repr_tree(&ctx)); +// node3.send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -137,7 +143,7 @@ async fn main() { .offset(Vector2::new(5, 0)), ); - let label = ctx.read().unwrap().type_term_to_str(&node1.get_type()); +/* let label = ctx.read().unwrap().type_term_to_str(&node1.get_type()); compositor .write() .unwrap() @@ -147,7 +153,8 @@ async fn main() { .write() .unwrap() .push(node1.display_view().offset(Vector2::new(15, 2))); - +*/ + /* let label2 = ctx.read().unwrap().type_term_to_str(&node2.get_type()); compositor .write() @@ -170,7 +177,7 @@ async fn main() { .write() .unwrap() .push(node3.display_view().offset(Vector2::new(25, 4))); - +*/ /* write the changes in the view of `term_port` to the terminal */ app.show().await.expect("output error!"); diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index b60326a..7acfa82 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -47,6 +47,9 @@ pub struct NestedNodeEdit { >, } +/* + * TODO: rename to EditNode + */ #[derive(Clone)] pub struct NestedNode { /// context diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 8294576..40ea021 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -17,11 +17,13 @@ use { }; pub fn init_ctx( ctx: &mut Context ) { + /* ctx.add_node_ctor( "Char", Arc::new(|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { Some(CharEditor::new_node(ctx, depth)) })); + */ } pub struct CharEditor { @@ -76,10 +78,12 @@ impl CharEditor { NestedNode::new( ctx0.clone(), + /* ReprTree::new_leaf( ctx0.read().unwrap().type_term_from_str("Char").unwrap(), data.get_port().into() ), + */ depth ) .set_cmd( editor.clone() ) diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index 67188ec..91d068d 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -89,7 +89,7 @@ impl DigitEditor { let ed = editor.write().unwrap(); let r = ed.radix; - NestedNode::new(ed.ctx.clone(), data, depth) + NestedNode::new(ed.ctx.clone(), /*data,*/ depth) .set_cmd(editor.clone()) /* .set_view( @@ -144,6 +144,7 @@ pub struct PosIntEditor { impl PosIntEditor { pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self { + /* let mut node = Context::make_node( &ctx, Context::parse(&ctx, format!("<List <Digit {}>>", radix).as_str()), @@ -159,6 +160,7 @@ impl PosIntEditor { TypeTerm::TypeID(ctx.read().unwrap().get_typeid("BigEndian").unwrap()) ] )); + */ /* PTYListController::for_node( &mut node, Some(' '), None ); PTYListStyle::for_node( &mut node, @@ -177,7 +179,10 @@ impl PosIntEditor { */ PosIntEditor { radix, - digits: node + digits: NestedNode::new( + ctx, + r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() + ) } } diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 2eefc7f..8cb8c37 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -13,7 +13,7 @@ use { pub fn init_ctx(ctx: &mut Context) { ctx.add_typename("ListCmd".into()); ctx.add_list_typename("List".into()); - +/* ctx.add_node_ctor( "List", Arc::new( |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { @@ -37,5 +37,6 @@ pub fn init_ctx(ctx: &mut Context) { } ) ); + */ } diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 8619012..5a971b4 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -307,7 +307,7 @@ impl ListEditor { self.nexd(); let mut b = item.edit.spillbuf.write().unwrap(); - +/* TODO let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap(); tail_node.goto(TreeCursor::home()); @@ -322,6 +322,7 @@ impl ListEditor { ) ); } + b.clear(); drop(b); drop(item); @@ -334,7 +335,7 @@ impl ListEditor { self.insert( Arc::new(RwLock::new(tail_node)) ); - +*/ } else { self.up(); self.listlist_split(); diff --git a/lib-nested-core/src/editors/mod.rs b/lib-nested-core/src/editors/mod.rs index 669b5d8..eebac4e 100644 --- a/lib-nested-core/src/editors/mod.rs +++ b/lib-nested-core/src/editors/mod.rs @@ -1,11 +1,11 @@ pub mod list; //pub mod product; -pub mod sum; +//pub mod sum; pub mod char; -pub mod integer; -pub mod typeterm; +//pub mod integer; +//pub mod typeterm; pub trait Commander { diff --git a/lib-nested-core/src/editors/sum/editor.rs b/lib-nested-core/src/editors/sum/editor.rs index aa71f01..b995da5 100644 --- a/lib-nested-core/src/editors/sum/editor.rs +++ b/lib-nested-core/src/editors/sum/editor.rs @@ -55,7 +55,7 @@ impl SumEditor { NestedNode::new( ctx.clone(), - ReprTree::new_arc(TypeTerm::TypeID(ctx.read().unwrap().get_typeid("Sum").unwrap())), +// ReprTree::new_arc(TypeTerm::TypeID(ctx.read().unwrap().get_typeid("Sum").unwrap())), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() ) // .set_view(view) diff --git a/lib-nested-core/src/editors/typeterm/ctx.rs b/lib-nested-core/src/editors/typeterm/ctx.rs index 984bb19..00d851e 100644 --- a/lib-nested-core/src/editors/typeterm/ctx.rs +++ b/lib-nested-core/src/editors/typeterm/ctx.rs @@ -25,6 +25,7 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_list_typename("Type::App".into()); // = <T1 T2 ...> ctx.add_list_typename("Type::Ladder".into()); // = T1~T2~... +/* ctx.add_morphism( MorphismType { src_tyid: Context::parse(&ctx, "<List T>"), dst_tyid: Context::parse(&ctx, "Type") }, Arc::new(move |node, _dst_type:_| { @@ -34,6 +35,7 @@ pub fn init_ctx(ctx: &mut Context) { let new_node = TypeTermEditor::with_node( ctx, node.clone(), State::Any ); Some(new_node) })); + */ /* ctx.add_morphism( MorphismTypePattern { src_tyid: ctx.get_typeid("List"), dst_tyid: ctx.get_typeid("Type::Ladder").unwrap() }, diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 264e3cc..dbdd92a 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -66,6 +66,12 @@ impl Context { } } + pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> { + let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() ))); + ctx.read().unwrap().morphisms.morph( rt.clone(), t ); + rt + } + pub fn parse(ctx: &Arc<RwLock<Self>>, s: &str) -> TypeTerm { ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term") } diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index cc08e05..2cb58cc 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -43,7 +43,7 @@ impl MorphismBase { pub fn add_morphism( &mut self, morph_type: MorphismType, - repr_tree_op: impl Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + Send + Sync + repr_tree_op: impl Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + Send + Sync + 'static ) { self.morphisms.push( GenericReprTreeMorphism { @@ -82,7 +82,7 @@ impl MorphismBase { target_type: &TypeTerm ) { if let Some((m, σ)) = self.find_morphism( repr_tree.read().unwrap().get_type(), target_type ) { - (m.repr_tree_op)( repr_tree, &σ ); + (m.repr_tree_op)( repr_tree.clone(), &σ ); } else { eprintln!("could not find morphism"); } diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index fb3f9a4..9b0cdd9 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -219,6 +219,7 @@ impl PTYListController { match cur.mode { ListCursorMode::Insert => { + /* TODO let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth.map(|d| d+1)).unwrap(); new_edit.goto(TreeCursor::home()); @@ -231,6 +232,8 @@ impl PTYListController { TreeNavResult::Exit } } + */ + TreeNavResult::Continue }, ListCursorMode::Select => { if let Some(item) = e.get_item_mut() { diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index dfc07ee..3d2a7b4 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -16,7 +16,7 @@ use { atom::TerminalAtom } }; - +/* pub fn node_make_char_view( node: NestedNode ) -> NestedNode { @@ -81,4 +81,4 @@ pub fn node_make_tty_view( node } } - +*/ From 47a35f22b7a0c1e68468524891c9ed5264c22e32 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 6 Jan 2024 17:04:15 +0100 Subject: [PATCH 19/75] some work on repr tree example --- examples/tty-02-node/src/main.rs | 214 +++++++++--------- lib-nested-core/src/editors/char/mod.rs | 11 +- lib-nested-core/src/editors/integer/editor.rs | 44 ++-- lib-nested-core/src/editors/mod.rs | 3 +- lib-nested-core/src/repr_tree/mod.rs | 11 +- lib-nested-tty/src/editors/mod.rs | 38 +++- 6 files changed, 170 insertions(+), 151 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index d041723..53f82bb 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -14,6 +14,7 @@ use { nested_tty::{ DisplaySegment, TTYApplication, TerminalCompositor, TerminalStyle, TerminalView, + TerminalAtom }, r3vi::{ buffer::{singleton::*, vec::*}, @@ -21,112 +22,126 @@ use { std::sync::{Arc, RwLock}, }; -/* -struct ParseDigit { radix: u32 } -impl Morphism for ParseDigit { - fn new( - ctx: &Arc<RwLock<Context>> - ) -> Self { - - } - - fn setup_projection(&self, repr_tree: Arc<RwLock<ReprTree>>) { - if let Some( char_view ) = repr_tree.get_out(Context::parse(&ctx, "Char~")) { - - } - } -} - -get_morphism( ) -> Morphism { - -} -*/ #[async_std::main] async fn main() { /* setup context & create Editor-Tree */ let ctx = Arc::new(RwLock::new(Context::new())); - /* Create a Char-Node with editor & view + /* structure of Repr-Tree + * + * === Repr-Tree === + * + * <Digit 10> + * / | \ + * / | \ + * / | \ + * u32 [ EditTree ] Char + * - Editor \ + * - Display [ EditTree ] + * / | \ - Editor + * / | \ - Display + * TTY PixelBuf SDF / | \ + * / | \ + * TTY PixelBuf SDF + */ + let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 10>") ); + let port_char = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = char>>::new(); + let port_u32 = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = u32>>::new(); + let port_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = NestedNode>>::new(); + let port_char_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = NestedNode>>::new(); + + rt_digit.write().unwrap() + .insert_leaf( + vec![ Context::parse(&ctx, "Char") ].into_iter(), + port_char.outer().into() + ); + + rt_digit.write().unwrap() + .insert_leaf( + vec![ Context::parse(&ctx, "Char"), Context::parse(&ctx, "EditTree") ].into_iter(), + port_char_edit.outer().into() + ); + + rt_digit.write().unwrap() + .insert_leaf( + vec![ Context::parse(&ctx, "EditTree") ].into_iter(), + port_edit.outer().into() + ); + + rt_digit.write().unwrap() + .insert_leaf( + vec![ Context::parse(&ctx, "u32") ].into_iter(), + port_u32.outer().into() + ); + + /* setup projections between representations */ - let mut char_obj = ReprTree::make_leaf( - Context::parse(&ctx, "Char"), - SingletonBuffer::new('X').get_port().into() - ); + // created by Char ==> Char~EditTree + let mut edittree_char = + nested::editors::char::CharEditor::new_edit_tree( + ctx.clone(), + r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + ); + + node_edit_char = nested_tty::editors::edittree_make_char_view( edittree_char ); + let mut edit_char = node_edit_char.get_edit::< nested::editors::char::CharEditor >().unwrap(); + port_char.attach_to( edit_char.read().unwrap().get_port() ); + + let buf_edit_char = r3vi::buffer::singleton::SingletonBuffer::new( node_edit_char.clone() ); + port_char_edit.attach_to( buf_edit_char.get_port() ); + + + + // created by <Digit 10> ==> <Digit 10>~EditTree + let mut node_edit_digit = + nested::editors::integer::DigitEditor::new( + ctx.clone(), + 16 + ).into_node( + r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + ); + + node_edit_digit = nested_tty::editors::edittree_make_digit_view( node_edit_digit ); + let mut edit_digit = node_edit_digit.get_edit::< nested::editors::integer::DigitEditor >().unwrap(); + + // created by <Digit 10> ==> <Digit 10>~U32 + port_u32.attach_to( port_char.outer().map(|c| c.to_digit(16).unwrap_or(0)) ); + // port_u32.attach_to( edit_digit.read().unwrap().get_data_port().map(|d| d.unwrap_or(0)) ); + + let port_proj_u32_to_char = port_u32.outer().map(|val| char::from_digit(val, 16).unwrap_or('?') ); + + let buf_edit_digit = r3vi::buffer::singleton::SingletonBuffer::new( node_edit_digit ); + port_edit.attach_to( buf_edit_digit.get_port() ); + /* - char_obj.insert_branch( - Context::parse(&ctx, "EditTree"), - SingletonBuffer::new( - NestedNode::new() + ctx.write().unwrap() + .morphisms + .add_morphism( + MorphismType { + src_type: Context::parse(&ctx, "Char"), + dst_type: Context::parse(&ctx, "Char~EditTree") + }, + + |rt, _σ| { + rt.write().unwrap() + .insert_branch( + Context::parse(&ctx, "") + ); + } ) - ); - - let mut vec_obj = ReprTree::make_leaf( - Context::parse(&ctx, "<Vec Char>"), - VecBuffer::new(vec!['a', 'b', 'c']).get_port().into() - ); - - let mut char_edit = Context::new_edit_tree( - &ctx, - // node type - Context::parse(&ctx, "Char"), - // depth - SingletonBuffer::new(0).get_port(), - ) - .unwrap(); */ - // add a display view to the node - //node1 = nested_tty::editors::node_make_tty_view(node1); - /* Create a <List Char>-Node with editor & view - */ - -/* - let mut node2 = Context::make_node( - &ctx, - // node type - Context::parse(&ctx, "<List Char>"), - // depth - SingletonBuffer::new(0).get_port(), - ) - .unwrap(); -*/ - // add a display view to the node - //node2 = nested_tty::editors::node_make_tty_view(node2); - - /* Create a <List Char>-Node with editor & view - */ -/* - let mut node3 = Context::make_node( - &ctx, - // node type - Context::parse(&ctx, "<List <List Char>>"), - // depth - SingletonBuffer::new(0).get_port(), - ) - .unwrap(); -*/ - // add a display view to the node - //node3 = nested_tty::editors::node_make_tty_view(node3); - /* setup terminal */ let app = TTYApplication::new({ /* event handler */ - let ctx = ctx.clone(); - // let node1 = node1.clone(); -// let node2 = node2.clone(); -// let node3 = node3.clone(); + let node1 = buf_edit_digit.clone(); move |ev| { -// let mut node1 = node1.clone(); -// let mut node2 = node2.clone(); -// let mut node3 = node3.clone(); -// node1.send_cmd_obj(ev.to_repr_tree(&ctx)); -// node2.send_cmd_obj(ev.to_repr_tree(&ctx)); -// node3.send_cmd_obj(ev.to_repr_tree(&ctx)); + node1.get().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -142,6 +157,7 @@ async fn main() { }) .offset(Vector2::new(5, 0)), ); + compositor.write().unwrap().push( buf_edit_digit.get().display_view().offset(Vector2::new(0,2)) ); /* let label = ctx.read().unwrap().type_term_to_str(&node1.get_type()); compositor @@ -153,30 +169,6 @@ async fn main() { .write() .unwrap() .push(node1.display_view().offset(Vector2::new(15, 2))); -*/ - /* - let label2 = ctx.read().unwrap().type_term_to_str(&node2.get_type()); - compositor - .write() - .unwrap() - .push(nested_tty::make_label(&label2).offset(Vector2::new(0, 3))); - - compositor - .write() - .unwrap() - .push(node2.display_view().offset(Vector2::new(15, 3))); - - - let label3 = ctx.read().unwrap().type_term_to_str(&node3.get_type()); - compositor - .write() - .unwrap() - .push(nested_tty::make_label(&label3).offset(Vector2::new(0, 4))); - - compositor - .write() - .unwrap() - .push(node3.display_view().offset(Vector2::new(25, 4))); */ /* write the changes in the view of `term_port` to the terminal */ diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 40ea021..12614f1 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -71,19 +71,16 @@ impl CharEditor { self.get_port().get_view().unwrap().get() } - pub fn new_node(ctx0: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode { + pub fn new_edit_tree( + ctx0: Arc<RwLock<Context>>, + depth: OuterViewPort<dyn SingletonView<Item = usize>> + ) -> NestedNode { let data = SingletonBuffer::new('\0'); let ctx = ctx0.clone(); let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() })); NestedNode::new( ctx0.clone(), - /* - ReprTree::new_leaf( - ctx0.read().unwrap().type_term_from_str("Char").unwrap(), - data.get_port().into() - ), - */ depth ) .set_cmd( editor.clone() ) diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index 91d068d..e37f495 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -49,9 +49,7 @@ impl ObjCommander for DigitEditor { /* in case the character c is not in the range of digit-chars, add a message to the diagnostics view */ - /* - let message = IndexBuffer::from_iter(vec![ (Point2::new(1, 0), make_label("invalid digit '")), (Point2::new(2, 0), make_label(&format!("{}", c)) @@ -61,7 +59,7 @@ impl ObjCommander for DigitEditor { self.msg.push(crate::diagnostics::make_error(message.get_port().flatten())); */ - + self.data.set(Some(c)); } else { self.data.set(Some(c)); @@ -89,34 +87,33 @@ impl DigitEditor { let ed = editor.write().unwrap(); let r = ed.radix; - NestedNode::new(ed.ctx.clone(), /*data,*/ depth) + NestedNode::new(ed.ctx.clone(), depth) + .set_editor(editor.clone()) .set_cmd(editor.clone()) - /* - .set_view( - ed.data - .get_port() - .map(move |c| { - TerminalAtom::new( - c.unwrap_or('?'), - if c.unwrap_or('?').to_digit(r).is_some() { - TerminalStyle::fg_color((90, 160, 90)) - } else { - //TerminalStyle::bg_color((90, 10, 10)) - TerminalStyle::fg_color((200, 40, 40)) - }, - ) - }) - .to_grid() - ) .set_diag( ed.msg.get_port().to_sequence() ) + } + + pub fn attach_to(&mut self, source: OuterViewPort<dyn SingletonView<Item = u32>>) { + /* + source.add_observer( + Arc::new(NotifyFnObserver::new(|_msg| { + self.data.set( source.get() ) + })) + ); */ } - pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> { + pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Result<u32, char>>> { let radix = self.radix; - self.data.get_port().map(move |c| c?.to_digit(radix)) + self.data.get_port().map(move |c| + if let Some(d) = c.unwrap_or('?').to_digit(radix) { + Ok(d) + } else { + Err(c.unwrap_or('?')) + } + ) } pub fn get_type(&self) -> TypeTerm { @@ -134,7 +131,6 @@ impl DigitEditor { } } - pub struct PosIntEditor { radix: u32, digits: NestedNode, diff --git a/lib-nested-core/src/editors/mod.rs b/lib-nested-core/src/editors/mod.rs index eebac4e..3a720c3 100644 --- a/lib-nested-core/src/editors/mod.rs +++ b/lib-nested-core/src/editors/mod.rs @@ -4,7 +4,7 @@ pub mod list; //pub mod sum; pub mod char; -//pub mod integer; +pub mod integer; //pub mod typeterm; @@ -24,3 +24,4 @@ pub trait ObjCommander { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult; } + diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index dc6e7d9..bd62527 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -7,7 +7,7 @@ pub use { }; use { - r3vi::view::{AnyOuterViewPort, OuterViewPort, View}, + r3vi::view::{AnyOuterViewPort, OuterViewPort, View, singleton::*}, laddertypes::{TypeTerm}, std::{ collections::HashMap, @@ -99,7 +99,14 @@ impl ReprTree { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - + + pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { + self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available") + } + + pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { + self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available") + } pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 3d2a7b4..4839841 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -13,22 +13,22 @@ use { crate::{ make_label, DisplaySegment, - atom::TerminalAtom + atom::{TerminalAtom, TerminalStyle} } }; -/* -pub fn node_make_char_view( + +pub fn edittree_make_char_view( node: NestedNode ) -> NestedNode { node.disp.view .write().unwrap() .insert_branch(ReprTree::new_leaf( Context::parse(&node.ctx, "TerminalView"), - node.data + node.get_edit::< nested::editors::char::CharEditor >() + .unwrap() .read() .unwrap() - .get_port::<dyn SingletonView<Item = char>>() - .expect("unable to get Char-view") + .get_port() .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) .to_grid() .into(), @@ -37,6 +37,32 @@ pub fn node_make_char_view( node } +pub fn edittree_make_digit_view( + node: NestedNode +) -> NestedNode { + node.disp.view + .write().unwrap() + .insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), + node.get_edit::< nested::editors::integer::DigitEditor >() + .unwrap() + .read() + .unwrap() + .get_data_port() + .map(move |digit| + match digit { + Ok(digit) => TerminalAtom::new( char::from_digit(digit, 16).unwrap_or('?'), TerminalStyle::fg_color((220, 220, 0)) ), + Err(c) => TerminalAtom::new( c, TerminalStyle::fg_color((220, 0, 0)) ) + } + ) + .to_grid() + .into(), + )); + + node +} + +/* pub fn node_make_seq_view( mut node: NestedNode ) -> NestedNode { From 668b0b8b96a41a54fc5384ff7751508cd70c549a Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 7 Jan 2024 20:04:23 +0100 Subject: [PATCH 20/75] rename NestedNode to EditTree --- examples/tty-02-node/src/main.rs | 13 +++-- lib-nested-core/src/edit_tree/mod.rs | 2 +- lib-nested-core/src/edit_tree/node.rs | 50 +++++++++---------- lib-nested-core/src/editors/char/mod.rs | 6 +-- lib-nested-core/src/editors/integer/editor.rs | 12 ++--- lib-nested-core/src/editors/list/cmd.rs | 4 +- lib-nested-core/src/editors/list/editor.rs | 32 ++++++------ lib-nested-core/src/editors/list/segment.rs | 8 +-- lib-nested-core/src/repr_tree/context.rs | 2 +- lib-nested-tty/src/edit_tree/keymap.rs | 9 ++-- lib-nested-tty/src/editors/list.rs | 16 +++--- lib-nested-tty/src/editors/mod.rs | 10 ++-- lib-nested-tty/src/lib.rs | 2 +- lib-nested-tty/src/tty_application.rs | 2 +- 14 files changed, 84 insertions(+), 84 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 53f82bb..253dbbc 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -9,7 +9,7 @@ use { nested::{ editors::ObjCommander, repr_tree::{Context, ReprTree}, - edit_tree::{NestedNode} + edit_tree::{EditTree} }, nested_tty::{ DisplaySegment, TTYApplication, @@ -48,8 +48,8 @@ async fn main() { let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 10>") ); let port_char = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = char>>::new(); let port_u32 = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = u32>>::new(); - let port_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = NestedNode>>::new(); - let port_char_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = NestedNode>>::new(); + let port_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>::new(); + let port_char_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>::new(); rt_digit.write().unwrap() .insert_leaf( @@ -85,15 +85,14 @@ async fn main() { r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() ); - node_edit_char = nested_tty::editors::edittree_make_char_view( edittree_char ); - let mut edit_char = node_edit_char.get_edit::< nested::editors::char::CharEditor >().unwrap(); + edittree_char = nested_tty::editors::edittree_make_char_view( edittree_char ); + let mut edit_char = edittree_char.get_edit::< nested::editors::char::CharEditor >().unwrap(); port_char.attach_to( edit_char.read().unwrap().get_port() ); - let buf_edit_char = r3vi::buffer::singleton::SingletonBuffer::new( node_edit_char.clone() ); + let buf_edit_char = r3vi::buffer::singleton::SingletonBuffer::new( edittree_char.clone() ); port_char_edit.attach_to( buf_edit_char.get_port() ); - // created by <Digit 10> ==> <Digit 10>~EditTree let mut node_edit_digit = nested::editors::integer::DigitEditor::new( diff --git a/lib-nested-core/src/edit_tree/mod.rs b/lib-nested-core/src/edit_tree/mod.rs index 81251d0..92e0411 100644 --- a/lib-nested-core/src/edit_tree/mod.rs +++ b/lib-nested-core/src/edit_tree/mod.rs @@ -10,6 +10,6 @@ pub use { cursor::TreeCursor, nav::{TreeNav, TreeNavResult, TreeHeightOp}, treetype::{TreeType}, - node::NestedNode + node::EditTree }; diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index 7acfa82..6a69dbf 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -14,7 +14,7 @@ use { }; #[derive(Clone)] -pub struct NestedNodeDisplay { +pub struct EdittreeDisplay { /// display view pub view: Arc<RwLock<ReprTree>>, @@ -26,13 +26,13 @@ pub struct NestedNodeDisplay { } #[derive(Clone)] -pub struct NestedNodeEdit { +pub struct EdittreeControl { /// abstract editor pub editor: SingletonBuffer< Option< Arc<dyn Any + Send + Sync> > >, - pub spillbuf: Arc<RwLock< Vec< Arc<RwLock< NestedNode >> > >>, + pub spillbuf: Arc<RwLock< Vec< Arc<RwLock< EditTree >> > >>, /// commander & navigation pub cmd: SingletonBuffer< @@ -51,26 +51,26 @@ pub struct NestedNodeEdit { * TODO: rename to EditNode */ #[derive(Clone)] -pub struct NestedNode { +pub struct EditTree { /// context pub ctx: Arc<RwLock<Context>>, /// viewports for terminal display - pub disp: NestedNodeDisplay, + pub disp: EdittreeDisplay, /// editor & commander objects - pub edit: NestedNodeEdit + pub ctrl: EdittreeControl } -impl NestedNode { +impl EditTree { pub fn new(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self { - NestedNode { - disp: NestedNodeDisplay { + EditTree { + disp: EdittreeDisplay { view: ReprTree::new_arc(Context::parse(&ctx, "Display")), diag: None, depth, }, - edit: NestedNodeEdit { + ctrl: EdittreeControl { editor: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())), cmd: SingletonBuffer::new(None), @@ -82,17 +82,17 @@ impl NestedNode { } pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self { - self.edit.editor.set(Some(editor)); + self.ctrl.editor.set(Some(editor)); self } pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self { - self.edit.cmd.set(Some(cmd)); + self.ctrl.cmd.set(Some(cmd)); self } pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self { - self.edit.tree_nav.set(Some(nav)); + self.ctrl.tree_nav.set(Some(nav)); self } @@ -108,7 +108,7 @@ impl NestedNode { } pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> { - if let Some(edit) = self.edit.editor.get() { + if let Some(edit) = self.ctrl.editor.get() { if let Ok(edit) = edit.downcast::<RwLock<T>>() { Some(edit) } else { @@ -132,9 +132,9 @@ impl TreeType for NestedNode { } */ -impl TreeNav for NestedNode { +impl TreeNav for EditTree { fn get_cursor(&self) -> TreeCursor { - if let Some(tn) = self.edit.tree_nav.get() { + if let Some(tn) = self.ctrl.tree_nav.get() { tn.read().unwrap().get_cursor() } else { TreeCursor::default() @@ -142,7 +142,7 @@ impl TreeNav for NestedNode { } fn get_addr_view(&self) -> OuterViewPort<dyn SequenceView<Item = isize>> { - if let Some(tn) = self.edit.tree_nav.get() { + if let Some(tn) = self.ctrl.tree_nav.get() { tn.read().unwrap().get_addr_view() } else { OuterViewPort::default() @@ -150,7 +150,7 @@ impl TreeNav for NestedNode { } fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> { - if let Some(tn) = self.edit.tree_nav.get() { + if let Some(tn) = self.ctrl.tree_nav.get() { tn.read().unwrap().get_mode_view() } else { OuterViewPort::default() @@ -158,7 +158,7 @@ impl TreeNav for NestedNode { } fn get_cursor_warp(&self) -> TreeCursor { - if let Some(tn) = self.edit.tree_nav.get() { + if let Some(tn) = self.ctrl.tree_nav.get() { tn.read().unwrap().get_cursor_warp() } else { TreeCursor::default() @@ -166,7 +166,7 @@ impl TreeNav for NestedNode { } fn get_height(&self, op: &TreeHeightOp) -> usize { - if let Some(tn) = self.edit.tree_nav.get() { + if let Some(tn) = self.ctrl.tree_nav.get() { tn.read().unwrap().get_height( op ) } else { 0 @@ -174,7 +174,7 @@ impl TreeNav for NestedNode { } fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult { - if let Some(tn) = self.edit.tree_nav.get() { + if let Some(tn) = self.ctrl.tree_nav.get() { tn.write().unwrap().goby(direction) } else { TreeNavResult::Exit @@ -182,7 +182,7 @@ impl TreeNav for NestedNode { } fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult { - if let Some(tn) = self.edit.tree_nav.get() { + if let Some(tn) = self.ctrl.tree_nav.get() { tn.write().unwrap().goto(new_cursor) } else { TreeNavResult::Exit @@ -192,7 +192,7 @@ impl TreeNav for NestedNode { use crate::edit_tree::nav::TreeNavCmd; -impl ObjCommander for NestedNode { +impl ObjCommander for EditTree { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { if cmd_obj.read().unwrap().get_type() == &Context::parse(&self.ctx, "TreeNavCmd") { @@ -211,7 +211,7 @@ impl ObjCommander for NestedNode { } else { TreeNavResult::Exit } - } else if let Some(cmd) = self.edit.cmd.get() { + } else if let Some(cmd) = self.ctrl.cmd.get() { // todo: filter out tree-nav cmds and send them to tree_nav cmd.write().unwrap().send_cmd_obj(cmd_obj) } else { @@ -221,7 +221,7 @@ impl ObjCommander for NestedNode { } -impl Diagnostics for NestedNode { +impl Diagnostics for EditTree { fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> { self.get_diag() } diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 12614f1..d4123e8 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -9,7 +9,7 @@ use { laddertypes::{TypeTerm}, crate::{ repr_tree::{Context, ReprTree}, - edit_tree::{NestedNode, TreeNavResult}, + edit_tree::{EditTree, TreeNavResult}, editors::ObjCommander, }, std::sync::Arc, @@ -74,12 +74,12 @@ impl CharEditor { pub fn new_edit_tree( ctx0: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>> - ) -> NestedNode { + ) -> EditTree { let data = SingletonBuffer::new('\0'); let ctx = ctx0.clone(); let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() })); - NestedNode::new( + EditTree::new( ctx0.clone(), depth ) diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index e37f495..ae4bf9b 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -14,7 +14,7 @@ use { crate::{ editors::{list::{ListCmd}, ObjCommander}, repr_tree::{Context, ReprTree}, - edit_tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}}, + edit_tree::{EditTree, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}}, }, std::sync::Arc, std::sync::RwLock, @@ -81,13 +81,13 @@ impl DigitEditor { } } - pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode { + pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree { let data = self.get_data(); let editor = Arc::new(RwLock::new(self)); let ed = editor.write().unwrap(); let r = ed.radix; - NestedNode::new(ed.ctx.clone(), depth) + EditTree::new(ed.ctx.clone(), depth) .set_editor(editor.clone()) .set_cmd(editor.clone()) .set_diag( @@ -133,7 +133,7 @@ impl DigitEditor { pub struct PosIntEditor { radix: u32, - digits: NestedNode, + digits: EditTree, // todo: endianness } @@ -175,7 +175,7 @@ impl PosIntEditor { */ PosIntEditor { radix, - digits: NestedNode::new( + digits: EditTree::new( ctx, r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() ) @@ -203,7 +203,7 @@ impl PosIntEditor { self.digits.goto(TreeCursor::none()); } - pub fn into_node(self) -> NestedNode { + pub fn into_node(self) -> EditTree { self.digits } diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs index a8a09c8..82b5023 100644 --- a/lib-nested-core/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -5,7 +5,7 @@ use { crate::{ editors::{list::{ListEditor, ListCursor, ListCursorMode}, ObjCommander}, repr_tree::{Context, ReprTree}, - edit_tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, + edit_tree::{EditTree, TreeNav, TreeNavResult, TreeCursor}, }, std::sync::{Arc, RwLock} }; @@ -35,7 +35,7 @@ impl ObjCommander for ListEditor { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { let cmd_repr = cmd_obj.read().unwrap(); - if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = NestedNode>>() { + if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = EditTree>>() { let node = view.get(); let cur = self.cursor.get(); diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 5a971b4..89c2642 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -6,7 +6,7 @@ use { laddertypes::{TypeTerm}, crate::{ repr_tree::{Context, ReprTree}, - edit_tree::{NestedNode, TreeNav, TreeCursor, diagnostics::Diagnostics}, + edit_tree::{EditTree, TreeNav, TreeCursor, diagnostics::Diagnostics}, editors::{list::{ListCursor, ListCursorMode, ListCmd}, ObjCommander}, }, std::sync::{Arc, RwLock} @@ -18,9 +18,9 @@ pub struct ListEditor { pub cursor: SingletonBuffer<ListCursor>, // todo: (?) remove RwLock<..> around NestedNode ?? - pub data: VecBuffer< Arc<RwLock<NestedNode>> >, + pub data: VecBuffer< Arc<RwLock<EditTree>> >, - pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>, + pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<EditTree>>>>>, pub(super) addr_port: OuterViewPort<dyn SequenceView<Item = isize>>, pub(super) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>, @@ -39,7 +39,7 @@ impl ListEditor { typ: TypeTerm, ) -> Self { let cursor = SingletonBuffer::new(ListCursor::default()); - let data : VecBuffer<Arc<RwLock<NestedNode>>> = VecBuffer::new(); + let data : VecBuffer<Arc<RwLock<EditTree>>> = VecBuffer::new(); ListEditor { mode_port: cursor @@ -100,7 +100,7 @@ impl ListEditor { } } - pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode { + pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree { let data = self.get_data(); let ctx = self.ctx.clone(); @@ -109,7 +109,7 @@ impl ListEditor { let e = editor.read().unwrap(); - let mut node = NestedNode::new(ctx, depth) + let mut node = EditTree::new(ctx, depth) .set_editor(editor.clone()) .set_nav(editor.clone()) .set_cmd(editor.clone()) @@ -131,7 +131,7 @@ impl ListEditor { .flatten() ); - node.edit.spillbuf = e.spillbuf.clone(); + node.ctrl.spillbuf = e.spillbuf.clone(); node } @@ -150,7 +150,7 @@ impl ListEditor { self.cursor.get_port() } - pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> { + pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> { self.data.get_port().to_sequence().map( |x| x.read().unwrap().clone() ) @@ -164,7 +164,7 @@ impl ListEditor { ) } - pub fn get_item(&self) -> Option<NestedNode> { + pub fn get_item(&self) -> Option<EditTree> { if let Some(idx) = self.cursor.get().idx { let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; if idx < self.data.len() { @@ -177,7 +177,7 @@ impl ListEditor { } } - pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<NestedNode>>>> { + pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<EditTree>>>> { if let Some(idx) = self.cursor.get().idx { let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; if idx < self.data.len() { @@ -228,7 +228,7 @@ impl ListEditor { } /// insert a new element - pub fn insert(&mut self, item: Arc<RwLock<NestedNode>>) { + pub fn insert(&mut self, item: Arc<RwLock<EditTree>>) { item.read().unwrap().disp.depth.0.set_view( self.depth.map(|d| d+1).get_view() ); @@ -306,7 +306,7 @@ impl ListEditor { self.set_leaf_mode(ListCursorMode::Insert); self.nexd(); - let mut b = item.edit.spillbuf.write().unwrap(); + let mut b = item.ctrl.spillbuf.write().unwrap(); /* TODO let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap(); tail_node.goto(TreeCursor::home()); @@ -366,12 +366,12 @@ impl ListEditor { let old_cur = pxv_editor.get_cursor(); - let data = cur_editor.edit.spillbuf.read().unwrap(); + let data = cur_editor.ctrl.spillbuf.read().unwrap(); for x in data.iter() { pxv_editor.send_cmd_obj( ReprTree::new_leaf( Context::parse(&self.ctx, "NestedNode"), - SingletonBuffer::<NestedNode>::new( + SingletonBuffer::<EditTree>::new( x.read().unwrap().clone() ).get_port().into() ) @@ -424,13 +424,13 @@ impl ListEditor { leaf_mode: ListCursorMode::Insert }); - let data = nxd_editor.edit.spillbuf.read().unwrap(); + let data = nxd_editor.ctrl.spillbuf.read().unwrap(); for x in data.iter() { cur_editor.send_cmd_obj( ReprTree::new_leaf( Context::parse(&self.ctx, "NestedNode"), - SingletonBuffer::<NestedNode>::new( + SingletonBuffer::<EditTree>::new( x.read().unwrap().clone() ).get_port().into() ) diff --git a/lib-nested-core/src/editors/list/segment.rs b/lib-nested-core/src/editors/list/segment.rs index 9e23550..f8dbdc7 100644 --- a/lib-nested-core/src/editors/list/segment.rs +++ b/lib-nested-core/src/editors/list/segment.rs @@ -9,7 +9,7 @@ use { }, crate::{ editors::list::{ListCursor, ListCursorMode}, - edit_tree::{NestedNode} + edit_tree::{EditTree} }, std::sync::Arc, std::sync::RwLock, @@ -18,13 +18,13 @@ use { pub enum ListSegment { InsertCursor, Item { - editor: NestedNode, + editor: EditTree, cur_dist: isize, } } pub struct ListSegmentSequence { - data: Arc<dyn SequenceView<Item = NestedNode>>, + data: Arc<dyn SequenceView<Item = EditTree>>, cursor: Arc<dyn SingletonView<Item = ListCursor>>, cur_cursor: ListCursor, @@ -88,7 +88,7 @@ impl SequenceView for ListSegmentSequence { impl ListSegmentSequence { pub fn new( cursor_port: OuterViewPort<dyn SingletonView<Item = ListCursor>>, - data_port: OuterViewPort<dyn SequenceView<Item = NestedNode>>, + data_port: OuterViewPort<dyn SequenceView<Item = EditTree>>, ) -> Arc<RwLock<Self>> { let out_port = ViewPort::new(); let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone()); diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index dbdd92a..e280a9d 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -3,7 +3,7 @@ use { laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ repr_tree::{ReprTree, MorphismType, GenericReprTreeMorphism, MorphismBase}, - edit_tree::NestedNode + edit_tree::EditTree }, std::{ collections::HashMap, diff --git a/lib-nested-tty/src/edit_tree/keymap.rs b/lib-nested-tty/src/edit_tree/keymap.rs index 54e4679..1afc123 100644 --- a/lib-nested-tty/src/edit_tree/keymap.rs +++ b/lib-nested-tty/src/edit_tree/keymap.rs @@ -99,11 +99,12 @@ impl TerminalEvent { } } _ => { - ReprTree::new_leaf( - Context::parse(&ctx, "TerminalEvent"), - SingletonBuffer::new(self.clone()).get_port().into() - ) + ReprTree::new_leaf( + Context::parse(&ctx, "TerminalEvent"), + SingletonBuffer::new(self.clone()).get_port().into() + ) } } } } + diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 9b0cdd9..0075089 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -6,7 +6,7 @@ use { nested::{ repr_tree::{Context, ReprTree}, editors::list::*, - edit_tree::{TreeCursor, TreeNav, TreeNavResult, NestedNode}, + edit_tree::{TreeCursor, TreeNav, TreeNavResult, EditTree}, }, crate::{ DisplaySegment, @@ -91,7 +91,7 @@ impl PTYListStyle { .flatten() } - pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) { + pub fn for_node(node: &mut EditTree, style: (&str, &str, &str)) { node.disp.view .write().unwrap() .insert_branch(ReprTree::new_leaf( @@ -135,7 +135,7 @@ impl PTYListController { } pub fn for_node( - node: &mut NestedNode, + node: &mut EditTree, split_char: Option<char>, close_char: Option<char> ) { @@ -154,11 +154,11 @@ impl PTYListController { let editor = node.get_edit::<ListEditor>().unwrap(); let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.disp.depth.clone() ))); - node.edit.cmd.set(Some(controller.clone())); - node.edit.close_char.set(close_char); + node.ctrl.cmd.set(Some(controller.clone())); + node.ctrl.close_char.set(close_char); } - pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> { + pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> { self.editor.read().unwrap().get_data_port() } @@ -166,7 +166,7 @@ impl PTYListController { self.editor.write().unwrap().clear(); } - pub fn get_item(&self) -> Option<NestedNode> { + pub fn get_item(&self) -> Option<EditTree> { self.editor.read().unwrap().get_item() } @@ -238,7 +238,7 @@ impl PTYListController { ListCursorMode::Select => { if let Some(item) = e.get_item_mut() { let res = item.write().unwrap().send_cmd_obj(cmd_obj.clone()); - let child_close_char = item.read().unwrap().edit.close_char.get(); + let child_close_char = item.read().unwrap().ctrl.close_char.get(); match res { TreeNavResult::Continue => TreeNavResult::Continue, diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 4839841..5d65af6 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -3,7 +3,7 @@ pub mod list; use { nested::{ - edit_tree::{NestedNode}, + edit_tree::{EditTree}, repr_tree::{ReprTree, Context} }, r3vi::{ @@ -18,8 +18,8 @@ use { }; pub fn edittree_make_char_view( - node: NestedNode -) -> NestedNode { + node: EditTree +) -> EditTree { node.disp.view .write().unwrap() .insert_branch(ReprTree::new_leaf( @@ -38,8 +38,8 @@ pub fn edittree_make_char_view( } pub fn edittree_make_digit_view( - node: NestedNode -) -> NestedNode { + node: EditTree +) -> EditTree { node.disp.view .write().unwrap() .insert_branch(ReprTree::new_leaf( diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index e7c03a3..07f49f6 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -42,7 +42,7 @@ pub trait DisplaySegment { use nested::repr_tree::Context; use std::sync::{Arc, RwLock}; -impl DisplaySegment for nested::edit_tree::NestedNode { +impl DisplaySegment for nested::edit_tree::EditTree { fn display_view(&self) -> OuterViewPort<dyn TerminalView> { if let Some( tv_repr ) = self.disp.view .read().unwrap() diff --git a/lib-nested-tty/src/tty_application.rs b/lib-nested-tty/src/tty_application.rs index abcbf0b..aade2bb 100644 --- a/lib-nested-tty/src/tty_application.rs +++ b/lib-nested-tty/src/tty_application.rs @@ -1,7 +1,7 @@ use { cgmath::Vector2, nested::{ - edit_tree::NestedNode, + edit_tree::EditTree, repr_tree::{Context, ReprTree}, }, crate::{ From caa0c9a5c09a77f665fd8b6389a55ccb67963fee Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 14 Jan 2024 16:23:58 +0100 Subject: [PATCH 21/75] define char-editor constructor as morphism --- examples/tty-02-node/src/main.rs | 88 +++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 13 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 253dbbc..b561928 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -46,7 +46,7 @@ async fn main() { * TTY PixelBuf SDF */ let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 10>") ); - let port_char = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = char>>::new(); +// let port_char = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = char>>::new(); let port_u32 = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = u32>>::new(); let port_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>::new(); let port_char_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>::new(); @@ -54,14 +54,12 @@ async fn main() { rt_digit.write().unwrap() .insert_leaf( vec![ Context::parse(&ctx, "Char") ].into_iter(), - port_char.outer().into() + SingletonBuffer::new('x').get_port().into() ); - rt_digit.write().unwrap() - .insert_leaf( - vec![ Context::parse(&ctx, "Char"), Context::parse(&ctx, "EditTree") ].into_iter(), - port_char_edit.outer().into() - ); + let port_char = rt_digit.read().unwrap() + .descend(Context::parse(&ctx, "Char")).unwrap().read().unwrap() + .get_port::<dyn r3vi::view::singleton::SingletonView<Item = char>>().unwrap().0; rt_digit.write().unwrap() .insert_leaf( @@ -75,24 +73,88 @@ async fn main() { port_u32.outer().into() ); + let morphtype = + nested::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "Char"), + dst_type: Context::parse(&ctx, "Char~EditTree") + }; + + ctx.write().unwrap() + .morphisms + .add_morphism( + morphtype, + { + let ctx =ctx.clone(); + move |rt, σ| { + /* Create EditTree object + */ + let mut edittree_char = nested::editors::char::CharEditor::new_edit_tree( + ctx.clone(), + r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + ); + edittree_char = nested_tty::editors::edittree_make_char_view( edittree_char ); + + /* Insert EditTree into ReprTree + */ + rt.write().unwrap() + .insert_leaf( + vec![ Context::parse(&ctx, "EditTree") ].into_iter(), + SingletonBuffer::new(edittree_char).get_port().into() + ); + } + } + ); +/* + let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<Seq Char>") ); + + let vec_string = Arc::new(RwLock::new(Vec::new())); + + rt_string.write().unwrap() + .insert_leaf( + vec![ Context::parse(&ctx, "<Vec Char>") ].into_iter(), + r3vi::view::ViewPort::with_view(vec_string).into_outer() + ); +*/ + /* setup projections between representations */ - + /* // created by Char ==> Char~EditTree let mut edittree_char = nested::editors::char::CharEditor::new_edit_tree( ctx.clone(), r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() ); +*/ + + eprintln!("morph [ Char ==> Char~EditTree ]"); + ctx.read().unwrap() + .morphisms + .morph( + rt_digit.read().unwrap() + .descend(Context::parse(&ctx, "Char")) + .unwrap().clone(), + &Context::parse(&ctx, "Char~EditTree") + ); + + let edittree_char = + ReprTree::descend_ladder( + &rt_digit, + vec![ + Context::parse(&ctx, "Char"), + Context::parse(&ctx, "EditTree") + ].into_iter() + ).unwrap() + .read().unwrap() + .get_view::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>().unwrap() + .get(); - edittree_char = nested_tty::editors::edittree_make_char_view( edittree_char ); let mut edit_char = edittree_char.get_edit::< nested::editors::char::CharEditor >().unwrap(); port_char.attach_to( edit_char.read().unwrap().get_port() ); let buf_edit_char = r3vi::buffer::singleton::SingletonBuffer::new( edittree_char.clone() ); port_char_edit.attach_to( buf_edit_char.get_port() ); - // created by <Digit 10> ==> <Digit 10>~EditTree let mut node_edit_digit = nested::editors::integer::DigitEditor::new( @@ -110,7 +172,7 @@ async fn main() { // port_u32.attach_to( edit_digit.read().unwrap().get_data_port().map(|d| d.unwrap_or(0)) ); let port_proj_u32_to_char = port_u32.outer().map(|val| char::from_digit(val, 16).unwrap_or('?') ); - + let buf_edit_digit = r3vi::buffer::singleton::SingletonBuffer::new( node_edit_digit ); port_edit.attach_to( buf_edit_digit.get_port() ); @@ -158,12 +220,12 @@ async fn main() { ); compositor.write().unwrap().push( buf_edit_digit.get().display_view().offset(Vector2::new(0,2)) ); -/* let label = ctx.read().unwrap().type_term_to_str(&node1.get_type()); + let label = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); compositor .write() .unwrap() .push(nested_tty::make_label(&label).offset(Vector2::new(0, 2))); - +/* compositor .write() .unwrap() From 8471c7a90f6df2e07d0c9c51157b3f75faeccdd4 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 18 Jan 2024 18:17:26 +0100 Subject: [PATCH 22/75] move morphism to editors/char mod --- examples/tty-02-node/src/main.rs | 85 +++++------------------ lib-nested-core/src/editors/char/mod.rs | 44 +++++++++--- lib-nested-core/src/repr_tree/mod.rs | 4 +- lib-nested-core/src/repr_tree/morphism.rs | 1 - 4 files changed, 54 insertions(+), 80 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index b561928..c3bc61b 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -28,6 +28,8 @@ async fn main() { */ let ctx = Arc::new(RwLock::new(Context::new())); + nested::editors::char::init_ctx( ctx.clone() ); + /* structure of Repr-Tree * * === Repr-Tree === @@ -67,43 +69,6 @@ async fn main() { port_edit.outer().into() ); - rt_digit.write().unwrap() - .insert_leaf( - vec![ Context::parse(&ctx, "u32") ].into_iter(), - port_u32.outer().into() - ); - - let morphtype = - nested::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "Char"), - dst_type: Context::parse(&ctx, "Char~EditTree") - }; - - ctx.write().unwrap() - .morphisms - .add_morphism( - morphtype, - { - let ctx =ctx.clone(); - move |rt, σ| { - /* Create EditTree object - */ - let mut edittree_char = nested::editors::char::CharEditor::new_edit_tree( - ctx.clone(), - r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() - ); - edittree_char = nested_tty::editors::edittree_make_char_view( edittree_char ); - - /* Insert EditTree into ReprTree - */ - rt.write().unwrap() - .insert_leaf( - vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - SingletonBuffer::new(edittree_char).get_port().into() - ); - } - } - ); /* let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<Seq Char>") ); @@ -118,25 +83,24 @@ async fn main() { /* setup projections between representations */ - /* - // created by Char ==> Char~EditTree - let mut edittree_char = - nested::editors::char::CharEditor::new_edit_tree( - ctx.clone(), - r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() - ); -*/ - + eprintln!("rt_digit = {:?}", rt_digit); eprintln!("morph [ Char ==> Char~EditTree ]"); + + let rt_char = rt_digit.read().unwrap() + .descend(Context::parse(&ctx, "Char")) + .unwrap().clone(); + + eprintln!("rt_char = {:?}", rt_char); + ctx.read().unwrap() .morphisms .morph( - rt_digit.read().unwrap() - .descend(Context::parse(&ctx, "Char")) - .unwrap().clone(), + rt_char.clone(), &Context::parse(&ctx, "Char~EditTree") ); + eprintln!("rt_digit = {:?}", rt_char); + let edittree_char = ReprTree::descend_ladder( &rt_digit, @@ -166,34 +130,17 @@ async fn main() { node_edit_digit = nested_tty::editors::edittree_make_digit_view( node_edit_digit ); let mut edit_digit = node_edit_digit.get_edit::< nested::editors::integer::DigitEditor >().unwrap(); - +/* // created by <Digit 10> ==> <Digit 10>~U32 port_u32.attach_to( port_char.outer().map(|c| c.to_digit(16).unwrap_or(0)) ); // port_u32.attach_to( edit_digit.read().unwrap().get_data_port().map(|d| d.unwrap_or(0)) ); let port_proj_u32_to_char = port_u32.outer().map(|val| char::from_digit(val, 16).unwrap_or('?') ); + */ let buf_edit_digit = r3vi::buffer::singleton::SingletonBuffer::new( node_edit_digit ); port_edit.attach_to( buf_edit_digit.get_port() ); -/* - ctx.write().unwrap() - .morphisms - .add_morphism( - MorphismType { - src_type: Context::parse(&ctx, "Char"), - dst_type: Context::parse(&ctx, "Char~EditTree") - }, - - |rt, _σ| { - rt.write().unwrap() - .insert_branch( - Context::parse(&ctx, "") - ); - } - ) -*/ - /* setup terminal */ let app = TTYApplication::new({ @@ -224,7 +171,7 @@ async fn main() { compositor .write() .unwrap() - .push(nested_tty::make_label(&label).offset(Vector2::new(0, 2))); + .push(nested_tty::make_label(&label).offset(Vector2::new(0, 1))); /* compositor .write() diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index d4123e8..7be55a3 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -16,14 +16,42 @@ use { std::sync::RwLock }; -pub fn init_ctx( ctx: &mut Context ) { - /* - ctx.add_node_ctor( - "Char", - Arc::new(|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { - Some(CharEditor::new_node(ctx, depth)) - })); - */ +pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { + + let morphtype = + crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "Char"), + dst_type: Context::parse(&ctx, "Char~EditTree") + }; + + ctx.write().unwrap() + .morphisms + .add_morphism( + morphtype, + { + let ctx = ctx.clone(); + move |rt, σ| { + /* Create EditTree object + */ + let mut edittree_char = CharEditor::new_edit_tree( + ctx.clone(), + r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + ); +/* + /* setup tty-view for EditTree + */ + edittree_char = nested_tty::editors::edittree_make_char_view( edittree_char ); +*/ + /* Insert EditTree into ReprTree + */ + let mut rt = rt.write().unwrap(); + rt.insert_leaf( + vec![ Context::parse(&ctx, "EditTree") ].into_iter(), + SingletonBuffer::new(edittree_char).get_port().into() + ); + } + } + ); } pub struct CharEditor { diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index bd62527..1f5ce63 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -26,10 +26,10 @@ pub struct ReprTree { impl std::fmt::Debug for ReprTree { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "type: {:?}", self.type_tag)?; + writeln!(f, "| type: {:?}", self.type_tag)?; for (_k,x) in self.branches.iter() { - write!(f, "child: {:?}", x)?; + writeln!(f, "|--> child: {:?}", x)?; } Ok(()) diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index 2cb58cc..b7cc3bc 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -68,7 +68,6 @@ impl MorphismBase { ); if let Ok(σ) = unification_problem.solve() { - eprintln!("found matching morphism"); return Some((m, σ)); } } From fdf2d60b35c782b3bfe086800d088be3fd89ad34 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 18 Jan 2024 18:18:14 +0100 Subject: [PATCH 23/75] MorphismBase: fix deadlock --- lib-nested-core/src/repr_tree/morphism.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index b7cc3bc..689cffc 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -80,7 +80,8 @@ impl MorphismBase { repr_tree: Arc<RwLock<ReprTree>>, target_type: &TypeTerm ) { - if let Some((m, σ)) = self.find_morphism( repr_tree.read().unwrap().get_type(), target_type ) { + let t = repr_tree.read().unwrap().get_type().clone(); + if let Some((m, σ)) = self.find_morphism( &t, target_type ) { (m.repr_tree_op)( repr_tree.clone(), &σ ); } else { eprintln!("could not find morphism"); From 863fe95848b67d86b6fb23d3fa8a3544043aeaef Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Tue, 16 Jan 2024 15:20:51 +0100 Subject: [PATCH 24/75] example wip --- examples/tty-02-node/src/main.rs | 142 ++++++++---------- lib-nested-core/src/editors/char/mod.rs | 8 +- lib-nested-core/src/editors/integer/editor.rs | 45 ++++++ lib-nested-core/src/editors/list/ctx.rs | 39 ++++- lib-nested-tty/src/editors/mod.rs | 39 ++--- lib-nested-tty/src/lib.rs | 4 +- 6 files changed, 168 insertions(+), 109 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index c3bc61b..7731127 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -29,6 +29,8 @@ async fn main() { let ctx = Arc::new(RwLock::new(Context::new())); nested::editors::char::init_ctx( ctx.clone() ); + nested::editors::integer::editor::init_ctx( ctx.clone() ); + nested::editors::list::init_ctx( ctx.clone() ); /* structure of Repr-Tree * @@ -47,12 +49,11 @@ async fn main() { * / | \ * TTY PixelBuf SDF */ - let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 10>") ); -// let port_char = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = char>>::new(); - let port_u32 = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = u32>>::new(); - let port_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>::new(); - let port_char_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>::new(); + let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); + /* add initial representation + * <Digit 16> ~ Char + */ rt_digit.write().unwrap() .insert_leaf( vec![ Context::parse(&ctx, "Char") ].into_iter(), @@ -63,93 +64,73 @@ async fn main() { .descend(Context::parse(&ctx, "Char")).unwrap().read().unwrap() .get_port::<dyn r3vi::view::singleton::SingletonView<Item = char>>().unwrap().0; - rt_digit.write().unwrap() - .insert_leaf( - vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - port_edit.outer().into() + ctx.read().unwrap() + .morphisms + .morph( + rt_digit.clone(), + &Context::parse(&ctx, "<Digit 16>~EditTree") ); -/* - let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<Seq Char>") ); + let port_edit = rt_digit.read().unwrap() + .descend(Context::parse(&ctx, "EditTree")).unwrap() + .read().unwrap() + .get_port::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>> >>().unwrap(); - let vec_string = Arc::new(RwLock::new(Vec::new())); + /* setup TTY-Display for DigitEditor + */ + { + let et = port_edit.get_view().unwrap().get().clone(); + let mut et = et.write().unwrap(); + *et = nested_tty::editors::edittree_make_digit_view(et.clone()); + } + + //--- + let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <Digit 10>>") ); + ctx.read().unwrap() + .morphisms + .morph( + rt_string.clone(), + &Context::parse(&ctx, "<List <Digit 10>>~EditTree") + ); + + let editport_string = rt_string.read().unwrap() + .descend(Context::parse(&ctx, "EditTree")).unwrap() + .read().unwrap() + .get_port::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>>> >().unwrap(); + + /* setup TTY-Display for ListEditor + */ + { + let et = editport_string.get_view().unwrap().get().clone(); + let mut et = et.write().unwrap(); + *et = nested_tty::editors::edittree_make_list_edit(et.clone()); + } +/* + let vec_string = Arc::new(RwLock::new(Vec::<char>::new())); rt_string.write().unwrap() .insert_leaf( vec![ Context::parse(&ctx, "<Vec Char>") ].into_iter(), - r3vi::view::ViewPort::with_view(vec_string).into_outer() + r3vi::view::ViewPort::with_view(vec_string).into_outer().into() + ); + + + rt_string.write().unwrap() + .insert_leaf( + vec![ Context::parse(&ctx, "EditTree") ].into_iter(), + r3vi::view::ViewPort::with_view() ); */ - /* setup projections between representations - */ - eprintln!("rt_digit = {:?}", rt_digit); - eprintln!("morph [ Char ==> Char~EditTree ]"); - - let rt_char = rt_digit.read().unwrap() - .descend(Context::parse(&ctx, "Char")) - .unwrap().clone(); - - eprintln!("rt_char = {:?}", rt_char); - - ctx.read().unwrap() - .morphisms - .morph( - rt_char.clone(), - &Context::parse(&ctx, "Char~EditTree") - ); - - eprintln!("rt_digit = {:?}", rt_char); - - let edittree_char = - ReprTree::descend_ladder( - &rt_digit, - vec![ - Context::parse(&ctx, "Char"), - Context::parse(&ctx, "EditTree") - ].into_iter() - ).unwrap() - .read().unwrap() - .get_view::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>().unwrap() - .get(); - - let mut edit_char = edittree_char.get_edit::< nested::editors::char::CharEditor >().unwrap(); - port_char.attach_to( edit_char.read().unwrap().get_port() ); - - let buf_edit_char = r3vi::buffer::singleton::SingletonBuffer::new( edittree_char.clone() ); - port_char_edit.attach_to( buf_edit_char.get_port() ); - - // created by <Digit 10> ==> <Digit 10>~EditTree - let mut node_edit_digit = - nested::editors::integer::DigitEditor::new( - ctx.clone(), - 16 - ).into_node( - r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() - ); - - node_edit_digit = nested_tty::editors::edittree_make_digit_view( node_edit_digit ); - let mut edit_digit = node_edit_digit.get_edit::< nested::editors::integer::DigitEditor >().unwrap(); -/* - // created by <Digit 10> ==> <Digit 10>~U32 - port_u32.attach_to( port_char.outer().map(|c| c.to_digit(16).unwrap_or(0)) ); - // port_u32.attach_to( edit_digit.read().unwrap().get_data_port().map(|d| d.unwrap_or(0)) ); - - let port_proj_u32_to_char = port_u32.outer().map(|val| char::from_digit(val, 16).unwrap_or('?') ); - */ - - let buf_edit_digit = r3vi::buffer::singleton::SingletonBuffer::new( node_edit_digit ); - port_edit.attach_to( buf_edit_digit.get_port() ); - /* setup terminal */ let app = TTYApplication::new({ /* event handler */ let ctx = ctx.clone(); - let node1 = buf_edit_digit.clone(); + let et1 = editport_string.clone(); move |ev| { - node1.get().send_cmd_obj(ev.to_repr_tree(&ctx)); + et1.get_view().unwrap().get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -165,19 +146,22 @@ async fn main() { }) .offset(Vector2::new(5, 0)), ); - compositor.write().unwrap().push( buf_edit_digit.get().display_view().offset(Vector2::new(0,2)) ); + compositor.write().unwrap().push( port_edit.get_view().unwrap().get().read().unwrap().display_view().offset(Vector2::new(0,2)) ); let label = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); compositor .write() .unwrap() .push(nested_tty::make_label(&label).offset(Vector2::new(0, 1))); -/* + + compositor.write().unwrap().push( editport_string.get_view().unwrap().get().read().unwrap().display_view().offset(Vector2::new(0,4)) ); + + let label = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type()); compositor .write() .unwrap() - .push(node1.display_view().offset(Vector2::new(15, 2))); -*/ + .push(nested_tty::make_label(&label).offset(Vector2::new(0, 3))); + /* write the changes in the view of `term_port` to the terminal */ app.show().await.expect("output error!"); diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 7be55a3..3b3c1ff 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -37,17 +37,13 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { ctx.clone(), r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() ); -/* - /* setup tty-view for EditTree - */ - edittree_char = nested_tty::editors::edittree_make_char_view( edittree_char ); -*/ + /* Insert EditTree into ReprTree */ let mut rt = rt.write().unwrap(); rt.insert_leaf( vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - SingletonBuffer::new(edittree_char).get_port().into() + SingletonBuffer::new( Arc::new(RwLock::new( edittree_char )) ).get_port().into() ); } } diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index ae4bf9b..0a911c9 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -22,6 +22,51 @@ use { cgmath::{Point2} }; + +pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { + + // todo: proper scoping of Radix variable + ctx.write().unwrap().add_varname("Radix"); + let morphtype = + crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<Digit Radix>"), + dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree") + }; + + ctx.write().unwrap() + .morphisms + .add_morphism( + morphtype, + { + let ctx = ctx.clone(); + move |rt, σ| { + let radix = + match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + Some(TypeTerm::Num(n)) => *n as u32, + _ => 0 + }; + + /* Create EditTree object + */ + let mut edittree_digit = DigitEditor::new( + ctx.clone(), + radix + ).into_node( + r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + ); + + /* Insert EditTree into ReprTree + */ + let mut rt = rt.write().unwrap(); + rt.insert_leaf( + vec![ Context::parse(&ctx, "EditTree") ].into_iter(), + SingletonBuffer::new( Arc::new(RwLock::new(edittree_digit)) ).get_port().into() + ); + } + } + ); +} + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct DigitEditor { diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 8cb8c37..90ef8c5 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -1,5 +1,5 @@ use { - r3vi::{view::{OuterViewPort, singleton::*}}, + r3vi::{view::{OuterViewPort, singleton::*}, buffer::singleton::*}, laddertypes::{TypeTerm}, crate::{ repr_tree::{Context}, @@ -10,10 +10,43 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -pub fn init_ctx(ctx: &mut Context) { +pub fn init_ctx(ctx: Arc<RwLock<Context>>) { + + ctx.write().unwrap().add_varname("Item"); + let mt = crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<List Item>"), + dst_type: Context::parse(&ctx, "<List Item>~EditTree") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |rt, σ| { + let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); + if let Some( item_type ) = σ.get( &item_id ) { + eprintln!("create list of {:?}", item_type); + let mut edittree_list = ListEditor::new( + ctx.clone(), + item_type.clone() + ).into_node( + r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + ); + + let mut rt = rt.write().unwrap(); + rt.insert_leaf( + vec![ Context::parse(&ctx, "EditTree") ].into_iter(), + SingletonBuffer::new( Arc::new(RwLock::new( edittree_list )) ).get_port().into() + ); + } else { + eprintln!("no item type"); + } + } + } + ); +/* + ctx.add_typename("ListCmd".into()); ctx.add_list_typename("List".into()); -/* ctx.add_node_ctor( "List", Arc::new( |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 5d65af6..4e2e30a 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -61,21 +61,21 @@ pub fn edittree_make_digit_view( node } - /* -pub fn node_make_seq_view( - mut node: NestedNode -) -> NestedNode { +pub fn edittree_make_seq_view( + mut node: EditTree +) -> EditTree { node.disp.view .write().unwrap() .insert_branch(ReprTree::new_leaf( Context::parse(&node.ctx, "TerminalView"), - node.data - .read() + node.get_edit::< nested::editors::list::ListEditor >() .unwrap() - .get_port::<dyn SequenceView<Item = NestedNode>>() - .expect("unable to get Seq-view") - .map(move |char_node| node_make_tty_view(char_node.clone()).display_view() ) + .read().unwrap() + .get_data_port() + .map(move |item_edittree| + edittree_make_tty_view( item_edittree ).display_view() + ) .wrap(make_label("("), make_label(")")) .to_grid_horizontal() .flatten() @@ -83,24 +83,25 @@ pub fn node_make_seq_view( )); node } +*/ -pub fn node_make_list_edit( - mut node: NestedNode -) -> NestedNode { +pub fn edittree_make_list_edit( + mut node: EditTree +) -> EditTree { list::PTYListStyle::for_node( &mut node, ("(", "", ")") ); list::PTYListController::for_node( &mut node, None, None ); node } - -pub fn node_make_tty_view( - node: NestedNode -) -> NestedNode { - if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { +/* +pub fn edittree_make_tty_view( + et: EditTree +) -> EditTree { + if et.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { node_make_char_view( node ) - } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") { + } else if et.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") { node_make_seq_view( node ) - } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") { + } else if et.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") { node_make_list_edit( node ) } else { eprintln!("couldnt add view"); diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index 07f49f6..f5631af 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -56,10 +56,10 @@ impl DisplaySegment for nested::edit_tree::EditTree { } else { - make_label("?") + make_label("# could not get ViewPort #") } } else { - make_label("?") + make_label("# No TTY View available #") .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((220, 30, 30)))) } } From 0ac4a3474317962bcd544e5e92b1327bd79045e9 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 17 Jan 2024 03:42:47 +0100 Subject: [PATCH 25/75] example wip: create display for edit tree --- examples/tty-02-node/Cargo.toml | 1 + examples/tty-02-node/src/main.rs | 94 +++++++++--------------- lib-nested-core/src/editors/list/ctx.rs | 31 +------- lib-nested-core/src/repr_tree/context.rs | 42 ++++++++++- lib-nested-tty/src/editors/list.rs | 20 ++--- lib-nested-tty/src/editors/mod.rs | 1 - 6 files changed, 87 insertions(+), 102 deletions(-) diff --git a/examples/tty-02-node/Cargo.toml b/examples/tty-02-node/Cargo.toml index 589ee96..ccfc655 100644 --- a/examples/tty-02-node/Cargo.toml +++ b/examples/tty-02-node/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +laddertypes = { path = "../../../lib-laddertypes" } r3vi = { path = "../../../lib-r3vi" } nested = { path = "../../lib-nested-core" } nested-tty = { path = "../../lib-nested-tty" } diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 7731127..8607683 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -32,6 +32,32 @@ async fn main() { nested::editors::integer::editor::init_ctx( ctx.clone() ); nested::editors::list::init_ctx( ctx.clone() ); + + let char_type = Context::parse(&ctx, "Char"); + let digit_type = Context::parse(&ctx, "<Digit Radix>"); + let list_type = Context::parse(&ctx, "<List Item>"); + + ctx.write().unwrap().set_edittree_hook( + Arc::new( + move |et: Arc<RwLock<EditTree>>, t: laddertypes::TypeTerm| { + if let Ok(σ) = laddertypes::unify(&t, &char_type) { + let mut et = et.write().unwrap(); + *et = nested_tty::editors::edittree_make_char_view(et.clone()); + } + else if let Ok(σ) = laddertypes::unify(&t, &digit_type) { + let mut et = et.write().unwrap(); + *et = nested_tty::editors::edittree_make_digit_view(et.clone()); + } + else if let Ok(σ) = laddertypes::unify(&t, &list_type) { + let mut et = et.write().unwrap(); + nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("(", ",", ")")); + nested_tty::editors::list::PTYListController::for_node( &mut *et, None, None ); + *et = nested_tty::editors::edittree_make_list_edit(et.clone()); + } + } + ) + ); + /* structure of Repr-Tree * * === Repr-Tree === @@ -60,67 +86,13 @@ async fn main() { SingletonBuffer::new('x').get_port().into() ); - let port_char = rt_digit.read().unwrap() - .descend(Context::parse(&ctx, "Char")).unwrap().read().unwrap() - .get_port::<dyn r3vi::view::singleton::SingletonView<Item = char>>().unwrap().0; - - ctx.read().unwrap() - .morphisms - .morph( - rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~EditTree") - ); - - let port_edit = rt_digit.read().unwrap() - .descend(Context::parse(&ctx, "EditTree")).unwrap() - .read().unwrap() - .get_port::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>> >>().unwrap(); - /* setup TTY-Display for DigitEditor */ - { - let et = port_edit.get_view().unwrap().get().clone(); - let mut et = et.write().unwrap(); - *et = nested_tty::editors::edittree_make_digit_view(et.clone()); - } + let edittree_digit = ctx.read().unwrap().setup_edittree(rt_digit.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); //--- - let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <Digit 10>>") ); - ctx.read().unwrap() - .morphisms - .morph( - rt_string.clone(), - &Context::parse(&ctx, "<List <Digit 10>>~EditTree") - ); - - let editport_string = rt_string.read().unwrap() - .descend(Context::parse(&ctx, "EditTree")).unwrap() - .read().unwrap() - .get_port::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>>> >().unwrap(); - - /* setup TTY-Display for ListEditor - */ - { - let et = editport_string.get_view().unwrap().get().clone(); - let mut et = et.write().unwrap(); - *et = nested_tty::editors::edittree_make_list_edit(et.clone()); - } -/* - let vec_string = Arc::new(RwLock::new(Vec::<char>::new())); - - rt_string.write().unwrap() - .insert_leaf( - vec![ Context::parse(&ctx, "<Vec Char>") ].into_iter(), - r3vi::view::ViewPort::with_view(vec_string).into_outer().into() - ); - - - rt_string.write().unwrap() - .insert_leaf( - vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - r3vi::view::ViewPort::with_view() - ); -*/ + let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <List <Digit 16>>>") ); + let edittree = ctx.read().unwrap().setup_edittree(rt_string.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); /* setup terminal */ @@ -128,9 +100,9 @@ async fn main() { /* event handler */ let ctx = ctx.clone(); - let et1 = editport_string.clone(); + let et1 = edittree.clone(); move |ev| { - et1.get_view().unwrap().get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); + et1.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -146,7 +118,7 @@ async fn main() { }) .offset(Vector2::new(5, 0)), ); - compositor.write().unwrap().push( port_edit.get_view().unwrap().get().read().unwrap().display_view().offset(Vector2::new(0,2)) ); + compositor.write().unwrap().push( edittree_digit.read().unwrap().display_view().offset(Vector2::new(0,2)) ); let label = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); compositor @@ -154,7 +126,7 @@ async fn main() { .unwrap() .push(nested_tty::make_label(&label).offset(Vector2::new(0, 1))); - compositor.write().unwrap().push( editport_string.get_view().unwrap().get().read().unwrap().display_view().offset(Vector2::new(0,4)) ); + compositor.write().unwrap().push( edittree.read().unwrap().display_view().offset(Vector2::new(0,4)) ); let label = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type()); compositor diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 90ef8c5..0ef2180 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -11,7 +11,7 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub fn init_ctx(ctx: Arc<RwLock<Context>>) { - + ctx.write().unwrap().add_list_typename("List".into()); ctx.write().unwrap().add_varname("Item"); let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Item>"), @@ -24,7 +24,6 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { move |rt, σ| { let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); if let Some( item_type ) = σ.get( &item_id ) { - eprintln!("create list of {:?}", item_type); let mut edittree_list = ListEditor::new( ctx.clone(), item_type.clone() @@ -43,33 +42,5 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } } ); -/* - - ctx.add_typename("ListCmd".into()); - ctx.add_list_typename("List".into()); - ctx.add_node_ctor( - "List", Arc::new( - |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { - match ty { - TypeTerm::App(args) => { - if args.len() > 1 { - let typ = args[1].clone(); - - let mut node = ListEditor::new(ctx.clone(), typ).into_node(depth); - -// PTYListController::for_node( &mut node, Some(','), Some('}') ); -// PTYListStyle::for_node( &mut node, ("{",", ","}") ); - - Some(node) - } else { - None - } - } - _ => None - } - } - ) - ); - */ } diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index e280a9d..ef07efe 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -29,12 +29,16 @@ pub struct Context { pub list_types: Vec< TypeID >, pub meta_chars: Vec< char >, + edittree_hook: Arc< dyn Fn(Arc<RwLock<EditTree>>, TypeTerm) + Send +Sync +'static >, + /// recursion parent: Option<Arc<RwLock<Context>>>, } impl Context { - pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self { + pub fn with_parent( + parent: Option<Arc<RwLock<Context>>> + ) -> Self { Context { type_dict: match parent.as_ref() { Some(p) => p.read().unwrap().type_dict.clone(), @@ -51,6 +55,8 @@ impl Context { None => Vec::new() }, parent, + + edittree_hook: Arc::new(|_et, _t| {}) } } @@ -58,6 +64,10 @@ impl Context { Context::with_parent(None) } + pub fn set_edittree_hook(&mut self, hook: Arc< dyn Fn(Arc<RwLock<EditTree>>, TypeTerm) + Send +Sync +'static >) { + self.edittree_hook = hook; + } + pub fn depth(&self) -> usize { if let Some(parent) = self.parent.as_ref() { parent.read().unwrap().depth() + 1 @@ -165,6 +175,36 @@ impl Context { None } } + + pub fn setup_edittree( + &self, + rt: Arc<RwLock<ReprTree>>, + depth: OuterViewPort<dyn SingletonView<Item = usize>> + ) -> Arc<RwLock<EditTree>> { + let ladder = TypeTerm::Ladder(vec![ + rt.read().unwrap().get_type().clone(), + self.type_term_from_str("EditTree").expect("") + ]); + + self.morphisms.morph( + rt.clone(), + &ladder + ); + + let new_edittree = rt + .read().unwrap() + .descend( + self.type_term_from_str("EditTree").expect("") + ).unwrap() + .read().unwrap() + .get_view::<dyn SingletonView<Item = Arc<RwLock<EditTree>> >>() + .unwrap() + .get(); + + (*self.edittree_hook)( new_edittree.clone(), rt.read().unwrap().get_type().clone() ); + + new_edittree + } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 0075089..64cf6a1 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -139,6 +139,7 @@ impl PTYListController { split_char: Option<char>, close_char: Option<char> ) { + /* { let ctx = node.ctx.as_ref(); let mut ctx = ctx.write().unwrap(); @@ -150,7 +151,7 @@ impl PTYListController { ctx.meta_chars.push(*c); } } - + */ let editor = node.get_edit::<ListEditor>().unwrap(); let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.disp.depth.clone() ))); @@ -219,21 +220,22 @@ impl PTYListController { match cur.mode { ListCursorMode::Insert => { - /* TODO - let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth.map(|d| d+1)).unwrap(); - new_edit.goto(TreeCursor::home()); - - match new_edit.send_cmd_obj(cmd_obj.clone()) { + let rt = ReprTree::new_arc(e.typ.clone()); + let new_edittree = ctx.setup_edittree( + rt, + self.depth.map(|d| d+1) + ); + let mut ne = new_edittree.write().unwrap(); + match ne.send_cmd_obj(cmd_obj.clone()) { TreeNavResult::Continue => { - e.insert(Arc::new(RwLock::new(new_edit.clone()))); + drop(ne); + e.insert(new_edittree.clone()); TreeNavResult::Continue } TreeNavResult::Exit => { TreeNavResult::Exit } } - */ - TreeNavResult::Continue }, ListCursorMode::Select => { if let Some(item) = e.get_item_mut() { diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 4e2e30a..eee1b74 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -90,7 +90,6 @@ pub fn edittree_make_list_edit( ) -> EditTree { list::PTYListStyle::for_node( &mut node, ("(", "", ")") ); list::PTYListController::for_node( &mut node, None, None ); - node } /* From e46c143decf2969fbfe27cf46c7024dd3b2aec41 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 18 Jan 2024 17:16:20 +0100 Subject: [PATCH 26/75] test different style for <List Char>, add meta-chars to ctx globally to avoid deadlock --- examples/tty-02-node/src/main.rs | 28 ++++++++++++++++------ lib-nested-core/src/edit_tree/node.rs | 4 ++-- lib-nested-core/src/editors/list/editor.rs | 2 +- lib-nested-tty/src/editors/list.rs | 4 ++-- lib-nested-tty/src/editors/mod.rs | 25 +------------------ 5 files changed, 27 insertions(+), 36 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 8607683..1bafa37 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -32,15 +32,18 @@ async fn main() { nested::editors::integer::editor::init_ctx( ctx.clone() ); nested::editors::list::init_ctx( ctx.clone() ); - let char_type = Context::parse(&ctx, "Char"); let digit_type = Context::parse(&ctx, "<Digit Radix>"); let list_type = Context::parse(&ctx, "<List Item>"); + let posint_type = Context::parse(&ctx, "<PosInt Radix>"); + let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap(); + ctx.write().unwrap().meta_chars.push(','); + ctx.write().unwrap().meta_chars.push('\"'); ctx.write().unwrap().set_edittree_hook( Arc::new( move |et: Arc<RwLock<EditTree>>, t: laddertypes::TypeTerm| { - if let Ok(σ) = laddertypes::unify(&t, &char_type) { + if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) { let mut et = et.write().unwrap(); *et = nested_tty::editors::edittree_make_char_view(et.clone()); } @@ -48,14 +51,25 @@ async fn main() { let mut et = et.write().unwrap(); *et = nested_tty::editors::edittree_make_digit_view(et.clone()); } + else if let Ok(σ) = laddertypes::unify(&t, &posint_type) { + let mut et = et.write().unwrap(); + nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("0d", "", "")); + nested_tty::editors::list::PTYListController::for_node( &mut *et, None, None ); + } else if let Ok(σ) = laddertypes::unify(&t, &list_type) { let mut et = et.write().unwrap(); - nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("(", ",", ")")); - nested_tty::editors::list::PTYListController::for_node( &mut *et, None, None ); - *et = nested_tty::editors::edittree_make_list_edit(et.clone()); + let item_type = σ.get( &laddertypes::TypeID::Var(item_tyid) ).unwrap(); + if item_type == &char_type { + nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("\"", "", "\"")); + nested_tty::editors::list::PTYListController::for_node( &mut *et, None, Some('\"') ); + } else { + nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("{", ", ", "}")); + nested_tty::editors::list::PTYListController::for_node( &mut *et, Some(','), Some('}') ); + } + //*et = nested_tty::editors::edittree_make_list_edit(et.clone()); } } - ) + ) ); /* structure of Repr-Tree @@ -91,7 +105,7 @@ async fn main() { let edittree_digit = ctx.read().unwrap().setup_edittree(rt_digit.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); //--- - let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <List <Digit 16>>>") ); + let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <List Char>>") ); let edittree = ctx.read().unwrap().setup_edittree(rt_string.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); /* setup terminal diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index 6a69dbf..0be85f7 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -74,13 +74,13 @@ impl EditTree { editor: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())), cmd: SingletonBuffer::new(None), - close_char: SingletonBuffer::new(None), + close_char: SingletonBuffer::new(None), tree_nav: SingletonBuffer::new(None), }, ctx } } - + pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self { self.ctrl.editor.set(Some(editor)); self diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 89c2642..2b0bfff 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -175,7 +175,7 @@ impl ListEditor { } else { None } - } + } pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<EditTree>>>> { if let Some(idx) = self.cursor.get().idx { diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 64cf6a1..83ec4ec 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -139,7 +139,7 @@ impl PTYListController { split_char: Option<char>, close_char: Option<char> ) { - /* +/* { let ctx = node.ctx.as_ref(); let mut ctx = ctx.write().unwrap(); @@ -151,7 +151,7 @@ impl PTYListController { ctx.meta_chars.push(*c); } } - */ +*/ let editor = node.get_edit::<ListEditor>().unwrap(); let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.disp.depth.clone() ))); diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index eee1b74..3133edd 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -61,6 +61,7 @@ pub fn edittree_make_digit_view( node } + /* pub fn edittree_make_seq_view( mut node: EditTree @@ -84,27 +85,3 @@ pub fn edittree_make_seq_view( node } */ - -pub fn edittree_make_list_edit( - mut node: EditTree -) -> EditTree { - list::PTYListStyle::for_node( &mut node, ("(", "", ")") ); - list::PTYListController::for_node( &mut node, None, None ); - node -} -/* -pub fn edittree_make_tty_view( - et: EditTree -) -> EditTree { - if et.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { - node_make_char_view( node ) - } else if et.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") { - node_make_seq_view( node ) - } else if et.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") { - node_make_list_edit( node ) - } else { - eprintln!("couldnt add view"); - node - } -} -*/ From 647a5d77b688feafcd73d1da12bd8b7bee4006e1 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 18 Jan 2024 21:34:14 +0100 Subject: [PATCH 27/75] list: reactivate item creation on split --- lib-nested-core/src/editors/list/editor.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 2b0bfff..f0e7cb7 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -307,8 +307,14 @@ impl ListEditor { self.nexd(); let mut b = item.ctrl.spillbuf.write().unwrap(); -/* TODO - let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap(); + + let rt = ReprTree::new_arc(self.typ.clone()); + let new_edittree = self.ctx.read().unwrap() + .setup_edittree( + rt, + self.depth.map(|d| d+1) + ); + let mut tail_node = new_edittree.write().unwrap(); tail_node.goto(TreeCursor::home()); for node in b.iter() { @@ -316,7 +322,7 @@ impl ListEditor { .send_cmd_obj( ReprTree::new_leaf( Context::parse(&self.ctx, "NestedNode"), - SingletonBuffer::<NestedNode>::new( + SingletonBuffer::<EditTree>::new( node.read().unwrap().clone() ).get_port().into() ) @@ -331,11 +337,12 @@ impl ListEditor { if cur.tree_addr.len() > 1 { tail_node.dn(); } + drop(tail_node); self.insert( - Arc::new(RwLock::new(tail_node)) + new_edittree ); -*/ + } else { self.up(); self.listlist_split(); From 73d457ba24f3008836ce2ab6886ab5b9162720d4 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 10 Feb 2024 23:21:11 +0100 Subject: [PATCH 28/75] fix dependencies in pty-server & display-server-tty --- display-server-tty/Cargo.toml | 5 +++-- pty-server/Cargo.toml | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/display-server-tty/Cargo.toml b/display-server-tty/Cargo.toml index 4d933da..3c5d783 100644 --- a/display-server-tty/Cargo.toml +++ b/display-server-tty/Cargo.toml @@ -1,11 +1,12 @@ [package] authors = ["Michael Sippel <micha@fragmental.art>"] -name = "display_server" +name = "display-server-tty" version = "0.1.0" edition = "2018" [dependencies] -nested = { path = "../../nested" } +nested = { path = "../lib-nested-core" } +nested-tty = { path = "../lib-nested-tty" } termion = "1.5.5" cgmath = { version = "0.18.0", features = ["serde"] } serde = { version = "1.0", features = ["serde_derive"] } diff --git a/pty-server/Cargo.toml b/pty-server/Cargo.toml index 2b1ca1d..86e08e0 100644 --- a/pty-server/Cargo.toml +++ b/pty-server/Cargo.toml @@ -1,11 +1,12 @@ [package] authors = ["Michael Sippel <micha@fragmental.art>"] -name = "ansi_parser" +name = "pty-server" version = "0.1.0" edition = "2018" [dependencies] -nested = { path = "../../nested" } +nested = { path = "../lib-nested-core" } +nested-tty = { path = "../lib-nested-tty" } cgmath = { version = "0.18.0", features = ["serde"] } serde = { version = "1.0", features = ["serde_derive"] } bincode = "1.3.3" From 77d9e64531f788122043b6525086de4e78c363a8 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 10 Mar 2024 14:04:08 +0100 Subject: [PATCH 29/75] add notes, formatting, shallow simplifications --- examples/tty-02-node/src/main.rs | 79 ++++++++++++------- lib-nested-core/src/edit_tree/nav.rs | 2 +- lib-nested-core/src/edit_tree/node.rs | 7 +- lib-nested-core/src/editors/char/mod.rs | 6 ++ lib-nested-core/src/editors/integer/editor.rs | 33 -------- lib-nested-core/src/editors/list/cmd.rs | 1 + lib-nested-core/src/repr_tree/mod.rs | 4 + lib-nested-tty/src/editors/list.rs | 6 +- 8 files changed, 69 insertions(+), 69 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 1bafa37..8bfdaca 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -40,26 +40,31 @@ async fn main() { ctx.write().unwrap().meta_chars.push(','); ctx.write().unwrap().meta_chars.push('\"'); + ctx.write().unwrap().meta_chars.push('}'); + + // Define a hook which is executed when a new editTree of type `t` is created. + // this will setup the display and navigation elements of the editor. + // It provides the necessary bridge to the rendering- & input-backend. ctx.write().unwrap().set_edittree_hook( Arc::new( move |et: Arc<RwLock<EditTree>>, t: laddertypes::TypeTerm| { + let mut et = et.write().unwrap(); + if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) { - let mut et = et.write().unwrap(); *et = nested_tty::editors::edittree_make_char_view(et.clone()); } else if let Ok(σ) = laddertypes::unify(&t, &digit_type) { - let mut et = et.write().unwrap(); *et = nested_tty::editors::edittree_make_digit_view(et.clone()); } else if let Ok(σ) = laddertypes::unify(&t, &posint_type) { - let mut et = et.write().unwrap(); nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("0d", "", "")); nested_tty::editors::list::PTYListController::for_node( &mut *et, None, None ); } else if let Ok(σ) = laddertypes::unify(&t, &list_type) { - let mut et = et.write().unwrap(); let item_type = σ.get( &laddertypes::TypeID::Var(item_tyid) ).unwrap(); - if item_type == &char_type { + + // choose style based on element type + if *item_type == char_type { nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("\"", "", "\"")); nested_tty::editors::list::PTYListController::for_node( &mut *et, None, Some('\"') ); } else { @@ -97,16 +102,23 @@ async fn main() { rt_digit.write().unwrap() .insert_leaf( vec![ Context::parse(&ctx, "Char") ].into_iter(), - SingletonBuffer::new('x').get_port().into() + SingletonBuffer::new('4').get_port().into() ); /* setup TTY-Display for DigitEditor */ - let edittree_digit = ctx.read().unwrap().setup_edittree(rt_digit.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); + let edittree_digit = ctx.read().unwrap() + .setup_edittree( + rt_digit + .read().unwrap() + .descend( Context::parse(&ctx, "Char") ).unwrap() + .clone(), + r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); //--- - let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <List Char>>") ); - let edittree = ctx.read().unwrap().setup_edittree(rt_string.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); + let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <Digit 10>>") ); + let edittree = ctx.read().unwrap() + .setup_edittree(rt_string.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); /* setup terminal */ @@ -125,28 +137,39 @@ async fn main() { let compositor = TerminalCompositor::new(app.port.inner()); // add some views to the display compositor - compositor.write().unwrap().push( - nested_tty::make_label("Hello World") - .map_item(|p, a| { - a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) - }) - .offset(Vector2::new(5, 0)), - ); - compositor.write().unwrap().push( edittree_digit.read().unwrap().display_view().offset(Vector2::new(0,2)) ); + { + let mut comp = compositor.write().unwrap(); - let label = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); - compositor - .write() - .unwrap() - .push(nested_tty::make_label(&label).offset(Vector2::new(0, 1))); + comp.push( + nested_tty::make_label("Hello World") + .map_item(|p, a| { + a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) + }) + .offset(Vector2::new(5, 0)), + ); - compositor.write().unwrap().push( edittree.read().unwrap().display_view().offset(Vector2::new(0,4)) ); + comp.push( + edittree_digit.read().unwrap().display_view() + .offset(Vector2::new(0,2)) + ); - let label = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type()); - compositor - .write() - .unwrap() - .push(nested_tty::make_label(&label).offset(Vector2::new(0, 3))); + let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); + comp.push( + nested_tty::make_label(&label_str) + .offset(Vector2::new(0, 1)) + ); + + comp.push( + edittree.read().unwrap().display_view() + .offset(Vector2::new(0,4)) + ); + + let label_str = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type()); + comp.push( + nested_tty::make_label(&label_str) + .offset(Vector2::new(0, 3)) + ); + } /* write the changes in the view of `term_port` to the terminal */ diff --git a/lib-nested-core/src/edit_tree/nav.rs b/lib-nested-core/src/edit_tree/nav.rs index a47204d..a8dc371 100644 --- a/lib-nested-core/src/edit_tree/nav.rs +++ b/lib-nested-core/src/edit_tree/nav.rs @@ -38,7 +38,7 @@ pub enum TreeNavCmd { pub trait TreeNav { /* CORE - */ + */ fn get_cursor(&self) -> TreeCursor { TreeCursor::default() } diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index 0be85f7..8b5a8a6 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -32,7 +32,9 @@ pub struct EdittreeControl { Option< Arc<dyn Any + Send + Sync> > >, - pub spillbuf: Arc<RwLock< Vec< Arc<RwLock< EditTree >> > >>, + pub spillbuf: Arc<RwLock< + Vec< Arc<RwLock< EditTree >> > + >>, /// commander & navigation pub cmd: SingletonBuffer< @@ -47,9 +49,6 @@ pub struct EdittreeControl { >, } -/* - * TODO: rename to EditNode - */ #[derive(Clone)] pub struct EditTree { /// context diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 3b3c1ff..d6a4d07 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -31,10 +31,15 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { { let ctx = ctx.clone(); move |rt, σ| { + if let Some(v) = rt.read().unwrap().get_view::<dyn SingletonView<Item = char>>() { + eprintln!("prev value: {}", v.get()); + } + /* Create EditTree object */ let mut edittree_char = CharEditor::new_edit_tree( ctx.clone(), + SingletonBuffer::new('>'), r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() ); @@ -97,6 +102,7 @@ impl CharEditor { pub fn new_edit_tree( ctx0: Arc<RwLock<Context>>, + data: SingletonBuffer<char>, depth: OuterViewPort<dyn SingletonView<Item = usize>> ) -> EditTree { let data = SingletonBuffer::new('\0'); diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index 0a911c9..934888a 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -185,39 +185,6 @@ pub struct PosIntEditor { impl PosIntEditor { pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self { - /* - let mut node = Context::make_node( - &ctx, - Context::parse(&ctx, format!("<List <Digit {}>>", radix).as_str()), - r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() - ).unwrap(); - - // Set Type - node.data = ReprTree::ascend( - &node.data.clone(), - TypeTerm::App(vec![ - TypeTerm::TypeID(ctx.read().unwrap().get_typeid("PosInt").unwrap()), - TypeTerm::Num(radix as i64).into(), - TypeTerm::TypeID(ctx.read().unwrap().get_typeid("BigEndian").unwrap()) - ] - )); - */ -/* - PTYListController::for_node( &mut node, Some(' '), None ); - PTYListStyle::for_node( &mut node, - ( - match radix { - 2 => "0b".into(), - 8 => "0o".into(), - 10 => "0d".into(), - 16 => "0x".into(), - _ => "".into() - }, - "".into(), - "".into() - ) - ); -*/ PosIntEditor { radix, digits: EditTree::new( diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs index 82b5023..4c37ae0 100644 --- a/lib-nested-core/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -22,6 +22,7 @@ pub enum ListCmd { } impl ListCmd { + // note: cant use Into becaue of ctx (maybe global typedict?) pub fn into_repr_tree(self, ctx: &Arc<RwLock<Context>>) -> Arc<RwLock<ReprTree>> { let buf = r3vi::buffer::singleton::SingletonBuffer::new(self); ReprTree::new_leaf( diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 1f5ce63..3ea0c0c 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -24,6 +24,8 @@ pub struct ReprTree { branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>, } +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + impl std::fmt::Debug for ReprTree { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f, "| type: {:?}", self.type_tag)?; @@ -36,6 +38,8 @@ impl std::fmt::Debug for ReprTree { } } +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + impl ReprTree { pub fn new(type_tag: impl Into<TypeTerm>) -> Self { ReprTree { diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 83ec4ec..3affc68 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -190,15 +190,15 @@ impl PTYListController { } pub fn handle_meta_char(&mut self, c: char, child_close_char: Option<char>) -> TreeNavResult { - eprintln!("handle meta char: got '{}', child_close={:?}, self.close={:?}, split={:?}", c, child_close_char, self.close_char, self.split_char); +// eprintln!("handle meta char: got '{}', child_close={:?}, self.close={:?}, split={:?}", c, child_close_char, self.close_char, self.split_char); let mut e = self.editor.write().unwrap(); let cur = e.cursor.get(); - + if Some(c) == self.split_char // || Some(c) == child_close_char { e.listlist_split(); - eprintln!("done listlist split"); + // eprintln!("done listlist split"); TreeNavResult::Continue } else if Some(c) == child_close_char { e.goto(TreeCursor::none()); From d7d0a46c7beb8962fb1398d757317b75979ab903 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 10 Mar 2024 16:17:24 +0100 Subject: [PATCH 30/75] move digit into separate module --- examples/tty-02-node/src/main.rs | 7 +- lib-nested-core/src/editors/integer/ctx.rs | 37 +--- lib-nested-core/src/editors/integer/editor.rs | 160 +----------------- lib-nested-core/src/editors/integer/mod.rs | 2 +- lib-nested-core/src/editors/mod.rs | 1 + lib-nested-tty/src/editors/mod.rs | 2 +- 6 files changed, 16 insertions(+), 193 deletions(-) diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index 8bfdaca..b44d2bf 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -29,7 +29,8 @@ async fn main() { let ctx = Arc::new(RwLock::new(Context::new())); nested::editors::char::init_ctx( ctx.clone() ); - nested::editors::integer::editor::init_ctx( ctx.clone() ); + nested::editors::digit::init_ctx( ctx.clone() ); + nested::editors::integer::init_ctx( ctx.clone() ); nested::editors::list::init_ctx( ctx.clone() ); let char_type = Context::parse(&ctx, "Char"); @@ -85,9 +86,9 @@ async fn main() { * / | \ * / | \ * / | \ - * u32 [ EditTree ] Char + * u32 EditTree Char * - Editor \ - * - Display [ EditTree ] + * - Display EditTree * / | \ - Editor * / | \ - Display * TTY PixelBuf SDF / | \ diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 86875d0..b8bfac2 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -15,39 +15,8 @@ use { std::sync::{Arc, RwLock} }; -pub fn init_ctx(ctx: &mut Context) { +pub fn init_ctx(ctx: Arc<RwLock<Context>>) { /* - ctx.add_typename("MachineInt".into()); - ctx.add_typename("u32".into()); - ctx.add_typename("u64".into()); - ctx.add_typename("LittleEndian".into()); - ctx.add_typename("BigEndian".into()); - - ctx.add_node_ctor( - "Digit", Arc::new( - |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { - match ty { - TypeTerm::App(args) => { - if args.len() > 1 { - match args[1] { - TypeTerm::Num(radix) => { - let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(depth); - Some( - node - ) - }, - _ => None - } - } else { - None - } - } - _ => None - } - } - ) - ); - ctx.add_list_typename("PosInt".into()); let pattern = MorphismTypePattern { src_tyid: ctx.get_typeid("List"), @@ -127,7 +96,8 @@ pub fn init_ctx(ctx: &mut Context) { } ) ); -*/ + */ + /* ctx.add_typename("Date".into()); ctx.add_typename("ISO-8601".into()); ctx.add_typename("TimeSince".into()); @@ -137,5 +107,6 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_typename("Duration".into()); ctx.add_typename("Seconds".into()); ctx.add_typename("ℕ".into()); + */ } diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs index 934888a..4fdfe23 100644 --- a/lib-nested-core/src/editors/integer/editor.rs +++ b/lib-nested-core/src/editors/integer/editor.rs @@ -12,7 +12,11 @@ use { }, laddertypes::{TypeTerm}, crate::{ - editors::{list::{ListCmd}, ObjCommander}, + editors::{ + digit::DigitEditor, + list::{ListCmd}, + ObjCommander + }, repr_tree::{Context, ReprTree}, edit_tree::{EditTree, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}}, }, @@ -22,160 +26,6 @@ use { cgmath::{Point2} }; - -pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { - - // todo: proper scoping of Radix variable - ctx.write().unwrap().add_varname("Radix"); - let morphtype = - crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<Digit Radix>"), - dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree") - }; - - ctx.write().unwrap() - .morphisms - .add_morphism( - morphtype, - { - let ctx = ctx.clone(); - move |rt, σ| { - let radix = - match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { - Some(TypeTerm::Num(n)) => *n as u32, - _ => 0 - }; - - /* Create EditTree object - */ - let mut edittree_digit = DigitEditor::new( - ctx.clone(), - radix - ).into_node( - r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() - ); - - /* Insert EditTree into ReprTree - */ - let mut rt = rt.write().unwrap(); - rt.insert_leaf( - vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - SingletonBuffer::new( Arc::new(RwLock::new(edittree_digit)) ).get_port().into() - ); - } - } - ); -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct DigitEditor { - ctx: Arc<RwLock<Context>>, - radix: u32, - data: SingletonBuffer<Option<char>>, - msg: VecBuffer<Message>, -} - -impl ObjCommander for DigitEditor { - fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { - let cmd_obj = cmd_obj.read().unwrap(); - let cmd_type = cmd_obj.get_type().clone(); - - if cmd_type == Context::parse(&self.ctx, "Char") { - if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() { - let c = cmd_view.get(); - - self.msg.clear(); - - if self.ctx.read().unwrap().meta_chars.contains(&c) { - return TreeNavResult::Exit; - - } else if c.to_digit(self.radix).is_none() { - /* in case the character c is not in the range of digit-chars, - add a message to the diagnostics view - */ -/* - let message = IndexBuffer::from_iter(vec![ - (Point2::new(1, 0), make_label("invalid digit '")), - (Point2::new(2, 0), make_label(&format!("{}", c)) - .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))), - (Point2::new(3, 0), make_label("'")) - ]); - - self.msg.push(crate::diagnostics::make_error(message.get_port().flatten())); -*/ - - self.data.set(Some(c)); - } else { - self.data.set(Some(c)); - } - } - } - - TreeNavResult::Continue - } -} - -impl DigitEditor { - pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self { - DigitEditor { - ctx, - radix, - data: SingletonBuffer::new(None), - msg: VecBuffer::new(), - } - } - - pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree { - let data = self.get_data(); - let editor = Arc::new(RwLock::new(self)); - let ed = editor.write().unwrap(); - let r = ed.radix; - - EditTree::new(ed.ctx.clone(), depth) - .set_editor(editor.clone()) - .set_cmd(editor.clone()) - .set_diag( - ed.msg.get_port().to_sequence() - ) - } - - pub fn attach_to(&mut self, source: OuterViewPort<dyn SingletonView<Item = u32>>) { - /* - source.add_observer( - Arc::new(NotifyFnObserver::new(|_msg| { - self.data.set( source.get() ) - })) - ); - */ - } - - pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Result<u32, char>>> { - let radix = self.radix; - self.data.get_port().map(move |c| - if let Some(d) = c.unwrap_or('?').to_digit(radix) { - Ok(d) - } else { - Err(c.unwrap_or('?')) - } - ) - } - - pub fn get_type(&self) -> TypeTerm { - TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap()) - } - - pub fn get_data(&self) -> Arc<RwLock<ReprTree>> { - ReprTree::ascend( - &ReprTree::new_leaf( - self.ctx.read().unwrap().type_term_from_str("<Seq u32>").unwrap(), - self.get_data_port().into() - ), - self.get_type() - ) - } -} - pub struct PosIntEditor { radix: u32, digits: EditTree, diff --git a/lib-nested-core/src/editors/integer/mod.rs b/lib-nested-core/src/editors/integer/mod.rs index bdbf565..70b0759 100644 --- a/lib-nested-core/src/editors/integer/mod.rs +++ b/lib-nested-core/src/editors/integer/mod.rs @@ -5,7 +5,7 @@ pub mod ctx; pub use { add::Add, - editor::{DigitEditor, PosIntEditor}, + editor::PosIntEditor, radix::RadixProjection, ctx::init_ctx }; diff --git a/lib-nested-core/src/editors/mod.rs b/lib-nested-core/src/editors/mod.rs index 3a720c3..4de5274 100644 --- a/lib-nested-core/src/editors/mod.rs +++ b/lib-nested-core/src/editors/mod.rs @@ -4,6 +4,7 @@ pub mod list; //pub mod sum; pub mod char; +pub mod digit; pub mod integer; //pub mod typeterm; diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 3133edd..8194268 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -44,7 +44,7 @@ pub fn edittree_make_digit_view( .write().unwrap() .insert_branch(ReprTree::new_leaf( Context::parse(&node.ctx, "TerminalView"), - node.get_edit::< nested::editors::integer::DigitEditor >() + node.get_edit::< nested::editors::digit::DigitEditor >() .unwrap() .read() .unwrap() From 03dc9f113321f369fc0a115a21e7b31cd99339a2 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 10 Mar 2024 19:27:51 +0100 Subject: [PATCH 31/75] add ReprTreeExt trait for Arc<Rwlock<>> --- lib-nested-core/src/repr_tree/mod.rs | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 3ea0c0c..4ce5391 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -38,6 +38,54 @@ impl std::fmt::Debug for ReprTree { } } +pub trait ReprTreeExt { + fn get_type(&self) -> TypeTerm; + + fn insert_leaf(&mut self, type_ladder: impl Iterator<Item = TypeTerm>, port: AnyOuterViewPort); + fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>); + + fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>; + fn descend_ladder(&self, ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>; + + fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>; + fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>; + fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>; +} + +impl ReprTreeExt for Arc<RwLock<ReprTree>> { + fn get_type(&self) -> TypeTerm { + self.read().unwrap().get_type().clone() + } + + fn insert_leaf(&mut self, type_ladder: impl Iterator<Item = TypeTerm>, port: AnyOuterViewPort) { + self.write().unwrap().insert_leaf(type_ladder, port) + } + + fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { + self.write().unwrap().insert_branch(repr) + } + + fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + self.read().unwrap().descend(target_type) + } + + fn descend_ladder(&self, ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + ReprTree::descend_ladder(self, ladder) + } + + fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { + self.read().unwrap().view_char() + } + + fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> { + self.read().unwrap().view_u8() + } + + fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { + self.read().unwrap().view_u64() + } +} + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> impl ReprTree { @@ -108,6 +156,10 @@ impl ReprTree { self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available") } + pub fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> { + self.get_port::<dyn SingletonView<Item = u8>>().expect("no u8-view available") + } + pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available") } From 658f5c10005d6798df599a39ee4d5877e9653186 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 15 Mar 2024 18:54:25 +0100 Subject: [PATCH 32/75] refactor ReprTree - ReprLeaf with In- & Out-Ports - Optional Buffers --- examples/tty-02-node/src/main.rs | 95 +++-- lib-nested-core/src/editors/char/mod.rs | 30 +- lib-nested-core/src/editors/digit/cmd.rs | 52 +++ lib-nested-core/src/editors/digit/ctx.rs | 149 +++++++ lib-nested-core/src/editors/digit/editor.rs | 89 ++++ lib-nested-core/src/editors/digit/mod.rs | 8 + lib-nested-core/src/editors/list/cmd.rs | 7 +- lib-nested-core/src/editors/list/ctx.rs | 15 +- lib-nested-core/src/editors/list/editor.rs | 30 +- lib-nested-core/src/repr_tree/context.rs | 42 +- lib-nested-core/src/repr_tree/mod.rs | 436 ++++++++++++++------ lib-nested-core/src/repr_tree/morphism.rs | 28 +- lib-nested-core/src/repr_tree/tests.rs | 168 ++++++++ lib-nested-tty/src/edit_tree/keymap.rs | 20 +- lib-nested-tty/src/editors/list.rs | 8 +- lib-nested-tty/src/editors/mod.rs | 8 +- lib-nested-tty/src/lib.rs | 3 +- 17 files changed, 946 insertions(+), 242 deletions(-) create mode 100644 lib-nested-core/src/editors/digit/cmd.rs create mode 100644 lib-nested-core/src/editors/digit/ctx.rs create mode 100644 lib-nested-core/src/editors/digit/editor.rs create mode 100644 lib-nested-core/src/editors/digit/mod.rs create mode 100644 lib-nested-core/src/repr_tree/tests.rs diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index b44d2bf..7e40c63 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -8,17 +8,19 @@ use { cgmath::Vector2, nested::{ editors::ObjCommander, - repr_tree::{Context, ReprTree}, + repr_tree::{Context, ReprTree, ReprTreeExt}, edit_tree::{EditTree} }, nested_tty::{ DisplaySegment, TTYApplication, TerminalCompositor, TerminalStyle, TerminalView, - TerminalAtom + TerminalAtom, TerminalEvent }, r3vi::{ buffer::{singleton::*, vec::*}, + view::{port::UpdateTask} }, +// termion::{}, std::sync::{Arc, RwLock}, }; @@ -48,8 +50,8 @@ async fn main() { // It provides the necessary bridge to the rendering- & input-backend. ctx.write().unwrap().set_edittree_hook( Arc::new( - move |et: Arc<RwLock<EditTree>>, t: laddertypes::TypeTerm| { - let mut et = et.write().unwrap(); + move |et: &mut EditTree, t: laddertypes::TypeTerm| { +// let mut et = et.write().unwrap(); if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) { *et = nested_tty::editors::edittree_make_char_view(et.clone()); @@ -95,31 +97,49 @@ async fn main() { * / | \ * TTY PixelBuf SDF */ - let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); /* add initial representation * <Digit 16> ~ Char */ - rt_digit.write().unwrap() - .insert_leaf( - vec![ Context::parse(&ctx, "Char") ].into_iter(), - SingletonBuffer::new('4').get_port().into() - ); + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + /* furthermore, setup projections to and from u8 value, + * this synchronizes the buffers + */ + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "<Digit 16>~Char"), + &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8") + ); /* setup TTY-Display for DigitEditor + * + * `setup_edittree` will setup the projection + * Char -> Char~EditTree + * and call the hook defined above with `set_edittree_hook()` + * */ let edittree_digit = ctx.read().unwrap() .setup_edittree( - rt_digit - .read().unwrap() - .descend( Context::parse(&ctx, "Char") ).unwrap() - .clone(), - r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); + rt_digit.clone(), + r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() + ); + + let mut digit_u8_buffer = rt_digit + .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() + .singleton_buffer::<u8>(); //--- - let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <Digit 10>>") ); - let edittree = ctx.read().unwrap() - .setup_edittree(rt_string.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); + let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); + + let edittree_list = ctx.read().unwrap() + .setup_edittree( + rt_string.clone(), + r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); /* setup terminal */ @@ -127,9 +147,22 @@ async fn main() { /* event handler */ let ctx = ctx.clone(); - let et1 = edittree.clone(); + let mut editors = Vec::new(); + editors.push(edittree_digit.clone()); + editors.push(edittree_list.clone()); + + let edit_select = Arc::new(RwLock::new(0)); move |ev| { - et1.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); + match ev { + TerminalEvent::Input(termion::event::Event::Key(termion::event::Key::Char('\t'))) => { + let mut i = edit_select.write().unwrap(); + *i = (*i + 1) % editors.len(); + } + _ => { + let i = edit_select.read().unwrap(); + editors[*i].get().send_cmd_obj(ev.to_repr_tree(&ctx)); + } + } } }); @@ -150,25 +183,37 @@ async fn main() { ); comp.push( - edittree_digit.read().unwrap().display_view() - .offset(Vector2::new(0,2)) + edittree_digit.get().display_view() + .offset(Vector2::new(2,2)) ); let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); comp.push( nested_tty::make_label(&label_str) + .map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) .offset(Vector2::new(0, 1)) ); comp.push( - edittree.read().unwrap().display_view() - .offset(Vector2::new(0,4)) + digit_u8_buffer.get_port().map( + |d| nested_tty::make_label(&format!("Digit={}", d)) + ) + .to_grid() + .flatten() + .offset(Vector2::new(2,3)) + ); + + + comp.push( + edittree_list.get().display_view() + .offset(Vector2::new(2,6)) ); let label_str = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type()); comp.push( nested_tty::make_label(&label_str) - .offset(Vector2::new(0, 3)) + .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) + .offset(Vector2::new(0, 5)) ); } diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index d6a4d07..8b587ad 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -3,12 +3,13 @@ use { view::{ OuterViewPort, singleton::*, + port::UpdateTask }, buffer::singleton::* }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, ReprTree}, + repr_tree::{Context, ReprTree, ReprTreeExt}, edit_tree::{EditTree, TreeNavResult}, editors::ObjCommander, }, @@ -17,7 +18,6 @@ use { }; pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { - let morphtype = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "Char"), @@ -37,19 +37,25 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { /* Create EditTree object */ - let mut edittree_char = CharEditor::new_edit_tree( + rt.view_char().0.update(); + + let char_buf = rt.write().unwrap().singleton_buffer::<char>().unwrap(); + + eprintln!("make edittree: char val = {}", char_buf.get()); + let mut edittree = CharEditor::new_edit_tree( ctx.clone(), - SingletonBuffer::new('>'), + char_buf, r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() ); - /* Insert EditTree into ReprTree - */ - let mut rt = rt.write().unwrap(); - rt.insert_leaf( - vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - SingletonBuffer::new( Arc::new(RwLock::new( edittree_char )) ).get_port().into() - ); + eprintln!("insert Char~EditTree"); + rt.write().unwrap() + .insert_branch( + ReprTree::from_singleton_buffer( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new(edittree) + ) + ); } } ); @@ -105,7 +111,7 @@ impl CharEditor { data: SingletonBuffer<char>, depth: OuterViewPort<dyn SingletonView<Item = usize>> ) -> EditTree { - let data = SingletonBuffer::new('\0'); + //let data = SingletonBuffer::new('\0'); let ctx = ctx0.clone(); let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() })); diff --git a/lib-nested-core/src/editors/digit/cmd.rs b/lib-nested-core/src/editors/digit/cmd.rs new file mode 100644 index 0000000..ae56f9f --- /dev/null +++ b/lib-nested-core/src/editors/digit/cmd.rs @@ -0,0 +1,52 @@ + +use { + r3vi::view::singleton::SingletonView, + crate::{ + repr_tree::{ReprTree, Context}, + edit_tree::{TreeNav, TreeNavResult}, + editors::{ObjCommander, digit::DigitEditor} + }, + + std::sync::{Arc, RwLock} +}; + +impl ObjCommander for DigitEditor { + fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { + let cmd_obj = cmd_obj.read().unwrap(); + let cmd_type = cmd_obj.get_type().clone(); + + if cmd_type == Context::parse(&self.ctx, "Char") { + if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() { + let c = cmd_view.get(); + + self.msg.clear(); + + if self.ctx.read().unwrap().meta_chars.contains(&c) { + return TreeNavResult::Exit; + + } else if c.to_digit(self.radix).is_none() { + /* in case the character c is not in the range of digit-chars, + add a message to the diagnostics view + */ +/* + let message = IndexBuffer::from_iter(vec![ + (Point2::new(1, 0), make_label("invalid digit '")), + (Point2::new(2, 0), make_label(&format!("{}", c)) + .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))), + (Point2::new(3, 0), make_label("'")) + ]); + + self.msg.push(crate::diagnostics::make_error(message.get_port().flatten())); +*/ + + self.data.set(c); + } else { + self.data.set(c); + } + } + } + + TreeNavResult::Continue + } +} + diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs new file mode 100644 index 0000000..bb022a7 --- /dev/null +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -0,0 +1,149 @@ + +use { + laddertypes::TypeTerm, + r3vi::{ + buffer::singleton::SingletonBuffer, + view::{ + AnyOuterViewPort, + singleton::* + } + }, + crate::{ + repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, + editors::digit::DigitEditor, + }, + std::sync::{Arc, RwLock} +}; + +pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { + + // todo: proper scoping of Radix variable + ctx.write().unwrap().add_varname("Radix"); + + let morphtype = + crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<Digit Radix>"), + dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree") + }; + + ctx.write().unwrap() + .morphisms + .add_morphism( + morphtype, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let radix = + match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + Some(TypeTerm::Num(n)) => *n as u32, + _ => 0 + }; + + /* Create EditTree object + */ + let mut edittree = DigitEditor::new( + ctx.clone(), + radix, + src_rt.descend( + Context::parse(&ctx, "Char") + ).unwrap() + .singleton_buffer::<char>() + ).into_node( + r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + ); + + src_rt.write().unwrap() + .insert_branch( + ReprTree::from_singleton_buffer( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new(edittree) + ) + ); + } + } + ); + + let morphtype = + crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<Digit Radix>~Char"), + dst_type: Context::parse(&ctx, "<Digit Radix>~ℤ_256~machine::UInt8") + }; + + ctx.write().unwrap() + .morphisms + .add_morphism( + morphtype, + { + let ctx = ctx.clone(); + move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| { + /* infer radix from type + */ + let radix = + match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + Some(TypeTerm::Num(n)) => (*n) as u32, + _ => 0 + }; + + if radix <= 256 { + + if let Some(src_rt) = rt.descend(Context::parse(&ctx, "Char")) { + /* insert projected view into ReprTree + */ + let u8_view = + src_rt.view_char() + .map(move |c| c.to_digit(radix).unwrap_or(0) as u8); + + rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = u8>>( + Context::parse(&ctx, "ℤ_256~machine::UInt8").get_lnf_vec().into_iter(), + u8_view + ); + } else { + eprintln!("could not find required source representation: <Digit {}>~Char", radix); + } + } else { + eprintln!("radix too large ({})", radix); + } + } + } + ); + + + let morphtype = + crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<Digit Radix>~ℤ_256~machine::UInt8"), + dst_type: Context::parse(&ctx, "<Digit Radix>~Char") + }; + + ctx.write().unwrap().morphisms + .add_morphism(morphtype, { + let ctx = ctx.clone(); + move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| { + /* infer radix from type + */ + let radix = + match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + Some(TypeTerm::Num(n)) => (*n) as u32, + _ => 0 + }; + + if radix <= 256 { + /* insert projected view into ReprTree + */ + let char_view = + rt.descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")) + .unwrap() + .view_u8() + .map(move |digit| char::from_digit(digit as u32, radix).unwrap_or('?')); + + rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = char>>( + Context::parse(&ctx, "Char").get_lnf_vec().into_iter(), + char_view + ); + } else { + eprintln!("radix too large ({})", radix); + } + } + }); +} + + diff --git a/lib-nested-core/src/editors/digit/editor.rs b/lib-nested-core/src/editors/digit/editor.rs new file mode 100644 index 0000000..a73733b --- /dev/null +++ b/lib-nested-core/src/editors/digit/editor.rs @@ -0,0 +1,89 @@ + +use { + laddertypes::TypeTerm, + r3vi::{ + view::{OuterViewPort,singleton::*}, + buffer::{singleton::*, vec::*} + }, + crate::{ + repr_tree::{ReprTree, Context}, + edit_tree::{ + EditTree, + diagnostics::Message + } + }, + + std::sync::{Arc, RwLock} +}; + + +pub struct DigitEditor { + pub(super) ctx: Arc<RwLock<Context>>, + pub(super) radix: u32, + pub(super) data: SingletonBuffer<char>, + pub(super) msg: VecBuffer<Message>, +} + + +impl DigitEditor { + pub fn new(ctx: Arc<RwLock<Context>>, radix: u32, data: SingletonBuffer<char>) -> Self { + DigitEditor { + ctx, + radix, + data, + msg: VecBuffer::new(), + } + } + + pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree { + // let data = self.get_data(); + let editor = Arc::new(RwLock::new(self)); + let ed = editor.write().unwrap(); + let r = ed.radix; + + EditTree::new(ed.ctx.clone(), depth) + .set_editor(editor.clone()) + .set_cmd(editor.clone()) + .set_diag( + ed.msg.get_port().to_sequence() + ) + } + + pub fn attach_to(&mut self, source: OuterViewPort<dyn SingletonView<Item = u32>>) { + /* + source.add_observer( + Arc::new(NotifyFnObserver::new(|_msg| { + self.data.set( source.get() ) + })) + ); + */ + } + + pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Result<u32, char>>> { + let radix = self.radix; + self.data.get_port().map(move |c| + if let Some(d) = c.to_digit(radix) { + Ok(d) + } else { + Err(c) + } + ) + } + + pub fn get_type(&self) -> TypeTerm { + TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap()) + } +/* + pub fn get_data(&self) -> Arc<RwLock<ReprTree>> { + ReprTree::ascend( + &ReprTree::from_view( + self.ctx.read().unwrap().type_term_from_str("<Seq u32>").unwrap(), + self.get_data_port() + ), + self.get_type() + ) + } + */ +} + + diff --git a/lib-nested-core/src/editors/digit/mod.rs b/lib-nested-core/src/editors/digit/mod.rs new file mode 100644 index 0000000..980db26 --- /dev/null +++ b/lib-nested-core/src/editors/digit/mod.rs @@ -0,0 +1,8 @@ + +pub mod ctx; +pub mod cmd; +pub mod editor; + +pub use editor::DigitEditor; +pub use ctx::init_ctx; + diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs index 4c37ae0..bbdd19c 100644 --- a/lib-nested-core/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -24,10 +24,9 @@ pub enum ListCmd { impl ListCmd { // note: cant use Into becaue of ctx (maybe global typedict?) pub fn into_repr_tree(self, ctx: &Arc<RwLock<Context>>) -> Arc<RwLock<ReprTree>> { - let buf = r3vi::buffer::singleton::SingletonBuffer::new(self); - ReprTree::new_leaf( - Context::parse(ctx, "ListCmd"), - buf.get_port().into() + ReprTree::from_singleton_buffer( + Context::parse(ctx, "ListCmd"), + r3vi::buffer::singleton::SingletonBuffer::new(self) ) } } diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 0ef2180..3c3ae8f 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -2,7 +2,7 @@ use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::singleton::*}, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context}, + repr_tree::{Context, ReprTree}, editors::list::{ListEditor}//, PTYListController, PTYListStyle} }, std::sync::{Arc, RwLock} @@ -13,6 +13,7 @@ use { pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.write().unwrap().add_list_typename("List".into()); ctx.write().unwrap().add_varname("Item"); + let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Item>"), dst_type: Context::parse(&ctx, "<List Item>~EditTree") @@ -21,9 +22,10 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { mt, { let ctx = ctx.clone(); - move |rt, σ| { + move |src_rt, σ| { let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); if let Some( item_type ) = σ.get( &item_id ) { + let mut edittree_list = ListEditor::new( ctx.clone(), item_type.clone() @@ -31,10 +33,11 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() ); - let mut rt = rt.write().unwrap(); - rt.insert_leaf( - vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - SingletonBuffer::new( Arc::new(RwLock::new( edittree_list )) ).get_port().into() + src_rt.write().unwrap().insert_branch( + ReprTree::from_singleton_buffer( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new(edittree_list) + ) ); } else { eprintln!("no item type"); diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index f0e7cb7..00020e7 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -101,7 +101,6 @@ impl ListEditor { } pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree { - let data = self.get_data(); let ctx = self.ctx.clone(); self.depth = depth.clone(); @@ -155,7 +154,7 @@ impl ListEditor { |x| x.read().unwrap().clone() ) } - +/* pub fn get_data(&self) -> Arc<RwLock<ReprTree>> { let data_view = self.get_data_port(); ReprTree::new_leaf( @@ -163,7 +162,7 @@ impl ListEditor { data_view.into() ) } - +*/ pub fn get_item(&self) -> Option<EditTree> { if let Some(idx) = self.cursor.get().idx { let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; @@ -309,22 +308,23 @@ impl ListEditor { let mut b = item.ctrl.spillbuf.write().unwrap(); let rt = ReprTree::new_arc(self.typ.clone()); - let new_edittree = self.ctx.read().unwrap() + let edittree = self.ctx.read().unwrap() .setup_edittree( rt, self.depth.map(|d| d+1) ); - let mut tail_node = new_edittree.write().unwrap(); + + let mut tail_node = edittree.get_mut(); tail_node.goto(TreeCursor::home()); for node in b.iter() { tail_node .send_cmd_obj( - ReprTree::new_leaf( - Context::parse(&self.ctx, "NestedNode"), + ReprTree::from_singleton_buffer( + Context::parse(&self.ctx, "EditTree"), SingletonBuffer::<EditTree>::new( node.read().unwrap().clone() - ).get_port().into() + ) ) ); } @@ -340,7 +340,7 @@ impl ListEditor { drop(tail_node); self.insert( - new_edittree + edittree.value.clone() ); } else { @@ -376,11 +376,11 @@ impl ListEditor { let data = cur_editor.ctrl.spillbuf.read().unwrap(); for x in data.iter() { pxv_editor.send_cmd_obj( - ReprTree::new_leaf( - Context::parse(&self.ctx, "NestedNode"), + ReprTree::from_singleton_buffer( + Context::parse(&self.ctx, "EditTree"), SingletonBuffer::<EditTree>::new( x.read().unwrap().clone() - ).get_port().into() + ) ) ); } @@ -435,11 +435,11 @@ impl ListEditor { for x in data.iter() { cur_editor.send_cmd_obj( - ReprTree::new_leaf( - Context::parse(&self.ctx, "NestedNode"), + ReprTree::from_singleton_buffer( + Context::parse(&self.ctx, "EditTree"), SingletonBuffer::<EditTree>::new( x.read().unwrap().clone() - ).get_port().into() + ) ) ); } diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index ef07efe..abd23ff 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -2,7 +2,7 @@ use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ - repr_tree::{ReprTree, MorphismType, GenericReprTreeMorphism, MorphismBase}, + repr_tree::{ReprTree, ReprTreeExt, MorphismType, GenericReprTreeMorphism, MorphismBase}, edit_tree::EditTree }, std::{ @@ -29,7 +29,7 @@ pub struct Context { pub list_types: Vec< TypeID >, pub meta_chars: Vec< char >, - edittree_hook: Arc< dyn Fn(Arc<RwLock<EditTree>>, TypeTerm) + Send +Sync +'static >, + edittree_hook: Arc< dyn Fn(&mut EditTree, TypeTerm) + Send +Sync +'static >, /// recursion parent: Option<Arc<RwLock<Context>>>, @@ -64,7 +64,7 @@ impl Context { Context::with_parent(None) } - pub fn set_edittree_hook(&mut self, hook: Arc< dyn Fn(Arc<RwLock<EditTree>>, TypeTerm) + Send +Sync +'static >) { + pub fn set_edittree_hook(&mut self, hook: Arc< dyn Fn(&mut EditTree, TypeTerm) + Send +Sync +'static >) { self.edittree_hook = hook; } @@ -78,7 +78,7 @@ impl Context { pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> { let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() ))); - ctx.read().unwrap().morphisms.morph( rt.clone(), t ); + ctx.read().unwrap().morphisms.apply_morphism( rt.clone(), &TypeTerm::unit(), t ); rt } @@ -180,30 +180,32 @@ impl Context { &self, rt: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>> - ) -> Arc<RwLock<EditTree>> { + ) -> SingletonBuffer<EditTree> { let ladder = TypeTerm::Ladder(vec![ rt.read().unwrap().get_type().clone(), self.type_term_from_str("EditTree").expect("") ]); - - self.morphisms.morph( + + eprintln!("setp_edittree: apply morphism T -> T~EditTree"); + self.morphisms.apply_morphism( rt.clone(), + &rt.get_type(), &ladder ); - let new_edittree = rt - .read().unwrap() - .descend( - self.type_term_from_str("EditTree").expect("") - ).unwrap() - .read().unwrap() - .get_view::<dyn SingletonView<Item = Arc<RwLock<EditTree>> >>() - .unwrap() - .get(); - - (*self.edittree_hook)( new_edittree.clone(), rt.read().unwrap().get_type().clone() ); - - new_edittree + eprintln!("get repr-node of editTree"); + if let Some(new_edittree) = + rt.descend(self.type_term_from_str("EditTree").unwrap()) + { + let buf = new_edittree.singleton_buffer::<EditTree>(); + (*self.edittree_hook)( + &mut *buf.get_mut(), + rt.read().unwrap().get_type().clone() + ); + buf + } else { + unreachable!(); + } } } diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 4ce5391..816f6b7 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -1,27 +1,50 @@ pub mod context; pub mod morphism; +#[cfg(test)] +mod tests; + pub use { context::{Context}, morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase} }; use { - r3vi::view::{AnyOuterViewPort, OuterViewPort, View, singleton::*}, + r3vi::{ + view::{ + ViewPort, OuterViewPort, + AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, + port::UpdateTask, + View, + singleton::*, sequence::* + }, + buffer::{singleton::*, vec::*} + }, laddertypes::{TypeTerm}, std::{ collections::HashMap, sync::{Arc, RwLock}, + any::Any }, }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] -pub struct ReprTree { +pub struct ReprLeaf { + out_port: AnyViewPort, + in_port: AnyInnerViewPort, + data: Option< Arc<dyn Any + Send + Sync> >, + + /// keepalive for the observer that updates the buffer from in_port + keepalive: Option<Arc<dyn Any + Send + Sync>>, +} + +#[derive(Clone)] +pub struct ReprTree { type_tag: TypeTerm, - port: Option<AnyOuterViewPort>, branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>, + leaf: Option< ReprLeaf > } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -38,18 +61,282 @@ impl std::fmt::Debug for ReprTree { } } +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl ReprLeaf { + pub fn from_view<V>( src_port: OuterViewPort<V> ) -> Self + where V: View + ?Sized + 'static, + V::Msg: Clone + { + let mut in_port = ViewPort::<V>::new(); + in_port.attach_to(src_port); + + let mut buf_port = ViewPort::<V>::new(); + buf_port.attach_to(in_port.outer()); + + ReprLeaf { + keepalive: None, + in_port: in_port.inner().into(), + out_port: buf_port.into(), + data: None, + } + } + + pub fn attach_to<V>(&mut self, src_port: OuterViewPort<V>) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + self.in_port.clone() + .downcast::<V>().ok().unwrap() + .0.attach_to( src_port ); + } + + pub fn from_singleton_buffer<T>( buffer: SingletonBuffer<T> ) -> Self + where T: Clone + Send + Sync + 'static + { + let in_port = ViewPort::<dyn SingletonView<Item = T>>::new(); + ReprLeaf { + keepalive: Some(buffer.attach_to(in_port.outer())), + in_port: in_port.inner().into(), + out_port: buffer.get_port().0.into(), + data: Some(buffer.into_inner()) + } + } + + pub fn as_singleton_buffer<T>(&mut self) -> Option<SingletonBuffer<T>> + where T: Clone + Send + Sync + 'static + { + let sgl_port = self.get_port::< dyn SingletonView<Item = T> >().unwrap().0; + + let data_arc = + if let Some(data) = self.data.as_ref() { + data.clone().downcast::<RwLock<T>>().ok() + } else { + sgl_port.update(); + let value = sgl_port.outer().get_view().unwrap().get(); + eprintln!("make new data ARC from old value"); + Some(Arc::new(RwLock::new( value ))) + }; + + if let Some(data_arc) = data_arc { + self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); + let buf = SingletonBuffer { + value: data_arc, + port: sgl_port.inner() + }; + self.keepalive = Some(buf.attach_to( + self.in_port.0.clone() + .downcast::<dyn SingletonView<Item = T>>() + .ok().unwrap() + .outer() + )); + Some(buf) + } else { + None + } + } + + pub fn get_port<V>(&self) -> Option<OuterViewPort<V>> + where V: View + ?Sized + 'static, + V::Msg: Clone + { + self.out_port.clone().downcast::<V>().ok().map(|p| p.outer()) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl ReprTree { + pub fn new(type_tag: impl Into<TypeTerm>) -> Self { + ReprTree { + type_tag: type_tag.into(), + branches: HashMap::new(), + leaf: None + } + } + + pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> { + Arc::new(RwLock::new(Self::new(type_tag))) + } + + pub fn get_type(&self) -> &TypeTerm { + &self.type_tag + } + + pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { + self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone()); + } + + pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char ) -> Arc<RwLock<Self>> { + ReprTree::from_singleton_buffer( + Context::parse(ctx, "Char"), + SingletonBuffer::new(c) + ) + } + + pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> Arc<RwLock<Self>> + where V: View + ?Sized + 'static, + V::Msg: Clone + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_view(view)); + Arc::new(RwLock::new(rt)) + } + + pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> Arc<RwLock<Self>> + where T: Clone + Send + Sync + 'static + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_singleton_buffer(buf)); + Arc::new(RwLock::new(rt)) + } + + /// find, and if necessary, create corresponding path in repr-tree. + /// Attach src_port to input of that node + pub fn attach_leaf_to<V>( + &mut self, + mut type_ladder: impl Iterator<Item = TypeTerm>, + src_port: OuterViewPort<V> + ) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + if let Some(rung_type) = type_ladder.next() { + if let Some(next_repr) = self.branches.get(&rung_type) { + next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); + } else { + let mut next_repr = ReprTree::new(rung_type.clone()); + next_repr.attach_leaf_to(type_ladder, src_port); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } + } else { + if let Some(leaf) = self.leaf.as_mut() { + leaf.attach_to(src_port); + } else { + self.leaf = Some(ReprLeaf::from_view(src_port)); + } + } + } + + pub fn insert_leaf( + &mut self, + mut type_ladder: impl Iterator<Item = TypeTerm>, + leaf: ReprLeaf + ) { + if let Some(type_term) = type_ladder.next() { + if let Some(next_repr) = self.branches.get(&type_term) { + next_repr.write().unwrap().insert_leaf(type_ladder, leaf); + } else { + let mut next_repr = ReprTree::new(type_term.clone()); + next_repr.insert_leaf(type_ladder, leaf); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } + } else { + self.leaf = Some(leaf) + } + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + let dst_type = dst_type.into(); + assert!( dst_type.is_flat() ); + self.branches.get(&dst_type).cloned() + } + + pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + if let Some(first) = repr_ladder.next() { + let rt = rt.read().unwrap(); + repr_ladder.fold( + rt.descend_one(first), + |s, t| s?.descend(t)) + } else { + Some(rt.clone()) + } + } + + pub fn descend(rt: &Arc<RwLock<Self>>, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + ReprTree::descend_ladder(rt, dst_type.into().get_lnf_vec().into_iter()) + } + + pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> { + let mut n = Self::new(type_term); + n.insert_branch(rt.clone()); + Arc::new(RwLock::new(n)) + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn singleton_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<SingletonBuffer<T>> { + if let Some(leaf) = self.leaf.as_mut() { + leaf.as_singleton_buffer::<T>() + } else { + None + } + } + +/* + pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> Option<VecBuffer<T>> { + } +*/ + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> + where + V::Msg: Clone, + { + if let Some(leaf) = self.leaf.as_ref() { + leaf.get_port::<V>() + } else { + None + } + } + + pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>> + where + V::Msg: Clone, + { + self.get_port::<V>()? + .get_view() + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn view_seq<T: 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> { + self.get_port::<dyn SequenceView<Item = T>>().expect("no sequence-view available") + } + + pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { + self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available") + } + + pub fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> { + self.get_port::<dyn SingletonView<Item = u8>>().expect("no u8-view available") + } + + pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { + self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available") + } +} + + + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + pub trait ReprTreeExt { fn get_type(&self) -> TypeTerm; - fn insert_leaf(&mut self, type_ladder: impl Iterator<Item = TypeTerm>, port: AnyOuterViewPort); + fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf); fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>); - fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>; - fn descend_ladder(&self, ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>; fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>; fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>; fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>; + + fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>; +// fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>; } impl ReprTreeExt for Arc<RwLock<ReprTree>> { @@ -57,8 +344,8 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { self.read().unwrap().get_type().clone() } - fn insert_leaf(&mut self, type_ladder: impl Iterator<Item = TypeTerm>, port: AnyOuterViewPort) { - self.write().unwrap().insert_leaf(type_ladder, port) + fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf) { + self.write().unwrap().insert_leaf(type_ladder.into().get_lnf_vec().into_iter(), leaf) } fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { @@ -66,11 +353,7 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { } fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { - self.read().unwrap().descend(target_type) - } - - fn descend_ladder(&self, ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { - ReprTree::descend_ladder(self, ladder) + ReprTree::descend( self, target_type ) } fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { @@ -84,125 +367,16 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { self.read().unwrap().view_u64() } + + fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T> { + self.write().unwrap().singleton_buffer::<T>().expect("") + } +/* + fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T> { + self.read().unwrap().vec_buffer::<T>().expect("") + } + */ } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -impl ReprTree { - pub fn new(type_tag: impl Into<TypeTerm>) -> Self { - ReprTree { - type_tag: type_tag.into(), - port: None, - branches: HashMap::new(), - } - } - - pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> { - Arc::new(RwLock::new(Self::new(type_tag))) - } - - pub fn get_type(&self) -> &TypeTerm { - &self.type_tag - } - - pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char) -> Arc<RwLock<Self>> { - let buf = r3vi::buffer::singleton::SingletonBuffer::<char>::new(c); - ReprTree::new_leaf( - Context::parse(ctx, "Char"), - buf.get_port().into() - ) - } - - pub fn from_u64(ctx: &Arc<RwLock<Context>>, v: u64) -> Arc<RwLock<Self>> { - let buf = r3vi::buffer::singleton::SingletonBuffer::<u64>::new(v); - ReprTree::new_leaf( - Context::parse(ctx, "<MachineInt 64>"), - buf.get_port().into() - ) - } - - pub fn new_leaf(type_tag: impl Into<TypeTerm>, port: AnyOuterViewPort) -> Arc<RwLock<Self>> { - let mut tree = ReprTree::new(type_tag.into()); - tree.insert_leaf(vec![].into_iter(), port); - Arc::new(RwLock::new(tree)) - } - - pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { - self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone()); - } - - pub fn insert_leaf( - &mut self, - mut type_ladder: impl Iterator<Item = TypeTerm>, - port: AnyOuterViewPort, - ) { - if let Some(type_term) = type_ladder.next() { - if let Some(next_repr) = self.branches.get(&type_term) { - next_repr.write().unwrap().insert_leaf(type_ladder, port); - } else { - let mut next_repr = ReprTree::new(type_term.clone()); - next_repr.insert_leaf(type_ladder, port); - self.insert_branch(Arc::new(RwLock::new(next_repr))); - } - } else { - self.port = Some(port); - } - } - - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - - - pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { - self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available") - } - - pub fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> { - self.get_port::<dyn SingletonView<Item = u8>>().expect("no u8-view available") - } - - pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { - self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available") - } - - pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> - where - V::Msg: Clone, - { - Some( - self.port - .clone()? - .downcast::<V>() - .ok()? - ) - } - - pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>> - where - V::Msg: Clone, - { - self.get_port::<V>()? - .get_view() - } - - pub fn descend(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { - self.branches.get(&dst_type.into()).cloned() - } - - pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { - if let Some(first) = repr_ladder.next() { - let rt = rt.read().unwrap(); - repr_ladder.fold( - rt.descend(first), - |s, t| s?.read().unwrap().descend(t)) - } else { - Some(rt.clone()) - } - } - - pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> { - let mut n = Self::new(type_term); - n.insert_branch(rt.clone()); - Arc::new(RwLock::new(n)) - } -} - diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index 689cffc..64ea186 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -1,7 +1,8 @@ use { laddertypes::{TypeTerm, TypeID}, + r3vi::view::AnyOuterViewPort, crate::{ - repr_tree::{ReprTree}, + repr_tree::{ReprTree, ReprTreeExt, ReprLeaf}, }, std::{ sync::{Arc, RwLock}, @@ -20,8 +21,9 @@ pub struct MorphismType { #[derive(Clone)] pub struct GenericReprTreeMorphism { morph_type: MorphismType, - repr_tree_op: Arc< - dyn Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + setup_projection: Arc< + dyn Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) +// -> Result< ReprLeaf, () > + Send + Sync > } @@ -43,12 +45,15 @@ impl MorphismBase { pub fn add_morphism( &mut self, morph_type: MorphismType, - repr_tree_op: impl Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + Send + Sync + 'static + setup_projection: + impl Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) +// -> Result< ReprLeaf, () /* TODO: error */ > + + Send + Sync + 'static ) { self.morphisms.push( GenericReprTreeMorphism { morph_type, - repr_tree_op: Arc::new(repr_tree_op) + setup_projection: Arc::new(setup_projection) } ); } @@ -75,14 +80,15 @@ impl MorphismBase { None } - pub fn morph( + pub fn apply_morphism( &self, - repr_tree: Arc<RwLock<ReprTree>>, - target_type: &TypeTerm + mut repr_tree: Arc<RwLock<ReprTree>>, + src_type: &TypeTerm, + dst_type: &TypeTerm ) { - let t = repr_tree.read().unwrap().get_type().clone(); - if let Some((m, σ)) = self.find_morphism( &t, target_type ) { - (m.repr_tree_op)( repr_tree.clone(), &σ ); +// let t = repr_tree.read().unwrap().get_type().clone(); + if let Some((m, σ)) = self.find_morphism( &src_type, dst_type ) { + (m.setup_projection)( &mut repr_tree, &σ ); } else { eprintln!("could not find morphism"); } diff --git a/lib-nested-core/src/repr_tree/tests.rs b/lib-nested-core/src/repr_tree/tests.rs new file mode 100644 index 0000000..19fa23c --- /dev/null +++ b/lib-nested-core/src/repr_tree/tests.rs @@ -0,0 +1,168 @@ + +use { + r3vi::{ + buffer::singleton::{ + SingletonBuffer + }, + view::port::UpdateTask + }, + crate::{ + repr_tree::{Context, ReprTreeExt, ReprTree, ReprLeaf} + }, + std::sync::{Arc, RwLock} +}; + +#[test] +fn char_view() { + let ctx = Arc::new(RwLock::new(Context::new())); + crate::editors::digit::init_ctx( ctx.clone() ); + + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + //<><><><> + let mut digit_char_buffer = rt_digit + .descend( Context::parse(&ctx, "Char") ).unwrap() + .singleton_buffer::<char>(); + + assert_eq!( digit_char_buffer.get(), '5' ); + //<><><><> + + let digit_char_view = rt_digit + .descend(Context::parse(&ctx, "Char")).unwrap() + .view_char(); + + assert_eq!( digit_char_view.get_view().unwrap().get(), '5' ); + + + //<><><><> + // `Char-view` is correctly coupled to `char-buffer` + digit_char_buffer.set('2'); + assert_eq!( digit_char_view.get_view().unwrap().get(), '2' ); +} + +#[test] +fn digit_projection_char_to_u8() { + let ctx = Arc::new(RwLock::new(Context::new())); + crate::editors::digit::init_ctx( ctx.clone() ); + + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); + + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + //<><><><> + // add another representation + + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "<Digit 16>~Char"), + &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8") + ); + + let digit_u8_view = rt_digit + .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() + .view_u8(); + + assert_eq!( digit_u8_view.get_view().unwrap().get(), 5 as u8 ); + + + // projection behaves accordingly , when buffer is changed + + let mut digit_char_buffer = rt_digit + .descend( Context::parse(&ctx, "Char") ).unwrap() + .singleton_buffer::<char>(); + + digit_char_buffer.set('2'); + assert_eq!( digit_u8_view.get_view().unwrap().get(), 2 as u8 ); +} + +#[test] +fn digit_projection_u8_to_char() { + let ctx = Arc::new(RwLock::new(Context::new())); + crate::editors::digit::init_ctx( ctx.clone() ); + + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); + + rt_digit.insert_leaf( + Context::parse(&ctx, "ℤ_256~machine::UInt8"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new(5 as u8) ) + ); + + //<><><><> + // add another representation + + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8"), + &Context::parse(&ctx, "<Digit 16>~Char") + ); + + let digit_u8_view = rt_digit + .descend(Context::parse(&ctx, "Char")).unwrap() + .view_char(); + + assert_eq!( digit_u8_view.get_view().unwrap().get(), '5' ); +} + + +#[test] +fn char_buffered_projection() { + let ctx = Arc::new(RwLock::new(Context::new())); + crate::editors::digit::init_ctx( ctx.clone() ); + + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); + + rt_digit.insert_leaf( + Context::parse(&ctx, "ℤ_256~machine::UInt8"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new(8 as u8) ) + ); + + let mut digit_u8_buffer = rt_digit + .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() + .singleton_buffer::<u8>(); + + assert_eq!( digit_u8_buffer.get(), 8 ); + + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + let digit_char_buf = rt_digit + .descend(Context::parse(&ctx, "Char")).unwrap() + .singleton_buffer::<char>(); + let digit_char_view = rt_digit + .descend(Context::parse(&ctx, "Char")).unwrap() + .view_char(); + + // before setting up the morphism, char-view remains as initialized + assert_eq!( digit_char_buf.get(), '5' ); + assert_eq!( digit_char_view.get_view().unwrap().get(), '5' ); + + // now we attach the char-repr to the u8-repr + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8"), + &Context::parse(&ctx, "<Digit 16>~Char") + ); + + // char buffer and view should now follow the u8-buffer + assert_eq!( digit_char_view.get_view().unwrap().get(), '8' ); + assert_eq!( digit_char_buf.get(), '8' ); + + // now u8-buffer changes, and char-buffer should change accordingly + digit_u8_buffer.set(3); + assert_eq!( digit_u8_buffer.get(), 3 ); + + // char buffer should follow + digit_char_view.0.update(); + assert_eq!( digit_char_buf.get(), '3' ); + assert_eq!( digit_char_view.get_view().unwrap().get(), '3' ); +} + diff --git a/lib-nested-tty/src/edit_tree/keymap.rs b/lib-nested-tty/src/edit_tree/keymap.rs index 1afc123..09a3609 100644 --- a/lib-nested-tty/src/edit_tree/keymap.rs +++ b/lib-nested-tty/src/edit_tree/keymap.rs @@ -68,20 +68,20 @@ impl TerminalEvent { match self { TerminalEvent::Input(Event::Key(key)) => { if let Some(tree_nav_cmd) = neo2_treenav_keymap(key) { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "TreeNavCmd"), - SingletonBuffer::new(tree_nav_cmd).get_port().into() + SingletonBuffer::new(tree_nav_cmd) ) } else if let Some(tree_nav_cmd) = universal_treenav_keymap(key) { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "TreeNavCmd"), - SingletonBuffer::new(tree_nav_cmd).get_port().into() + SingletonBuffer::new(tree_nav_cmd) ) } else { if let Some(list_cmd) = tty_list_keymap(key) { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "ListCmd"), - SingletonBuffer::new(list_cmd).get_port().into() + SingletonBuffer::new(list_cmd) ) } else { match key { @@ -89,9 +89,9 @@ impl TerminalEvent { ReprTree::from_char(&ctx, *c) } _ => { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "TerminalEvent"), - SingletonBuffer::new(self.clone()).get_port().into() + SingletonBuffer::new(self.clone()) ) } } @@ -99,9 +99,9 @@ impl TerminalEvent { } } _ => { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "TerminalEvent"), - SingletonBuffer::new(self.clone()).get_port().into() + SingletonBuffer::new(self.clone()) ) } } diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 3affc68..b3ce8a9 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -94,12 +94,12 @@ impl PTYListStyle { pub fn for_node(node: &mut EditTree, style: (&str, &str, &str)) { node.disp.view .write().unwrap() - .insert_branch(ReprTree::new_leaf( + .insert_branch(ReprTree::from_view( Context::parse(&node.ctx, "TerminalView"), Self::new(style) .pty_view( &node.get_edit::<ListEditor>().unwrap().read().unwrap() - ).into() + ) )); } } @@ -225,6 +225,7 @@ impl PTYListController { rt, self.depth.map(|d| d+1) ); + /* let mut ne = new_edittree.write().unwrap(); match ne.send_cmd_obj(cmd_obj.clone()) { TreeNavResult::Continue => { @@ -233,9 +234,12 @@ impl PTYListController { TreeNavResult::Continue } TreeNavResult::Exit => { + */ TreeNavResult::Exit + /* } } + */ }, ListCursorMode::Select => { if let Some(item) = e.get_item_mut() { diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 8194268..4ce366e 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -17,12 +17,14 @@ use { } }; + pub fn edittree_make_char_view( node: EditTree ) -> EditTree { + eprintln!("nested-tty: EditTree make char-view"); node.disp.view .write().unwrap() - .insert_branch(ReprTree::new_leaf( + .insert_branch(ReprTree::from_view( Context::parse(&node.ctx, "TerminalView"), node.get_edit::< nested::editors::char::CharEditor >() .unwrap() @@ -31,7 +33,6 @@ pub fn edittree_make_char_view( .get_port() .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) .to_grid() - .into(), )); node @@ -42,7 +43,7 @@ pub fn edittree_make_digit_view( ) -> EditTree { node.disp.view .write().unwrap() - .insert_branch(ReprTree::new_leaf( + .insert_branch(ReprTree::from_view( Context::parse(&node.ctx, "TerminalView"), node.get_edit::< nested::editors::digit::DigitEditor >() .unwrap() @@ -56,7 +57,6 @@ pub fn edittree_make_digit_view( } ) .to_grid() - .into(), )); node diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index f5631af..0da7946 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -39,13 +39,12 @@ pub trait DisplaySegment { } -use nested::repr_tree::Context; +use nested::repr_tree::{Context, ReprTreeExt}; use std::sync::{Arc, RwLock}; impl DisplaySegment for nested::edit_tree::EditTree { fn display_view(&self) -> OuterViewPort<dyn TerminalView> { if let Some( tv_repr ) = self.disp.view - .read().unwrap() .descend( Context::parse(&self.ctx, "TerminalView") ) { if let Some(port) = From ecaa74ccfd0f56b078adae56cc2a24b631b5dacf Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 21 Mar 2024 10:37:24 +0100 Subject: [PATCH 33/75] add morphism to extract value-list from ListEditor --- lib-nested-core/src/editors/char/mod.rs | 25 +++++++----- lib-nested-core/src/editors/list/ctx.rs | 52 ++++++++++++++++++++++-- lib-nested-core/src/repr_tree/context.rs | 4 +- lib-nested-tty/src/editors/list.rs | 9 ++-- 4 files changed, 66 insertions(+), 24 deletions(-) diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 8b587ad..079fa85 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -9,7 +9,7 @@ use { }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, ReprTree, ReprTreeExt}, + repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt}, edit_tree::{EditTree, TreeNavResult}, editors::ObjCommander, }, @@ -31,24 +31,27 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { { let ctx = ctx.clone(); move |rt, σ| { - if let Some(v) = rt.read().unwrap().get_view::<dyn SingletonView<Item = char>>() { - eprintln!("prev value: {}", v.get()); + { + let mut rt = rt.write().unwrap(); + if let Some(buf) = rt.singleton_buffer::<char>() { + // buffer already exists + } else { + rt.insert_leaf( + vec![].into_iter(), + ReprLeaf::from_singleton_buffer( + SingletonBuffer::new('\0') + )); + } } - /* Create EditTree object - */ - rt.view_char().0.update(); + let char_buf = rt.singleton_buffer::<char>(); - let char_buf = rt.write().unwrap().singleton_buffer::<char>().unwrap(); - - eprintln!("make edittree: char val = {}", char_buf.get()); let mut edittree = CharEditor::new_edit_tree( ctx.clone(), char_buf, - r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + SingletonBuffer::<usize>::new(0).get_port() ); - eprintln!("insert Char~EditTree"); rt.write().unwrap() .insert_branch( ReprTree::from_singleton_buffer( diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 3c3ae8f..0f97c3c 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -1,9 +1,19 @@ use { - r3vi::{view::{OuterViewPort, singleton::*}, buffer::singleton::*}, + r3vi::{ + view::{ + ViewPort, + OuterViewPort, Observer, singleton::* + }, + buffer::{singleton::*, vec::*} + }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, ReprTree}, - editors::list::{ListEditor}//, PTYListController, PTYListStyle} + repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt}, + edit_tree::{EditTree}, + editors::{ + char::{CharEditor}, + list::{ListEditor}//, PTYListController, PTYListStyle} + } }, std::sync::{Arc, RwLock} }; @@ -30,7 +40,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.clone(), item_type.clone() ).into_node( - r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + SingletonBuffer::<usize>::new(0).get_port() ); src_rt.write().unwrap().insert_branch( @@ -45,5 +55,39 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } } ); + + let mt = crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<List Char>~EditTree"), + dst_type: Context::parse(&ctx, "<List Char>") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let edittree = + src_rt + .descend(Context::parse(&ctx, "EditTree")).unwrap() + .singleton_buffer::<EditTree>(); + + let list_edit = edittree.get().get_edit::< ListEditor >().unwrap(); + let edittree_items = list_edit.read().unwrap().data.get_port().to_list(); + src_rt.write().unwrap().insert_leaf( + vec![].into_iter(), + ReprLeaf::from_view( + edittree_items + .map( + |edittree_char| + edittree_char + .read().unwrap() + .get_edit::<CharEditor>().unwrap() + .read().unwrap() + .get() + ) + ) + ); + } + } + ); } diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index abd23ff..3d0bfce 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -153,12 +153,12 @@ impl Context { pub fn type_term_to_str(&self, t: &TypeTerm) -> String { self.type_dict.read().unwrap().unparse(&t) } + /// adds an object without any representations pub fn add_obj(ctx: Arc<RwLock<Context>>, name: String, typename: &str) { let type_tag = ctx.read().unwrap() .type_dict.write().unwrap() .parse(typename).unwrap(); - /* if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) { ctx.write().unwrap().nodes.insert(name, node); @@ -186,14 +186,12 @@ impl Context { self.type_term_from_str("EditTree").expect("") ]); - eprintln!("setp_edittree: apply morphism T -> T~EditTree"); self.morphisms.apply_morphism( rt.clone(), &rt.get_type(), &ladder ); - eprintln!("get repr-node of editTree"); if let Some(new_edittree) = rt.descend(self.type_term_from_str("EditTree").unwrap()) { diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index b3ce8a9..4af92fc 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -225,21 +225,18 @@ impl PTYListController { rt, self.depth.map(|d| d+1) ); - /* - let mut ne = new_edittree.write().unwrap(); + + let mut ne = new_edittree.get(); match ne.send_cmd_obj(cmd_obj.clone()) { TreeNavResult::Continue => { drop(ne); - e.insert(new_edittree.clone()); + e.insert(new_edittree.value.clone()); TreeNavResult::Continue } TreeNavResult::Exit => { - */ TreeNavResult::Exit - /* } } - */ }, ListCursorMode::Select => { if let Some(item) = e.get_item_mut() { From 33e97ed5e329aece7464f63a3a8c1906e091a5a7 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 21 Mar 2024 13:26:18 +0100 Subject: [PATCH 34/75] cleanup examples - move initialization of edittree-hook into lib-nested-tty - split examples into separate digit/string examples --- Cargo.toml | 3 +- .../{tty-02-node => tty-02-digit}/Cargo.toml | 2 +- examples/tty-02-digit/src/main.rs | 144 +++++++++++ examples/tty-02-node/src/main.rs | 223 ------------------ examples/tty-03-string/Cargo.toml | 19 ++ examples/tty-03-string/src/main.rs | 118 +++++++++ lib-nested-tty/Cargo.toml | 1 + lib-nested-tty/src/lib.rs | 51 ++++ 8 files changed, 336 insertions(+), 225 deletions(-) rename examples/{tty-02-node => tty-02-digit}/Cargo.toml (95%) create mode 100644 examples/tty-02-digit/src/main.rs delete mode 100644 examples/tty-02-node/src/main.rs create mode 100644 examples/tty-03-string/Cargo.toml create mode 100644 examples/tty-03-string/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index ce6bd01..73f07fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = [ "lib-nested-core", "lib-nested-tty", "examples/tty-01-hello", - "examples/tty-02-node" + "examples/tty-02-digit", + "examples/tty-03-string", ] diff --git a/examples/tty-02-node/Cargo.toml b/examples/tty-02-digit/Cargo.toml similarity index 95% rename from examples/tty-02-node/Cargo.toml rename to examples/tty-02-digit/Cargo.toml index ccfc655..b875ea5 100644 --- a/examples/tty-02-node/Cargo.toml +++ b/examples/tty-02-digit/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "tty-02-node" +name = "tty-02-digit" version = "0.1.0" edition = "2021" diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs new file mode 100644 index 0000000..12b4f71 --- /dev/null +++ b/examples/tty-02-digit/src/main.rs @@ -0,0 +1,144 @@ +extern crate cgmath; +extern crate nested; +extern crate nested_tty; +extern crate r3vi; +extern crate termion; + +use { + cgmath::Vector2, + nested::{ + editors::ObjCommander, + repr_tree::{Context, ReprTree, ReprTreeExt}, + edit_tree::{EditTree} + }, + nested_tty::{ + DisplaySegment, TTYApplication, + TerminalCompositor, TerminalStyle, TerminalView, + TerminalAtom, TerminalEvent + }, + r3vi::{ + buffer::{singleton::*, vec::*}, + view::{port::UpdateTask, list::*} + }, + std::sync::{Arc, RwLock}, +}; + +#[async_std::main] +async fn main() { + /* setup context & create Editor-Tree + */ + let ctx = Arc::new(RwLock::new(Context::new())); + + nested::editors::char::init_ctx( ctx.clone() ); + nested::editors::digit::init_ctx( ctx.clone() ); + nested::editors::integer::init_ctx( ctx.clone() ); + nested::editors::list::init_ctx( ctx.clone() ); + + nested_tty::setup_edittree_hook(&ctx); + + /* structure of Repr-Tree + * + * === Repr-Tree === + * + * <Digit 10> + * / | \ + * / | \ + * / | \ + * u32 EditTree Char + * - Editor \ + * - Display EditTree + * / | \ - Editor + * / | \ - Display + * TTY PixelBuf SDF / | \ + * / | \ + * TTY PixelBuf SDF + */ + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); + + /* add initial representation + * <Digit 16> ~ Char + */ + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + /* furthermore, setup projections to and from u8 value, + * this synchronizes the buffers + */ + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "<Digit 16>~Char"), + &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8") + ); + + /* setup TTY-Display for DigitEditor + * + * `setup_edittree` will setup the projection + * Char -> Char~EditTree + * and call the hook defined above with `set_edittree_hook()` + * + */ + let edittree_digit = ctx.read().unwrap() + .setup_edittree( + rt_digit.clone(), + SingletonBuffer::new(0).get_port() + ); + + let mut digit_u8_buffer = rt_digit + .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() + .singleton_buffer::<u8>(); + + /* setup terminal + */ + let app = TTYApplication::new({ + /* event handler + */ + let ctx = ctx.clone(); + + let mut edittree_digit = edittree_digit.clone(); + move |ev| { + edittree_digit.get().send_cmd_obj(ev.to_repr_tree(&ctx)); + } + }); + + /* setup display view routed to `app.port` + */ + let compositor = TerminalCompositor::new(app.port.inner()); + + // add some views to the display compositor + { + let mut comp = compositor.write().unwrap(); + + comp.push( + nested_tty::make_label("Hello World") + .map_item(|p, a| { + a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) + }) + .offset(Vector2::new(5, 0)), + ); + + let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); + comp.push( + nested_tty::make_label(&label_str) + .map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) + .offset(Vector2::new(1, 1)) + ); + comp.push( + edittree_digit.get().display_view() + .offset(Vector2::new(3,2)) + ); + comp.push( + digit_u8_buffer.get_port().map( + |d| nested_tty::make_label(&format!("Digit value={}", d)) + ) + .to_grid() + .flatten() + .offset(Vector2::new(5,3)) + ); + } + + /* write the changes in the view of `term_port` to the terminal + */ + app.show().await.expect("output error!"); +} diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs deleted file mode 100644 index 7e40c63..0000000 --- a/examples/tty-02-node/src/main.rs +++ /dev/null @@ -1,223 +0,0 @@ -extern crate cgmath; -extern crate nested; -extern crate nested_tty; -extern crate r3vi; -extern crate termion; - -use { - cgmath::Vector2, - nested::{ - editors::ObjCommander, - repr_tree::{Context, ReprTree, ReprTreeExt}, - edit_tree::{EditTree} - }, - nested_tty::{ - DisplaySegment, TTYApplication, - TerminalCompositor, TerminalStyle, TerminalView, - TerminalAtom, TerminalEvent - }, - r3vi::{ - buffer::{singleton::*, vec::*}, - view::{port::UpdateTask} - }, -// termion::{}, - std::sync::{Arc, RwLock}, -}; - -#[async_std::main] -async fn main() { - /* setup context & create Editor-Tree - */ - let ctx = Arc::new(RwLock::new(Context::new())); - - nested::editors::char::init_ctx( ctx.clone() ); - nested::editors::digit::init_ctx( ctx.clone() ); - nested::editors::integer::init_ctx( ctx.clone() ); - nested::editors::list::init_ctx( ctx.clone() ); - - let char_type = Context::parse(&ctx, "Char"); - let digit_type = Context::parse(&ctx, "<Digit Radix>"); - let list_type = Context::parse(&ctx, "<List Item>"); - let posint_type = Context::parse(&ctx, "<PosInt Radix>"); - let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap(); - - ctx.write().unwrap().meta_chars.push(','); - ctx.write().unwrap().meta_chars.push('\"'); - ctx.write().unwrap().meta_chars.push('}'); - - // Define a hook which is executed when a new editTree of type `t` is created. - // this will setup the display and navigation elements of the editor. - // It provides the necessary bridge to the rendering- & input-backend. - ctx.write().unwrap().set_edittree_hook( - Arc::new( - move |et: &mut EditTree, t: laddertypes::TypeTerm| { -// let mut et = et.write().unwrap(); - - if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) { - *et = nested_tty::editors::edittree_make_char_view(et.clone()); - } - else if let Ok(σ) = laddertypes::unify(&t, &digit_type) { - *et = nested_tty::editors::edittree_make_digit_view(et.clone()); - } - else if let Ok(σ) = laddertypes::unify(&t, &posint_type) { - nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("0d", "", "")); - nested_tty::editors::list::PTYListController::for_node( &mut *et, None, None ); - } - else if let Ok(σ) = laddertypes::unify(&t, &list_type) { - let item_type = σ.get( &laddertypes::TypeID::Var(item_tyid) ).unwrap(); - - // choose style based on element type - if *item_type == char_type { - nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("\"", "", "\"")); - nested_tty::editors::list::PTYListController::for_node( &mut *et, None, Some('\"') ); - } else { - nested_tty::editors::list::PTYListStyle::for_node( &mut *et, ("{", ", ", "}")); - nested_tty::editors::list::PTYListController::for_node( &mut *et, Some(','), Some('}') ); - } - //*et = nested_tty::editors::edittree_make_list_edit(et.clone()); - } - } - ) - ); - - /* structure of Repr-Tree - * - * === Repr-Tree === - * - * <Digit 10> - * / | \ - * / | \ - * / | \ - * u32 EditTree Char - * - Editor \ - * - Display EditTree - * / | \ - Editor - * / | \ - Display - * TTY PixelBuf SDF / | \ - * / | \ - * TTY PixelBuf SDF - */ - let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); - - /* add initial representation - * <Digit 16> ~ Char - */ - rt_digit.insert_leaf( - Context::parse(&ctx, "Char"), - nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) - ); - - /* furthermore, setup projections to and from u8 value, - * this synchronizes the buffers - */ - ctx.read().unwrap().morphisms.apply_morphism( - rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~Char"), - &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8") - ); - - /* setup TTY-Display for DigitEditor - * - * `setup_edittree` will setup the projection - * Char -> Char~EditTree - * and call the hook defined above with `set_edittree_hook()` - * - */ - let edittree_digit = ctx.read().unwrap() - .setup_edittree( - rt_digit.clone(), - r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() - ); - - let mut digit_u8_buffer = rt_digit - .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() - .singleton_buffer::<u8>(); - - //--- - let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); - - let edittree_list = ctx.read().unwrap() - .setup_edittree( - rt_string.clone(), - r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); - - /* setup terminal - */ - let app = TTYApplication::new({ - /* event handler - */ - let ctx = ctx.clone(); - let mut editors = Vec::new(); - editors.push(edittree_digit.clone()); - editors.push(edittree_list.clone()); - - let edit_select = Arc::new(RwLock::new(0)); - move |ev| { - match ev { - TerminalEvent::Input(termion::event::Event::Key(termion::event::Key::Char('\t'))) => { - let mut i = edit_select.write().unwrap(); - *i = (*i + 1) % editors.len(); - } - _ => { - let i = edit_select.read().unwrap(); - editors[*i].get().send_cmd_obj(ev.to_repr_tree(&ctx)); - } - } - } - }); - - /* setup display view routed to `app.port` - */ - let compositor = TerminalCompositor::new(app.port.inner()); - - // add some views to the display compositor - { - let mut comp = compositor.write().unwrap(); - - comp.push( - nested_tty::make_label("Hello World") - .map_item(|p, a| { - a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) - }) - .offset(Vector2::new(5, 0)), - ); - - comp.push( - edittree_digit.get().display_view() - .offset(Vector2::new(2,2)) - ); - - let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); - comp.push( - nested_tty::make_label(&label_str) - .map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) - .offset(Vector2::new(0, 1)) - ); - - comp.push( - digit_u8_buffer.get_port().map( - |d| nested_tty::make_label(&format!("Digit={}", d)) - ) - .to_grid() - .flatten() - .offset(Vector2::new(2,3)) - ); - - - comp.push( - edittree_list.get().display_view() - .offset(Vector2::new(2,6)) - ); - - let label_str = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type()); - comp.push( - nested_tty::make_label(&label_str) - .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) - .offset(Vector2::new(0, 5)) - ); - } - - /* write the changes in the view of `term_port` to the terminal - */ - app.show().await.expect("output error!"); -} diff --git a/examples/tty-03-string/Cargo.toml b/examples/tty-03-string/Cargo.toml new file mode 100644 index 0000000..10763ef --- /dev/null +++ b/examples/tty-03-string/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "tty-03-string" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +laddertypes = { path = "../../../lib-laddertypes" } +r3vi = { path = "../../../lib-r3vi" } +nested = { path = "../../lib-nested-core" } +nested-tty = { path = "../../lib-nested-tty" } +termion = "*" +cgmath = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] + diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs new file mode 100644 index 0000000..de84271 --- /dev/null +++ b/examples/tty-03-string/src/main.rs @@ -0,0 +1,118 @@ +extern crate cgmath; +extern crate nested; +extern crate nested_tty; +extern crate r3vi; +extern crate termion; + +use { + cgmath::Vector2, + nested::{ + editors::ObjCommander, + repr_tree::{Context, ReprTree, ReprTreeExt}, + edit_tree::{EditTree} + }, + nested_tty::{ + DisplaySegment, TTYApplication, + TerminalCompositor, TerminalStyle, TerminalView, + TerminalAtom, TerminalEvent + }, + r3vi::{ + buffer::{singleton::*, vec::*}, + view::{port::UpdateTask, list::*} + }, + std::sync::{Arc, RwLock}, +}; + +#[async_std::main] +async fn main() { + /* setup context + */ + let ctx = Arc::new(RwLock::new(Context::new())); + nested::editors::char::init_ctx( ctx.clone() ); + nested::editors::digit::init_ctx( ctx.clone() ); + nested::editors::integer::init_ctx( ctx.clone() ); + nested::editors::list::init_ctx( ctx.clone() ); + nested_tty::setup_edittree_hook(&ctx); + + + /* Create a Representation-Tree of type <List Char> + */ + let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); + + /* Setup an Editor for this ReprTree + * (by adding the representation <List Char>~EditTree to the ReprTree) + */ + let edittree_list = ctx.read().unwrap() + .setup_edittree( + rt_string.clone(), + SingletonBuffer::new(0).get_port()); + + /* In order to get acces to the values that are modified by the Editor, + * we apply a morphism that, given the List of Edit-Trees, extracts + * the value from each EditTree and shows them in a ListView. + */ + ctx.read().unwrap().morphisms.apply_morphism( + rt_string.clone(), + &Context::parse(&ctx, "<List Char>~EditTree"), + &Context::parse(&ctx, "<List Char>") + ); + + /* Now, get the ListView that serves our char-values. + * This view is a projection created by the morphism that was called above. + */ + let mut chars_view = rt_string + .read().unwrap() + .get_port::<dyn ListView<char>>() + .unwrap(); + + /* transform ListView<char> into a TerminalView + */ + let string_view_tty = chars_view + .to_sequence() + .to_grid_vertical() + .map_item(|_pt,c| TerminalAtom::new(*c, TerminalStyle::fg_color((200,10,60)))); + + /* setup terminal + */ + let app = TTYApplication::new({ + let edittree_list = edittree_list.clone(); + + /* event handler + */ + let ctx = ctx.clone(); + move |ev| { + edittree_list.get().send_cmd_obj(ev.to_repr_tree(&ctx)); + } + }); + + /* Setup the compositor to serve as root-view + * by routing it to the `app.port` Viewport, + * so it will be displayed on TTY-output. + */ + let compositor = TerminalCompositor::new(app.port.inner()); + + /* Now add some views to our compositor + */ + { + let mut comp = compositor.write().unwrap(); + + let label_str = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type()); + comp.push( + nested_tty::make_label(&label_str) + .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) + .offset(Vector2::new(1, 1))); + + comp.push( + edittree_list.get() + .display_view() + .offset(Vector2::new(3,2))); + + comp.push( + string_view_tty + .offset(Vector2::new(5,3))); + } + + /* write the changes in the view of `term_port` to the terminal + */ + app.show().await.expect("output error!"); +} diff --git a/lib-nested-tty/Cargo.toml b/lib-nested-tty/Cargo.toml index e85b2d9..0e5b412 100644 --- a/lib-nested-tty/Cargo.toml +++ b/lib-nested-tty/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] r3vi = { path = "../../lib-r3vi" } +laddertypes = { path = "../../lib-laddertypes" } nested = { path = "../lib-nested-core" } cgmath = { version = "0.18.0", features = ["serde"] } serde = { version = "1.0", features = ["serde_derive"] } diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index 0da7946..2bc1138 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -114,3 +114,54 @@ impl TerminalProjections for OuterViewPort<dyn TerminalView> { } +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) { + + let char_type = Context::parse(&ctx, "Char"); + let digit_type = Context::parse(&ctx, "<Digit Radix>"); + let list_type = Context::parse(&ctx, "<List Item>"); + let posint_type = Context::parse(&ctx, "<PosInt Radix>"); + let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap(); + + ctx.write().unwrap().meta_chars.push(','); + ctx.write().unwrap().meta_chars.push('\"'); + ctx.write().unwrap().meta_chars.push('}'); + + // Define a hook which is executed when a new editTree of type `t` is created. + // this will setup the display and navigation elements of the editor. + // It provides the necessary bridge to the rendering- & input-backend. + ctx.write().unwrap().set_edittree_hook( + Arc::new( + move |et: &mut nested::edit_tree::EditTree, t: laddertypes::TypeTerm| { +// let mut et = et.write().unwrap(); + + if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) { + *et = crate::editors::edittree_make_char_view(et.clone()); + } + else if let Ok(σ) = laddertypes::unify(&t, &digit_type) { + *et = crate::editors::edittree_make_digit_view(et.clone()); + } + else if let Ok(σ) = laddertypes::unify(&t, &posint_type) { + crate::editors::list::PTYListStyle::for_node( &mut *et, ("0d", "", "")); + crate::editors::list::PTYListController::for_node( &mut *et, None, None ); + } + else if let Ok(σ) = laddertypes::unify(&t, &list_type) { + let item_type = σ.get( &laddertypes::TypeID::Var(item_tyid) ).unwrap(); + + // choose style based on element type + if *item_type == char_type { + crate::editors::list::PTYListStyle::for_node( &mut *et, ("\"", "", "\"")); + crate::editors::list::PTYListController::for_node( &mut *et, None, Some('\"') ); + } else { + crate::editors::list::PTYListStyle::for_node( &mut *et, ("{", ", ", "}")); + crate::editors::list::PTYListController::for_node( &mut *et, Some(','), Some('}') ); + } + //*et = nested_tty::editors::edittree_make_list_edit(et.clone()); + } + } + ) + ); + +} + From 473dd5f4dceafe8faedd7cba03686d143ee92d8b Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 21 Mar 2024 18:17:04 +0100 Subject: [PATCH 35/75] add short READMEs for examples --- examples/tty-01-hello/README.md | 8 ++++++++ examples/tty-01-hello/src/main.rs | 23 ++++++++++++++++++++--- examples/tty-02-digit/README.md | 4 ++++ examples/tty-02-digit/src/main.rs | 3 +++ examples/tty-03-string/README.md | 8 ++++++++ examples/tty-03-string/src/main.rs | 9 ++++++++- 6 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 examples/tty-01-hello/README.md create mode 100644 examples/tty-02-digit/README.md create mode 100644 examples/tty-03-string/README.md diff --git a/examples/tty-01-hello/README.md b/examples/tty-01-hello/README.md new file mode 100644 index 0000000..b1be4e7 --- /dev/null +++ b/examples/tty-01-hello/README.md @@ -0,0 +1,8 @@ +# tty-01-hello + +This example shows how to: + - initialize the TTY backend (`lib-nestetd-tty`), + - create a simple 'Hello World' output, + - create color gradients on the outputted text + utilizing basic projection functionality from `lib-r3vi`, + - perform basic layouting & compositing. diff --git a/examples/tty-01-hello/src/main.rs b/examples/tty-01-hello/src/main.rs index 45856c0..468d8f5 100644 --- a/examples/tty-01-hello/src/main.rs +++ b/examples/tty-01-hello/src/main.rs @@ -1,3 +1,10 @@ +//! This example shows how to: +//! - initialize the TTY backend (`lib-nestetd-tty`), +//! - create a simple 'Hello World' output, +//! - create color gradients on the outputted text +//! utilizing basic projection functionality from `lib-r3vi`, +//! - perform basic layouting & compositing. + extern crate cgmath; extern crate nested; extern crate nested_tty; @@ -15,19 +22,29 @@ use { #[async_std::main] async fn main() { - /* initialize our terminal + /* Initialize our terminal. */ let tty_app = TTYApplication::new(|event| { /* handle event */ }); - /* populate the view in `term_port` + /* Setup our "root" view of the application. + * This will be the compositor, which is able to + * mix multiple `TerminalView`-Views together. + * Its output is routed to the `app.port` Viewport, + * so it will be displayed on TTY-output. */ let compositor = TerminalCompositor::new(tty_app.port.inner()); + /* Add the label 'test' at position (7, 2) + */ compositor .write() .unwrap() .push(nested_tty::make_label("test").offset(Vector2::new(7, 2))); + /* Add a 'Hello World' label at position (5, 3) + * and set a coloring determined by formula from + * the position of each character. + */ compositor.write().unwrap().push( nested_tty::make_label("Hello World") .map_item(|p, a| { @@ -36,7 +53,7 @@ async fn main() { .offset(Vector2::new(5, 3)), ); - /* write the changes in the view of `term_port` to the terminal + /* write the changes in the root-view to the terminal */ tty_app.show().await.expect("output error!"); } diff --git a/examples/tty-02-digit/README.md b/examples/tty-02-digit/README.md new file mode 100644 index 0000000..23b502b --- /dev/null +++ b/examples/tty-02-digit/README.md @@ -0,0 +1,4 @@ +# tty-02-digit + +This example demonstrates how a very simple editor for hexadecimal digits +can be created with `lib-nested` and the `lib-nested-tty` backend. diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs index 12b4f71..61603b1 100644 --- a/examples/tty-02-digit/src/main.rs +++ b/examples/tty-02-digit/src/main.rs @@ -1,3 +1,6 @@ +//! This example demonstrates how a very simple editor for hexadecimal digits +//! can be created with `lib-nested` and the `lib-nested-tty` backend. + extern crate cgmath; extern crate nested; extern crate nested_tty; diff --git a/examples/tty-03-string/README.md b/examples/tty-03-string/README.md new file mode 100644 index 0000000..85305aa --- /dev/null +++ b/examples/tty-03-string/README.md @@ -0,0 +1,8 @@ +# tty-03-string + +Similarly to `tty-02-digit`, a editor is created +but of type <List Char>. +The contents of the editor can be retrieved by +a morphism from the `EditTree` node. +To demonstrate that, the values are are mapped +to the TTY-display in different form. diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs index de84271..d0ad31a 100644 --- a/examples/tty-03-string/src/main.rs +++ b/examples/tty-03-string/src/main.rs @@ -1,3 +1,10 @@ +//! Similarly to `tty-02-digit`, a editor is created +//! but of type <List Char>. +//! The contents of the editor can be retrieved by +//! a morphism from the `EditTree` node. +//! To demonstrate that, the values are are mapped +//! to the TTY-display in different form. + extern crate cgmath; extern crate nested; extern crate nested_tty; @@ -100,7 +107,7 @@ async fn main() { comp.push( nested_tty::make_label(&label_str) .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) - .offset(Vector2::new(1, 1))); + .offset(Vector2::new(1,1))); comp.push( edittree_list.get() From edf088b85304cc8b0356f7bcd23426574fcdddfb Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 23 Mar 2024 20:57:07 +0100 Subject: [PATCH 36/75] add vec-access to ReprTree and morphism to collect <List Char> to <Vec Char> --- examples/tty-03-string/src/main.rs | 34 ++++++++- lib-nested-core/src/editors/list/ctx.rs | 29 +++++++- lib-nested-core/src/repr_tree/mod.rs | 95 ++++++++++++++++++++++--- 3 files changed, 145 insertions(+), 13 deletions(-) diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs index d0ad31a..0d8f670 100644 --- a/examples/tty-03-string/src/main.rs +++ b/examples/tty-03-string/src/main.rs @@ -41,13 +41,12 @@ async fn main() { nested::editors::list::init_ctx( ctx.clone() ); nested_tty::setup_edittree_hook(&ctx); - /* Create a Representation-Tree of type <List Char> */ let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); /* Setup an Editor for this ReprTree - * (by adding the representation <List Char>~EditTree to the ReprTree) + * (this will add the representation <List Char>~EditTree to the ReprTree) */ let edittree_list = ctx.read().unwrap() .setup_edittree( @@ -72,7 +71,24 @@ async fn main() { .get_port::<dyn ListView<char>>() .unwrap(); - /* transform ListView<char> into a TerminalView + + /* Lets add another morphism which will store the values + * of the character-list in a `Vec<char>` + */ + ctx.read().unwrap().morphisms.apply_morphism( + rt_string.clone(), + &Context::parse(&ctx, "<List Char>"), + &Context::parse(&ctx, "<List Char>~<Vec Char>") + ); + + /* Access the Vec<char> object (wrapped behind a VecBuffer<char>) + * from the ReprTree. + */ + let chars_vec = rt_string + .descend(Context::parse(&ctx, "<Vec Char>")).unwrap() + .vec_buffer::<char>(); + + /* transform `ListView<char>` into a `TerminalView` */ let string_view_tty = chars_view .to_sequence() @@ -122,4 +138,16 @@ async fn main() { /* write the changes in the view of `term_port` to the terminal */ app.show().await.expect("output error!"); + + /* need to call update because changes are applied lazily + */ + chars_vec.get_port().0.update(); + + /* Vec<char> to String + */ + let string = chars_vec.data + .read().unwrap() + .iter().collect::<String>(); + + eprintln!("value of the editor was: {}\n\n", string); } diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 0f97c3c..79943db 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -2,7 +2,9 @@ use { r3vi::{ view::{ ViewPort, - OuterViewPort, Observer, singleton::* + OuterViewPort, Observer, + singleton::*, + list::* }, buffer::{singleton::*, vec::*} }, @@ -89,5 +91,30 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } } ); + + + let mt = crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<List Char>"), + dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let buf = VecBuffer::<char>::new(); + let mut leaf = ReprLeaf::from_vec_buffer(buf); + leaf.attach_to( + src_rt.read().unwrap() + .get_port::<dyn ListView<char>>() + .unwrap() + ); + src_rt.write().unwrap().insert_leaf( + vec![ Context::parse(&ctx, "<Vec Char>") ].into_iter(), + leaf + ); + } + } + ); } diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 816f6b7..3b58eb8 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -16,7 +16,9 @@ use { AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, port::UpdateTask, View, - singleton::*, sequence::* + singleton::*, + sequence::*, + list::* }, buffer::{singleton::*, vec::*} }, @@ -35,7 +37,7 @@ pub struct ReprLeaf { out_port: AnyViewPort, in_port: AnyInnerViewPort, data: Option< Arc<dyn Any + Send + Sync> >, - + /// keepalive for the observer that updates the buffer from in_port keepalive: Option<Arc<dyn Any + Send + Sync>>, } @@ -103,6 +105,19 @@ impl ReprLeaf { } } + pub fn from_vec_buffer<T>( buffer: VecBuffer<T> ) -> Self + where T: Clone + Send + Sync + 'static + { + eprintln!("ReprLeaf from vec buffer (LEN ={})", buffer.len()); + let in_port = ViewPort::< dyn ListView<T> >::new(); + ReprLeaf { + keepalive: Some(buffer.attach_to(in_port.outer())), + in_port: in_port.inner().into(), + out_port: buffer.get_port().0.into(), + data: Some(buffer.into_inner()) + } + } + pub fn as_singleton_buffer<T>(&mut self) -> Option<SingletonBuffer<T>> where T: Clone + Send + Sync + 'static { @@ -136,6 +151,50 @@ impl ReprLeaf { } } + pub fn as_vec_buffer<T>(&mut self) -> Option<VecBuffer<T>> + where T: Clone + Send + Sync + 'static + { + let vec_port = self.get_port::< RwLock<Vec<T>> >().unwrap().0; + + let data_arc = + if let Some(data) = self.data.as_ref() { + eprintln!("downcast existing vec-data"); + data.clone().downcast::<RwLock<Vec<T>>>().ok() + } else { + vec_port.update(); + if let Some(value) = vec_port.outer().get_view() { + let value = value.read().unwrap().clone(); + eprintln!("make new data ARC from old VECTOR-value"); + Some(Arc::new(RwLock::new( value ))) + } else { + eprintln!("no data vec"); + Some(Arc::new(RwLock::new( Vec::new() ))) +// None + } + }; + + if let Some(data_arc) = data_arc { + eprintln!("ReprLeaf: have Vec-like data-arc"); + eprintln!("LEN = {}", data_arc.read().unwrap().len()); + + self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); + let buf = VecBuffer { + data: data_arc, + port: vec_port.inner() + }; + self.keepalive = Some(buf.attach_to( + self.in_port.0.clone() + .downcast::< dyn ListView<T> >() + .ok().unwrap() + .outer() + )); + Some(buf) + } else { + None + } + } + + pub fn get_port<V>(&self) -> Option<OuterViewPort<V>> where V: View + ?Sized + 'static, V::Msg: Clone @@ -191,6 +250,15 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } + + pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> Arc<RwLock<Self>> + where T: Clone + Send + Sync + 'static + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_vec_buffer(buf)); + Arc::new(RwLock::new(rt)) + } + /// find, and if necessary, create corresponding path in repr-tree. /// Attach src_port to input of that node pub fn attach_leaf_to<V>( @@ -271,14 +339,24 @@ impl ReprTree { if let Some(leaf) = self.leaf.as_mut() { leaf.as_singleton_buffer::<T>() } else { + // create new singleton buffer + /* + // default value?? + let buf = SingletonBuffer::<T>::default(); + self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone())); + Some(buf) + */ None } } -/* - pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> Option<VecBuffer<T>> { + pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<VecBuffer<T>> { + if let Some(leaf) = self.leaf.as_mut() { + leaf.as_vec_buffer::<T>() + } else { + None + } } -*/ //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -336,7 +414,7 @@ pub trait ReprTreeExt { fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>; fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>; -// fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>; + fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>; } impl ReprTreeExt for Arc<RwLock<ReprTree>> { @@ -371,11 +449,10 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T> { self.write().unwrap().singleton_buffer::<T>().expect("") } -/* + fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T> { - self.read().unwrap().vec_buffer::<T>().expect("") + self.write().unwrap().vec_buffer::<T>().expect("") } - */ } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> From 91e56d876d6998d2a6045d0e1e31cd36312783e7 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 23 Mar 2024 21:32:12 +0100 Subject: [PATCH 37/75] digit editor: create char repr if not available --- lib-nested-core/src/editors/digit/ctx.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index bb022a7..8547552 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -39,6 +39,20 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { _ => 0 }; + /* get char representation or create it if not available + */ + let char_rt = + if let Some(crt) = src_rt.descend(Context::parse(&ctx, "Char")) { + crt + } else { + let crt = ReprTree::from_singleton_buffer( + Context::parse(&ctx, "Char"), + SingletonBuffer::new('\0') + ); + src_rt.insert_branch(crt.clone()); + crt + }; + /* Create EditTree object */ let mut edittree = DigitEditor::new( From 40a5da45122c2f918b726253035daed98f1c4821 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 25 May 2024 00:39:47 +0200 Subject: [PATCH 38/75] int example & testing out more int projections --- Cargo.toml | 1 + examples/tty-04-posint/Cargo.toml | 19 ++ examples/tty-04-posint/README.md | 7 + examples/tty-04-posint/src/main.rs | 208 ++++++++++++++++++ lib-nested-core/src/editors/char/mod.rs | 1 + lib-nested-core/src/editors/digit/ctx.rs | 10 +- lib-nested-core/src/editors/digit/editor.rs | 5 + lib-nested-core/src/editors/integer/ctx.rs | 212 +++++++++++-------- lib-nested-core/src/editors/integer/mod.rs | 136 ++++++++++++ lib-nested-core/src/editors/integer/radix.rs | 167 +++++++++------ lib-nested-core/src/editors/list/ctx.rs | 35 +++ lib-nested-core/src/lib.rs | 2 + lib-nested-core/src/repr_tree/mod.rs | 9 + 13 files changed, 661 insertions(+), 151 deletions(-) create mode 100644 examples/tty-04-posint/Cargo.toml create mode 100644 examples/tty-04-posint/README.md create mode 100644 examples/tty-04-posint/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 73f07fc..b3de67d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,5 +5,6 @@ members = [ "examples/tty-01-hello", "examples/tty-02-digit", "examples/tty-03-string", + "examples/tty-04-posint" ] diff --git a/examples/tty-04-posint/Cargo.toml b/examples/tty-04-posint/Cargo.toml new file mode 100644 index 0000000..0e4e285 --- /dev/null +++ b/examples/tty-04-posint/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "tty-04-posint" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +laddertypes = { path = "../../../lib-laddertypes" } +r3vi = { path = "../../../lib-r3vi" } +nested = { path = "../../lib-nested-core" } +nested-tty = { path = "../../lib-nested-tty" } +termion = "*" +cgmath = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] + diff --git a/examples/tty-04-posint/README.md b/examples/tty-04-posint/README.md new file mode 100644 index 0000000..1f85cdd --- /dev/null +++ b/examples/tty-04-posint/README.md @@ -0,0 +1,7 @@ +# tty-04-posint + +In the following example, a <List Char> editor +as before is used, but its data is morphed into +representing a positional integer which is then +projected into different radices and displayed +in different views on screen diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs new file mode 100644 index 0000000..687d345 --- /dev/null +++ b/examples/tty-04-posint/src/main.rs @@ -0,0 +1,208 @@ +//! In the following example, a <List Char> editor +//! as before is used, but its data is morphed into +//! representing a positional integer which is then +//! projected into different radices and displayed +//! in different views on screen + +extern crate cgmath; +extern crate nested; +extern crate nested_tty; +extern crate r3vi; +extern crate termion; + +use { + cgmath::Vector2, + nested::{ + editors::{ + ObjCommander + }, + repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, + edit_tree::{EditTree} + }, + nested_tty::{ + DisplaySegment, TTYApplication, + TerminalCompositor, TerminalStyle, TerminalView, + TerminalAtom, TerminalEvent + }, + r3vi::{ + buffer::{singleton::*, vec::*}, + view::{port::UpdateTask, list::*, sequence::*}, + projection::* + }, + std::sync::{Arc, RwLock}, +}; + +#[async_std::main] +async fn main() { + /* setup context + */ + let ctx = Arc::new(RwLock::new(Context::new())); + nested::editors::char::init_ctx( ctx.clone() ); + nested::editors::digit::init_ctx( ctx.clone() ); + nested::editors::integer::init_ctx( ctx.clone() ); + nested::editors::list::init_ctx( ctx.clone() ); + nested_tty::setup_edittree_hook(&ctx); + + /* Create a Representation-Tree of type <List <Digit 16>> + */ + let mut rt_digitlist = ReprTree::new_arc( Context::parse(&ctx, "<List <Digit 16>>") ); + let mut rt_digitseq = ReprTree::new_arc( Context::parse(&ctx, "<Seq <Digit 16>>") ); + rt_digitseq.insert_branch( rt_digitlist ); + let mut rt_posint = ReprTree::new_arc(Context::parse(&ctx, "<PosInt 16 BigEndian>")); + rt_posint.insert_branch( rt_digitseq ); + let mut rt_int = ReprTree::new_arc( Context::parse(&ctx, "ℕ") ); + rt_int.insert_branch( rt_posint ); + + /* Setup an Editor for this ReprTree + * (this will add the representation <List <Digit 16>>~EditTree to the ReprTree) + */ + let rt_edittree_list = ctx.read().unwrap() + .setup_edittree( + ReprTree::descend( + &rt_int, + Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq~List <Digit 16>>") + ).expect("cant descend reprtree"), + SingletonBuffer::new(0).get_port() + ); + + ctx.read().unwrap().morphisms.apply_morphism( + ReprTree::descend(&rt_int, + Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~<Seq <Digit 16>> + ~<List <Digit 16>> + ") + ).expect("cant descend repr tree"), + &Context::parse(&ctx, "<List <Digit 16>>~EditTree"), + &Context::parse(&ctx, "<List <Digit 16>~Char>") + ); + + /* + * map seq of chars to seq of u64 digits + */ + let mut chars_view = + ReprTree::descend( + &rt_int, + Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char>") + ).expect("cant descend") + .read().unwrap() + .get_port::<dyn ListView<char>>() + .unwrap(); + + let mut digits_view = chars_view + .to_sequence() + .filter_map( + |digit_char| + + /* TODO: call morphism + */ + match digit_char.to_digit(16) { + Some(d) => Some(d as usize), + None => None + } + ); + + rt_int.write().unwrap().insert_leaf( + vec![ + Context::parse(&ctx, "<PosInt 16 BigEndian>"), + Context::parse(&ctx, "<Seq <Digit 16>>"), + Context::parse(&ctx, "<Seq ℤ_2^64>"), + Context::parse(&ctx, "<Seq machine.UInt64>") + ].into_iter(), + nested::repr_tree::ReprLeaf::from_view( digits_view.clone() ) + ); + // + // + + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.clone(), + &Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>"), + &Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.clone(), + &Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>"), + &Context::parse(&ctx, "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.clone(), + &Context::parse(&ctx, "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>"), + &Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>") + ); + + let dec_digits_view = ReprTree::descend(&rt_int, + Context::parse(&ctx, " + <PosInt 10 BigEndian> + ~< Seq <Digit 10>~ℤ_2^64~machine.UInt64 > + ") + ).expect("cant descend repr tree") + .read().unwrap() + .get_port::<dyn SequenceView<Item = usize>>().unwrap() + .map( + /* TODO: call morphism + */ + |digit| { + TerminalAtom::from( + char::from_digit(*digit as u32, 10) + ) + } + ) + .to_grid_horizontal(); + + let hex_digits_view = + ReprTree::descend( + &rt_int, + Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~<Seq <Digit 16> > + ~<List <Digit 16> + ~Char>") + ).expect("cant descend") + .read().unwrap() + .get_port::<dyn ListView<char>>().unwrap() + .to_sequence() + .to_grid_horizontal() + .map_item(|_pt,c| TerminalAtom::new(*c, TerminalStyle::fg_color((30,90,200)))); + + /* setup terminal + */ + let app = TTYApplication::new({ + let edittree_list = rt_edittree_list.clone(); + + /* event handler + */ + let ctx = ctx.clone(); + move |ev| { + edittree_list.get().send_cmd_obj(ev.to_repr_tree(&ctx)); + } + }); + + /* Setup the compositor to serve as root-view + * by routing it to the `app.port` Viewport, + * so it will be displayed on TTY-output. + */ + let compositor = TerminalCompositor::new(app.port.inner()); + + /* Now add some views to our compositor + */ + { + let mut comp = compositor.write().unwrap(); + + let label_str = ctx.read().unwrap().type_term_to_str(&rt_int.read().unwrap().get_type()); + comp.push( + nested_tty::make_label(&label_str) + .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) + .offset(Vector2::new(1,1))); + + comp.push(rt_edittree_list.get() + .display_view() + .offset(Vector2::new(3,2))); + + comp.push(dec_digits_view.offset(Vector2::new(3,4))); + comp.push(hex_digits_view.offset(Vector2::new(3,5))); + } + + /* write the changes in the view of `term_port` to the terminal + */ + app.show().await.expect("output error!"); +} diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 079fa85..b4d0e51 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -36,6 +36,7 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { if let Some(buf) = rt.singleton_buffer::<char>() { // buffer already exists } else { + // create char buffer rt.insert_leaf( vec![].into_iter(), ReprLeaf::from_singleton_buffer( diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index 8547552..d5822c2 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -80,7 +80,7 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { let morphtype = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<Digit Radix>~Char"), - dst_type: Context::parse(&ctx, "<Digit Radix>~ℤ_256~machine::UInt8") + dst_type: Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64") }; ctx.write().unwrap() @@ -124,7 +124,7 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { let morphtype = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<Digit Radix>~ℤ_256~machine::UInt8"), + src_type: Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64"), dst_type: Context::parse(&ctx, "<Digit Radix>~Char") }; @@ -144,10 +144,10 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { /* insert projected view into ReprTree */ let char_view = - rt.descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")) + rt.descend(Context::parse(&ctx, "ℤ_2^64~machine::UInt64")) .unwrap() - .view_u8() - .map(move |digit| char::from_digit(digit as u32, radix).unwrap_or('?')); + .view_usize() + .map(move |digit| char::from_digit((digit%radix as usize) as u32, radix).unwrap_or('?')); rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = char>>( Context::parse(&ctx, "Char").get_lnf_vec().into_iter(), diff --git a/lib-nested-core/src/editors/digit/editor.rs b/lib-nested-core/src/editors/digit/editor.rs index a73733b..125d2a3 100644 --- a/lib-nested-core/src/editors/digit/editor.rs +++ b/lib-nested-core/src/editors/digit/editor.rs @@ -73,6 +73,11 @@ impl DigitEditor { pub fn get_type(&self) -> TypeTerm { TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap()) } + + pub fn get_char(&self) -> char { + self.data.get() + } + /* pub fn get_data(&self) -> Arc<RwLock<ReprTree>> { ReprTree::ascend( diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index b8bfac2..23eeab6 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -5,8 +5,7 @@ use { }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context}, - repr_tree::{MorphismType}, + repr_tree::{ReprTree, ReprLeaf, Context, MorphismType}, editors::{ list::*, integer::* @@ -16,97 +15,142 @@ use { }; pub fn init_ctx(ctx: Arc<RwLock<Context>>) { - /* - ctx.add_list_typename("PosInt".into()); - let pattern = MorphismTypePattern { - src_tyid: ctx.get_typeid("List"), - dst_tyid: ctx.get_typeid("PosInt").unwrap() + // TODO: proper scoping + // ctx.write().unwrap().add_varname("Radix"); + ctx.write().unwrap().add_varname("SrcRadix"); + ctx.write().unwrap().add_varname("DstRadix"); + + let morphism_type = MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>") }; - ctx.add_morphism(pattern, - Arc::new( - |mut node, dst_type| { - // todo: check src_type parameter to be ( Digit radix ) - match dst_type { - TypeTerm::App(args) => { - if args.len() > 1 { - match args[1] { - TypeTerm::Num(_radix) => { - /* FIXME - PTYListController::for_node( - &mut node, - Some(','), - None, - ); + ctx.write().unwrap().morphisms.add_morphism( + morphism_type, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_digits = ReprTree::descend( + &src_rt, + Context::parse(&ctx, " + <PosInt Radix BigEndian> + ~<Seq <Digit Radix>~ℤ_2^64~machine.UInt64 > + ") + .apply_substitution(&|k|σ.get(k).cloned()).clone() + ).expect("cant descend") + .read().unwrap() + .view_seq::< usize >(); - PTYListStyle::for_node( - &mut node, - ("0d", "", "") - ); -*/ - Some(node) - }, - _ => None - } - } else { - None - } - } - _ => None - } + src_rt.write().unwrap().insert_leaf( + vec![ + Context::parse(&ctx, "<PosInt Radix LittleEndian>") + .apply_substitution(&|k|σ.get(k).cloned()).clone(), + Context::parse(&ctx, "<Seq <Digit Radix>>") + .apply_substitution(&|k|σ.get(k).cloned()).clone(), + Context::parse(&ctx, "<Seq ℤ_2^64>"), + Context::parse(&ctx, "<Seq machine.UInt64>") + ].into_iter(), + + ReprLeaf::from_view( src_digits.reverse() ) + ); } - ) + } ); - ctx.add_node_ctor( - "PosInt", Arc::new( - |ctx0: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { - match dst_typ.clone() { - TypeTerm::App(args) => { - if args.len() > 1 { - match args[1] { - TypeTerm::Num(radix) => { - let ctx = ctx0.read().unwrap(); - let mut node = Context::make_node( - &ctx0, - TypeTerm::App(vec![ - TypeTerm::TypeID(ctx.get_typeid("List").unwrap()), - TypeTerm::TypeID( - ctx.get_typeid("Digit").unwrap() - ) - .num_arg(radix) - .clone() - .into() - ]), - depth.map(|d| d+1) - ).unwrap(); - node = node.morph(dst_typ); - Some(node) - } - _ => None - } - } else { - None - } - } - _ => None - } + + let morphism_type = MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>") + }; + + ctx.write().unwrap().morphisms.add_morphism( + morphism_type, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_digits = ReprTree::descend( + &src_rt, + Context::parse(&ctx, " + <PosInt Radix LittleEndian> + ~<Seq <Digit Radix>~ℤ_2^64~machine.UInt64 > + ") + .apply_substitution(&|k|σ.get(k).cloned()).clone() + ).expect("cant descend") + .read().unwrap() + .view_seq::< usize >(); + + src_rt.write().unwrap().insert_leaf( + vec![ + Context::parse(&ctx, "<PosInt Radix BigEndian>") + .apply_substitution(&|k|σ.get(k).cloned()).clone(), + Context::parse(&ctx, "<Seq <Digit Radix>>") + .apply_substitution(&|k|σ.get(k).cloned()).clone(), + Context::parse(&ctx, "<Seq ℤ_2^64>"), + Context::parse(&ctx, "<Seq machine.UInt64>") + ].into_iter(), + + ReprLeaf::from_view( src_digits.reverse() ) + ); } - ) + } + ); + + + + + let morphism_type = MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>") + }; + + ctx.write().unwrap().morphisms.add_morphism( + morphism_type, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_radix = match σ.get(&laddertypes::TypeID::Var( + ctx.read().unwrap().get_var_typeid("SrcRadix").unwrap() + )) { + Some(laddertypes::TypeTerm::Num(n)) => *n as usize, + _ => 0 + }; + + let dst_radix = match σ.get(&laddertypes::TypeID::Var( + ctx.read().unwrap().get_var_typeid("DstRadix").unwrap() + )) { + Some(laddertypes::TypeTerm::Num(n)) => *n as usize, + _ => 0 + }; + + let src_digits_rt = ReprTree::descend( + src_rt, + Context::parse(&ctx, " + <PosInt SrcRadix LittleEndian> + ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64 >" + ).apply_substitution(&|k|σ.get(k).cloned()).clone() + ).expect("cant descend repr tree"); + + let dst_digits_port = + src_digits_rt.read().unwrap() + .view_seq::<usize>() + .to_positional_uint( src_radix ) + .transform_radix( dst_radix ) + ; + + src_rt.write().unwrap() + .insert_leaf( + vec![ + Context::parse(&ctx, "<PosInt DstRadix LittleEndian>").apply_substitution(&|k|σ.get(k).cloned()).clone(), + Context::parse(&ctx, "<Seq <Digit DstRadix>>").apply_substitution(&|k|σ.get(k).cloned()).clone(), + Context::parse(&ctx, "<Seq ℤ_2^64>"), + Context::parse(&ctx, "<Seq machine.UInt64>"), + ].into_iter(), + ReprLeaf::from_view(dst_digits_port) + ); + } + } ); - */ - /* - ctx.add_typename("Date".into()); - ctx.add_typename("ISO-8601".into()); - ctx.add_typename("TimeSince".into()); - ctx.add_typename("UnixEpoch".into()); - ctx.add_typename("AnnoDomini".into()); - ctx.add_typename("Epoch".into()); - ctx.add_typename("Duration".into()); - ctx.add_typename("Seconds".into()); - ctx.add_typename("ℕ".into()); - */ } diff --git a/lib-nested-core/src/editors/integer/mod.rs b/lib-nested-core/src/editors/integer/mod.rs index 70b0759..e86a431 100644 --- a/lib-nested-core/src/editors/integer/mod.rs +++ b/lib-nested-core/src/editors/integer/mod.rs @@ -10,3 +10,139 @@ pub use { ctx::init_ctx }; +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +use { + r3vi::{ + view::{ + View, ViewPort, OuterViewPort, + Observer, + ObserverBroadcast, + sequence::* + } + }, + crate::{ + editors::integer::radix::{ + PosIntProjections + } + }, + std::sync::{Arc, RwLock} +}; + +pub trait PositionalUInt : SequenceView<Item = usize> { + fn get_radix(&self) -> usize; + fn get_value(&self) -> usize { + let mut val = 0; + let mut r = 1; + for i in 0..self.len().unwrap_or(0) { + val += r * self.get(&i).unwrap(); + r *= self.get_radix(); + } + + val + } +} + +impl<V: PositionalUInt> PositionalUInt for RwLock<V> { + fn get_radix(&self) -> usize { + self.read().unwrap().get_radix() + } +} + +struct PosUIntFromDigits { + radix: usize, + src_digits: Option<Arc<dyn SequenceView<Item = usize>>>, + cast: Arc<RwLock<ObserverBroadcast<dyn PositionalUInt>>> +} + +impl View for PosUIntFromDigits { + type Msg = usize; +} + +impl SequenceView for PosUIntFromDigits { + type Item = usize; + + fn get(&self, idx: &usize) -> Option<usize> { + self.src_digits.get(idx) + } + + fn len(&self) -> Option<usize> { + self.src_digits.len() + } +} + +impl PositionalUInt for PosUIntFromDigits { + fn get_radix(&self) -> usize { + self.radix + } +} + +impl Observer<dyn SequenceView<Item = usize>> for PosUIntFromDigits { + fn reset(&mut self, new_src: Option<Arc<dyn SequenceView<Item = usize>>>) { + self.src_digits = new_src; +// self.cast.write().unwrap().notify(0); + } + + fn notify(&mut self, idx: &usize) { + self.cast.write().unwrap().notify(idx); + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub trait DigitSeqProjection { + fn to_positional_uint(&self, radix: usize) -> OuterViewPort<dyn PositionalUInt>; +} + +impl DigitSeqProjection for OuterViewPort<dyn SequenceView<Item = usize>> { + fn to_positional_uint(&self, radix: usize) -> OuterViewPort<dyn PositionalUInt> { + let port = ViewPort::new(); + port.add_update_hook(Arc::new(self.0.clone())); + + let proj = Arc::new(RwLock::new(PosUIntFromDigits { + radix, + src_digits: None, + cast: port.inner().get_broadcast() + })); + + self.add_observer(proj.clone()); + port.set_view(Some(proj)); + port.into_outer() + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +struct PosUIntToDigits { + src: Option<Arc<dyn PositionalUInt>>, + cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = usize>>>> +} + +impl View for PosUIntToDigits { + type Msg = usize; +} + +impl SequenceView for PosUIntToDigits { + type Item = usize; + + fn get(&self, idx: &usize) -> Option<usize> { + self.src.get(idx) + } + + fn len(&self) -> Option<usize> { + self.src.len() + } +} + +impl Observer<dyn PositionalUInt> for PosUIntToDigits { + fn reset(&mut self, view: Option<Arc<dyn PositionalUInt>>) { + self.src = view; +// self.cast.notify_all(); + } + + fn notify(&mut self, idx: &usize) { + self.cast.notify(idx); + } +} + + diff --git a/lib-nested-core/src/editors/integer/radix.rs b/lib-nested-core/src/editors/integer/radix.rs index bcc12da..db3506c 100644 --- a/lib-nested-core/src/editors/integer/radix.rs +++ b/lib-nested-core/src/editors/integer/radix.rs @@ -1,69 +1,127 @@ use { r3vi::{ view::{ + View, ViewPort, InnerViewPort, Observer, OuterViewPort, + ObserverBroadcast, sequence::*, + list::* }, buffer::{vec::*} }, + crate::{ + editors::integer::{ + PositionalUInt + }, + repr_tree::{ReprTree, ReprLeaf} + }, std::sync::{Arc, RwLock}, }; +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub trait PosIntProjections { + fn transform_radix(&self, dst_radix: usize) -> OuterViewPort<dyn SequenceView<Item = usize>>; +// fn to_digits(&self) -> OuterViewPort<dyn SequenceView<Item = usize>>; +} + +impl PosIntProjections for OuterViewPort<dyn PositionalUInt> { + fn transform_radix(&self, dst_radix: usize) -> OuterViewPort<dyn SequenceView<Item = usize>> { + let port = ViewPort::<dyn SequenceView<Item = usize>>::new(); + port.add_update_hook(Arc::new(self.0.clone())); + +// let mut vec_port = ViewPort::new(); + let proj = Arc::new(RwLock::new(RadixProjection { + src: None, + dst_radix, + dst_digits: VecBuffer::new(), + cast: port.inner().get_broadcast() + })); + + self.add_observer(proj.clone()); + port.set_view(Some(proj as Arc<dyn SequenceView<Item = usize>>)); + port.into_outer() + } +/* + fn to_digits(&self) -> OuterViewPort<dyn SequenceView<Item = usize>> { + let port = ViewPort::new(); + port.add_update_hook(Arc::new(self.0.clone())); + let proj = Arc::new(RwLock::new(PosUIntToDigits { + src: None, + cast: port.inner().get_broadcast() + })); + self.add_observer(proj.clone()); + port.inner().set_view(Some(proj)); + port.into_outer() + } + */ +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + pub struct RadixProjection { - src_radix: usize, + src: Option<Arc<dyn PositionalUInt>>, dst_radix: usize, - src_digits: Option<Arc<dyn SequenceView<Item = usize>>>, - dst_digits: RwLock<VecBuffer<usize>>, + dst_digits: VecBuffer<usize>, + cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = usize>>>> +} + +impl View for RadixProjection { + type Msg = usize; +} + +impl SequenceView for RadixProjection { + type Item = usize; + + fn get(&self, idx: &usize) -> Option<usize> { + if *idx < self.dst_digits.len() { + Some(self.dst_digits.get(*idx)) + } else { + None + } + } + + fn len(&self) -> Option<usize> { + Some(self.dst_digits.len()) + } +} + +impl PositionalUInt for RadixProjection { + fn get_radix(&self) -> usize { + self.dst_radix + } +} + +impl Observer< dyn PositionalUInt > for RadixProjection { + fn reset(&mut self, view: Option<Arc<dyn PositionalUInt>>) { + self.src = view; + self.update(); + } + + fn notify(&mut self, idx: &usize) { + self.update(); + // self.update_digit(idx) + } } impl RadixProjection { - pub fn new( - // static parameters - //--- - src_radix: usize, - dst_radix: usize, - //--- + /// recalculate everything + fn update(&mut self) { +// let mut dst = self.dst_digits; + let old_len = self.dst_digits.len(); + self.dst_digits.clear(); - // dynamic parameters - //--- - // input - src_digits: OuterViewPort<dyn SequenceView<Item = usize>>, - // output - dst_digits: InnerViewPort<RwLock<Vec<usize>>>, - //--- - ) -> Arc<RwLock<Self>> { - dst_digits.0.add_update_hook(Arc::new(src_digits.0.clone())); - let proj = Arc::new(RwLock::new(RadixProjection { - src_radix, - dst_radix, - src_digits: None, - dst_digits: RwLock::new(VecBuffer::with_port(dst_digits)), - })); - src_digits.add_observer(proj.clone()); - proj - } - - fn machine_int(&self) -> usize { - let mut val = 0; - let mut r = 1; - for i in 0..self.src_digits.len().unwrap_or(0) { - val += r * self.src_digits.get(&i).unwrap(); - r *= self.src_radix; + if let Some(src) = self.src.as_ref() { + let mut val = src.get_value(); + while val > 0 { + self.dst_digits.push(val % self.dst_radix); + val /= self.dst_radix; + } } - val - } - - // recalculate everything - fn update(&self) { - let mut dst = self.dst_digits.write().unwrap(); - dst.clear(); - - let mut val = self.machine_int(); - - while val > 0 { - dst.push(val % self.dst_radix); - val /= self.dst_radix; + let new_len = self.dst_digits.len(); + for i in 0 .. usize::max(old_len, new_len) { + self.cast.write().unwrap().notify(&i); } } @@ -84,18 +142,3 @@ impl RadixProjection { } } -impl Observer<dyn SequenceView<Item = usize>> for RadixProjection { - fn reset(&mut self, view: Option<Arc<dyn SequenceView<Item = usize>>>) { - self.src_digits = view; - } - - fn notify(&mut self, _idx: &usize) { - // todo: - // src digit i changed. - // which dst-digits does it affect? - // update dst-digit j: - - // ...but for now the easy way - self.update(); - } -} diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 79943db..808e28c 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -92,6 +92,41 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } ); + let mt = crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<List <Digit 16>>~EditTree"), + dst_type: Context::parse(&ctx, "<List <Digit 16>~Char>") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let edittree = + src_rt + .descend(Context::parse(&ctx, "EditTree")).unwrap() + .singleton_buffer::<EditTree>(); + + let list_edit = edittree.get().get_edit::< ListEditor >().unwrap(); + let edittree_items = list_edit.read().unwrap().data.get_port().to_list(); + src_rt.write().unwrap().insert_leaf( + vec![ Context::parse(&ctx, "<List Char>") ].into_iter(), + ReprLeaf::from_view( + edittree_items + .map( + |edittree_char| + edittree_char + .read().unwrap() + .get_edit::<crate::editors::digit::editor::DigitEditor>().unwrap() + .read().unwrap() + .get_char() + ) + ) + ); + } + } + ); + + let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Char>"), diff --git a/lib-nested-core/src/lib.rs b/lib-nested-core/src/lib.rs index bca12dc..b942062 100644 --- a/lib-nested-core/src/lib.rs +++ b/lib-nested-core/src/lib.rs @@ -1,4 +1,6 @@ +#![feature(trait_upcasting)] + pub mod repr_tree; pub mod edit_tree; pub mod editors; diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 3b58eb8..a5c47a8 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -396,6 +396,10 @@ impl ReprTree { pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available") } + + pub fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>> { + self.get_port::<dyn SingletonView<Item = usize>>().expect("no usize-view available") + } } @@ -412,6 +416,7 @@ pub trait ReprTreeExt { fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>; fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>; fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>; + fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>>; fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>; fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>; @@ -446,6 +451,10 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { self.read().unwrap().view_u64() } + fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>> { + self.read().unwrap().view_usize() + } + fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T> { self.write().unwrap().singleton_buffer::<T>().expect("") } From fdecc29e809bcb2caf5b287617a7819dbefd08b5 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 25 May 2024 19:21:16 +0200 Subject: [PATCH 39/75] clean up posint example & use u64 instead of usize in PositionalUInt trait --- examples/tty-04-posint/src/main.rs | 164 +++++++++++-------- lib-nested-core/src/editors/digit/ctx.rs | 22 +-- lib-nested-core/src/editors/integer/ctx.rs | 12 +- lib-nested-core/src/editors/integer/mod.rs | 34 ++-- lib-nested-core/src/editors/integer/radix.rs | 20 +-- lib-nested-core/src/repr_tree/mod.rs | 20 +++ lib-nested-core/src/repr_tree/tests.rs | 50 +++--- 7 files changed, 184 insertions(+), 138 deletions(-) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index 687d345..659d499 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -43,48 +43,54 @@ async fn main() { nested::editors::list::init_ctx( ctx.clone() ); nested_tty::setup_edittree_hook(&ctx); - /* Create a Representation-Tree of type <List <Digit 16>> - */ - let mut rt_digitlist = ReprTree::new_arc( Context::parse(&ctx, "<List <Digit 16>>") ); - let mut rt_digitseq = ReprTree::new_arc( Context::parse(&ctx, "<Seq <Digit 16>>") ); - rt_digitseq.insert_branch( rt_digitlist ); - let mut rt_posint = ReprTree::new_arc(Context::parse(&ctx, "<PosInt 16 BigEndian>")); - rt_posint.insert_branch( rt_digitseq ); - let mut rt_int = ReprTree::new_arc( Context::parse(&ctx, "ℕ") ); - rt_int.insert_branch( rt_posint ); - /* Setup an Editor for this ReprTree - * (this will add the representation <List <Digit 16>>~EditTree to the ReprTree) + /* Create a Representation-Tree of type `ℕ` + */ + let mut rt_int = ReprTree::new_arc( Context::parse(&ctx, "ℕ") ); + + /* Add a specific Representation-Path (big-endian hexadecimal) + */ + rt_int.create_branch( + Context::parse(&ctx, "<PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>>") + ); + + /* Setup an Editor for the big-endian hexadecimal representation + * (this will add the representation `<List <Digit 16>>~EditTree` to the ReprTree) */ let rt_edittree_list = ctx.read().unwrap() .setup_edittree( - ReprTree::descend( - &rt_int, - Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq~List <Digit 16>>") - ).expect("cant descend reprtree"), + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ")).expect("cant descend reprtree"), SingletonBuffer::new(0).get_port() ); + /* Setup a morphism to extract Char values from the list-editor + */ ctx.read().unwrap().morphisms.apply_morphism( - ReprTree::descend(&rt_int, - Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~<Seq <Digit 16>> - ~<List <Digit 16>> - ") - ).expect("cant descend repr tree"), + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ")).expect("cant descend reprtree"), &Context::parse(&ctx, "<List <Digit 16>>~EditTree"), &Context::parse(&ctx, "<List <Digit 16>~Char>") ); /* * map seq of chars to seq of u64 digits + * and add this projection to the ReprTree */ - let mut chars_view = - ReprTree::descend( - &rt_int, - Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char>") - ).expect("cant descend") + + // + //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV + let mut chars_view = rt_int.descend(Context::parse(&ctx, " + < PosInt 16 BigEndian > + ~ < Seq <Digit 16> > + ~ < List <Digit 16>~Char > + ")).expect("cant descend") .read().unwrap() .get_port::<dyn ListView<char>>() .unwrap(); @@ -94,75 +100,85 @@ async fn main() { .filter_map( |digit_char| - /* TODO: call morphism + /* TODO: call morphism for each item */ match digit_char.to_digit(16) { - Some(d) => Some(d as usize), + Some(d) => Some(d as u64), None => None } ); - rt_int.write().unwrap().insert_leaf( - vec![ - Context::parse(&ctx, "<PosInt 16 BigEndian>"), - Context::parse(&ctx, "<Seq <Digit 16>>"), - Context::parse(&ctx, "<Seq ℤ_2^64>"), - Context::parse(&ctx, "<Seq machine.UInt64>") - ].into_iter(), + rt_int.insert_leaf(Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~ <Seq <Digit 16> + ~ ℤ_2^64 + ~ machine.UInt64 > + "), nested::repr_tree::ReprLeaf::from_view( digits_view.clone() ) ); - // + //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ // + + /* convert to little endian + */ ctx.read().unwrap().morphisms.apply_morphism( rt_int.clone(), &Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>"), &Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>") ); + + /* convert to decimal + */ ctx.read().unwrap().morphisms.apply_morphism( rt_int.clone(), &Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>"), &Context::parse(&ctx, "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>") ); + + /* convert back to big endian + */ ctx.read().unwrap().morphisms.apply_morphism( rt_int.clone(), &Context::parse(&ctx, "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>"), &Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>") ); - let dec_digits_view = ReprTree::descend(&rt_int, - Context::parse(&ctx, " - <PosInt 10 BigEndian> - ~< Seq <Digit 10>~ℤ_2^64~machine.UInt64 > - ") - ).expect("cant descend repr tree") - .read().unwrap() - .get_port::<dyn SequenceView<Item = usize>>().unwrap() - .map( - /* TODO: call morphism - */ - |digit| { - TerminalAtom::from( - char::from_digit(*digit as u32, 10) - ) - } - ) - .to_grid_horizontal(); + /* map seq of u64 digits to seq of chars + * and add this projection to the ReprTree + */ - let hex_digits_view = - ReprTree::descend( - &rt_int, - Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~<Seq <Digit 16> > - ~<List <Digit 16> - ~Char>") - ).expect("cant descend") + // + //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV + let dec_digits_view = + rt_int.descend(Context::parse(&ctx, " + < PosInt 10 BigEndian > + ~ < Seq <Digit 10> + ~ ℤ_2^64 + ~ machine.UInt64 > + ")).expect("cant descend repr tree") .read().unwrap() - .get_port::<dyn ListView<char>>().unwrap() - .to_sequence() - .to_grid_horizontal() - .map_item(|_pt,c| TerminalAtom::new(*c, TerminalStyle::fg_color((30,90,200)))); + .get_port::<dyn SequenceView<Item = u64>>().unwrap() + .map(|digit| TerminalAtom::from(char::from_digit(*digit as u32, 10))) + .to_grid_horizontal(); + //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ + // + //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV + let hex_digits_view = + rt_int.descend(Context::parse(&ctx, " + < PosInt 16 BigEndian > + ~ < Seq <Digit 16> + ~ ℤ_2^64 + ~ machine.UInt64 > + ")).expect("cant descend") + .read().unwrap() + .view_seq::< u64 >() + .map(|digit| TerminalAtom::from(char::from_digit(*digit as u32, 16))) + .to_grid_horizontal(); + //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ + // + + /* setup terminal */ @@ -198,11 +214,19 @@ async fn main() { .display_view() .offset(Vector2::new(3,2))); - comp.push(dec_digits_view.offset(Vector2::new(3,4))); - comp.push(hex_digits_view.offset(Vector2::new(3,5))); + comp.push(nested_tty::make_label("dec: ").offset(Vector2::new(3,4))); + comp.push(dec_digits_view.offset(Vector2::new(8,4)).map_item(|_,a| { + a.add_style_back(TerminalStyle::fg_color((30,90,200))) + })); + + comp.push(nested_tty::make_label("hex: ").offset(Vector2::new(3,5))); + comp.push(hex_digits_view.offset(Vector2::new(8,5)).map_item(|_,a| { + a.add_style_back(TerminalStyle::fg_color((200, 200, 30))) + })); } /* write the changes in the view of `term_port` to the terminal */ app.show().await.expect("output error!"); } + diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index d5822c2..b87e5ec 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -98,18 +98,18 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { _ => 0 }; - if radix <= 256 { + if radix <= 16 { if let Some(src_rt) = rt.descend(Context::parse(&ctx, "Char")) { /* insert projected view into ReprTree */ - let u8_view = + let u64_view = src_rt.view_char() - .map(move |c| c.to_digit(radix).unwrap_or(0) as u8); + .map(move |c| c.to_digit(radix).unwrap_or(0) as u64); - rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = u8>>( - Context::parse(&ctx, "ℤ_256~machine::UInt8").get_lnf_vec().into_iter(), - u8_view + rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = u64>>( + Context::parse(&ctx, "ℤ_2^64~machine.UInt64").get_lnf_vec().into_iter(), + u64_view ); } else { eprintln!("could not find required source representation: <Digit {}>~Char", radix); @@ -134,20 +134,20 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| { /* infer radix from type */ - let radix = + let radix = match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { Some(TypeTerm::Num(n)) => (*n) as u32, _ => 0 }; - if radix <= 256 { + if radix <= 16 { /* insert projected view into ReprTree */ let char_view = - rt.descend(Context::parse(&ctx, "ℤ_2^64~machine::UInt64")) + rt.descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")) .unwrap() - .view_usize() - .map(move |digit| char::from_digit((digit%radix as usize) as u32, radix).unwrap_or('?')); + .view_u64() + .map(move |digit| char::from_digit((digit%radix as u64) as u32, radix).unwrap_or('?')); rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = char>>( Context::parse(&ctx, "Char").get_lnf_vec().into_iter(), diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 23eeab6..958ec65 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -39,7 +39,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { .apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend") .read().unwrap() - .view_seq::< usize >(); + .view_seq::< u64 >(); src_rt.write().unwrap().insert_leaf( vec![ @@ -60,6 +60,8 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { + + let morphism_type = MorphismType { src_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>"), dst_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>") @@ -79,7 +81,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { .apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend") .read().unwrap() - .view_seq::< usize >(); + .view_seq::< u64 >(); src_rt.write().unwrap().insert_leaf( vec![ @@ -113,14 +115,14 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { let src_radix = match σ.get(&laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("SrcRadix").unwrap() )) { - Some(laddertypes::TypeTerm::Num(n)) => *n as usize, + Some(laddertypes::TypeTerm::Num(n)) => *n as u64, _ => 0 }; let dst_radix = match σ.get(&laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("DstRadix").unwrap() )) { - Some(laddertypes::TypeTerm::Num(n)) => *n as usize, + Some(laddertypes::TypeTerm::Num(n)) => *n as u64, _ => 0 }; @@ -134,7 +136,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { let dst_digits_port = src_digits_rt.read().unwrap() - .view_seq::<usize>() + .view_seq::<u64>() .to_positional_uint( src_radix ) .transform_radix( dst_radix ) ; diff --git a/lib-nested-core/src/editors/integer/mod.rs b/lib-nested-core/src/editors/integer/mod.rs index e86a431..b7cd6df 100644 --- a/lib-nested-core/src/editors/integer/mod.rs +++ b/lib-nested-core/src/editors/integer/mod.rs @@ -29,9 +29,9 @@ use { std::sync::{Arc, RwLock} }; -pub trait PositionalUInt : SequenceView<Item = usize> { - fn get_radix(&self) -> usize; - fn get_value(&self) -> usize { +pub trait PositionalUInt : SequenceView<Item = u64> { + fn get_radix(&self) -> u64; + fn get_value(&self) -> u64 { let mut val = 0; let mut r = 1; for i in 0..self.len().unwrap_or(0) { @@ -44,14 +44,14 @@ pub trait PositionalUInt : SequenceView<Item = usize> { } impl<V: PositionalUInt> PositionalUInt for RwLock<V> { - fn get_radix(&self) -> usize { + fn get_radix(&self) -> u64 { self.read().unwrap().get_radix() } } struct PosUIntFromDigits { - radix: usize, - src_digits: Option<Arc<dyn SequenceView<Item = usize>>>, + radix: u64, + src_digits: Option<Arc<dyn SequenceView<Item = u64>>>, cast: Arc<RwLock<ObserverBroadcast<dyn PositionalUInt>>> } @@ -60,9 +60,9 @@ impl View for PosUIntFromDigits { } impl SequenceView for PosUIntFromDigits { - type Item = usize; + type Item = u64; - fn get(&self, idx: &usize) -> Option<usize> { + fn get(&self, idx: &usize) -> Option<u64> { self.src_digits.get(idx) } @@ -72,13 +72,13 @@ impl SequenceView for PosUIntFromDigits { } impl PositionalUInt for PosUIntFromDigits { - fn get_radix(&self) -> usize { + fn get_radix(&self) -> u64 { self.radix } } -impl Observer<dyn SequenceView<Item = usize>> for PosUIntFromDigits { - fn reset(&mut self, new_src: Option<Arc<dyn SequenceView<Item = usize>>>) { +impl Observer<dyn SequenceView<Item = u64>> for PosUIntFromDigits { + fn reset(&mut self, new_src: Option<Arc<dyn SequenceView<Item = u64>>>) { self.src_digits = new_src; // self.cast.write().unwrap().notify(0); } @@ -91,11 +91,11 @@ impl Observer<dyn SequenceView<Item = usize>> for PosUIntFromDigits { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub trait DigitSeqProjection { - fn to_positional_uint(&self, radix: usize) -> OuterViewPort<dyn PositionalUInt>; + fn to_positional_uint(&self, radix: u64) -> OuterViewPort<dyn PositionalUInt>; } -impl DigitSeqProjection for OuterViewPort<dyn SequenceView<Item = usize>> { - fn to_positional_uint(&self, radix: usize) -> OuterViewPort<dyn PositionalUInt> { +impl DigitSeqProjection for OuterViewPort<dyn SequenceView<Item = u64>> { + fn to_positional_uint(&self, radix: u64) -> OuterViewPort<dyn PositionalUInt> { let port = ViewPort::new(); port.add_update_hook(Arc::new(self.0.clone())); @@ -115,7 +115,7 @@ impl DigitSeqProjection for OuterViewPort<dyn SequenceView<Item = usize>> { struct PosUIntToDigits { src: Option<Arc<dyn PositionalUInt>>, - cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = usize>>>> + cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = u64>>>> } impl View for PosUIntToDigits { @@ -123,9 +123,9 @@ impl View for PosUIntToDigits { } impl SequenceView for PosUIntToDigits { - type Item = usize; + type Item = u64; - fn get(&self, idx: &usize) -> Option<usize> { + fn get(&self, idx: &usize) -> Option<u64> { self.src.get(idx) } diff --git a/lib-nested-core/src/editors/integer/radix.rs b/lib-nested-core/src/editors/integer/radix.rs index db3506c..4c5cf31 100644 --- a/lib-nested-core/src/editors/integer/radix.rs +++ b/lib-nested-core/src/editors/integer/radix.rs @@ -21,13 +21,13 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub trait PosIntProjections { - fn transform_radix(&self, dst_radix: usize) -> OuterViewPort<dyn SequenceView<Item = usize>>; + fn transform_radix(&self, dst_radix: u64) -> OuterViewPort<dyn SequenceView<Item = u64>>; // fn to_digits(&self) -> OuterViewPort<dyn SequenceView<Item = usize>>; } impl PosIntProjections for OuterViewPort<dyn PositionalUInt> { - fn transform_radix(&self, dst_radix: usize) -> OuterViewPort<dyn SequenceView<Item = usize>> { - let port = ViewPort::<dyn SequenceView<Item = usize>>::new(); + fn transform_radix(&self, dst_radix: u64) -> OuterViewPort<dyn SequenceView<Item = u64>> { + let port = ViewPort::<dyn SequenceView<Item = u64>>::new(); port.add_update_hook(Arc::new(self.0.clone())); // let mut vec_port = ViewPort::new(); @@ -39,7 +39,7 @@ impl PosIntProjections for OuterViewPort<dyn PositionalUInt> { })); self.add_observer(proj.clone()); - port.set_view(Some(proj as Arc<dyn SequenceView<Item = usize>>)); + port.set_view(Some(proj as Arc<dyn SequenceView<Item = u64>>)); port.into_outer() } /* @@ -61,9 +61,9 @@ impl PosIntProjections for OuterViewPort<dyn PositionalUInt> { pub struct RadixProjection { src: Option<Arc<dyn PositionalUInt>>, - dst_radix: usize, - dst_digits: VecBuffer<usize>, - cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = usize>>>> + dst_radix: u64, + dst_digits: VecBuffer<u64>, + cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = u64>>>> } impl View for RadixProjection { @@ -71,9 +71,9 @@ impl View for RadixProjection { } impl SequenceView for RadixProjection { - type Item = usize; + type Item = u64; - fn get(&self, idx: &usize) -> Option<usize> { + fn get(&self, idx: &usize) -> Option<u64> { if *idx < self.dst_digits.len() { Some(self.dst_digits.get(*idx)) } else { @@ -87,7 +87,7 @@ impl SequenceView for RadixProjection { } impl PositionalUInt for RadixProjection { - fn get_radix(&self) -> usize { + fn get_radix(&self) -> u64 { self.dst_radix } } diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index a5c47a8..55c74ec 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -411,6 +411,7 @@ pub trait ReprTreeExt { fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf); fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>); + fn create_branch(&mut self, rung: impl Into<TypeTerm>); fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>; fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>; @@ -435,6 +436,25 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { self.write().unwrap().insert_branch(repr) } + fn create_branch(&mut self, rung: impl Into<TypeTerm>) { + let lnf = rung.into().get_lnf_vec(); + eprintln!("lnf ={:?}",lnf); + + let mut child = None; + for rung in lnf.iter().rev() { + eprintln!("create {:?}",rung); + let mut parent = ReprTree::new_arc( rung.clone() ); + if let Some(c) = child.take() { + parent.insert_branch( c ); + } + child = Some(parent); + } + + if let Some(child) = child.take() { + self.insert_branch(child); + } + } + fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { ReprTree::descend( self, target_type ) } diff --git a/lib-nested-core/src/repr_tree/tests.rs b/lib-nested-core/src/repr_tree/tests.rs index 19fa23c..4970d06 100644 --- a/lib-nested-core/src/repr_tree/tests.rs +++ b/lib-nested-core/src/repr_tree/tests.rs @@ -45,7 +45,7 @@ fn char_view() { } #[test] -fn digit_projection_char_to_u8() { +fn digit_projection_char_to_u64() { let ctx = Arc::new(RwLock::new(Context::new())); crate::editors::digit::init_ctx( ctx.clone() ); @@ -62,14 +62,14 @@ fn digit_projection_char_to_u8() { ctx.read().unwrap().morphisms.apply_morphism( rt_digit.clone(), &Context::parse(&ctx, "<Digit 16>~Char"), - &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8") + &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64") ); - let digit_u8_view = rt_digit - .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() - .view_u8(); + let digit_u64_view = rt_digit + .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap() + .view_u64(); - assert_eq!( digit_u8_view.get_view().unwrap().get(), 5 as u8 ); + assert_eq!( digit_u64_view.get_view().unwrap().get(), 5 as u64 ); // projection behaves accordingly , when buffer is changed @@ -79,19 +79,19 @@ fn digit_projection_char_to_u8() { .singleton_buffer::<char>(); digit_char_buffer.set('2'); - assert_eq!( digit_u8_view.get_view().unwrap().get(), 2 as u8 ); + assert_eq!( digit_u64_view.get_view().unwrap().get(), 2 as u64 ); } #[test] -fn digit_projection_u8_to_char() { +fn digit_projection_u64_to_char() { let ctx = Arc::new(RwLock::new(Context::new())); crate::editors::digit::init_ctx( ctx.clone() ); let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); rt_digit.insert_leaf( - Context::parse(&ctx, "ℤ_256~machine::UInt8"), - ReprLeaf::from_singleton_buffer( SingletonBuffer::new(5 as u8) ) + Context::parse(&ctx, "ℤ_2^64~machine.UInt64"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new(5 as u64) ) ); //<><><><> @@ -99,15 +99,15 @@ fn digit_projection_u8_to_char() { ctx.read().unwrap().morphisms.apply_morphism( rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8"), + &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64"), &Context::parse(&ctx, "<Digit 16>~Char") ); - let digit_u8_view = rt_digit + let digit_u64_view = rt_digit .descend(Context::parse(&ctx, "Char")).unwrap() .view_char(); - assert_eq!( digit_u8_view.get_view().unwrap().get(), '5' ); + assert_eq!( digit_u64_view.get_view().unwrap().get(), '5' ); } @@ -119,15 +119,15 @@ fn char_buffered_projection() { let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); rt_digit.insert_leaf( - Context::parse(&ctx, "ℤ_256~machine::UInt8"), - ReprLeaf::from_singleton_buffer( SingletonBuffer::new(8 as u8) ) + Context::parse(&ctx, "ℤ_2^64~machine.UInt64"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new(8 as u64) ) ); - let mut digit_u8_buffer = rt_digit - .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() - .singleton_buffer::<u8>(); + let mut digit_u64_buffer = rt_digit + .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap() + .singleton_buffer::<u64>(); - assert_eq!( digit_u8_buffer.get(), 8 ); + assert_eq!( digit_u64_buffer.get(), 8 ); rt_digit.insert_leaf( Context::parse(&ctx, "Char"), @@ -145,20 +145,20 @@ fn char_buffered_projection() { assert_eq!( digit_char_buf.get(), '5' ); assert_eq!( digit_char_view.get_view().unwrap().get(), '5' ); - // now we attach the char-repr to the u8-repr + // now we attach the char-repr to the u64-repr ctx.read().unwrap().morphisms.apply_morphism( rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8"), + &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64"), &Context::parse(&ctx, "<Digit 16>~Char") ); - // char buffer and view should now follow the u8-buffer + // char buffer and view should now follow the u64-buffer assert_eq!( digit_char_view.get_view().unwrap().get(), '8' ); assert_eq!( digit_char_buf.get(), '8' ); - // now u8-buffer changes, and char-buffer should change accordingly - digit_u8_buffer.set(3); - assert_eq!( digit_u8_buffer.get(), 3 ); + // now u64-buffer changes, and char-buffer should change accordingly + digit_u64_buffer.set(3); + assert_eq!( digit_u64_buffer.get(), 3 ); // char buffer should follow digit_char_view.0.update(); From d02f33ee177958631ede178a41f0f73db6550db6 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 30 May 2024 23:35:54 +0200 Subject: [PATCH 40/75] ReprTree: add halo type --- lib-nested-core/src/repr_tree/mod.rs | 55 ++++++++++++++++++-------- lib-nested-core/src/repr_tree/tests.rs | 24 +++++++++++ 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 55c74ec..13c3daa 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -44,6 +44,7 @@ pub struct ReprLeaf { #[derive(Clone)] pub struct ReprTree { + halo: TypeTerm, type_tag: TypeTerm, branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>, leaf: Option< ReprLeaf > @@ -207,8 +208,13 @@ impl ReprLeaf { impl ReprTree { pub fn new(type_tag: impl Into<TypeTerm>) -> Self { + let type_tag = type_tag.into(); + + assert!(type_tag.is_flat()); + ReprTree { - type_tag: type_tag.into(), + halo: TypeTerm::unit(), + type_tag: type_tag.clone(), branches: HashMap::new(), leaf: None } @@ -222,8 +228,31 @@ impl ReprTree { &self.type_tag } + pub fn set_halo(&mut self, halo_type: impl Into<TypeTerm>) { + self.halo = halo_type.into(); + for (branch_type, branch) in self.branches.iter() { + branch.write().unwrap().set_halo( TypeTerm::Ladder(vec![ + self.halo.clone(), + self.type_tag.clone() + ]).normalize() + ); + } + } + + pub fn get_halo_type(&self) -> &TypeTerm { + &self.halo + } + pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { - self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone()); + let branch_type = repr.read().unwrap().get_type().clone(); + + assert!(branch_type.is_flat()); + + repr.write().unwrap().set_halo( TypeTerm::Ladder(vec![ + self.halo.clone(), + self.type_tag.clone() + ]).normalize() ); + self.branches.insert(branch_type, repr.clone()); } pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char ) -> Arc<RwLock<Self>> { @@ -250,7 +279,6 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } - pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> Arc<RwLock<Self>> where T: Clone + Send + Sync + 'static { @@ -437,21 +465,16 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { } fn create_branch(&mut self, rung: impl Into<TypeTerm>) { - let lnf = rung.into().get_lnf_vec(); - eprintln!("lnf ={:?}",lnf); + let mut lnf = rung.into().get_lnf_vec().into_iter(); + if let Some(rung) = lnf.next() { + let mut parent = ReprTree::new_arc( rung ); + self.insert_branch( parent.clone() ); - let mut child = None; - for rung in lnf.iter().rev() { - eprintln!("create {:?}",rung); - let mut parent = ReprTree::new_arc( rung.clone() ); - if let Some(c) = child.take() { - parent.insert_branch( c ); + for rung in lnf { + let r = ReprTree::new_arc( rung ); + parent.insert_branch(r.clone()); + parent = r; } - child = Some(parent); - } - - if let Some(child) = child.take() { - self.insert_branch(child); } } diff --git a/lib-nested-core/src/repr_tree/tests.rs b/lib-nested-core/src/repr_tree/tests.rs index 4970d06..4e6aa21 100644 --- a/lib-nested-core/src/repr_tree/tests.rs +++ b/lib-nested-core/src/repr_tree/tests.rs @@ -12,6 +12,30 @@ use { std::sync::{Arc, RwLock} }; +#[test] +fn halo_type() { + let ctx = Arc::new(RwLock::new(Context::new())); + + let mut rt1 = ReprTree::new_arc(Context::parse(&ctx, "ℕ")); + let mut rt2 = ReprTree::new_arc(Context::parse(&ctx, "<PosInt 10 BigEndian>")); + rt1.insert_branch( rt2.clone() ); + assert_eq!( rt2.read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ") ); + + let mut rt3 = ReprTree::new_arc(Context::parse(&ctx, "<Seq <Digit 10>>")); + rt2.insert_branch( rt3.clone() ); + assert_eq!( rt3.read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ~<PosInt 10 BigEndian>") ); + + let rt4 = ReprTree::new_arc(Context::parse(&ctx, "<List <Digit 10>>")); + rt3.insert_branch( rt4.clone() ); + assert_eq!( rt4.read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ~<PosInt 10 BigEndian>~<Seq <Digit 10>>") ); + + + let mut r = ReprTree::new_arc(Context::parse(&ctx, "ℕ")); + r.create_branch(Context::parse(&ctx, "<PosInt 10 BigEndian>~<Seq <Digit 10>>")); + assert_eq!( r.descend(Context::parse(&ctx, "<PosInt 10 BigEndian>")).unwrap().read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ") ); + assert_eq!( r.descend(Context::parse(&ctx, "<PosInt 10 BigEndian>~<Seq <Digit 10>>")).unwrap().read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ~<PosInt 10 BigEndian>") ); +} + #[test] fn char_view() { let ctx = Arc::new(RwLock::new(Context::new())); From cdf03c9aae6ccc2a3368185a775474d8508d16f7 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 3 Jun 2024 17:02:08 +0200 Subject: [PATCH 41/75] improve morphisms for integer example --- examples/tty-04-posint/src/main.rs | 230 ++++++++++++++---- lib-nested-core/src/editors/integer/ctx.rs | 256 ++++++++++++++++++--- lib-nested-core/src/editors/list/ctx.rs | 142 +++++++++--- lib-nested-core/src/editors/list/editor.rs | 13 +- lib-nested-core/src/repr_tree/context.rs | 1 - lib-nested-tty/src/editors/mod.rs | 1 - 6 files changed, 543 insertions(+), 100 deletions(-) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index 659d499..d6887d4 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -17,7 +17,7 @@ use { ObjCommander }, repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, - edit_tree::{EditTree} + edit_tree::{EditTree, TreeNav, TreeCursor} }, nested_tty::{ DisplaySegment, TTYApplication, @@ -26,7 +26,7 @@ use { }, r3vi::{ buffer::{singleton::*, vec::*}, - view::{port::UpdateTask, list::*, sequence::*}, + view::{port::UpdateTask, singleton::*, list::*, sequence::*}, projection::* }, std::sync::{Arc, RwLock}, @@ -43,7 +43,6 @@ async fn main() { nested::editors::list::init_ctx( ctx.clone() ); nested_tty::setup_edittree_hook(&ctx); - /* Create a Representation-Tree of type `ℕ` */ let mut rt_int = ReprTree::new_arc( Context::parse(&ctx, "ℕ") ); @@ -51,45 +50,163 @@ async fn main() { /* Add a specific Representation-Path (big-endian hexadecimal) */ rt_int.create_branch( - Context::parse(&ctx, "<PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>>") + Context::parse(&ctx, "<PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>~Char>") + ); + rt_int.create_branch( + Context::parse(&ctx, "<PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>~Char>") + ); + rt_int.create_branch( + Context::parse(&ctx, "<PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10>~Char>") + ); + + eprintln!("make big endian hex repr"); + let mut b = VecBuffer::with_data(vec![ 'c', 'f', 'f' ]); + rt_int.insert_leaf( + Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>"), + nested::repr_tree::ReprLeaf::from_view( b.get_port().to_list() ) + ); + + let mut b_le = VecBuffer::with_data(vec!['3', '2', '1']); + rt_int.insert_leaf( + Context::parse(&ctx, "<PosInt 16 LittleEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>"), + nested::repr_tree::ReprLeaf::from_view( b_le.get_port().to_list() ) + ); + + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ~ <List Char> + ")).expect("descend"), + &Context::parse(&ctx, "<List Char>"), + &Context::parse(&ctx, "<List Char~EditTree>") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16> > + ~ <List <Digit 16>~Char~EditTree > + ")).expect("descend"), + &Context::parse(&ctx, "<List EditTree>"), + &Context::parse(&ctx, "<List EditTree>~<Vec EditTree>") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>~Char> + ")).expect("descend"), + &Context::parse(&ctx, "<List Char>~<List EditTree>~<Vec EditTree>"), + &Context::parse(&ctx, "<List Char>~EditTree") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>~Char > + ")).expect("descend"), + &Context::parse(&ctx, "<List Char>~EditTree"), + &Context::parse(&ctx, "<List Char>") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.clone(), + &Context::parse(&ctx, " + ℕ + ~ <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ~ <List Char> + "), + &Context::parse(&ctx, " + ℕ + ~ <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ~ <List Char> + ") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.clone(), + &Context::parse(&ctx, " + ℕ + ~ <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ~ <List Char> + "), + &Context::parse(&ctx, " + ℕ + ~ <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ~ <List Char> + ") + ); + + let edittree_hex_le_list = ctx.read().unwrap() + .setup_edittree( + rt_int.descend(Context::parse(&ctx," + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>~Char > + ")).expect("descend"), + SingletonBuffer::new(0).get_port() + ); + + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char> + ")).expect("descend"), + &Context::parse(&ctx, "<List Char>"), + &Context::parse(&ctx, "<List Char~EditTree>") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char~EditTree> + ")).expect("descend"), + &Context::parse(&ctx, "<List EditTree>"), + &Context::parse(&ctx, "<List EditTree>~<Vec EditTree>") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char> + ")).expect("descend"), + &Context::parse(&ctx, "<List Char>~<List EditTree>~<Vec EditTree>"), + &Context::parse(&ctx, "<List Char>~EditTree") + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char> + ")).expect("descend"), + &Context::parse(&ctx, "<List Char>~EditTree"), + &Context::parse(&ctx, "<List Char>") ); /* Setup an Editor for the big-endian hexadecimal representation * (this will add the representation `<List <Digit 16>>~EditTree` to the ReprTree) */ - let rt_edittree_list = ctx.read().unwrap() + let edittree_hex_be_list = ctx.read().unwrap() .setup_edittree( rt_int.descend(Context::parse(&ctx, " <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>> + ~ <List Char> ")).expect("cant descend reprtree"), SingletonBuffer::new(0).get_port() ); - /* Setup a morphism to extract Char values from the list-editor - */ - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ")).expect("cant descend reprtree"), - &Context::parse(&ctx, "<List <Digit 16>>~EditTree"), - &Context::parse(&ctx, "<List <Digit 16>~Char>") - ); - /* * map seq of chars to seq of u64 digits * and add this projection to the ReprTree */ - // //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV let mut chars_view = rt_int.descend(Context::parse(&ctx, " - < PosInt 16 BigEndian > - ~ < Seq <Digit 16> > - ~ < List <Digit 16>~Char > + <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>~Char> ")).expect("cant descend") .read().unwrap() .get_port::<dyn ListView<char>>() @@ -119,13 +236,24 @@ async fn main() { //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ // - /* convert to little endian */ ctx.read().unwrap().morphisms.apply_morphism( rt_int.clone(), - &Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>"), - &Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>") + &Context::parse(&ctx, " + ℕ + ~ <PosInt 16 BigEndian> + ~ <Seq <Digit 16> + ~ ℤ_2^64 + ~ machine.UInt64 > + "), + &Context::parse(&ctx, " + ℕ + ~ <PosInt 16 LittleEndian> + ~ <Seq <Digit 16> + ~ ℤ_2^64 + ~ machine.UInt64 > + ") ); /* convert to decimal @@ -144,6 +272,7 @@ async fn main() { &Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>") ); + /* map seq of u64 digits to seq of chars * and add this projection to the ReprTree */ @@ -178,18 +307,32 @@ async fn main() { //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ // + /* list of both editors + */ + let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); + list_editor.data.push( edittree_hex_be_list.value.clone() ); + list_editor.data.push( edittree_hex_le_list.value.clone() ); + let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); - + /* cursors are a bit screwed initially so fix them up + * TODO: how to fix this generally? + */ + edittree_hex_be_list.get().goto(TreeCursor::none()); + edittree_hex_le_list.get().goto(TreeCursor::none()); + edittree.goto(TreeCursor{ + leaf_mode: nested::editors::list::ListCursorMode::Insert, + tree_addr: vec![0,0] + }); + let edittree = Arc::new(RwLock::new(edittree)); + /* setup terminal */ let app = TTYApplication::new({ - let edittree_list = rt_edittree_list.clone(); - /* event handler */ let ctx = ctx.clone(); move |ev| { - edittree_list.get().send_cmd_obj(ev.to_repr_tree(&ctx)); + edittree.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -204,23 +347,32 @@ async fn main() { { let mut comp = compositor.write().unwrap(); - let label_str = ctx.read().unwrap().type_term_to_str(&rt_int.read().unwrap().get_type()); - comp.push( - nested_tty::make_label(&label_str) + fn show_edit_tree( ctx: &Arc<RwLock<Context>>, comp: &mut TerminalCompositor, rt: &Arc<RwLock<ReprTree>>, y: i16 ) + { + let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend"); + let halo_type = rt_edittree.read().unwrap().get_halo_type().clone(); + let edittree = rt_edittree.read().unwrap().get_view::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>().unwrap().get(); + + comp.push( nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) - .offset(Vector2::new(1,1))); + .offset(Vector2::new(1,y))); - comp.push(rt_edittree_list.get() - .display_view() - .offset(Vector2::new(3,2))); + comp.push( edittree.display_view() + .offset(Vector2::new(1,y+1))); + } - comp.push(nested_tty::make_label("dec: ").offset(Vector2::new(3,4))); - comp.push(dec_digits_view.offset(Vector2::new(8,4)).map_item(|_,a| { + show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>")).expect(""), 1); + show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>~Char>")).expect(""), 4); + + /* project the seq of u64 representations to a view + */ + comp.push(nested_tty::make_label("dec: ").offset(Vector2::new(3,7))); + comp.push(dec_digits_view.offset(Vector2::new(8,7)).map_item(|_,a| { a.add_style_back(TerminalStyle::fg_color((30,90,200))) })); - comp.push(nested_tty::make_label("hex: ").offset(Vector2::new(3,5))); - comp.push(hex_digits_view.offset(Vector2::new(8,5)).map_item(|_,a| { + comp.push(nested_tty::make_label("hex: ").offset(Vector2::new(3,8))); + comp.push(hex_digits_view.offset(Vector2::new(8,8)).map_item(|_,a| { a.add_style_back(TerminalStyle::fg_color((200, 200, 30))) })); } diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 958ec65..7ca2a22 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -1,11 +1,11 @@ use { r3vi::{ - view::{OuterViewPort, singleton::*} + view::{OuterViewPort, singleton::*, list::*} }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{ReprTree, ReprLeaf, Context, MorphismType}, + repr_tree::{ReprTree, ReprTreeExt, ReprLeaf, Context, MorphismType}, editors::{ list::*, integer::* @@ -16,13 +16,71 @@ use { pub fn init_ctx(ctx: Arc<RwLock<Context>>) { // TODO: proper scoping - // ctx.write().unwrap().add_varname("Radix"); + ctx.write().unwrap().add_varname("Radix"); ctx.write().unwrap().add_varname("SrcRadix"); ctx.write().unwrap().add_varname("DstRadix"); + let morphism_type = + MorphismType { + src_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix BigEndian> + ~ <Seq <Digit Radix> + ~ ℤ_2^64 + ~ machine.UInt64 >"), + dst_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix> + ~ ℤ_2^64 + ~ machine.UInt64 >") + }; + ctx.write().unwrap().morphisms.add_morphism( + morphism_type, { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_digits = src_rt.descend( + Context::parse(&ctx, " + <PosInt Radix BigEndian> + ~ <Seq <Digit Radix> + ~ ℤ_2^64 + ~ machine.UInt64 > + ") + .apply_substitution(&|k|σ.get(k).cloned()) + .clone() + ).expect("cant descend") + .read().unwrap() + .view_seq::< u64 >(); + + src_rt.insert_leaf(Context::parse(&ctx, " + <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix> + ~ ℤ_2^64 + ~ machine.UInt64 > + ").apply_substitution(&|k|σ.get(k).cloned()).clone(), + ReprLeaf::from_view( src_digits.reverse() ) + ); + } + } + ); + let morphism_type = MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>") + src_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List ℤ_2^64> + ~ <List machine.UInt64> + "), + dst_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List ℤ_2^64> + ~ <List machine.UInt64> + ") }; ctx.write().unwrap().morphisms.add_morphism( @@ -30,29 +88,67 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { { let ctx = ctx.clone(); move |src_rt, σ| { - let src_digits = ReprTree::descend( - &src_rt, - Context::parse(&ctx, " - <PosInt Radix BigEndian> - ~<Seq <Digit Radix>~ℤ_2^64~machine.UInt64 > + let src_digits = src_rt.descend(Context::parse(&ctx, " + <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > ") .apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend") .read().unwrap() - .view_seq::< u64 >(); + .get_port::< dyn ListView<u64> >().unwrap(); - src_rt.write().unwrap().insert_leaf( - vec![ - Context::parse(&ctx, "<PosInt Radix LittleEndian>") - .apply_substitution(&|k|σ.get(k).cloned()).clone(), - Context::parse(&ctx, "<Seq <Digit Radix>>") - .apply_substitution(&|k|σ.get(k).cloned()).clone(), - Context::parse(&ctx, "<Seq ℤ_2^64>"), - Context::parse(&ctx, "<Seq machine.UInt64>") - ].into_iter(), + src_rt.insert_leaf( + Context::parse(&ctx, " + <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64> + ").apply_substitution(&|k| σ.get(k).cloned()).clone(), + ReprLeaf::from_view( src_digits.reverse() ) + ); + } + } + ); - ReprLeaf::from_view( src_digits.reverse() ) - ); + + let mt = MorphismType { + src_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List Char> + "), + dst_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List Char> + ") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_digits = src_rt.descend(Context::parse(&ctx, " + <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>~Char > + ").apply_substitution(&|k|σ.get(k).cloned()).clone() + ).expect("cant descend") + .read().unwrap() + .get_port::< dyn ListView<char> >().unwrap(); + + src_rt.insert_leaf( + Context::parse(&ctx, " + < PosInt Radix LittleEndian > + ~ < Seq <Digit Radix> > + ~ < List <Digit Radix>~Char > + ").apply_substitution(&|k| σ.get(k).cloned()).clone(), + ReprLeaf::from_view( src_digits.reverse() ) + ); } } ); @@ -63,8 +159,8 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { let morphism_type = MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>") + src_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>") }; ctx.write().unwrap().morphisms.add_morphism( @@ -99,12 +195,117 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } ); + let morphism_type = + MorphismType { + src_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List ℤ_2^64> + ~ <List machine.UInt64> + "), + dst_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List ℤ_2^64> + ~ <List machine.UInt64> + ") + }; + ctx.write().unwrap().morphisms.add_morphism( + morphism_type, { + let ctx = ctx.clone(); + move |src_rt, σ| + { + let src_digits = ReprTree::descend( + &src_rt, + Context::parse(&ctx, " + <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>~ℤ_2^64~machine.UInt64 > + ") + .apply_substitution(&|k|σ.get(k).cloned()).clone() + ).expect("cant descend") + .read().unwrap() + .get_port::< dyn ListView<u64> >().unwrap(); + + src_rt.insert_leaf( + Context::parse(&ctx, " + <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>~ℤ_2^64~machine.UInt64 > + "), + ReprLeaf::from_view( src_digits.reverse() ) + ); + } + } + ); + + + + let mt = MorphismType { + src_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List Char> + "), + dst_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List Char> + ") + }; + + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_digits = src_rt.descend(Context::parse(&ctx, " + <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>~Char > + ").apply_substitution(&|k|σ.get(k).cloned()).clone() + ).expect("cant descend") + .read().unwrap() + .get_port::< dyn ListView<char> >().unwrap(); + + src_rt.insert_leaf( + Context::parse(&ctx, " + < PosInt Radix BigEndian > + ~ < Seq <Digit Radix> > + ~ < List <Digit Radix>~Char > + ").apply_substitution(&|k| σ.get(k).cloned()).clone(), + ReprLeaf::from_view( src_digits.reverse() ) + ); + } + } + ); + let morphism_type = MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>") + src_type: Context::parse(&ctx, " + ℕ + ~ <PosInt SrcRadix LittleEndian> + ~ <Seq <Digit SrcRadix> + ~ ℤ_2^64 + ~ machine.UInt64> + "), + dst_type: Context::parse(&ctx, " + ℕ + ~ <PosInt DstRadix LittleEndian> + ~ <Seq <Digit DstRadix> + ~ ℤ_2^64 + ~ machine.UInt64 > + ") }; ctx.write().unwrap().morphisms.add_morphism( @@ -138,8 +339,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { src_digits_rt.read().unwrap() .view_seq::<u64>() .to_positional_uint( src_radix ) - .transform_radix( dst_radix ) - ; + .transform_radix( dst_radix ); src_rt.write().unwrap() .insert_leaf( diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 808e28c..8bc584c 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -23,40 +23,99 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub fn init_ctx(ctx: Arc<RwLock<Context>>) { - ctx.write().unwrap().add_list_typename("List".into()); ctx.write().unwrap().add_varname("Item"); let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List Item>"), - dst_type: Context::parse(&ctx, "<List Item>~EditTree") + src_type: Context::parse(&ctx, "<List Char>"), + dst_type: Context::parse(&ctx, "<List Char~EditTree>") }; - ctx.write().unwrap().morphisms.add_morphism( - mt, - { - let ctx = ctx.clone(); - move |src_rt, σ| { - let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); - if let Some( item_type ) = σ.get( &item_id ) { + ctx.write().unwrap().morphisms.add_morphism(mt, { + let ctx = ctx.clone(); + move |src_rt, σ| { + let list_port = src_rt.read().unwrap().get_port::<dyn ListView<char>>().clone(); + if let Some(list_port) = list_port { + let edit_tree_list = + list_port + // for each char, create and EditTree + .map({ + let ctx = ctx.clone(); + move |c| { + let item_rt = ReprTree::from_char(&ctx, *c); + ctx.read().unwrap().setup_edittree( + item_rt.clone(), + SingletonBuffer::new(0).get_port() + ); + let et = item_rt + .descend(Context::parse(&ctx, "EditTree")).unwrap() + .read().unwrap() + .get_port::< dyn SingletonView<Item = EditTree> >() + .expect("cant get view port (EditTree)") + .get_view().unwrap() + .get(); + Arc::new(RwLock::new(et)) + } + }); - let mut edittree_list = ListEditor::new( - ctx.clone(), - item_type.clone() - ).into_node( - SingletonBuffer::<usize>::new(0).get_port() - ); - - src_rt.write().unwrap().insert_branch( - ReprTree::from_singleton_buffer( - Context::parse(&ctx, "EditTree"), - SingletonBuffer::new(edittree_list) - ) - ); - } else { - eprintln!("no item type"); - } + src_rt.write().unwrap().insert_leaf( + Context::parse(&ctx, "<List EditTree>").get_lnf_vec().into_iter(), + ReprLeaf::from_view( edit_tree_list ) + ); + } else { + eprintln!("morphism missing view port"); } } - ); + }); + + let mt = crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"), + dst_type: Context::parse(&ctx, "<List Item>~EditTree") + }; + ctx.write().unwrap().morphisms.add_morphism(mt, { + let ctx = ctx.clone(); + move |src_rt, σ| { + let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); + if let Some( item_type ) = σ.get( &item_id ) { + /* + let mut item_vec_buffer = VecBuffer::new(); + + eprintln!("try attach to data port"); + if let Some( list_port ) = + src_rt + .descend(Context::parse(&ctx, "<List EditTree>")).expect("") + .read().unwrap() + .get_port::< dyn ListView< Arc<RwLock<EditTree>> > >() + { + eprintln!("get list<edittree> port"); + item_vec_buffer.attach_to( list_port ); + }*/ + + let mut item_vec_rt = src_rt + .descend(Context::parse(&ctx, "<List EditTree>~<Vec EditTree>")) + .expect("cant descend src repr"); + + let item_vec_buffer = item_vec_rt + .write().unwrap() + .vec_buffer::< Arc<RwLock<EditTree>> >().expect("cant get vec buffer"); + + // eprintln!("create ListEditor"); + let mut list_editor = ListEditor::with_data(ctx.clone(), item_type.clone(), item_vec_buffer); + + let edittree_list = list_editor.into_node( + SingletonBuffer::<usize>::new(0).get_port() + ); + + // eprintln!("make edittree"); + src_rt.write().unwrap().insert_branch( + ReprTree::from_singleton_buffer( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new(edittree_list) + ) + ); + } else { + eprintln!("no item type"); + } + } + }); let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Char>~EditTree"), @@ -93,8 +152,8 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ); let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List <Digit 16>>~EditTree"), - dst_type: Context::parse(&ctx, "<List <Digit 16>~Char>") + src_type: Context::parse(&ctx, "<List <Digit Radix>>~EditTree"), + dst_type: Context::parse(&ctx, "<List <Digit Radix>~Char>") }; ctx.write().unwrap().morphisms.add_morphism( mt, @@ -127,7 +186,6 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ); - let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Char>"), dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>") @@ -151,5 +209,29 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } } ); + + let mt = crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<List EditTree>"), + dst_type: Context::parse(&ctx, "<List EditTree>~<Vec EditTree>") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let buf = VecBuffer::<Arc<RwLock<EditTree>>>::new(); + let mut leaf = ReprLeaf::from_vec_buffer(buf); + leaf.attach_to( + src_rt.read().unwrap() + .get_port::<dyn ListView< Arc<RwLock<EditTree>> >>() + .unwrap() + ); + src_rt.write().unwrap().insert_leaf( + vec![ Context::parse(&ctx, "<Vec EditTree>") ].into_iter(), + leaf + ); + } + } + ); } diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 00020e7..1bb0351 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -35,11 +35,22 @@ pub struct ListEditor { impl ListEditor { pub fn new( + ctx: Arc<RwLock<Context>>, + typ: TypeTerm + ) -> Self { + Self::with_data( + ctx, + typ, + VecBuffer::new() + ) + } + + pub fn with_data( ctx: Arc<RwLock<Context>>, typ: TypeTerm, + data: VecBuffer<Arc<RwLock<EditTree>>> ) -> Self { let cursor = SingletonBuffer::new(ListCursor::default()); - let data : VecBuffer<Arc<RwLock<EditTree>>> = VecBuffer::new(); ListEditor { mode_port: cursor diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 3d0bfce..4835736 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -55,7 +55,6 @@ impl Context { None => Vec::new() }, parent, - edittree_hook: Arc::new(|_et, _t| {}) } } diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 4ce366e..0cf01fb 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -21,7 +21,6 @@ use { pub fn edittree_make_char_view( node: EditTree ) -> EditTree { - eprintln!("nested-tty: EditTree make char-view"); node.disp.view .write().unwrap() .insert_branch(ReprTree::from_view( From ab51ea5d3d8bcd0d83d7deb8e7be6088435df7b5 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 5 Jun 2024 02:16:09 +0200 Subject: [PATCH 42/75] rename pty&tty servers --- Cargo.toml | 6 +++++- {pty-server => srv-pty-capture}/Cargo.toml | 2 +- {pty-server => srv-pty-capture}/src/main.rs | 2 +- {display-server-tty => srv-tty-output}/Cargo.toml | 2 +- {display-server-tty => srv-tty-output}/src/main.rs | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) rename {pty-server => srv-pty-capture}/Cargo.toml (93%) rename {pty-server => srv-pty-capture}/src/main.rs (99%) rename {display-server-tty => srv-tty-output}/Cargo.toml (92%) rename {display-server-tty => srv-tty-output}/src/main.rs (97%) diff --git a/Cargo.toml b/Cargo.toml index b3de67d..44403c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,9 +2,13 @@ members = [ "lib-nested-core", "lib-nested-tty", + + "srv-tty-output", + "srv-pty-capture", + "examples/tty-01-hello", "examples/tty-02-digit", "examples/tty-03-string", - "examples/tty-04-posint" + "examples/tty-04-posint", ] diff --git a/pty-server/Cargo.toml b/srv-pty-capture/Cargo.toml similarity index 93% rename from pty-server/Cargo.toml rename to srv-pty-capture/Cargo.toml index 86e08e0..3453d45 100644 --- a/pty-server/Cargo.toml +++ b/srv-pty-capture/Cargo.toml @@ -1,6 +1,6 @@ [package] authors = ["Michael Sippel <micha@fragmental.art>"] -name = "pty-server" +name = "srv-pty-capture" version = "0.1.0" edition = "2018" diff --git a/pty-server/src/main.rs b/srv-pty-capture/src/main.rs similarity index 99% rename from pty-server/src/main.rs rename to srv-pty-capture/src/main.rs index 0e4d532..5d531ac 100644 --- a/pty-server/src/main.rs +++ b/srv-pty-capture/src/main.rs @@ -2,7 +2,7 @@ use { cgmath::Point2, - nested::terminal::{TerminalAtom, TerminalStyle}, + nested_tty::{TerminalAtom, TerminalStyle}, std::{ fs::File, io::{stdin, Read, Write}, diff --git a/display-server-tty/Cargo.toml b/srv-tty-output/Cargo.toml similarity index 92% rename from display-server-tty/Cargo.toml rename to srv-tty-output/Cargo.toml index 3c5d783..314e9f5 100644 --- a/display-server-tty/Cargo.toml +++ b/srv-tty-output/Cargo.toml @@ -1,6 +1,6 @@ [package] authors = ["Michael Sippel <micha@fragmental.art>"] -name = "display-server-tty" +name = "srv-tty-output" version = "0.1.0" edition = "2018" diff --git a/display-server-tty/src/main.rs b/srv-tty-output/src/main.rs similarity index 97% rename from display-server-tty/src/main.rs rename to srv-tty-output/src/main.rs index a3f52fc..46f6c6e 100644 --- a/display-server-tty/src/main.rs +++ b/srv-tty-output/src/main.rs @@ -1,6 +1,6 @@ use { cgmath::{Point2, Vector2}, - nested::terminal::{TerminalAtom, TerminalStyle}, + nested_tty::{TerminalAtom, TerminalStyle}, std::io::{stdout, Read, Write}, termion::raw::IntoRawMode, }; From bb846afc7c0402978b76ea553e2b27b239fe527f Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 6 Jun 2024 15:21:52 +0200 Subject: [PATCH 43/75] ReprTree: add detach functions & attach_to helpers for Arc<ReprTree> --- lib-nested-core/src/repr_tree/mod.rs | 70 +++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 13c3daa..28488e5 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -15,7 +15,7 @@ use { ViewPort, OuterViewPort, AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, port::UpdateTask, - View, + View, Observer, singleton::*, sequence::*, list::* @@ -85,6 +85,20 @@ impl ReprLeaf { } } + pub fn detach<V>(&mut self) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + let ip = self.in_port.clone() + .downcast::<V>().ok() + .unwrap(); + + ip.0.update_hooks.write().unwrap().clear(); + ip.set_view(None) + .write().unwrap() + .reset(None); + } + pub fn attach_to<V>(&mut self, src_port: OuterViewPort<V>) where V: View + ?Sized + 'static, V::Msg: Clone @@ -109,7 +123,6 @@ impl ReprLeaf { pub fn from_vec_buffer<T>( buffer: VecBuffer<T> ) -> Self where T: Clone + Send + Sync + 'static { - eprintln!("ReprLeaf from vec buffer (LEN ={})", buffer.len()); let in_port = ViewPort::< dyn ListView<T> >::new(); ReprLeaf { keepalive: Some(buffer.attach_to(in_port.outer())), @@ -179,10 +192,7 @@ impl ReprLeaf { eprintln!("LEN = {}", data_arc.read().unwrap().len()); self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); - let buf = VecBuffer { - data: data_arc, - port: vec_port.inner() - }; + let buf = VecBuffer::with_data_arc_port(data_arc, vec_port.inner()); self.keepalive = Some(buf.attach_to( self.in_port.0.clone() .downcast::< dyn ListView<T> >() @@ -195,7 +205,6 @@ impl ReprLeaf { } } - pub fn get_port<V>(&self) -> Option<OuterViewPort<V>> where V: View + ?Sized + 'static, V::Msg: Clone @@ -314,6 +323,38 @@ impl ReprTree { } } + pub fn attach_to<V>( + &mut self, + src_port: OuterViewPort<V> + ) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + if let Some(leaf) = self.leaf.as_mut() { + leaf.attach_to(src_port); + } else { + eprintln!("cant attach branch without leaf"); + } + } + + pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { + if let Some(leaf) = self.leaf.as_mut() { + if self.type_tag == Context::parse(&ctx, "Char") { + leaf.detach::<dyn SingletonView<Item = char>>(); + } + if self.type_tag == Context::parse(&ctx, "<Vec Char>") { + leaf.detach::<dyn ListView<char>>(); + } + if self.type_tag == Context::parse(&ctx, "<List Char>") { + leaf.detach::<dyn ListView<char>>(); + } + } + + for (t,b) in self.branches.iter_mut() { + b.write().unwrap().detach(&ctx); + } + } + pub fn insert_leaf( &mut self, mut type_ladder: impl Iterator<Item = TypeTerm>, @@ -413,6 +454,10 @@ impl ReprTree { self.get_port::<dyn SequenceView<Item = T>>().expect("no sequence-view available") } + pub fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>> { + self.get_port::<dyn ListView<T>>().expect("no list-view available") + } + pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available") } @@ -442,6 +487,9 @@ pub trait ReprTreeExt { fn create_branch(&mut self, rung: impl Into<TypeTerm>); fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>; + fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone; + fn attach_leaf_to<V: View + ?Sized + 'static>(&self, t: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone; + fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>; fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>; fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>; @@ -478,6 +526,14 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { } } + fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone { + self.read().unwrap().get_port::<V>() + } + + fn attach_leaf_to<V: View + ?Sized + 'static>(&self, type_ladder: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone { + self.write().unwrap().attach_leaf_to::<V>(type_ladder.into().get_lnf_vec().into_iter(), v) + } + fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { ReprTree::descend( self, target_type ) } From e86070da500ca3a45ef55a14a82b3c03f0cbe03c Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 21 Jul 2024 18:16:43 +0200 Subject: [PATCH 44/75] fixes to make dual-editor with big/little endian projection work --- examples/tty-04-posint/src/main.rs | 479 +++++++++++---------- lib-nested-core/src/editors/char/mod.rs | 22 +- lib-nested-core/src/editors/integer/ctx.rs | 114 +++-- lib-nested-core/src/editors/list/ctx.rs | 168 +++----- lib-nested-core/src/editors/list/editor.rs | 6 +- lib-nested-core/src/repr_tree/context.rs | 13 +- lib-nested-core/src/repr_tree/mod.rs | 124 ++++-- lib-nested-core/src/repr_tree/morphism.rs | 73 +++- lib-nested-tty/src/editors/list.rs | 28 +- lib-nested-tty/src/editors/mod.rs | 1 - 10 files changed, 578 insertions(+), 450 deletions(-) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index d6887d4..b48d112 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -32,171 +32,57 @@ use { std::sync::{Arc, RwLock}, }; -#[async_std::main] -async fn main() { - /* setup context - */ - let ctx = Arc::new(RwLock::new(Context::new())); - nested::editors::char::init_ctx( ctx.clone() ); - nested::editors::digit::init_ctx( ctx.clone() ); - nested::editors::integer::init_ctx( ctx.clone() ); - nested::editors::list::init_ctx( ctx.clone() ); - nested_tty::setup_edittree_hook(&ctx); - - /* Create a Representation-Tree of type `ℕ` - */ - let mut rt_int = ReprTree::new_arc( Context::parse(&ctx, "ℕ") ); - - /* Add a specific Representation-Path (big-endian hexadecimal) - */ - rt_int.create_branch( - Context::parse(&ctx, "<PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>~Char>") - ); - rt_int.create_branch( - Context::parse(&ctx, "<PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>~Char>") - ); - rt_int.create_branch( - Context::parse(&ctx, "<PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10>~Char>") - ); - - eprintln!("make big endian hex repr"); - let mut b = VecBuffer::with_data(vec![ 'c', 'f', 'f' ]); - rt_int.insert_leaf( - Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>"), - nested::repr_tree::ReprLeaf::from_view( b.get_port().to_list() ) - ); - - let mut b_le = VecBuffer::with_data(vec!['3', '2', '1']); - rt_int.insert_leaf( - Context::parse(&ctx, "<PosInt 16 LittleEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>"), - nested::repr_tree::ReprLeaf::from_view( b_le.get_port().to_list() ) - ); - - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ~ <List Char> - ")).expect("descend"), - &Context::parse(&ctx, "<List Char>"), - &Context::parse(&ctx, "<List Char~EditTree>") - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16> > - ~ <List <Digit 16>~Char~EditTree > - ")).expect("descend"), - &Context::parse(&ctx, "<List EditTree>"), - &Context::parse(&ctx, "<List EditTree>~<Vec EditTree>") - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>~Char> - ")).expect("descend"), - &Context::parse(&ctx, "<List Char>~<List EditTree>~<Vec EditTree>"), - &Context::parse(&ctx, "<List Char>~EditTree") - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>~Char > - ")).expect("descend"), - &Context::parse(&ctx, "<List Char>~EditTree"), - &Context::parse(&ctx, "<List Char>") - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.clone(), - &Context::parse(&ctx, " - ℕ - ~ <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ~ <List Char> - "), - &Context::parse(&ctx, " - ℕ - ~ <PosInt 16 BigEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ~ <List Char> - ") - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.clone(), - &Context::parse(&ctx, " - ℕ - ~ <PosInt 16 BigEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ~ <List Char> - "), - &Context::parse(&ctx, " - ℕ - ~ <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ~ <List Char> - ") - ); - - let edittree_hex_le_list = ctx.read().unwrap() - .setup_edittree( - rt_int.descend(Context::parse(&ctx," - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>~Char > - ")).expect("descend"), - SingletonBuffer::new(0).get_port() +fn rebuild_projections( + ctx: Arc<RwLock<Context>>, + repr_tree: Arc<RwLock<ReprTree>>, + morph_types: Vec< (laddertypes::TypeTerm, laddertypes::TypeTerm) > +) { + repr_tree.write().unwrap().detach(&ctx); + for (src_type, dst_type) in morph_types.iter() { + ctx.read().unwrap().morphisms.apply_morphism( + repr_tree.clone(), + &src_type, + &dst_type ); + } +} - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char> - ")).expect("descend"), - &Context::parse(&ctx, "<List Char>"), - &Context::parse(&ctx, "<List Char~EditTree>") - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char~EditTree> - ")).expect("descend"), - &Context::parse(&ctx, "<List EditTree>"), - &Context::parse(&ctx, "<List EditTree>~<Vec EditTree>") - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char> - ")).expect("descend"), - &Context::parse(&ctx, "<List Char>~<List EditTree>~<Vec EditTree>"), - &Context::parse(&ctx, "<List Char>~EditTree") - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>~Char> - ")).expect("descend"), - &Context::parse(&ctx, "<List Char>~EditTree"), - &Context::parse(&ctx, "<List Char>") - ); +fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { + rebuild_projections( + ctx.clone(), + rt_int.clone(), + vec![ + // Little Endian Editor + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + ), - /* Setup an Editor for the big-endian hexadecimal representation - * (this will add the representation `<List <Digit 16>>~EditTree` to the ReprTree) - */ - let edittree_hex_be_list = ctx.read().unwrap() - .setup_edittree( - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ~ <List Char> - ")).expect("cant descend reprtree"), - SingletonBuffer::new(0).get_port() - ); + // Convert Endianness + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + ), + // Big Endian Editor + ( + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" + ), + ( + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>" + ), + ( + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" + ), + ].into_iter() + .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) + .collect() + ); +/* + /* * map seq of chars to seq of u64 digits * and add this projection to the ReprTree @@ -225,87 +111,203 @@ async fn main() { } ); - rt_int.insert_leaf(Context::parse(&ctx, " + rt_int.attach_leaf_to(Context::parse(&ctx, " <PosInt 16 BigEndian> ~ <Seq <Digit 16> ~ ℤ_2^64 ~ machine.UInt64 > "), - nested::repr_tree::ReprLeaf::from_view( digits_view.clone() ) + digits_view.clone() ); + //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ // + */ +} - /* convert to little endian - */ - ctx.read().unwrap().morphisms.apply_morphism( +fn setup_be_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { + rebuild_projections( + ctx.clone(), rt_int.clone(), - &Context::parse(&ctx, " - ℕ - ~ <PosInt 16 BigEndian> - ~ <Seq <Digit 16> - ~ ℤ_2^64 - ~ machine.UInt64 > - "), - &Context::parse(&ctx, " - ℕ - ~ <PosInt 16 LittleEndian> - ~ <Seq <Digit 16> - ~ ℤ_2^64 - ~ machine.UInt64 > - ") + vec![ + // Big Endian Editor + ( + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + ), + + // Convert Endianness + ( + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + ), + + // Big Endian Editor + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" + ), + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>" + ), + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" + ), + ].into_iter() + .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) + .collect() ); - /* convert to decimal - */ - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.clone(), - &Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>~ℤ_2^64~machine.UInt64>"), - &Context::parse(&ctx, "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>") - ); - - /* convert back to big endian - */ - ctx.read().unwrap().morphisms.apply_morphism( - rt_int.clone(), - &Context::parse(&ctx, "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>"), - &Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>~ℤ_2^64~machine.UInt64>") - ); - - - /* map seq of u64 digits to seq of chars + /* + /* + * map seq of chars to seq of u64 digits * and add this projection to the ReprTree */ - // //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV - let dec_digits_view = - rt_int.descend(Context::parse(&ctx, " - < PosInt 10 BigEndian > - ~ < Seq <Digit 10> - ~ ℤ_2^64 - ~ machine.UInt64 > - ")).expect("cant descend repr tree") - .read().unwrap() - .get_port::<dyn SequenceView<Item = u64>>().unwrap() - .map(|digit| TerminalAtom::from(char::from_digit(*digit as u32, 10))) - .to_grid_horizontal(); - //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ - // - //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV - let hex_digits_view = - rt_int.descend(Context::parse(&ctx, " - < PosInt 16 BigEndian > - ~ < Seq <Digit 16> - ~ ℤ_2^64 - ~ machine.UInt64 > + let mut chars_view = rt_int.descend(Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>~Char> ")).expect("cant descend") .read().unwrap() - .view_seq::< u64 >() - .map(|digit| TerminalAtom::from(char::from_digit(*digit as u32, 16))) - .to_grid_horizontal(); + .get_port::<dyn ListView<char>>() + .unwrap(); + + let mut digits_view = chars_view + .to_sequence() + .filter_map( + |digit_char| + + /* TODO: call morphism for each item + */ + match digit_char.to_digit(16) { + Some(d) => Some(d as u64), + None => None + } + ); + + rt_int.attach_leaf_to(Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~ <Seq <Digit 16> + ~ ℤ_2^64 + ~ machine.UInt64 > + "), + digits_view.clone() + ); + //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ // + */ +} + +#[async_std::main] +async fn main() { + /* setup context + */ + let ctx = Arc::new(RwLock::new(Context::new())); + nested::editors::char::init_ctx( ctx.clone() ); + nested::editors::digit::init_ctx( ctx.clone() ); + nested::editors::integer::init_ctx( ctx.clone() ); + nested::editors::list::init_ctx( ctx.clone() ); + nested_tty::setup_edittree_hook(&ctx); + + /* Create a Representation-Tree of type `ℕ` + */ + let mut rt_int = ReprTree::new_arc( Context::parse(&ctx, "ℕ") ); + + /* Add a specific Representation-Path (big-endian hexadecimal) + */ + let mut digits_be = VecBuffer::with_data(vec![ 'c', 'f', 'f' ]); + rt_int.insert_leaf( + Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>~<Vec Char>"), + nested::repr_tree::ReprLeaf::from_vec_buffer( digits_be.clone() ) + ); + + let mut digits_le = VecBuffer::with_data(vec!['3', '2', '1']); + rt_int.insert_leaf( + Context::parse(&ctx, "<PosInt 16 LittleEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>~<Vec Char>"), + nested::repr_tree::ReprLeaf::from_vec_buffer( digits_le.clone() ) + ); + + let mut digits_le_editvec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); + rt_int.insert_leaf( + Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16> + ~ Char + ~ EditTree> + ~ <Vec EditTree> + "), + nested::repr_tree::ReprLeaf::from_vec_buffer( digits_le_editvec.clone() ) + ); + + let mut digits_be_editvec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); + rt_int.insert_leaf( + Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16> + ~ Char + ~ EditTree> + ~ <Vec EditTree> + "), + nested::repr_tree::ReprLeaf::from_vec_buffer( digits_be_editvec.clone() ) + ); + + /* initially copy values from Vec to EditTree... + */ + rebuild_projections( + ctx.clone(), + rt_int.clone(), + // master representation + vec![ + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <Vec Char>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + ), + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" + ), + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree> ~ <Vec EditTree>" + ), + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree> ~ <Vec EditTree>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" + ), + ].into_iter() + .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) + .collect() + ); + + setup_le_master(&ctx, &rt_int); + + let edittree_hex_le_list = ctx.read().unwrap() + .setup_edittree( + rt_int.descend(Context::parse(&ctx," + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ~ <List Char> + ")).expect("descend"), + SingletonBuffer::new(0).get_port() + ).unwrap(); + let edittree_hex_be_list = ctx.read().unwrap() + .setup_edittree( + rt_int.descend(Context::parse(&ctx," + <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ~ <List Char> + ")).expect("descend"), + SingletonBuffer::new(0).get_port() + ).unwrap(); /* list of both editors */ @@ -321,7 +323,7 @@ async fn main() { edittree_hex_le_list.get().goto(TreeCursor::none()); edittree.goto(TreeCursor{ leaf_mode: nested::editors::list::ListCursorMode::Insert, - tree_addr: vec![0,0] + tree_addr: vec![1,0] }); let edittree = Arc::new(RwLock::new(edittree)); @@ -331,7 +333,31 @@ async fn main() { /* event handler */ let ctx = ctx.clone(); + let rt_int = rt_int.clone(); + let last_idx = RwLock::new(1); move |ev| { + + let cur = edittree.read().unwrap().get_cursor(); + if cur.tree_addr.len() > 0 { + match cur.tree_addr[0] { + 0 => { + let mut li = last_idx.write().unwrap(); + if *li != 0 { + setup_be_master(&ctx, &rt_int); + *li = 0; + } + } + 1 => { + let mut li = last_idx.write().unwrap(); + if *li != 1 { + setup_le_master(&ctx, &rt_int); + *li = 1; + } + } + _=>{} + } + } + edittree.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -341,7 +367,7 @@ async fn main() { * so it will be displayed on TTY-output. */ let compositor = TerminalCompositor::new(app.port.inner()); - + /* Now add some views to our compositor */ { @@ -366,15 +392,18 @@ async fn main() { /* project the seq of u64 representations to a view */ + /* comp.push(nested_tty::make_label("dec: ").offset(Vector2::new(3,7))); comp.push(dec_digits_view.offset(Vector2::new(8,7)).map_item(|_,a| { a.add_style_back(TerminalStyle::fg_color((30,90,200))) })); - + */ + /* comp.push(nested_tty::make_label("hex: ").offset(Vector2::new(3,8))); comp.push(hex_digits_view.offset(Vector2::new(8,8)).map_item(|_,a| { a.add_style_back(TerminalStyle::fg_color((200, 200, 30))) })); + */ } /* write the changes in the view of `term_port` to the terminal diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index b4d0e51..5d37008 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -32,16 +32,17 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { let ctx = ctx.clone(); move |rt, σ| { { - let mut rt = rt.write().unwrap(); - if let Some(buf) = rt.singleton_buffer::<char>() { + let mut b = rt.write().unwrap().singleton_buffer::<char>(); + if let Some(buf) = b { // buffer already exists } else { // create char buffer - rt.insert_leaf( + rt.write().unwrap().insert_leaf( vec![].into_iter(), ReprLeaf::from_singleton_buffer( - SingletonBuffer::new('\0') - )); + SingletonBuffer::new('\0') + ) + ); } } @@ -53,13 +54,10 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { SingletonBuffer::<usize>::new(0).get_port() ); - rt.write().unwrap() - .insert_branch( - ReprTree::from_singleton_buffer( - Context::parse(&ctx, "EditTree"), - SingletonBuffer::new(edittree) - ) - ); + rt.insert_leaf( + Context::parse(&ctx, "EditTree"), + ReprLeaf::from_singleton_buffer(SingletonBuffer::new(edittree)) + ); } } ); diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 7ca2a22..683dc61 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -20,6 +20,10 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.write().unwrap().add_varname("SrcRadix"); ctx.write().unwrap().add_varname("DstRadix"); + + /* + * MACHINE INT, SEQ + */ let morphism_type = MorphismType { src_type: Context::parse(&ctx, " @@ -49,21 +53,22 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { .apply_substitution(&|k|σ.get(k).cloned()) .clone() ).expect("cant descend") - .read().unwrap() - .view_seq::< u64 >(); + .view_seq::< u64 >(); - src_rt.insert_leaf(Context::parse(&ctx, " + src_rt.attach_leaf_to(Context::parse(&ctx, " <PosInt Radix LittleEndian> ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > ").apply_substitution(&|k|σ.get(k).cloned()).clone(), - ReprLeaf::from_view( src_digits.reverse() ) + src_digits.reverse() ); } } ); + /* MACHINE INT, LIST + */ let morphism_type = MorphismType { src_type: Context::parse(&ctx, " ℕ @@ -95,16 +100,15 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ") .apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend") - .read().unwrap() - .get_port::< dyn ListView<u64> >().unwrap(); + .get_port::< dyn ListView<u64> >().unwrap(); - src_rt.insert_leaf( + src_rt.attach_leaf_to( Context::parse(&ctx, " <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>> ~ <List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64> ").apply_substitution(&|k| σ.get(k).cloned()).clone(), - ReprLeaf::from_view( src_digits.reverse() ) + src_digits.reverse() ); } } @@ -113,14 +117,14 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { let mt = MorphismType { src_type: Context::parse(&ctx, " - ℕ + ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>> ~ <List <Digit Radix>> ~ <List Char> "), dst_type: Context::parse(&ctx, " - ℕ + ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>> ~ <List <Digit Radix>> @@ -132,22 +136,23 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { { let ctx = ctx.clone(); move |src_rt, σ| { + let radix = σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ); let src_digits = src_rt.descend(Context::parse(&ctx, " - <PosInt Radix BigEndian> + <PosInt Radix BigEndian> ~ <Seq <Digit Radix>> ~ <List <Digit Radix>~Char > ").apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend") - .read().unwrap() .get_port::< dyn ListView<char> >().unwrap(); - src_rt.insert_leaf( + let rev_port = src_digits.reverse(); + src_rt.attach_leaf_to( Context::parse(&ctx, " - < PosInt Radix LittleEndian > + < PosInt Radix LittleEndian > ~ < Seq <Digit Radix> > ~ < List <Digit Radix>~Char > ").apply_substitution(&|k| σ.get(k).cloned()).clone(), - ReprLeaf::from_view( src_digits.reverse() ) + rev_port ); } } @@ -176,21 +181,14 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ") .apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend") - .read().unwrap() - .view_seq::< u64 >(); + .view_seq::< u64 >(); - src_rt.write().unwrap().insert_leaf( - vec![ - Context::parse(&ctx, "<PosInt Radix BigEndian>") - .apply_substitution(&|k|σ.get(k).cloned()).clone(), - Context::parse(&ctx, "<Seq <Digit Radix>>") - .apply_substitution(&|k|σ.get(k).cloned()).clone(), - Context::parse(&ctx, "<Seq ℤ_2^64>"), - Context::parse(&ctx, "<Seq machine.UInt64>") - ].into_iter(), - - ReprLeaf::from_view( src_digits.reverse() ) - ); + src_rt.attach_leaf_to(Context::parse(&ctx, " + <PosInt Radix BigEndian> + ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64> + ").apply_substitution(&|k|σ.get(k).cloned()).clone(), + src_digits.reverse() + ); } } ); @@ -219,32 +217,29 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { let ctx = ctx.clone(); move |src_rt, σ| { - let src_digits = ReprTree::descend( - &src_rt, - Context::parse(&ctx, " + let src_digits = src_rt.descend( + Context::parse(&ctx, " <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>> ~ <List <Digit Radix>~ℤ_2^64~machine.UInt64 > - ") - .apply_substitution(&|k|σ.get(k).cloned()).clone() - ).expect("cant descend") - .read().unwrap() - .get_port::< dyn ListView<u64> >().unwrap(); + ").apply_substitution(&|k|σ.get(k).cloned()).clone() + ) + .expect("cant descend") + .view_list::<u64>(); - src_rt.insert_leaf( + src_rt.attach_leaf_to( Context::parse(&ctx, " <PosInt Radix BigEndian> ~ <Seq <Digit Radix>> ~ <List <Digit Radix>~ℤ_2^64~machine.UInt64 > - "), - ReprLeaf::from_view( src_digits.reverse() ) - ); + ").apply_substitution(&|k|σ.get(k).cloned()).clone(), + src_digits.reverse() + ); } } ); - let mt = MorphismType { src_type: Context::parse(&ctx, " ℕ @@ -273,16 +268,15 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ~ <List <Digit Radix>~Char > ").apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend") - .read().unwrap() - .get_port::< dyn ListView<char> >().unwrap(); + .view_list::<char>(); - src_rt.insert_leaf( + src_rt.attach_leaf_to( Context::parse(&ctx, " < PosInt Radix BigEndian > ~ < Seq <Digit Radix> > ~ < List <Digit Radix>~Char > ").apply_substitution(&|k| σ.get(k).cloned()).clone(), - ReprLeaf::from_view( src_digits.reverse() ) + src_digits.reverse() ); } } @@ -327,30 +321,24 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { _ => 0 }; - let src_digits_rt = ReprTree::descend( - src_rt, - Context::parse(&ctx, " + let src_digits_rt = src_rt.descend(Context::parse(&ctx, " <PosInt SrcRadix LittleEndian> - ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64 >" - ).apply_substitution(&|k|σ.get(k).cloned()).clone() + ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64 > + ").apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend repr tree"); let dst_digits_port = - src_digits_rt.read().unwrap() - .view_seq::<u64>() + src_digits_rt.view_seq::<u64>() .to_positional_uint( src_radix ) .transform_radix( dst_radix ); - src_rt.write().unwrap() - .insert_leaf( - vec![ - Context::parse(&ctx, "<PosInt DstRadix LittleEndian>").apply_substitution(&|k|σ.get(k).cloned()).clone(), - Context::parse(&ctx, "<Seq <Digit DstRadix>>").apply_substitution(&|k|σ.get(k).cloned()).clone(), - Context::parse(&ctx, "<Seq ℤ_2^64>"), - Context::parse(&ctx, "<Seq machine.UInt64>"), - ].into_iter(), - ReprLeaf::from_view(dst_digits_port) - ); + src_rt.attach_leaf_to( + Context::parse(&ctx, " + <PosInt DstRadix LittleEndian> + ~ <Seq <Digit DstRadix> ~ ℤ_2^64 ~ machine.UInt64> + ").apply_substitution(&|k|σ.get(k).cloned()).clone(), + dst_digits_port + ); } } ); diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 8bc584c..839110d 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -1,7 +1,7 @@ use { r3vi::{ view::{ - ViewPort, + ViewPort, port::UpdateTask, OuterViewPort, Observer, singleton::*, list::* @@ -32,33 +32,34 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.write().unwrap().morphisms.add_morphism(mt, { let ctx = ctx.clone(); move |src_rt, σ| { - let list_port = src_rt.read().unwrap().get_port::<dyn ListView<char>>().clone(); + let list_port = src_rt.descend(Context::parse(&ctx, "<List Char>")).expect("descend").get_port::<dyn ListView<char>>().clone(); if let Some(list_port) = list_port { + + // for each char, create EditTree let edit_tree_list = list_port - // for each char, create and EditTree .map({ let ctx = ctx.clone(); move |c| { let item_rt = ReprTree::from_char(&ctx, *c); + ctx.read().unwrap().setup_edittree( item_rt.clone(), SingletonBuffer::new(0).get_port() ); + let et = item_rt - .descend(Context::parse(&ctx, "EditTree")).unwrap() - .read().unwrap() - .get_port::< dyn SingletonView<Item = EditTree> >() - .expect("cant get view port (EditTree)") + .descend(Context::parse(&ctx, "Char ~ EditTree")).expect("cant descend repr tree") + .get_port::< dyn SingletonView<Item = EditTree> >().expect("cant get view port (EditTree)") .get_view().unwrap() .get(); Arc::new(RwLock::new(et)) } }); - src_rt.write().unwrap().insert_leaf( - Context::parse(&ctx, "<List EditTree>").get_lnf_vec().into_iter(), - ReprLeaf::from_view( edit_tree_list ) + src_rt.attach_leaf_to( + Context::parse(&ctx, "<List Char>~<List EditTree>"), + edit_tree_list ); } else { eprintln!("morphism missing view port"); @@ -70,44 +71,29 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { src_type: Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"), dst_type: Context::parse(&ctx, "<List Item>~EditTree") }; + ctx.write().unwrap().morphisms.add_morphism(mt, { let ctx = ctx.clone(); move |src_rt, σ| { let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); if let Some( item_type ) = σ.get( &item_id ) { - /* - let mut item_vec_buffer = VecBuffer::new(); - - eprintln!("try attach to data port"); - if let Some( list_port ) = - src_rt - .descend(Context::parse(&ctx, "<List EditTree>")).expect("") - .read().unwrap() - .get_port::< dyn ListView< Arc<RwLock<EditTree>> > >() - { - eprintln!("get list<edittree> port"); - item_vec_buffer.attach_to( list_port ); - }*/ - let mut item_vec_rt = src_rt - .descend(Context::parse(&ctx, "<List EditTree>~<Vec EditTree>")) + .descend( + Context::parse(&ctx, "<List Item~EditTree>~<Vec EditTree>") + .apply_substitution(&|id| σ.get(id).cloned()).clone() + ) .expect("cant descend src repr"); - let item_vec_buffer = item_vec_rt - .write().unwrap() - .vec_buffer::< Arc<RwLock<EditTree>> >().expect("cant get vec buffer"); + let item_vec_buffer = item_vec_rt.vec_buffer::< Arc<RwLock<EditTree>> >(); - // eprintln!("create ListEditor"); let mut list_editor = ListEditor::with_data(ctx.clone(), item_type.clone(), item_vec_buffer); - let edittree_list = list_editor.into_node( SingletonBuffer::<usize>::new(0).get_port() ); - - // eprintln!("make edittree"); - src_rt.write().unwrap().insert_branch( - ReprTree::from_singleton_buffer( - Context::parse(&ctx, "EditTree"), + src_rt.insert_leaf( + Context::parse(&ctx, "<List Item> ~ EditTree") + .apply_substitution(&|id| σ.get(id).cloned()).clone(), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new(edittree_list) ) ); @@ -128,64 +114,31 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { move |src_rt, σ| { let edittree = src_rt - .descend(Context::parse(&ctx, "EditTree")).unwrap() + .descend(Context::parse(&ctx, "<List Char>~EditTree")).unwrap() .singleton_buffer::<EditTree>(); let list_edit = edittree.get().get_edit::< ListEditor >().unwrap(); let edittree_items = list_edit.read().unwrap().data.get_port().to_list(); - src_rt.write().unwrap().insert_leaf( - vec![].into_iter(), - ReprLeaf::from_view( - edittree_items - .map( - |edittree_char| - edittree_char - .read().unwrap() - .get_edit::<CharEditor>().unwrap() - .read().unwrap() - .get() - ) - ) - ); - } - } - ); - let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List <Digit Radix>>~EditTree"), - dst_type: Context::parse(&ctx, "<List <Digit Radix>~Char>") - }; - ctx.write().unwrap().morphisms.add_morphism( - mt, - { - let ctx = ctx.clone(); - move |src_rt, σ| { - let edittree = - src_rt - .descend(Context::parse(&ctx, "EditTree")).unwrap() - .singleton_buffer::<EditTree>(); - - let list_edit = edittree.get().get_edit::< ListEditor >().unwrap(); - let edittree_items = list_edit.read().unwrap().data.get_port().to_list(); - src_rt.write().unwrap().insert_leaf( - vec![ Context::parse(&ctx, "<List Char>") ].into_iter(), + src_rt.insert_leaf( + Context::parse(&ctx, "<List Char>"), ReprLeaf::from_view( - edittree_items - .map( - |edittree_char| - edittree_char - .read().unwrap() - .get_edit::<crate::editors::digit::editor::DigitEditor>().unwrap() - .read().unwrap() - .get_char() - ) - ) + edittree_items + .map(|edittree_char| + edittree_char + .read().unwrap() + .get_edit::<CharEditor>().unwrap() + .read().unwrap() + .get() + )) ); } } ); + /* todo : unify the following two morphims with generic item parameter ? + */ let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Char>"), dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>") @@ -195,17 +148,30 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { { let ctx = ctx.clone(); move |src_rt, σ| { - let buf = VecBuffer::<char>::new(); - let mut leaf = ReprLeaf::from_vec_buffer(buf); - leaf.attach_to( - src_rt.read().unwrap() - .get_port::<dyn ListView<char>>() - .unwrap() - ); - src_rt.write().unwrap().insert_leaf( - vec![ Context::parse(&ctx, "<Vec Char>") ].into_iter(), - leaf - ); + src_rt + .attach_leaf_to( + Context::parse(&ctx, "<List Char>~<Vec Char>"), + src_rt + .descend(Context::parse(&ctx, "<List Char>")) + .expect("descend") + .view_list::<char>() + ); + } + } + ); + + let mt = crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "<List Char>~<Vec Char>"), + dst_type: Context::parse(&ctx, "<List Char>") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_port = src_rt.descend(Context::parse(&ctx, "<List Char>~<Vec Char>")).expect("descend") + .get_port::<RwLock<Vec<char>>>().unwrap(); + src_rt.attach_leaf_to( Context::parse(&ctx, "<List Char>"), src_port.to_list() ); } } ); @@ -219,16 +185,14 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { { let ctx = ctx.clone(); move |src_rt, σ| { - let buf = VecBuffer::<Arc<RwLock<EditTree>>>::new(); - let mut leaf = ReprLeaf::from_vec_buffer(buf); - leaf.attach_to( - src_rt.read().unwrap() - .get_port::<dyn ListView< Arc<RwLock<EditTree>> >>() - .unwrap() - ); - src_rt.write().unwrap().insert_leaf( - vec![ Context::parse(&ctx, "<Vec EditTree>") ].into_iter(), - leaf + let p = + src_rt + .descend(Context::parse(&ctx, "<List EditTree>")).expect("descend") + .get_port::<dyn ListView< Arc<RwLock<EditTree>> >>().unwrap(); + + src_rt.attach_leaf_to( + Context::parse(&ctx, "<List EditTree> ~ <Vec EditTree>"), + p ); } } diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 1bb0351..b9fa64e 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -319,12 +319,14 @@ impl ListEditor { let mut b = item.ctrl.spillbuf.write().unwrap(); let rt = ReprTree::new_arc(self.typ.clone()); - let edittree = self.ctx.read().unwrap() + let mut et = self.ctx.read().unwrap() .setup_edittree( rt, self.depth.map(|d| d+1) ); + if let Some(edittree) = et.as_mut(){ + let mut tail_node = edittree.get_mut(); tail_node.goto(TreeCursor::home()); @@ -354,6 +356,8 @@ impl ListEditor { edittree.value.clone() ); + } + } else { self.up(); self.listlist_split(); diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 4835736..78f2ed7 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -179,7 +179,7 @@ impl Context { &self, rt: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>> - ) -> SingletonBuffer<EditTree> { + ) -> Option<SingletonBuffer<EditTree>> { let ladder = TypeTerm::Ladder(vec![ rt.read().unwrap().get_type().clone(), self.type_term_from_str("EditTree").expect("") @@ -194,14 +194,19 @@ impl Context { if let Some(new_edittree) = rt.descend(self.type_term_from_str("EditTree").unwrap()) { + let typ = rt.read().unwrap().get_type().clone(); let buf = new_edittree.singleton_buffer::<EditTree>(); (*self.edittree_hook)( &mut *buf.get_mut(), - rt.read().unwrap().get_type().clone() + typ ); - buf + Some(buf) } else { - unreachable!(); + eprintln!("cant find edit tree repr {} ~Ψ~ {}", + self.type_term_to_str(rt.read().unwrap().get_halo_type()), + self.type_term_to_str(rt.read().unwrap().get_type()) + ); + None } } } diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 28488e5..072424f 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -40,6 +40,7 @@ pub struct ReprLeaf { /// keepalive for the observer that updates the buffer from in_port keepalive: Option<Arc<dyn Any + Send + Sync>>, + in_keepalive: Option<Arc<dyn Any + Send + Sync>>, } #[derive(Clone)] @@ -72,15 +73,16 @@ impl ReprLeaf { V::Msg: Clone { let mut in_port = ViewPort::<V>::new(); - in_port.attach_to(src_port); + let in_keepalive = in_port.attach_to(src_port); - let mut buf_port = ViewPort::<V>::new(); - buf_port.attach_to(in_port.outer()); + let mut out_port = ViewPort::<V>::new(); + let out_keepalive = out_port.attach_to(in_port.outer()); ReprLeaf { - keepalive: None, + keepalive: Some(out_keepalive), + in_keepalive: Some(in_keepalive), in_port: in_port.inner().into(), - out_port: buf_port.into(), + out_port: out_port.into(), data: None, } } @@ -89,23 +91,55 @@ impl ReprLeaf { where V: View + ?Sized + 'static, V::Msg: Clone { + self.keepalive = None; + self.in_keepalive = None; + let ip = self.in_port.clone() .downcast::<V>().ok() .unwrap(); + ip.0.detach(); - ip.0.update_hooks.write().unwrap().clear(); - ip.set_view(None) - .write().unwrap() - .reset(None); + if self.data.is_none() { + let mut op = self.out_port.clone() + .downcast::<V>().ok() + .unwrap(); + + op.detach(); + self.keepalive = Some(op.attach_to(ip.0.outer())); + } + } + + pub fn detach_vec<Item>(&mut self) + where Item: Clone + Send + Sync + 'static + { + self.keepalive = None; + self.in_keepalive = None; + + let ip = self.in_port.clone() + .downcast::<dyn ListView<Item>>().ok() + .unwrap(); + + ip.0.detach(); + + if let Some(data) = self.data.as_mut() { + let mut op = self.out_port.clone() + .downcast::<RwLock<Vec<Item>>>().ok() + .unwrap(); + op.detach(); + + let data = data.clone().downcast::< RwLock<Vec<Item>> >().ok().unwrap(); + let buffer = VecBuffer::with_data_arc_port(data, op.inner()); + self.keepalive = Some(buffer.attach_to(ip.0.outer())) + } } pub fn attach_to<V>(&mut self, src_port: OuterViewPort<V>) where V: View + ?Sized + 'static, V::Msg: Clone { - self.in_port.clone() + self.in_keepalive = Some(self.in_port.clone() .downcast::<V>().ok().unwrap() - .0.attach_to( src_port ); + .0.attach_to( src_port )); } pub fn from_singleton_buffer<T>( buffer: SingletonBuffer<T> ) -> Self @@ -113,6 +147,7 @@ impl ReprLeaf { { let in_port = ViewPort::<dyn SingletonView<Item = T>>::new(); ReprLeaf { + in_keepalive: None, keepalive: Some(buffer.attach_to(in_port.outer())), in_port: in_port.inner().into(), out_port: buffer.get_port().0.into(), @@ -125,6 +160,7 @@ impl ReprLeaf { { let in_port = ViewPort::< dyn ListView<T> >::new(); ReprLeaf { + in_keepalive: None, keepalive: Some(buffer.attach_to(in_port.outer())), in_port: in_port.inner().into(), out_port: buffer.get_port().0.into(), @@ -172,7 +208,6 @@ impl ReprLeaf { let data_arc = if let Some(data) = self.data.as_ref() { - eprintln!("downcast existing vec-data"); data.clone().downcast::<RwLock<Vec<T>>>().ok() } else { vec_port.update(); @@ -188,9 +223,6 @@ impl ReprLeaf { }; if let Some(data_arc) = data_arc { - eprintln!("ReprLeaf: have Vec-like data-arc"); - eprintln!("LEN = {}", data_arc.read().unwrap().len()); - self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); let buf = VecBuffer::with_data_arc_port(data_arc, vec_port.inner()); self.keepalive = Some(buf.attach_to( @@ -252,6 +284,22 @@ impl ReprTree { &self.halo } + pub fn get_leaf_types(&self) -> Vec< TypeTerm > { + let mut leaf_types = Vec::new(); + if self.leaf.is_some() { + leaf_types.push( self.get_type().clone() ); + } + for (branch_type, branch) in self.branches.iter() { + for t in branch.read().unwrap().get_leaf_types() { + leaf_types.push(TypeTerm::Ladder(vec![ + self.get_type().clone(), + t + ]).normalize()) + } + } + leaf_types + } + pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { let branch_type = repr.read().unwrap().get_type().clone(); @@ -261,6 +309,7 @@ impl ReprTree { self.halo.clone(), self.type_tag.clone() ]).normalize() ); + self.branches.insert(branch_type, repr.clone()); } @@ -307,12 +356,20 @@ impl ReprTree { V::Msg: Clone { if let Some(rung_type) = type_ladder.next() { - if let Some(next_repr) = self.branches.get(&rung_type) { - next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); + if &rung_type == self.get_type() { + if let Some(leaf) = self.leaf.as_mut() { + leaf.attach_to(src_port); + } else { + self.leaf = Some(ReprLeaf::from_view(src_port)); + } } else { - let mut next_repr = ReprTree::new(rung_type.clone()); - next_repr.attach_leaf_to(type_ladder, src_port); - self.insert_branch(Arc::new(RwLock::new(next_repr))); + if let Some(next_repr) = self.branches.get(&rung_type) { + next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); + } else { + let mut next_repr = ReprTree::new(rung_type.clone()); + next_repr.attach_leaf_to(type_ladder, src_port); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } } } else { if let Some(leaf) = self.leaf.as_mut() { @@ -337,13 +394,13 @@ impl ReprTree { } } - pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { + pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { if let Some(leaf) = self.leaf.as_mut() { if self.type_tag == Context::parse(&ctx, "Char") { leaf.detach::<dyn SingletonView<Item = char>>(); } if self.type_tag == Context::parse(&ctx, "<Vec Char>") { - leaf.detach::<dyn ListView<char>>(); + leaf.detach_vec::<char>(); } if self.type_tag == Context::parse(&ctx, "<List Char>") { leaf.detach::<dyn ListView<char>>(); @@ -393,7 +450,15 @@ impl ReprTree { } pub fn descend(rt: &Arc<RwLock<Self>>, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { - ReprTree::descend_ladder(rt, dst_type.into().get_lnf_vec().into_iter()) + let mut lnf = dst_type.into().get_lnf_vec(); + if lnf.len() > 0 { + if lnf[0] == rt.get_type() { + lnf.remove(0); + } + ReprTree::descend_ladder(rt, lnf.into_iter()) + } else { + Some(rt.clone()) + } } pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> { @@ -487,14 +552,17 @@ pub trait ReprTreeExt { fn create_branch(&mut self, rung: impl Into<TypeTerm>); fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>; - fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone; fn attach_leaf_to<V: View + ?Sized + 'static>(&self, t: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone; + fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone; fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>; fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>; fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>; fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>>; + fn view_seq<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>>; + fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>>; + fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>; fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>; } @@ -554,6 +622,14 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { self.read().unwrap().view_usize() } + fn view_seq<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> { + self.read().unwrap().view_seq::<T>() + } + + fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>> { + self.read().unwrap().view_list::<T>() + } + fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T> { self.write().unwrap().singleton_buffer::<T>().expect("") } diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index 64ea186..65eb5bb 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -52,7 +52,10 @@ impl MorphismBase { ) { self.morphisms.push( GenericReprTreeMorphism { - morph_type, + morph_type: MorphismType { + src_type: morph_type.src_type.normalize(), + dst_type: morph_type.dst_type.normalize() + }, setup_projection: Arc::new(setup_projection) } ); @@ -67,12 +70,13 @@ impl MorphismBase { let unification_problem = laddertypes::UnificationProblem::new( vec![ - ( src_type.clone(), m.morph_type.src_type.clone() ), - ( dst_type.clone(), m.morph_type.dst_type.clone() ) + ( src_type.clone().normalize(), m.morph_type.src_type.clone() ), + ( dst_type.clone().normalize(), m.morph_type.dst_type.clone() ) ] ); - if let Ok(σ) = unification_problem.solve() { + let unification_result = unification_problem.solve(); + if let Ok(σ) = unification_result { return Some((m, σ)); } } @@ -80,19 +84,70 @@ impl MorphismBase { None } + + pub fn find_morphism_ladder( + &self, + src_type: &TypeTerm, + dst_type: &TypeTerm, + ) -> Option<( + &GenericReprTreeMorphism, + TypeTerm, + HashMap<TypeID, TypeTerm> + )> { + let mut src_lnf = src_type.clone().get_lnf_vec(); + let mut dst_lnf = dst_type.clone().get_lnf_vec(); + let mut halo = vec![]; + + while src_lnf.len() > 0 && dst_lnf.len() > 0 { + if let Some((m, σ)) = self.find_morphism( &TypeTerm::Ladder(src_lnf.clone()), &TypeTerm::Ladder(dst_lnf.clone()) ) { + return Some((m, TypeTerm::Ladder(halo), σ)); + } else { + if src_lnf[0] == dst_lnf[0] { + src_lnf.remove(0); + halo.push(dst_lnf.remove(0)); + } else { + return None; + } + } + } + + None + } + pub fn apply_morphism( &self, - mut repr_tree: Arc<RwLock<ReprTree>>, + repr_tree: Arc<RwLock<ReprTree>>, src_type: &TypeTerm, dst_type: &TypeTerm ) { -// let t = repr_tree.read().unwrap().get_type().clone(); - if let Some((m, σ)) = self.find_morphism( &src_type, dst_type ) { - (m.setup_projection)( &mut repr_tree, &σ ); + if let Some((m, s, σ)) = self.find_morphism_ladder( &src_type, dst_type ) { + //eprintln!("apply morphism on subtree {:?}", s); + let mut rt = repr_tree.descend( s ).expect("descend"); + (m.setup_projection)( &mut rt, &σ ); } else { - eprintln!("could not find morphism"); + eprintln!("could not find morphism\n {:?}\n ====>\n {:?}", src_type, dst_type); } } +/* + pub fn apply_seq_map_morphism<SrcItem, DstItem>( + &self, + mut repr_tree: Arc<RwLock<ReprTree>>, + src_item_type: &TypeTerm, + dst_item_type: &TypeTerm + ) { + if let Some((item_morphism, σ)) = self.find_morphism( &src_item_type, dst_item_type ) { + + let src_port = repr_tree.read().unwrap().get_port::<dyn SequenceView<Item = Arc<RwLock<ReprTree>> >>().unwrap(); + src_port.map( + m.setup_projection + ) + + (m.setup_projection)( &mut repr_tree, &σ ); + } else { + eprintln!("could not find item morphism"); + } + } + */ } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 4af92fc..4584e9c 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -7,6 +7,7 @@ use { repr_tree::{Context, ReprTree}, editors::list::*, edit_tree::{TreeCursor, TreeNav, TreeNavResult, EditTree}, + repr_tree::{ReprTreeExt, ReprLeaf} }, crate::{ DisplaySegment, @@ -80,10 +81,12 @@ impl PTYListStyle { editor.get_cursor_port(), editor.get_data_port() ); - let seg_seq = seg_seq.read().unwrap(); + + let seg_seq0 = seg_seq.read().unwrap(); + let seg_seq = seg_seq0.get_view(); + drop(seg_seq0); seg_seq - .get_view() .map(move |segment| segment.display_view()) .separate(make_label(&self.style.1)) .wrap(make_label(&self.style.0), make_label(&self.style.2)) @@ -92,15 +95,14 @@ impl PTYListStyle { } pub fn for_node(node: &mut EditTree, style: (&str, &str, &str)) { + let editor = node.get_edit::<ListEditor>().unwrap(); + let editor = editor.read().unwrap(); + let pty_view = Self::new(style).pty_view(&editor); node.disp.view - .write().unwrap() - .insert_branch(ReprTree::from_view( + .attach_leaf_to( Context::parse(&node.ctx, "TerminalView"), - Self::new(style) - .pty_view( - &node.get_edit::<ListEditor>().unwrap().read().unwrap() - ) - )); + pty_view + ); } } @@ -226,6 +228,8 @@ impl PTYListController { self.depth.map(|d| d+1) ); + if let Some(new_edittree) = new_edittree { + let mut ne = new_edittree.get(); match ne.send_cmd_obj(cmd_obj.clone()) { TreeNavResult::Continue => { @@ -237,6 +241,12 @@ impl PTYListController { TreeNavResult::Exit } } + + } else { + + panic!("cant get edit tree"); + TreeNavResult::Continue + } }, ListCursorMode::Select => { if let Some(item) = e.get_item_mut() { diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 0cf01fb..669aab7 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -17,7 +17,6 @@ use { } }; - pub fn edittree_make_char_view( node: EditTree ) -> EditTree { From 6e8bb0aeb5c74cb70ef3215c9b11061b2042babf Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 1 Aug 2024 18:35:57 +0200 Subject: [PATCH 45/75] apply_list_map_morphism --- examples/tty-04-posint/src/main.rs | 177 +++++++++++---------- lib-nested-core/src/editors/digit/ctx.rs | 9 +- lib-nested-core/src/editors/integer/ctx.rs | 69 ++++++-- lib-nested-core/src/repr_tree/mod.rs | 9 ++ lib-nested-core/src/repr_tree/morphism.rs | 84 ++++++++-- 5 files changed, 237 insertions(+), 111 deletions(-) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index b48d112..2c12c17 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -37,7 +37,7 @@ fn rebuild_projections( repr_tree: Arc<RwLock<ReprTree>>, morph_types: Vec< (laddertypes::TypeTerm, laddertypes::TypeTerm) > ) { - repr_tree.write().unwrap().detach(&ctx); +// repr_tree.write().unwrap().detach(&ctx); for (src_type, dst_type) in morph_types.iter() { ctx.read().unwrap().morphisms.apply_morphism( repr_tree.clone(), @@ -48,6 +48,8 @@ fn rebuild_projections( } fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { + rt_int.write().unwrap().detach(&ctx); + rebuild_projections( ctx.clone(), rt_int.clone(), @@ -81,51 +83,38 @@ fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) .collect() ); -/* - /* - * map seq of chars to seq of u64 digits - * and add this projection to the ReprTree - */ - // - //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV - let mut chars_view = rt_int.descend(Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>~Char> - ")).expect("cant descend") - .read().unwrap() - .get_port::<dyn ListView<char>>() - .unwrap(); - - let mut digits_view = chars_view - .to_sequence() - .filter_map( - |digit_char| - - /* TODO: call morphism for each item - */ - match digit_char.to_digit(16) { - Some(d) => Some(d as u64), - None => None - } + let rt_digitseq = + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ")).expect("test"); + let src_type = Context::parse(&ctx, "<Digit 16> ~ Char"); + let dst_type = Context::parse(&ctx, "<Digit 16> ~ ℤ_2^64 ~ machine.UInt64"); + ctx.read().unwrap().morphisms + .apply_list_map_morphism::<char, u64>( + rt_digitseq, src_type, dst_type ); - rt_int.attach_leaf_to(Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~ <Seq <Digit 16> - ~ ℤ_2^64 - ~ machine.UInt64 > - "), - digits_view.clone() + rebuild_projections( + ctx.clone(), + rt_int.clone(), + vec![ + // Radix Convert + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" + ) + ].into_iter() + .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) + .collect() ); - - //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ - // - */ } fn setup_be_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { + rt_int.write().unwrap().detach(&ctx); + rebuild_projections( ctx.clone(), rt_int.clone(), @@ -142,7 +131,7 @@ fn setup_be_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" ), - // Big Endian Editor + // Little Endian Editor ( "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" @@ -160,47 +149,33 @@ fn setup_be_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { .collect() ); - /* - /* - * map seq of chars to seq of u64 digits - * and add this projection to the ReprTree - */ - // - //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV - let mut chars_view = rt_int.descend(Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>~Char> - ")).expect("cant descend") - .read().unwrap() - .get_port::<dyn ListView<char>>() - .unwrap(); - - let mut digits_view = chars_view - .to_sequence() - .filter_map( - |digit_char| - - /* TODO: call morphism for each item - */ - match digit_char.to_digit(16) { - Some(d) => Some(d as u64), - None => None - } + + let rt_digitseq = + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ")).expect("test"); + let src_type = Context::parse(&ctx, "<Digit 16> ~ Char"); + let dst_type = Context::parse(&ctx, "<Digit 16> ~ ℤ_2^64 ~ machine.UInt64"); + ctx.read().unwrap().morphisms + .apply_list_map_morphism::<char, u64>( + rt_digitseq, src_type, dst_type ); - rt_int.attach_leaf_to(Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~ <Seq <Digit 16> - ~ ℤ_2^64 - ~ machine.UInt64 > - "), - digits_view.clone() + rebuild_projections( + ctx.clone(), + rt_int.clone(), + vec![ + // Little Endian Editor + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" + ), + ].into_iter() + .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) + .collect() ); - - //ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ - // - */ } #[async_std::main] @@ -309,6 +284,47 @@ async fn main() { SingletonBuffer::new(0).get_port() ).unwrap(); + + + let rt_digitseq = + rt_int.descend(Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ")).expect("test"); + let src_type = Context::parse(&ctx, "<Digit 16> ~ Char"); + let dst_type = Context::parse(&ctx, "<Digit 16> ~ ℤ_2^64 ~ machine.UInt64"); + ctx.read().unwrap().morphisms + .apply_list_map_morphism::<char, u64>( + rt_digitseq, src_type, dst_type + ); + + let hex_digits_view = rt_int.descend(Context::parse(&ctx, " + <PosInt 16 LittleEndian> + ~ <Seq <Digit 16> > + ~ <List <Digit 16> + ~ ℤ_2^64 + ~ machine.UInt64 > + ")).expect("descend") + .view_list::<u64>() + .map(|v| TerminalAtom::from(char::from_digit(*v as u32, 16))) + .to_sequence() + .to_grid_horizontal() + ; + + let dec_digits_view = rt_int.descend(Context::parse(&ctx, " + <PosInt 10 LittleEndian> + ~ <Seq <Digit 10>> + ~ <List <Digit 10> + ~ ℤ_2^64 + ~ machine.UInt64 > + ")).expect("descend") + .view_list::<u64>() + .map(|v| TerminalAtom::from(char::from_digit(*v as u32, 10))) + .to_sequence() + .to_grid_horizontal() + ; + /* list of both editors */ let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); @@ -392,18 +408,15 @@ async fn main() { /* project the seq of u64 representations to a view */ - /* comp.push(nested_tty::make_label("dec: ").offset(Vector2::new(3,7))); comp.push(dec_digits_view.offset(Vector2::new(8,7)).map_item(|_,a| { a.add_style_back(TerminalStyle::fg_color((30,90,200))) })); - */ - /* + comp.push(nested_tty::make_label("hex: ").offset(Vector2::new(3,8))); comp.push(hex_digits_view.offset(Vector2::new(8,8)).map_item(|_,a| { a.add_style_back(TerminalStyle::fg_color((200, 200, 30))) })); - */ } /* write the changes in the view of `term_port` to the terminal diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index b87e5ec..ea5b8d6 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -92,14 +92,17 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| { /* infer radix from type */ + let radix_typeid = ctx.read().unwrap().get_var_typeid("Radix").unwrap(); let radix = - match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + match σ.get( &laddertypes::TypeID::Var(radix_typeid) ) { Some(TypeTerm::Num(n)) => (*n) as u32, - _ => 0 + x => { + eprintln!("invalid radix {:?}", x); + 0 + } }; if radix <= 16 { - if let Some(src_rt) = rt.descend(Context::parse(&ctx, "Char")) { /* insert projected view into ReprTree */ diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 683dc61..868acec 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -16,7 +16,6 @@ use { pub fn init_ctx(ctx: Arc<RwLock<Context>>) { // TODO: proper scoping - ctx.write().unwrap().add_varname("Radix"); ctx.write().unwrap().add_varname("SrcRadix"); ctx.write().unwrap().add_varname("DstRadix"); @@ -281,24 +280,66 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } } ); +/* + let mt = MorphismType { + src_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List Char> + "), + dst_type: Context::parse(&ctx, " + ℕ + ~ <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>> + ~ <List Char> + ") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_digits = src_rt.descend(Context::parse(&ctx, " + <PosInt Radix BigEndian> + ~ <Seq <Digit Radix>> + ~ <List <Digit Radix>~Char > + ").apply_substitution(&|k|σ.get(k).cloned()).clone() + ).expect("cant descend") + .view_list::<char>(); - + src_rt.attach_leaf_to( + Context::parse(&ctx, " + < PosInt Radix LittleEndian > + ~ < Seq <Digit Radix> > + ~ < List <Digit Radix>~Char > + ").apply_substitution(&|k| σ.get(k).cloned()).clone(), + src_digits.reverse() + ); + } + } + ); +*/ let morphism_type = MorphismType { src_type: Context::parse(&ctx, " ℕ ~ <PosInt SrcRadix LittleEndian> - ~ <Seq <Digit SrcRadix> + ~ <Seq <Digit SrcRadix>> + ~ <List <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64> "), dst_type: Context::parse(&ctx, " ℕ ~ <PosInt DstRadix LittleEndian> - ~ <Seq <Digit DstRadix> + ~ <Seq <Digit DstRadix>> + ~ <List <Digit DstRadix> ~ ℤ_2^64 - ~ machine.UInt64 > + ~ machine.UInt64> ") }; @@ -323,19 +364,27 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { let src_digits_rt = src_rt.descend(Context::parse(&ctx, " <PosInt SrcRadix LittleEndian> - ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64 > + ~ <Seq <Digit SrcRadix>> + ~ <List <Digit SrcRadix> + ~ ℤ_2^64 + ~ machine.UInt64 > ").apply_substitution(&|k|σ.get(k).cloned()).clone() ).expect("cant descend repr tree"); let dst_digits_port = - src_digits_rt.view_seq::<u64>() + src_digits_rt.view_list::<u64>() + .to_sequence() .to_positional_uint( src_radix ) - .transform_radix( dst_radix ); + .transform_radix( dst_radix ) + .to_list(); src_rt.attach_leaf_to( Context::parse(&ctx, " - <PosInt DstRadix LittleEndian> - ~ <Seq <Digit DstRadix> ~ ℤ_2^64 ~ machine.UInt64> + <PosInt DstRadix LittleEndian> + ~ <Seq <Digit DstRadix> > + ~ <List <Digit DstRadix> + ~ ℤ_2^64 + ~ machine.UInt64 > ").apply_substitution(&|k|σ.get(k).cloned()).clone(), dst_digits_port ); diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 072424f..bad1396 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -515,6 +515,10 @@ impl ReprTree { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + pub fn view_singleton<T: 'static>(&self) -> OuterViewPort<dyn SingletonView<Item = T>> { + self.get_port::<dyn SingletonView<Item = T>>().expect("no singleton-view available") + } + pub fn view_seq<T: 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> { self.get_port::<dyn SequenceView<Item = T>>().expect("no sequence-view available") } @@ -560,6 +564,7 @@ pub trait ReprTreeExt { fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>; fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>>; + fn view_singleton<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SingletonView<Item = T>>; fn view_seq<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>>; fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>>; @@ -622,6 +627,10 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { self.read().unwrap().view_usize() } + fn view_singleton<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SingletonView<Item = T>> { + self.read().unwrap().view_singleton::<T>() + } + fn view_seq<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> { self.read().unwrap().view_seq::<T>() } diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index 65eb5bb..d78f2c5 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -1,6 +1,6 @@ use { laddertypes::{TypeTerm, TypeID}, - r3vi::view::AnyOuterViewPort, + r3vi::view::{AnyOuterViewPort, port::UpdateTask}, crate::{ repr_tree::{ReprTree, ReprTreeExt, ReprLeaf}, }, @@ -128,26 +128,78 @@ impl MorphismBase { eprintln!("could not find morphism\n {:?}\n ====>\n {:?}", src_type, dst_type); } } -/* - pub fn apply_seq_map_morphism<SrcItem, DstItem>( - &self, - mut repr_tree: Arc<RwLock<ReprTree>>, - src_item_type: &TypeTerm, - dst_item_type: &TypeTerm - ) { - if let Some((item_morphism, σ)) = self.find_morphism( &src_item_type, dst_item_type ) { - let src_port = repr_tree.read().unwrap().get_port::<dyn SequenceView<Item = Arc<RwLock<ReprTree>> >>().unwrap(); - src_port.map( - m.setup_projection - ) - - (m.setup_projection)( &mut repr_tree, &σ ); + pub fn apply_list_map_morphism< + SrcItem: Clone + Send + Sync + 'static, + DstItem: Clone + Send + Sync + 'static + >( + &self, + repr_tree: Arc<RwLock<ReprTree>>, + mut src_item_type: TypeTerm, + mut dst_item_type: TypeTerm + ) { + if let Some((item_morphism, s, σ)) = self.find_morphism_ladder( &src_item_type, &dst_item_type ) { + let sl = s.get_lnf_vec().len()+1; + (&mut src_item_type).apply_substitution( &|v| σ.get(v).clone().cloned() ); + (&mut dst_item_type).apply_substitution( &|v| σ.get(v).clone().cloned() ); + + let src_item_type = + TypeTerm::Ladder({ + let mut l = src_item_type.clone().get_lnf_vec(); + for i in 0..sl { l.remove(0); } + l + }); + let dst_item_type = + TypeTerm::Ladder({ + let mut l = dst_item_type.clone().get_lnf_vec(); + for i in 0..sl { l.remove(0); } + l + }); + + let src_lst_type = + TypeTerm::App(vec![ + TypeTerm::TypeID(TypeID::Fun(10 /* FIXME: remove magic */)), + src_item_type.clone() + ]); + let dst_lst_type = + TypeTerm::App(vec![ + TypeTerm::TypeID(TypeID::Fun(10 /* FIXME: remove magic */)), + dst_item_type.clone() + ]); + + let src_port = repr_tree.descend( src_lst_type ).expect("descend src seq") + .view_list::<SrcItem>(); + + let dst_view = src_port.map({ + let dst_item_type = dst_item_type.clone(); + let item_morphism = item_morphism.clone(); + move |x| { + let mut item_ladder = src_item_type.clone().get_lnf_vec(); + let mut item_rt = ReprTree::from_singleton_buffer( + item_ladder.remove( item_ladder.len() - 1 ), + r3vi::buffer::singleton::SingletonBuffer::new(x.clone()) + ); + while item_ladder.len() > 0 { + let mut n = ReprTree::new_arc( item_ladder.remove( item_ladder.len() - 1) ); + n.insert_branch( item_rt ); + item_rt = n; + } + (item_morphism.setup_projection)( &mut item_rt, &σ ); + item_rt.descend( dst_item_type.clone() ).expect("descend to item rt") + .view_singleton::< DstItem >() + .get_view().unwrap() + .get() + } + }); + + repr_tree.attach_leaf_to( + dst_lst_type, + dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> > + ); } else { eprintln!("could not find item morphism"); } } - */ } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> From a3c701ce88097411860ab2500e81d9aa3f521945 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 2 Aug 2024 21:58:07 +0200 Subject: [PATCH 46/75] automatically generate list-map morphisms in find_morphism() this allows us to now to create <List EditTree> from <List Char> with apply_morphism() --- examples/tty-04-posint/src/main.rs | 97 ++++---------- lib-nested-core/src/editors/char/mod.rs | 7 +- lib-nested-core/src/editors/digit/ctx.rs | 4 +- lib-nested-core/src/editors/list/ctx.rs | 10 +- lib-nested-core/src/editors/list/editor.rs | 5 +- lib-nested-core/src/repr_tree/context.rs | 17 +-- lib-nested-core/src/repr_tree/morphism.rs | 144 ++++++++++++++------- lib-nested-tty/src/editors/list.rs | 14 +- 8 files changed, 150 insertions(+), 148 deletions(-) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index 2c12c17..67385eb 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -37,7 +37,7 @@ fn rebuild_projections( repr_tree: Arc<RwLock<ReprTree>>, morph_types: Vec< (laddertypes::TypeTerm, laddertypes::TypeTerm) > ) { -// repr_tree.write().unwrap().detach(&ctx); + repr_tree.write().unwrap().detach(&ctx); for (src_type, dst_type) in morph_types.iter() { ctx.read().unwrap().morphisms.apply_morphism( repr_tree.clone(), @@ -47,9 +47,7 @@ fn rebuild_projections( } } -fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { - rt_int.write().unwrap().detach(&ctx); - +fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { rebuild_projections( ctx.clone(), rt_int.clone(), @@ -79,33 +77,17 @@ fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>", "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" ), - ].into_iter() - .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) - .collect() - ); - - let rt_digitseq = - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ")).expect("test"); - let src_type = Context::parse(&ctx, "<Digit 16> ~ Char"); - let dst_type = Context::parse(&ctx, "<Digit 16> ~ ℤ_2^64 ~ machine.UInt64"); - ctx.read().unwrap().morphisms - .apply_list_map_morphism::<char, u64>( - rt_digitseq, src_type, dst_type - ); - rebuild_projections( - ctx.clone(), - rt_int.clone(), - vec![ + // convert to different digit-representation + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>" + ), // Radix Convert ( "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" - ) + ), ].into_iter() .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) .collect() @@ -113,8 +95,6 @@ fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { } fn setup_be_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { - rt_int.write().unwrap().detach(&ctx); - rebuild_projections( ctx.clone(), rt_int.clone(), @@ -144,35 +124,19 @@ fn setup_be_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>", "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" ), - ].into_iter() - .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) - .collect() - ); - - let rt_digitseq = - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ")).expect("test"); - let src_type = Context::parse(&ctx, "<Digit 16> ~ Char"); - let dst_type = Context::parse(&ctx, "<Digit 16> ~ ℤ_2^64 ~ machine.UInt64"); - ctx.read().unwrap().morphisms - .apply_list_map_morphism::<char, u64>( - rt_digitseq, src_type, dst_type - ); - rebuild_projections( - ctx.clone(), - rt_int.clone(), - vec![ - // Little Endian Editor + // convert to different digit-representation + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>" + ), + // Radix Convert ( "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" - ), - ].into_iter() + ) + ].into_iter() .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) .collect() ); @@ -272,7 +236,8 @@ async fn main() { ~ <List Char> ")).expect("descend"), SingletonBuffer::new(0).get_port() - ).unwrap(); + ).unwrap().get(); + let edittree_hex_be_list = ctx.read().unwrap() .setup_edittree( rt_int.descend(Context::parse(&ctx," @@ -282,23 +247,9 @@ async fn main() { ~ <List Char> ")).expect("descend"), SingletonBuffer::new(0).get_port() - ).unwrap(); + ).unwrap().get(); - - let rt_digitseq = - rt_int.descend(Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ")).expect("test"); - let src_type = Context::parse(&ctx, "<Digit 16> ~ Char"); - let dst_type = Context::parse(&ctx, "<Digit 16> ~ ℤ_2^64 ~ machine.UInt64"); - ctx.read().unwrap().morphisms - .apply_list_map_morphism::<char, u64>( - rt_digitseq, src_type, dst_type - ); - let hex_digits_view = rt_int.descend(Context::parse(&ctx, " <PosInt 16 LittleEndian> ~ <Seq <Digit 16> > @@ -328,15 +279,15 @@ async fn main() { /* list of both editors */ let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); - list_editor.data.push( edittree_hex_be_list.value.clone() ); - list_editor.data.push( edittree_hex_le_list.value.clone() ); + list_editor.data.push( edittree_hex_be_list.clone() ); + list_editor.data.push( edittree_hex_le_list.clone() ); let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); /* cursors are a bit screwed initially so fix them up * TODO: how to fix this generally? */ - edittree_hex_be_list.get().goto(TreeCursor::none()); - edittree_hex_le_list.get().goto(TreeCursor::none()); + edittree_hex_be_list.write().unwrap().goto(TreeCursor::none()); + edittree_hex_le_list.write().unwrap().goto(TreeCursor::none()); edittree.goto(TreeCursor{ leaf_mode: nested::editors::list::ListCursorMode::Insert, tree_addr: vec![1,0] @@ -393,7 +344,7 @@ async fn main() { { let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend"); let halo_type = rt_edittree.read().unwrap().get_halo_type().clone(); - let edittree = rt_edittree.read().unwrap().get_view::<dyn r3vi::view::singleton::SingletonView<Item = EditTree>>().unwrap().get(); + let edittree = rt_edittree.read().unwrap().get_view::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>>>>().unwrap().get().read().unwrap().clone(); comp.push( nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 5d37008..fb9abae 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -56,7 +56,12 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { rt.insert_leaf( Context::parse(&ctx, "EditTree"), - ReprLeaf::from_singleton_buffer(SingletonBuffer::new(edittree)) + ReprLeaf::from_singleton_buffer(SingletonBuffer::new(Arc::new(RwLock::new(edittree)))) + ); + + ctx.read().unwrap().setup_edittree( + rt.clone(), + SingletonBuffer::new(0).get_port() ); } } diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index ea5b8d6..538780c 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -19,7 +19,7 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { // todo: proper scoping of Radix variable ctx.write().unwrap().add_varname("Radix"); - +/* let morphtype = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<Digit Radix>"), @@ -76,7 +76,7 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { } } ); - +*/ let morphtype = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<Digit Radix>~Char"), diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 839110d..d35ec7a 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -24,7 +24,7 @@ use { pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.write().unwrap().add_varname("Item"); - +/* let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Char>"), dst_type: Context::parse(&ctx, "<List Char~EditTree>") @@ -66,7 +66,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } } }); - +*/ let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"), dst_type: Context::parse(&ctx, "<List Item>~EditTree") @@ -94,7 +94,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { Context::parse(&ctx, "<List Item> ~ EditTree") .apply_substitution(&|id| σ.get(id).cloned()).clone(), ReprLeaf::from_singleton_buffer( - SingletonBuffer::new(edittree_list) + SingletonBuffer::new(Arc::new(RwLock::new(edittree_list))) ) ); } else { @@ -115,9 +115,9 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { let edittree = src_rt .descend(Context::parse(&ctx, "<List Char>~EditTree")).unwrap() - .singleton_buffer::<EditTree>(); + .singleton_buffer::<Arc<RwLock<EditTree>>>(); - let list_edit = edittree.get().get_edit::< ListEditor >().unwrap(); + let list_edit = edittree.get().read().unwrap().get_edit::< ListEditor >().unwrap(); let edittree_items = list_edit.read().unwrap().data.get_port().to_list(); src_rt.insert_leaf( diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index b9fa64e..04cc63b 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -327,7 +327,8 @@ impl ListEditor { if let Some(edittree) = et.as_mut(){ - let mut tail_node = edittree.get_mut(); + let mut tail_node = edittree.get(); + let mut tail_node = tail_node.write().unwrap(); tail_node.goto(TreeCursor::home()); for node in b.iter() { @@ -353,7 +354,7 @@ impl ListEditor { drop(tail_node); self.insert( - edittree.value.clone() + edittree.value.read().unwrap().clone() ); } diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 78f2ed7..71add2a 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -179,25 +179,14 @@ impl Context { &self, rt: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>> - ) -> Option<SingletonBuffer<EditTree>> { - let ladder = TypeTerm::Ladder(vec![ - rt.read().unwrap().get_type().clone(), - self.type_term_from_str("EditTree").expect("") - ]); - - self.morphisms.apply_morphism( - rt.clone(), - &rt.get_type(), - &ladder - ); - + ) -> Option<SingletonBuffer<Arc<RwLock<EditTree>>>> { if let Some(new_edittree) = rt.descend(self.type_term_from_str("EditTree").unwrap()) { let typ = rt.read().unwrap().get_type().clone(); - let buf = new_edittree.singleton_buffer::<EditTree>(); + let buf = new_edittree.singleton_buffer::<Arc<RwLock<EditTree>>>(); (*self.edittree_hook)( - &mut *buf.get_mut(), + &mut *buf.get().write().unwrap(), typ ); Some(buf) diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index d78f2c5..68e837c 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -65,9 +65,48 @@ impl MorphismBase { &self, src_type: &TypeTerm, dst_type: &TypeTerm - ) -> Option<(&GenericReprTreeMorphism, HashMap<TypeID, TypeTerm>)> { - for m in self.morphisms.iter() { + ) -> Option<(GenericReprTreeMorphism, HashMap<TypeID, TypeTerm>)> { + // try list-map morphism + if let Ok(σ) = laddertypes::UnificationProblem::new(vec![ + (src_type.clone().param_normalize(), TypeTerm::App(vec![ TypeTerm::TypeID(TypeID::Fun(10)), TypeTerm::TypeID(TypeID::Var(100)) ])), + (dst_type.clone().param_normalize(), TypeTerm::App(vec![ TypeTerm::TypeID(TypeID::Fun(10)), TypeTerm::TypeID(TypeID::Var(101)) ])), + ]).solve() { + let src_item_type = σ.get(&TypeID::Var(100)).unwrap().clone(); + let dst_item_type = σ.get(&TypeID::Var(101)).unwrap().clone(); +/* + eprintln!("Got a List- Type, check if we find a list-map morphism"); + eprintln!("src-item-type : {:?}", src_item_type); + eprintln!("dst-item-type : {:?}", dst_item_type); +*/ + let src_item_type_lnf = src_item_type.clone().get_lnf_vec(); + let dst_item_type_lnf = dst_item_type.clone().get_lnf_vec(); + + /* if src_item_type ~== "Char", + dst_item_type ~== "machine.UInt64" + */ + if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(0))) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(4))) + { + if let Some((m, σ)) = self.find_list_map_morphism::< char, u64 >( src_item_type, dst_item_type ) { + return Some((m, σ)); + } + } + + /* if src_item_type ~== "Char" + dst_item_type ~== "EditTree" + */ + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(0))) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(1))) + { + if let Some((m, σ)) = self.find_list_map_morphism::< char, Arc<RwLock<crate::edit_tree::EditTree>> >( src_item_type, dst_item_type ) { + return Some((m, σ)); + } + } + } + + // otherwise + for m in self.morphisms.iter() { let unification_problem = laddertypes::UnificationProblem::new( vec![ ( src_type.clone().normalize(), m.morph_type.src_type.clone() ), @@ -77,7 +116,7 @@ impl MorphismBase { let unification_result = unification_problem.solve(); if let Ok(σ) = unification_result { - return Some((m, σ)); + return Some((m.clone(), σ)); } } @@ -90,7 +129,7 @@ impl MorphismBase { src_type: &TypeTerm, dst_type: &TypeTerm, ) -> Option<( - &GenericReprTreeMorphism, + GenericReprTreeMorphism, TypeTerm, HashMap<TypeID, TypeTerm> )> { @@ -129,33 +168,21 @@ impl MorphismBase { } } - pub fn apply_list_map_morphism< + pub fn find_list_map_morphism< SrcItem: Clone + Send + Sync + 'static, DstItem: Clone + Send + Sync + 'static >( &self, - repr_tree: Arc<RwLock<ReprTree>>, mut src_item_type: TypeTerm, mut dst_item_type: TypeTerm - ) { - if let Some((item_morphism, s, σ)) = self.find_morphism_ladder( &src_item_type, &dst_item_type ) { - let sl = s.get_lnf_vec().len()+1; + ) -> Option< + ( GenericReprTreeMorphism, HashMap< TypeID, TypeTerm > ) + > + { + if let Some((item_morphism, σ)) = self.find_morphism( &src_item_type, &dst_item_type ) { (&mut src_item_type).apply_substitution( &|v| σ.get(v).clone().cloned() ); (&mut dst_item_type).apply_substitution( &|v| σ.get(v).clone().cloned() ); - - let src_item_type = - TypeTerm::Ladder({ - let mut l = src_item_type.clone().get_lnf_vec(); - for i in 0..sl { l.remove(0); } - l - }); - let dst_item_type = - TypeTerm::Ladder({ - let mut l = dst_item_type.clone().get_lnf_vec(); - for i in 0..sl { l.remove(0); } - l - }); - + let src_lst_type = TypeTerm::App(vec![ TypeTerm::TypeID(TypeID::Fun(10 /* FIXME: remove magic */)), @@ -167,37 +194,54 @@ impl MorphismBase { dst_item_type.clone() ]); - let src_port = repr_tree.descend( src_lst_type ).expect("descend src seq") - .view_list::<SrcItem>(); + let sigmalol = σ.clone(); + let m = GenericReprTreeMorphism{ + morph_type: MorphismType { + src_type: src_lst_type.clone(), + dst_type: dst_lst_type.clone(), + }, + setup_projection: Arc::new(move |repr_tree, subst| { + let src_port = repr_tree.descend( src_lst_type.clone() ).expect("descend src seq") + .view_list::<SrcItem>(); - let dst_view = src_port.map({ - let dst_item_type = dst_item_type.clone(); - let item_morphism = item_morphism.clone(); - move |x| { - let mut item_ladder = src_item_type.clone().get_lnf_vec(); - let mut item_rt = ReprTree::from_singleton_buffer( - item_ladder.remove( item_ladder.len() - 1 ), - r3vi::buffer::singleton::SingletonBuffer::new(x.clone()) + let src_item_type = src_item_type.clone(); + let dst_item_type = dst_item_type.clone(); + let item_morphism = item_morphism.clone(); + let subst = subst.clone(); + + let dst_view = src_port.map( + move |x| { + let mut item_ladder = src_item_type.clone().get_lnf_vec(); + let mut item_rt = ReprTree::from_singleton_buffer( + item_ladder.remove( item_ladder.len() - 1 ), + r3vi::buffer::singleton::SingletonBuffer::new(x.clone()) + ); + + while item_ladder.len() > 0 { + let mut n = ReprTree::new_arc( item_ladder.remove( item_ladder.len() - 1) ); + n.insert_branch( item_rt ); + item_rt = n; + } + + (item_morphism.setup_projection)( &mut item_rt, &subst ); + item_rt.descend( dst_item_type.clone() ).expect("descend to item rt") + .view_singleton::< DstItem >() + .get_view().unwrap() + .get() + } ); - while item_ladder.len() > 0 { - let mut n = ReprTree::new_arc( item_ladder.remove( item_ladder.len() - 1) ); - n.insert_branch( item_rt ); - item_rt = n; - } - (item_morphism.setup_projection)( &mut item_rt, &σ ); - item_rt.descend( dst_item_type.clone() ).expect("descend to item rt") - .view_singleton::< DstItem >() - .get_view().unwrap() - .get() - } - }); - repr_tree.attach_leaf_to( - dst_lst_type, - dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> > - ); + repr_tree.attach_leaf_to( + dst_lst_type.clone(), + dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> > + ); + }) + }; + + Some((m, σ)) } else { - eprintln!("could not find item morphism"); + eprintln!("could not find item morphism\n"); + None } } } diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 4584e9c..f3ae4ee 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -223,6 +223,17 @@ impl PTYListController { match cur.mode { ListCursorMode::Insert => { let rt = ReprTree::new_arc(e.typ.clone()); + + let ladder = laddertypes::TypeTerm::Ladder(vec![ + rt.read().unwrap().get_type().clone(), + ctx.type_term_from_str("EditTree").expect("") + ]); + ctx.morphisms.apply_morphism( + rt.clone(), + &rt.get_type(), + &ladder + ); + let new_edittree = ctx.setup_edittree( rt, self.depth.map(|d| d+1) @@ -231,10 +242,11 @@ impl PTYListController { if let Some(new_edittree) = new_edittree { let mut ne = new_edittree.get(); + let mut ne = ne.write().unwrap(); match ne.send_cmd_obj(cmd_obj.clone()) { TreeNavResult::Continue => { drop(ne); - e.insert(new_edittree.value.clone()); + e.insert(new_edittree.value.read().unwrap().clone()); TreeNavResult::Continue } TreeNavResult::Exit => { From 830ce613ea18c677848f26e687cf0b20233cac98 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 2 Aug 2024 22:43:00 +0200 Subject: [PATCH 47/75] example: two editors with different radices --- examples/tty-04-posint/src/main.rs | 240 ++++++++++++---------- lib-nested-core/src/repr_tree/morphism.rs | 11 + 2 files changed, 140 insertions(+), 111 deletions(-) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index 67385eb..ed8311f 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -47,24 +47,101 @@ fn rebuild_projections( } } -fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { +fn setup_hex_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { rebuild_projections( ctx.clone(), rt_int.clone(), vec![ - // Little Endian Editor + // extract values from hex-editor ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" ), - // Convert Endianness + // convert to little-endian + ( + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + ), + // convert digit representation from char to u64 + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>" + ), + // convert radix to decimal + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" + ), + // convert decimal digit representation back to char + ( + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>", + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>" + ), + // convert to big-endian + ( + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>", + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>" + ), + + // decimal editor + ( + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>", + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char ~ EditTree>" + ), + ( + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char ~ EditTree>", + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char ~ EditTree> ~ <Vec EditTree>" + ), + ( + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char ~ EditTree> ~ <Vec EditTree>", + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree" + ), + + ].into_iter() + .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) + .collect() + ); +} + +fn setup_dec_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { + rebuild_projections( + ctx.clone(), + rt_int.clone(), + vec![ + // extract values from decimal-editor + ( + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree", + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>" + ), + + // convert to little-endian + ( + "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>", + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>" + ), + // convert digit representation to u64 + ( + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>", + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" + ), + // convert radix to decimal + ( + "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>" + ), + // convert back digit representation char + ( + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + ), + // convert back to big-endian ( "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" ), - // Big Endian Editor + // hex editor ( "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" @@ -77,65 +154,6 @@ fn setup_le_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>", "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" ), - - // convert to different digit-representation - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>" - ), - // Radix Convert - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" - ), - ].into_iter() - .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) - .collect() - ); -} - -fn setup_be_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { - rebuild_projections( - ctx.clone(), - rt_int.clone(), - vec![ - // Big Endian Editor - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" - ), - - // Convert Endianness - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" - ), - - // Little Endian Editor - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" - ), - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>" - ), - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" - ), - - - // convert to different digit-representation - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>" - ), - // Radix Convert - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" - ) ].into_iter() .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) .collect() @@ -159,32 +177,19 @@ async fn main() { /* Add a specific Representation-Path (big-endian hexadecimal) */ - let mut digits_be = VecBuffer::with_data(vec![ 'c', 'f', 'f' ]); + let mut digits_hex = VecBuffer::with_data(vec![ 'c', 'f', 'f' ]); rt_int.insert_leaf( Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>~<Vec Char>"), - nested::repr_tree::ReprLeaf::from_vec_buffer( digits_be.clone() ) + nested::repr_tree::ReprLeaf::from_vec_buffer( digits_hex.clone() ) ); - let mut digits_le = VecBuffer::with_data(vec!['3', '2', '1']); + let mut digits_dec = VecBuffer::with_data(vec!['3', '2', '1']); rt_int.insert_leaf( - Context::parse(&ctx, "<PosInt 16 LittleEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>~<Vec Char>"), - nested::repr_tree::ReprLeaf::from_vec_buffer( digits_le.clone() ) + Context::parse(&ctx, "<PosInt 10 BigEndian>~<Seq <Digit 10>>~<List <Digit 10>>~<List Char>~<Vec Char>"), + nested::repr_tree::ReprLeaf::from_vec_buffer( digits_dec.clone() ) ); - let mut digits_le_editvec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); - rt_int.insert_leaf( - Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16> - ~ Char - ~ EditTree> - ~ <Vec EditTree> - "), - nested::repr_tree::ReprLeaf::from_vec_buffer( digits_le_editvec.clone() ) - ); - - let mut digits_be_editvec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); + let mut digits_hex_editvec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); rt_int.insert_leaf( Context::parse(&ctx, " <PosInt 16 BigEndian> @@ -194,7 +199,20 @@ async fn main() { ~ EditTree> ~ <Vec EditTree> "), - nested::repr_tree::ReprLeaf::from_vec_buffer( digits_be_editvec.clone() ) + nested::repr_tree::ReprLeaf::from_vec_buffer( digits_hex_editvec.clone() ) + ); + + let mut digits_dec_editvec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); + rt_int.insert_leaf( + Context::parse(&ctx, " + <PosInt 10 BigEndian> + ~ <Seq <Digit 10>> + ~ <List <Digit 10> + ~ Char + ~ EditTree> + ~ <Vec EditTree> + "), + nested::repr_tree::ReprLeaf::from_vec_buffer( digits_dec_editvec.clone() ) ); /* initially copy values from Vec to EditTree... @@ -205,38 +223,27 @@ async fn main() { // master representation vec![ ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <Vec Char>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <Vec Char>", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" ), ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" ), ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree> ~ <Vec EditTree>" + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree>", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree> ~ <Vec EditTree>" ), ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree> ~ <Vec EditTree>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree> ~ <Vec EditTree>", + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" ), ].into_iter() .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) .collect() ); - setup_le_master(&ctx, &rt_int); - - let edittree_hex_le_list = ctx.read().unwrap() - .setup_edittree( - rt_int.descend(Context::parse(&ctx," - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ~ <List Char> - ")).expect("descend"), - SingletonBuffer::new(0).get_port() - ).unwrap().get(); + setup_hex_master(&ctx, &rt_int); let edittree_hex_be_list = ctx.read().unwrap() .setup_edittree( @@ -249,6 +256,17 @@ async fn main() { SingletonBuffer::new(0).get_port() ).unwrap().get(); + let edittree_dec_be_list = ctx.read().unwrap() + .setup_edittree( + rt_int.descend(Context::parse(&ctx," + <PosInt 10 BigEndian> + ~ <Seq <Digit 10>> + ~ <List <Digit 10>> + ~ <List Char> + ")).expect("descend"), + SingletonBuffer::new(0).get_port() + ).unwrap().get(); + let hex_digits_view = rt_int.descend(Context::parse(&ctx, " <PosInt 16 LittleEndian> @@ -280,17 +298,17 @@ async fn main() { */ let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); list_editor.data.push( edittree_hex_be_list.clone() ); - list_editor.data.push( edittree_hex_le_list.clone() ); + list_editor.data.push( edittree_dec_be_list.clone() ); let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); /* cursors are a bit screwed initially so fix them up * TODO: how to fix this generally? */ edittree_hex_be_list.write().unwrap().goto(TreeCursor::none()); - edittree_hex_le_list.write().unwrap().goto(TreeCursor::none()); + edittree_dec_be_list.write().unwrap().goto(TreeCursor::none()); edittree.goto(TreeCursor{ leaf_mode: nested::editors::list::ListCursorMode::Insert, - tree_addr: vec![1,0] + tree_addr: vec![0,0] }); let edittree = Arc::new(RwLock::new(edittree)); @@ -310,14 +328,14 @@ async fn main() { 0 => { let mut li = last_idx.write().unwrap(); if *li != 0 { - setup_be_master(&ctx, &rt_int); + setup_hex_master(&ctx, &rt_int); *li = 0; } } 1 => { let mut li = last_idx.write().unwrap(); if *li != 1 { - setup_le_master(&ctx, &rt_int); + setup_dec_master(&ctx, &rt_int); *li = 1; } } @@ -355,7 +373,7 @@ async fn main() { } show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>")).expect(""), 1); - show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>~Char>")).expect(""), 4); + show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char>")).expect(""), 4); /* project the seq of u64 representations to a view */ diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index 68e837c..32db193 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -93,6 +93,17 @@ impl MorphismBase { } } + /* if src_item_type ~== "machine.UInt64", + dst_item_type ~== "Char" + */ + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(4))) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(0))) + { + if let Some((m, σ)) = self.find_list_map_morphism::< u64, char >( src_item_type, dst_item_type ) { + return Some((m, σ)); + } + } + /* if src_item_type ~== "Char" dst_item_type ~== "EditTree" */ From 4c0e9da2d31272abc9609438731e23da85e1f3c7 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 3 Aug 2024 15:44:04 +0200 Subject: [PATCH 48/75] fixup examples also fix behaviour of insert_leaf() & attach_leaf_to() when type of current repr-node occurs inside the type of the leaf --- examples/tty-02-digit/src/main.rs | 25 ++++--- examples/tty-03-string/src/main.rs | 38 +++++++--- lib-nested-core/src/editors/digit/ctx.rs | 11 +-- lib-nested-core/src/editors/list/ctx.rs | 57 +++------------ lib-nested-core/src/repr_tree/mod.rs | 86 +++++++++++------------ lib-nested-core/src/repr_tree/morphism.rs | 2 +- 6 files changed, 101 insertions(+), 118 deletions(-) diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs index 61603b1..c7df17e 100644 --- a/examples/tty-02-digit/src/main.rs +++ b/examples/tty-02-digit/src/main.rs @@ -72,13 +72,16 @@ async fn main() { ctx.read().unwrap().morphisms.apply_morphism( rt_digit.clone(), &Context::parse(&ctx, "<Digit 16>~Char"), - &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8") + &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64") + ); + + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "<Digit 16>~Char"), + &Context::parse(&ctx, "<Digit 16>~EditTree") ); /* setup TTY-Display for DigitEditor - * - * `setup_edittree` will setup the projection - * Char -> Char~EditTree * and call the hook defined above with `set_edittree_hook()` * */ @@ -86,11 +89,11 @@ async fn main() { .setup_edittree( rt_digit.clone(), SingletonBuffer::new(0).get_port() - ); + ).unwrap(); - let mut digit_u8_buffer = rt_digit - .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() - .singleton_buffer::<u8>(); + let mut digit_u64_buffer = rt_digit + .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap() + .singleton_buffer::<u64>(); /* setup terminal */ @@ -101,7 +104,7 @@ async fn main() { let mut edittree_digit = edittree_digit.clone(); move |ev| { - edittree_digit.get().send_cmd_obj(ev.to_repr_tree(&ctx)); + edittree_digit.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -128,11 +131,11 @@ async fn main() { .offset(Vector2::new(1, 1)) ); comp.push( - edittree_digit.get().display_view() + edittree_digit.get().read().unwrap().display_view() .offset(Vector2::new(3,2)) ); comp.push( - digit_u8_buffer.get_port().map( + digit_u64_buffer.get_port().map( |d| nested_tty::make_label(&format!("Digit value={}", d)) ) .to_grid() diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs index 0d8f670..dfa84e1 100644 --- a/examples/tty-03-string/src/main.rs +++ b/examples/tty-03-string/src/main.rs @@ -25,7 +25,7 @@ use { }, r3vi::{ buffer::{singleton::*, vec::*}, - view::{port::UpdateTask, list::*} + view::{port::UpdateTask, list::*, sequence::SequenceViewExt} }, std::sync::{Arc, RwLock}, }; @@ -43,15 +43,32 @@ async fn main() { /* Create a Representation-Tree of type <List Char> */ - let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); + let mut rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); - /* Setup an Editor for this ReprTree - * (this will add the representation <List Char>~EditTree to the ReprTree) + let vec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); + rt_string.insert_leaf( + Context::parse(&ctx, "<List EditTree> ~ <Vec EditTree>"), + nested::repr_tree::ReprLeaf::from_vec_buffer( vec.clone() ) + ); + + let v2 = VecBuffer::<char>::new(); + rt_string.insert_leaf( + Context::parse(&ctx, "<Vec Char>"), + nested::repr_tree::ReprLeaf::from_vec_buffer( v2.clone() ) + ); + ctx.read().unwrap().morphisms.apply_morphism( + rt_string.clone(), + &Context::parse(&ctx, "<List Char~EditTree> ~ <Vec EditTree>"), + &Context::parse(&ctx, "<List Char> ~ EditTree") + ); + + /* Setup the Editor-View for this ReprTree */ let edittree_list = ctx.read().unwrap() .setup_edittree( rt_string.clone(), - SingletonBuffer::new(0).get_port()); + SingletonBuffer::new(0).get_port() + ).unwrap(); /* In order to get acces to the values that are modified by the Editor, * we apply a morphism that, given the List of Edit-Trees, extracts @@ -71,7 +88,6 @@ async fn main() { .get_port::<dyn ListView<char>>() .unwrap(); - /* Lets add another morphism which will store the values * of the character-list in a `Vec<char>` */ @@ -104,7 +120,7 @@ async fn main() { */ let ctx = ctx.clone(); move |ev| { - edittree_list.get().send_cmd_obj(ev.to_repr_tree(&ctx)); + edittree_list.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -127,6 +143,7 @@ async fn main() { comp.push( edittree_list.get() + .read().unwrap() .display_view() .offset(Vector2::new(3,2))); @@ -145,8 +162,11 @@ async fn main() { /* Vec<char> to String */ - let string = chars_vec.data - .read().unwrap() + let string = chars_vec + .get_port() + .to_sequence() + .get_view().unwrap() + //.data.read().unwrap() .iter().collect::<String>(); eprintln!("value of the editor was: {}\n\n", string); diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index 538780c..40a7826 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -19,10 +19,10 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { // todo: proper scoping of Radix variable ctx.write().unwrap().add_varname("Radix"); -/* + let morphtype = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<Digit Radix>"), + src_type: Context::parse(&ctx, "<Digit Radix>~Char"), dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree") }; @@ -45,6 +45,9 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { if let Some(crt) = src_rt.descend(Context::parse(&ctx, "Char")) { crt } else { + /* TODO: replace this with some formal specification + * of "required representations" + */ let crt = ReprTree::from_singleton_buffer( Context::parse(&ctx, "Char"), SingletonBuffer::new('\0') @@ -70,13 +73,13 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { .insert_branch( ReprTree::from_singleton_buffer( Context::parse(&ctx, "EditTree"), - SingletonBuffer::new(edittree) + SingletonBuffer::new(Arc::new(RwLock::new(edittree))) ) ); } } ); -*/ + let morphtype = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<Digit Radix>~Char"), diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index d35ec7a..93a47a5 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -24,49 +24,7 @@ use { pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.write().unwrap().add_varname("Item"); -/* - let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List Char>"), - dst_type: Context::parse(&ctx, "<List Char~EditTree>") - }; - ctx.write().unwrap().morphisms.add_morphism(mt, { - let ctx = ctx.clone(); - move |src_rt, σ| { - let list_port = src_rt.descend(Context::parse(&ctx, "<List Char>")).expect("descend").get_port::<dyn ListView<char>>().clone(); - if let Some(list_port) = list_port { - // for each char, create EditTree - let edit_tree_list = - list_port - .map({ - let ctx = ctx.clone(); - move |c| { - let item_rt = ReprTree::from_char(&ctx, *c); - - ctx.read().unwrap().setup_edittree( - item_rt.clone(), - SingletonBuffer::new(0).get_port() - ); - - let et = item_rt - .descend(Context::parse(&ctx, "Char ~ EditTree")).expect("cant descend repr tree") - .get_port::< dyn SingletonView<Item = EditTree> >().expect("cant get view port (EditTree)") - .get_view().unwrap() - .get(); - Arc::new(RwLock::new(et)) - } - }); - - src_rt.attach_leaf_to( - Context::parse(&ctx, "<List Char>~<List EditTree>"), - edit_tree_list - ); - } else { - eprintln!("morphism missing view port"); - } - } - }); -*/ let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"), dst_type: Context::parse(&ctx, "<List Item>~EditTree") @@ -93,6 +51,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { src_rt.insert_leaf( Context::parse(&ctx, "<List Item> ~ EditTree") .apply_substitution(&|id| σ.get(id).cloned()).clone(), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new(Arc::new(RwLock::new(edittree_list))) ) @@ -123,14 +82,15 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { src_rt.insert_leaf( Context::parse(&ctx, "<List Char>"), ReprLeaf::from_view( - edittree_items + edittree_items .map(|edittree_char| edittree_char .read().unwrap() .get_edit::<CharEditor>().unwrap() .read().unwrap() .get() - )) + ) + ) ); } } @@ -148,13 +108,12 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { { let ctx = ctx.clone(); move |src_rt, σ| { + let list_view = src_rt.view_list::<char>(); + src_rt .attach_leaf_to( - Context::parse(&ctx, "<List Char>~<Vec Char>"), - src_rt - .descend(Context::parse(&ctx, "<List Char>")) - .expect("descend") - .view_list::<char>() + Context::parse(&ctx, "<Vec Char>"), + list_view ); } } diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index bad1396..ac1d18b 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -345,41 +345,6 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } - /// find, and if necessary, create corresponding path in repr-tree. - /// Attach src_port to input of that node - pub fn attach_leaf_to<V>( - &mut self, - mut type_ladder: impl Iterator<Item = TypeTerm>, - src_port: OuterViewPort<V> - ) - where V: View + ?Sized + 'static, - V::Msg: Clone - { - if let Some(rung_type) = type_ladder.next() { - if &rung_type == self.get_type() { - if let Some(leaf) = self.leaf.as_mut() { - leaf.attach_to(src_port); - } else { - self.leaf = Some(ReprLeaf::from_view(src_port)); - } - } else { - if let Some(next_repr) = self.branches.get(&rung_type) { - next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); - } else { - let mut next_repr = ReprTree::new(rung_type.clone()); - next_repr.attach_leaf_to(type_ladder, src_port); - self.insert_branch(Arc::new(RwLock::new(next_repr))); - } - } - } else { - if let Some(leaf) = self.leaf.as_mut() { - leaf.attach_to(src_port); - } else { - self.leaf = Some(ReprLeaf::from_view(src_port)); - } - } - } - pub fn attach_to<V>( &mut self, src_port: OuterViewPort<V> @@ -394,6 +359,36 @@ impl ReprTree { } } + /// find, and if necessary, create corresponding path in repr-tree. + /// Attach src_port to input of that node + pub fn attach_leaf_to<V>( + &mut self, + mut type_ladder: impl Iterator<Item = TypeTerm>, + src_port: OuterViewPort<V> + ) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + while let Some(rung_type) = type_ladder.next() { + if &rung_type != self.get_type() { + if let Some(next_repr) = self.branches.get(&rung_type) { + next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); + } else { + let mut next_repr = ReprTree::new(rung_type.clone()); + next_repr.attach_leaf_to(type_ladder, src_port); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } + return; + } + } + + if let Some(leaf) = self.leaf.as_mut() { + leaf.attach_to(src_port); + } else { + self.leaf = Some(ReprLeaf::from_view(src_port)); + } + } + pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { if let Some(leaf) = self.leaf.as_mut() { if self.type_tag == Context::parse(&ctx, "Char") { @@ -417,17 +412,20 @@ impl ReprTree { mut type_ladder: impl Iterator<Item = TypeTerm>, leaf: ReprLeaf ) { - if let Some(type_term) = type_ladder.next() { - if let Some(next_repr) = self.branches.get(&type_term) { - next_repr.write().unwrap().insert_leaf(type_ladder, leaf); - } else { - let mut next_repr = ReprTree::new(type_term.clone()); - next_repr.insert_leaf(type_ladder, leaf); - self.insert_branch(Arc::new(RwLock::new(next_repr))); + while let Some(type_term) = type_ladder.next() { + if &type_term != self.get_type() { + if let Some(next_repr) = self.branches.get(&type_term) { + next_repr.write().unwrap().insert_leaf(type_ladder, leaf.clone()); + } else { + let mut next_repr = ReprTree::new(type_term.clone()); + next_repr.insert_leaf(type_ladder, leaf.clone()); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } + return; } - } else { - self.leaf = Some(leaf) } + + self.leaf = Some(leaf); } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index 32db193..1607d6a 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -251,7 +251,7 @@ impl MorphismBase { Some((m, σ)) } else { - eprintln!("could not find item morphism\n"); +// eprintln!("could not find item morphism\n"); None } } From 508e716a6a437f1566de68e5d630ecdcb1550c81 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 4 Aug 2024 19:27:36 +0200 Subject: [PATCH 49/75] repr tree: split leaf & node into separate files --- lib-nested-core/src/repr_tree/leaf.rs | 216 +++++++++++ lib-nested-core/src/repr_tree/mod.rs | 518 +------------------------- lib-nested-core/src/repr_tree/node.rs | 348 +++++++++++++++++ 3 files changed, 568 insertions(+), 514 deletions(-) create mode 100644 lib-nested-core/src/repr_tree/leaf.rs create mode 100644 lib-nested-core/src/repr_tree/node.rs diff --git a/lib-nested-core/src/repr_tree/leaf.rs b/lib-nested-core/src/repr_tree/leaf.rs new file mode 100644 index 0000000..6a12440 --- /dev/null +++ b/lib-nested-core/src/repr_tree/leaf.rs @@ -0,0 +1,216 @@ +use { + r3vi::{ + view::{ + ViewPort, OuterViewPort, + AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, + port::UpdateTask, + View, Observer, + singleton::*, + sequence::*, + list::* + }, + buffer::{singleton::*, vec::*} + }, + laddertypes::{TypeTerm}, + std::{ + collections::HashMap, + sync::{Arc, RwLock}, + any::Any + }, +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone)] +pub struct ReprLeaf { + out_port: AnyViewPort, + in_port: AnyInnerViewPort, + data: Option< Arc<dyn Any + Send + Sync> >, + + /// keepalive for the observer that updates the buffer from in_port + keepalive: Option<Arc<dyn Any + Send + Sync>>, + in_keepalive: Option<Arc<dyn Any + Send + Sync>>, +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl ReprLeaf { + pub fn from_view<V>( src_port: OuterViewPort<V> ) -> Self + where V: View + ?Sized + 'static, + V::Msg: Clone + { + let mut in_port = ViewPort::<V>::new(); + let in_keepalive = in_port.attach_to(src_port); + + let mut out_port = ViewPort::<V>::new(); + let out_keepalive = out_port.attach_to(in_port.outer()); + + ReprLeaf { + keepalive: Some(out_keepalive), + in_keepalive: Some(in_keepalive), + in_port: in_port.inner().into(), + out_port: out_port.into(), + data: None, + } + } + + pub fn detach<V>(&mut self) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + self.keepalive = None; + self.in_keepalive = None; + + let ip = self.in_port.clone() + .downcast::<V>().ok() + .unwrap(); + ip.0.detach(); + + if self.data.is_none() { + let mut op = self.out_port.clone() + .downcast::<V>().ok() + .unwrap(); + + op.detach(); + self.keepalive = Some(op.attach_to(ip.0.outer())); + } + } + + pub fn detach_vec<Item>(&mut self) + where Item: Clone + Send + Sync + 'static + { + self.keepalive = None; + self.in_keepalive = None; + + let ip = self.in_port.clone() + .downcast::<dyn ListView<Item>>().ok() + .unwrap(); + + ip.0.detach(); + + if let Some(data) = self.data.as_mut() { + let mut op = self.out_port.clone() + .downcast::<RwLock<Vec<Item>>>().ok() + .unwrap(); + op.detach(); + + let data = data.clone().downcast::< RwLock<Vec<Item>> >().ok().unwrap(); + let buffer = VecBuffer::with_data_arc_port(data, op.inner()); + self.keepalive = Some(buffer.attach_to(ip.0.outer())) + } + } + + pub fn attach_to<V>(&mut self, src_port: OuterViewPort<V>) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + self.in_keepalive = Some(self.in_port.clone() + .downcast::<V>().ok().unwrap() + .0.attach_to( src_port )); + } + + pub fn from_singleton_buffer<T>( buffer: SingletonBuffer<T> ) -> Self + where T: Clone + Send + Sync + 'static + { + let in_port = ViewPort::<dyn SingletonView<Item = T>>::new(); + ReprLeaf { + in_keepalive: None, + keepalive: Some(buffer.attach_to(in_port.outer())), + in_port: in_port.inner().into(), + out_port: buffer.get_port().0.into(), + data: Some(buffer.into_inner()) + } + } + + pub fn from_vec_buffer<T>( buffer: VecBuffer<T> ) -> Self + where T: Clone + Send + Sync + 'static + { + let in_port = ViewPort::< dyn ListView<T> >::new(); + ReprLeaf { + in_keepalive: None, + keepalive: Some(buffer.attach_to(in_port.outer())), + in_port: in_port.inner().into(), + out_port: buffer.get_port().0.into(), + data: Some(buffer.into_inner()) + } + } + + pub fn as_singleton_buffer<T>(&mut self) -> Option<SingletonBuffer<T>> + where T: Clone + Send + Sync + 'static + { + let sgl_port = self.get_port::< dyn SingletonView<Item = T> >().unwrap().0; + + let data_arc = + if let Some(data) = self.data.as_ref() { + data.clone().downcast::<RwLock<T>>().ok() + } else { + sgl_port.update(); + let value = sgl_port.outer().get_view().unwrap().get(); + eprintln!("make new data ARC from old value"); + Some(Arc::new(RwLock::new( value ))) + }; + + if let Some(data_arc) = data_arc { + self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); + let buf = SingletonBuffer { + value: data_arc, + port: sgl_port.inner() + }; + self.keepalive = Some(buf.attach_to( + self.in_port.0.clone() + .downcast::<dyn SingletonView<Item = T>>() + .ok().unwrap() + .outer() + )); + Some(buf) + } else { + None + } + } + + pub fn as_vec_buffer<T>(&mut self) -> Option<VecBuffer<T>> + where T: Clone + Send + Sync + 'static + { + let vec_port = self.get_port::< RwLock<Vec<T>> >().unwrap().0; + + let data_arc = + if let Some(data) = self.data.as_ref() { + data.clone().downcast::<RwLock<Vec<T>>>().ok() + } else { + vec_port.update(); + if let Some(value) = vec_port.outer().get_view() { + let value = value.read().unwrap().clone(); + eprintln!("make new data ARC from old VECTOR-value"); + Some(Arc::new(RwLock::new( value ))) + } else { + eprintln!("no data vec"); + Some(Arc::new(RwLock::new( Vec::new() ))) +// None + } + }; + + if let Some(data_arc) = data_arc { + self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); + let buf = VecBuffer::with_data_arc_port(data_arc, vec_port.inner()); + self.keepalive = Some(buf.attach_to( + self.in_port.0.clone() + .downcast::< dyn ListView<T> >() + .ok().unwrap() + .outer() + )); + Some(buf) + } else { + None + } + } + + pub fn get_port<V>(&self) -> Option<OuterViewPort<V>> + where V: View + ?Sized + 'static, + V::Msg: Clone + { + self.out_port.clone().downcast::<V>().ok().map(|p| p.outer()) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index ac1d18b..c2b71d4 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -1,3 +1,5 @@ +pub mod node; +pub mod leaf; pub mod context; pub mod morphism; @@ -6,6 +8,8 @@ mod tests; pub use { context::{Context}, + leaf::ReprLeaf, + node::ReprTree, morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase} }; @@ -30,520 +34,6 @@ use { }, }; -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone)] -pub struct ReprLeaf { - out_port: AnyViewPort, - in_port: AnyInnerViewPort, - data: Option< Arc<dyn Any + Send + Sync> >, - - /// keepalive for the observer that updates the buffer from in_port - keepalive: Option<Arc<dyn Any + Send + Sync>>, - in_keepalive: Option<Arc<dyn Any + Send + Sync>>, -} - -#[derive(Clone)] -pub struct ReprTree { - halo: TypeTerm, - type_tag: TypeTerm, - branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>, - leaf: Option< ReprLeaf > -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl std::fmt::Debug for ReprTree { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "| type: {:?}", self.type_tag)?; - - for (_k,x) in self.branches.iter() { - writeln!(f, "|--> child: {:?}", x)?; - } - - Ok(()) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl ReprLeaf { - pub fn from_view<V>( src_port: OuterViewPort<V> ) -> Self - where V: View + ?Sized + 'static, - V::Msg: Clone - { - let mut in_port = ViewPort::<V>::new(); - let in_keepalive = in_port.attach_to(src_port); - - let mut out_port = ViewPort::<V>::new(); - let out_keepalive = out_port.attach_to(in_port.outer()); - - ReprLeaf { - keepalive: Some(out_keepalive), - in_keepalive: Some(in_keepalive), - in_port: in_port.inner().into(), - out_port: out_port.into(), - data: None, - } - } - - pub fn detach<V>(&mut self) - where V: View + ?Sized + 'static, - V::Msg: Clone - { - self.keepalive = None; - self.in_keepalive = None; - - let ip = self.in_port.clone() - .downcast::<V>().ok() - .unwrap(); - ip.0.detach(); - - if self.data.is_none() { - let mut op = self.out_port.clone() - .downcast::<V>().ok() - .unwrap(); - - op.detach(); - self.keepalive = Some(op.attach_to(ip.0.outer())); - } - } - - pub fn detach_vec<Item>(&mut self) - where Item: Clone + Send + Sync + 'static - { - self.keepalive = None; - self.in_keepalive = None; - - let ip = self.in_port.clone() - .downcast::<dyn ListView<Item>>().ok() - .unwrap(); - - ip.0.detach(); - - if let Some(data) = self.data.as_mut() { - let mut op = self.out_port.clone() - .downcast::<RwLock<Vec<Item>>>().ok() - .unwrap(); - op.detach(); - - let data = data.clone().downcast::< RwLock<Vec<Item>> >().ok().unwrap(); - let buffer = VecBuffer::with_data_arc_port(data, op.inner()); - self.keepalive = Some(buffer.attach_to(ip.0.outer())) - } - } - - pub fn attach_to<V>(&mut self, src_port: OuterViewPort<V>) - where V: View + ?Sized + 'static, - V::Msg: Clone - { - self.in_keepalive = Some(self.in_port.clone() - .downcast::<V>().ok().unwrap() - .0.attach_to( src_port )); - } - - pub fn from_singleton_buffer<T>( buffer: SingletonBuffer<T> ) -> Self - where T: Clone + Send + Sync + 'static - { - let in_port = ViewPort::<dyn SingletonView<Item = T>>::new(); - ReprLeaf { - in_keepalive: None, - keepalive: Some(buffer.attach_to(in_port.outer())), - in_port: in_port.inner().into(), - out_port: buffer.get_port().0.into(), - data: Some(buffer.into_inner()) - } - } - - pub fn from_vec_buffer<T>( buffer: VecBuffer<T> ) -> Self - where T: Clone + Send + Sync + 'static - { - let in_port = ViewPort::< dyn ListView<T> >::new(); - ReprLeaf { - in_keepalive: None, - keepalive: Some(buffer.attach_to(in_port.outer())), - in_port: in_port.inner().into(), - out_port: buffer.get_port().0.into(), - data: Some(buffer.into_inner()) - } - } - - pub fn as_singleton_buffer<T>(&mut self) -> Option<SingletonBuffer<T>> - where T: Clone + Send + Sync + 'static - { - let sgl_port = self.get_port::< dyn SingletonView<Item = T> >().unwrap().0; - - let data_arc = - if let Some(data) = self.data.as_ref() { - data.clone().downcast::<RwLock<T>>().ok() - } else { - sgl_port.update(); - let value = sgl_port.outer().get_view().unwrap().get(); - eprintln!("make new data ARC from old value"); - Some(Arc::new(RwLock::new( value ))) - }; - - if let Some(data_arc) = data_arc { - self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); - let buf = SingletonBuffer { - value: data_arc, - port: sgl_port.inner() - }; - self.keepalive = Some(buf.attach_to( - self.in_port.0.clone() - .downcast::<dyn SingletonView<Item = T>>() - .ok().unwrap() - .outer() - )); - Some(buf) - } else { - None - } - } - - pub fn as_vec_buffer<T>(&mut self) -> Option<VecBuffer<T>> - where T: Clone + Send + Sync + 'static - { - let vec_port = self.get_port::< RwLock<Vec<T>> >().unwrap().0; - - let data_arc = - if let Some(data) = self.data.as_ref() { - data.clone().downcast::<RwLock<Vec<T>>>().ok() - } else { - vec_port.update(); - if let Some(value) = vec_port.outer().get_view() { - let value = value.read().unwrap().clone(); - eprintln!("make new data ARC from old VECTOR-value"); - Some(Arc::new(RwLock::new( value ))) - } else { - eprintln!("no data vec"); - Some(Arc::new(RwLock::new( Vec::new() ))) -// None - } - }; - - if let Some(data_arc) = data_arc { - self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); - let buf = VecBuffer::with_data_arc_port(data_arc, vec_port.inner()); - self.keepalive = Some(buf.attach_to( - self.in_port.0.clone() - .downcast::< dyn ListView<T> >() - .ok().unwrap() - .outer() - )); - Some(buf) - } else { - None - } - } - - pub fn get_port<V>(&self) -> Option<OuterViewPort<V>> - where V: View + ?Sized + 'static, - V::Msg: Clone - { - self.out_port.clone().downcast::<V>().ok().map(|p| p.outer()) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl ReprTree { - pub fn new(type_tag: impl Into<TypeTerm>) -> Self { - let type_tag = type_tag.into(); - - assert!(type_tag.is_flat()); - - ReprTree { - halo: TypeTerm::unit(), - type_tag: type_tag.clone(), - branches: HashMap::new(), - leaf: None - } - } - - pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> { - Arc::new(RwLock::new(Self::new(type_tag))) - } - - pub fn get_type(&self) -> &TypeTerm { - &self.type_tag - } - - pub fn set_halo(&mut self, halo_type: impl Into<TypeTerm>) { - self.halo = halo_type.into(); - for (branch_type, branch) in self.branches.iter() { - branch.write().unwrap().set_halo( TypeTerm::Ladder(vec![ - self.halo.clone(), - self.type_tag.clone() - ]).normalize() - ); - } - } - - pub fn get_halo_type(&self) -> &TypeTerm { - &self.halo - } - - pub fn get_leaf_types(&self) -> Vec< TypeTerm > { - let mut leaf_types = Vec::new(); - if self.leaf.is_some() { - leaf_types.push( self.get_type().clone() ); - } - for (branch_type, branch) in self.branches.iter() { - for t in branch.read().unwrap().get_leaf_types() { - leaf_types.push(TypeTerm::Ladder(vec![ - self.get_type().clone(), - t - ]).normalize()) - } - } - leaf_types - } - - pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { - let branch_type = repr.read().unwrap().get_type().clone(); - - assert!(branch_type.is_flat()); - - repr.write().unwrap().set_halo( TypeTerm::Ladder(vec![ - self.halo.clone(), - self.type_tag.clone() - ]).normalize() ); - - self.branches.insert(branch_type, repr.clone()); - } - - pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char ) -> Arc<RwLock<Self>> { - ReprTree::from_singleton_buffer( - Context::parse(ctx, "Char"), - SingletonBuffer::new(c) - ) - } - - pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> Arc<RwLock<Self>> - where V: View + ?Sized + 'static, - V::Msg: Clone - { - let mut rt = ReprTree::new(type_tag); - rt.leaf = Some(ReprLeaf::from_view(view)); - Arc::new(RwLock::new(rt)) - } - - pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> Arc<RwLock<Self>> - where T: Clone + Send + Sync + 'static - { - let mut rt = ReprTree::new(type_tag); - rt.leaf = Some(ReprLeaf::from_singleton_buffer(buf)); - Arc::new(RwLock::new(rt)) - } - - pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> Arc<RwLock<Self>> - where T: Clone + Send + Sync + 'static - { - let mut rt = ReprTree::new(type_tag); - rt.leaf = Some(ReprLeaf::from_vec_buffer(buf)); - Arc::new(RwLock::new(rt)) - } - - pub fn attach_to<V>( - &mut self, - src_port: OuterViewPort<V> - ) - where V: View + ?Sized + 'static, - V::Msg: Clone - { - if let Some(leaf) = self.leaf.as_mut() { - leaf.attach_to(src_port); - } else { - eprintln!("cant attach branch without leaf"); - } - } - - /// find, and if necessary, create corresponding path in repr-tree. - /// Attach src_port to input of that node - pub fn attach_leaf_to<V>( - &mut self, - mut type_ladder: impl Iterator<Item = TypeTerm>, - src_port: OuterViewPort<V> - ) - where V: View + ?Sized + 'static, - V::Msg: Clone - { - while let Some(rung_type) = type_ladder.next() { - if &rung_type != self.get_type() { - if let Some(next_repr) = self.branches.get(&rung_type) { - next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); - } else { - let mut next_repr = ReprTree::new(rung_type.clone()); - next_repr.attach_leaf_to(type_ladder, src_port); - self.insert_branch(Arc::new(RwLock::new(next_repr))); - } - return; - } - } - - if let Some(leaf) = self.leaf.as_mut() { - leaf.attach_to(src_port); - } else { - self.leaf = Some(ReprLeaf::from_view(src_port)); - } - } - - pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { - if let Some(leaf) = self.leaf.as_mut() { - if self.type_tag == Context::parse(&ctx, "Char") { - leaf.detach::<dyn SingletonView<Item = char>>(); - } - if self.type_tag == Context::parse(&ctx, "<Vec Char>") { - leaf.detach_vec::<char>(); - } - if self.type_tag == Context::parse(&ctx, "<List Char>") { - leaf.detach::<dyn ListView<char>>(); - } - } - - for (t,b) in self.branches.iter_mut() { - b.write().unwrap().detach(&ctx); - } - } - - pub fn insert_leaf( - &mut self, - mut type_ladder: impl Iterator<Item = TypeTerm>, - leaf: ReprLeaf - ) { - while let Some(type_term) = type_ladder.next() { - if &type_term != self.get_type() { - if let Some(next_repr) = self.branches.get(&type_term) { - next_repr.write().unwrap().insert_leaf(type_ladder, leaf.clone()); - } else { - let mut next_repr = ReprTree::new(type_term.clone()); - next_repr.insert_leaf(type_ladder, leaf.clone()); - self.insert_branch(Arc::new(RwLock::new(next_repr))); - } - return; - } - } - - self.leaf = Some(leaf); - } - - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - - pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { - let dst_type = dst_type.into(); - assert!( dst_type.is_flat() ); - self.branches.get(&dst_type).cloned() - } - - pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { - if let Some(first) = repr_ladder.next() { - let rt = rt.read().unwrap(); - repr_ladder.fold( - rt.descend_one(first), - |s, t| s?.descend(t)) - } else { - Some(rt.clone()) - } - } - - pub fn descend(rt: &Arc<RwLock<Self>>, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { - let mut lnf = dst_type.into().get_lnf_vec(); - if lnf.len() > 0 { - if lnf[0] == rt.get_type() { - lnf.remove(0); - } - ReprTree::descend_ladder(rt, lnf.into_iter()) - } else { - Some(rt.clone()) - } - } - - pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> { - let mut n = Self::new(type_term); - n.insert_branch(rt.clone()); - Arc::new(RwLock::new(n)) - } - - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - - pub fn singleton_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<SingletonBuffer<T>> { - if let Some(leaf) = self.leaf.as_mut() { - leaf.as_singleton_buffer::<T>() - } else { - // create new singleton buffer - /* - // default value?? - let buf = SingletonBuffer::<T>::default(); - self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone())); - Some(buf) - */ - None - } - } - - pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<VecBuffer<T>> { - if let Some(leaf) = self.leaf.as_mut() { - leaf.as_vec_buffer::<T>() - } else { - None - } - } - - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - - pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> - where - V::Msg: Clone, - { - if let Some(leaf) = self.leaf.as_ref() { - leaf.get_port::<V>() - } else { - None - } - } - - pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>> - where - V::Msg: Clone, - { - self.get_port::<V>()? - .get_view() - } - - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - - pub fn view_singleton<T: 'static>(&self) -> OuterViewPort<dyn SingletonView<Item = T>> { - self.get_port::<dyn SingletonView<Item = T>>().expect("no singleton-view available") - } - - pub fn view_seq<T: 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> { - self.get_port::<dyn SequenceView<Item = T>>().expect("no sequence-view available") - } - - pub fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>> { - self.get_port::<dyn ListView<T>>().expect("no list-view available") - } - - pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { - self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available") - } - - pub fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> { - self.get_port::<dyn SingletonView<Item = u8>>().expect("no u8-view available") - } - - pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { - self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available") - } - - pub fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>> { - self.get_port::<dyn SingletonView<Item = usize>>().expect("no usize-view available") - } -} - - - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub trait ReprTreeExt { diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs new file mode 100644 index 0000000..89dadf0 --- /dev/null +++ b/lib-nested-core/src/repr_tree/node.rs @@ -0,0 +1,348 @@ + + +use { + r3vi::{ + view::{ + ViewPort, OuterViewPort, + AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, + port::UpdateTask, + View, Observer, + singleton::*, + sequence::*, + list::* + }, + buffer::{singleton::*, vec::*} + }, + laddertypes::{TypeTerm}, + std::{ + collections::HashMap, + sync::{Arc, RwLock}, + any::Any + }, + super::{Context, ReprLeaf, ReprTreeExt} +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone)] +pub struct ReprTree { + halo: TypeTerm, + type_tag: TypeTerm, + branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>, + leaf: Option< ReprLeaf > +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl std::fmt::Debug for ReprTree { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "| type: {:?}", self.type_tag)?; + + for (_k,x) in self.branches.iter() { + writeln!(f, "|--> child: {:?}", x)?; + } + writeln!(f, ""); + + Ok(()) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl ReprTree { + pub fn new(type_tag: impl Into<TypeTerm>) -> Self { + let type_tag = type_tag.into(); + + assert!(type_tag.is_flat()); + + ReprTree { + halo: TypeTerm::unit(), + type_tag: type_tag.clone(), + branches: HashMap::new(), + leaf: None + } + } + + pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> { + Arc::new(RwLock::new(Self::new(type_tag))) + } + + pub fn get_type(&self) -> &TypeTerm { + &self.type_tag + } + + pub fn set_halo(&mut self, halo_type: impl Into<TypeTerm>) { + self.halo = halo_type.into(); + for (branch_type, branch) in self.branches.iter() { + branch.write().unwrap().set_halo( TypeTerm::Ladder(vec![ + self.halo.clone(), + self.type_tag.clone() + ]).normalize() + ); + } + } + + pub fn get_halo_type(&self) -> &TypeTerm { + &self.halo + } + + pub fn get_leaf_types(&self) -> Vec< TypeTerm > { + let mut leaf_types = Vec::new(); + if self.leaf.is_some() { + leaf_types.push( self.get_type().clone() ); + } + for (branch_type, branch) in self.branches.iter() { + for t in branch.read().unwrap().get_leaf_types() { + leaf_types.push(TypeTerm::Ladder(vec![ + self.get_type().clone(), + t + ]).normalize()) + } + } + leaf_types + } + + pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { + let branch_type = repr.read().unwrap().get_type().clone(); + + assert!(branch_type.is_flat()); + + repr.write().unwrap().set_halo( TypeTerm::Ladder(vec![ + self.halo.clone(), + self.type_tag.clone() + ]).normalize() ); + + self.branches.insert(branch_type, repr.clone()); + } + + pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char ) -> Arc<RwLock<Self>> { + ReprTree::from_singleton_buffer( + Context::parse(ctx, "Char"), + SingletonBuffer::new(c) + ) + } + + pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> Arc<RwLock<Self>> + where V: View + ?Sized + 'static, + V::Msg: Clone + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_view(view)); + Arc::new(RwLock::new(rt)) + } + + pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> Arc<RwLock<Self>> + where T: Clone + Send + Sync + 'static + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_singleton_buffer(buf)); + Arc::new(RwLock::new(rt)) + } + + pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> Arc<RwLock<Self>> + where T: Clone + Send + Sync + 'static + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_vec_buffer(buf)); + Arc::new(RwLock::new(rt)) + } + + pub fn attach_to<V>( + &mut self, + src_port: OuterViewPort<V> + ) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + if let Some(leaf) = self.leaf.as_mut() { + leaf.attach_to(src_port); + } else { + eprintln!("cant attach branch without leaf"); + } + } + + /// find, and if necessary, create corresponding path in repr-tree. + /// Attach src_port to input of that node + pub fn attach_leaf_to<V>( + &mut self, + mut type_ladder: impl Iterator<Item = TypeTerm>, + src_port: OuterViewPort<V> + ) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + while let Some(rung_type) = type_ladder.next() { + if &rung_type != self.get_type() { + if let Some(next_repr) = self.branches.get(&rung_type) { + next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); + } else { + let mut next_repr = ReprTree::new(rung_type.clone()); + next_repr.attach_leaf_to(type_ladder, src_port); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } + return; + } + } + + if let Some(leaf) = self.leaf.as_mut() { + leaf.attach_to(src_port); + } else { + self.leaf = Some(ReprLeaf::from_view(src_port)); + } + } + + pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { + if let Some(leaf) = self.leaf.as_mut() { + if self.type_tag == Context::parse(&ctx, "Char") { + leaf.detach::<dyn SingletonView<Item = char>>(); + } + if self.type_tag == Context::parse(&ctx, "<Vec Char>") { + leaf.detach_vec::<char>(); + } + if self.type_tag == Context::parse(&ctx, "<List Char>") { + leaf.detach::<dyn ListView<char>>(); + } + } + + for (t,b) in self.branches.iter_mut() { + b.write().unwrap().detach(&ctx); + } + } + + pub fn insert_leaf( + &mut self, + mut type_ladder: impl Iterator<Item = TypeTerm>, + leaf: ReprLeaf + ) { + while let Some(type_term) = type_ladder.next() { + if &type_term != self.get_type() { + if let Some(next_repr) = self.branches.get(&type_term) { + next_repr.write().unwrap().insert_leaf(type_ladder, leaf.clone()); + } else { + let mut next_repr = ReprTree::new(type_term.clone()); + next_repr.insert_leaf(type_ladder, leaf.clone()); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } + return; + } + } + + self.leaf = Some(leaf); + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + let dst_type = dst_type.into(); + assert!( dst_type.is_flat() ); + self.branches.get(&dst_type).cloned() + } + + pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + if let Some(first) = repr_ladder.next() { + let rt = rt.read().unwrap(); + repr_ladder.fold( + rt.descend_one(first), + |s, t| s?.descend(t)) + } else { + Some(rt.clone()) + } + } + + pub fn descend(rt: &Arc<RwLock<Self>>, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + let mut lnf = dst_type.into().get_lnf_vec(); + if lnf.len() > 0 { + if lnf[0] == rt.get_type() { + lnf.remove(0); + } + ReprTree::descend_ladder(rt, lnf.into_iter()) + } else { + Some(rt.clone()) + } + } + + pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> { + let mut n = Self::new(type_term); + n.insert_branch(rt.clone()); + Arc::new(RwLock::new(n)) + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn singleton_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<SingletonBuffer<T>> { + if let Some(leaf) = self.leaf.as_mut() { + leaf.as_singleton_buffer::<T>() + } else { + // create new singleton buffer + /* + // default value?? + let buf = SingletonBuffer::<T>::default(); + self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone())); + Some(buf) + */ + None + } + } + + pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<VecBuffer<T>> { + if let Some(leaf) = self.leaf.as_mut() { + leaf.as_vec_buffer::<T>() + } else { + None + } + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> + where + V::Msg: Clone, + { + if let Some(leaf) = self.leaf.as_ref() { + leaf.get_port::<V>() + } else { + None + } + } + + pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>> + where + V::Msg: Clone, + { + self.get_port::<V>()? + .get_view() + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn view_singleton<T: 'static>(&self) -> OuterViewPort<dyn SingletonView<Item = T>> { + self.get_port::<dyn SingletonView<Item = T>>().expect("no singleton-view available") + } + + pub fn view_seq<T: 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> { + self.get_port::<dyn SequenceView<Item = T>>().expect("no sequence-view available") + } + + pub fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>> { + self.get_port::<dyn ListView<T>>().expect("no list-view available") + } + + pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { + self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available") + } + + pub fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> { + self.get_port::<dyn SingletonView<Item = u8>>().expect("no u8-view available") + } + + pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> { + self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available") + } + + pub fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>> { + self.get_port::<dyn SingletonView<Item = usize>>().expect("no usize-view available") + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + From ffeb4b8e73a98dd7779152d3028091803049c09e Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Tue, 6 Aug 2024 15:40:05 +0200 Subject: [PATCH 50/75] repr tree: create new VecBuffer in case attach_to() is called on Vec<EditTree> --- lib-nested-core/src/repr_tree/node.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs index 89dadf0..6cb0e2a 100644 --- a/lib-nested-core/src/repr_tree/node.rs +++ b/lib-nested-core/src/repr_tree/node.rs @@ -187,7 +187,21 @@ impl ReprTree { if let Some(leaf) = self.leaf.as_mut() { leaf.attach_to(src_port); } else { - self.leaf = Some(ReprLeaf::from_view(src_port)); + if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TypeID::Fun(11)), + TypeTerm::TypeID(TypeID::Fun(2)) + ]) { + let mut leaf = ReprLeaf::from_vec_buffer( + VecBuffer::< + Arc<RwLock<crate::edit_tree::EditTree>> + >::new() + ); + + leaf.attach_to(src_port); + self.leaf = Some(leaf); + } else { + self.leaf = Some(ReprLeaf::from_view(src_port)); + } } } From 6e2b82585ebfb8dd7e947de837ba2aaa49a3559e Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Tue, 6 Aug 2024 16:20:02 +0200 Subject: [PATCH 51/75] in context.apply_morphism() now use find_morphism_path() to automatically find chained morphisms to create projections in ReprTree --- examples/tty-02-digit/src/main.rs | 21 +- examples/tty-03-string/src/main.rs | 41 ++- examples/tty-04-posint/src/main.rs | 212 ++----------- lib-nested-core/src/editors/char/mod.rs | 38 +-- lib-nested-core/src/editors/digit/ctx.rs | 87 ++---- lib-nested-core/src/editors/integer/ctx.rs | 335 ++++----------------- lib-nested-core/src/editors/list/ctx.rs | 128 ++++---- lib-nested-core/src/repr_tree/context.rs | 41 ++- lib-nested-core/src/repr_tree/mod.rs | 2 +- lib-nested-core/src/repr_tree/morphism.rs | 302 ++++++------------- lib-nested-core/src/repr_tree/node.rs | 15 +- lib-nested-core/src/repr_tree/tests.rs | 24 +- lib-nested-tty/src/editors/list.rs | 10 +- 13 files changed, 395 insertions(+), 861 deletions(-) diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs index c7df17e..60f6032 100644 --- a/examples/tty-02-digit/src/main.rs +++ b/examples/tty-02-digit/src/main.rs @@ -69,16 +69,19 @@ async fn main() { /* furthermore, setup projections to and from u8 value, * this synchronizes the buffers */ - ctx.read().unwrap().morphisms.apply_morphism( - rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~Char"), - &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64") + ctx.read().unwrap().apply_morphism( + &rt_digit, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<Digit 16>~Char"), + dst_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64") + } ); - - ctx.read().unwrap().morphisms.apply_morphism( - rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~Char"), - &Context::parse(&ctx, "<Digit 16>~EditTree") + ctx.read().unwrap().apply_morphism( + &rt_digit, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<Digit 16>~Char"), + dst_type: Context::parse(&ctx, "<Digit 16>~EditTree") + } ); /* setup TTY-Display for DigitEditor diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs index dfa84e1..c0b1bfc 100644 --- a/examples/tty-03-string/src/main.rs +++ b/examples/tty-03-string/src/main.rs @@ -45,21 +45,16 @@ async fn main() { */ let mut rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); - let vec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); rt_string.insert_leaf( - Context::parse(&ctx, "<List EditTree> ~ <Vec EditTree>"), - nested::repr_tree::ReprLeaf::from_vec_buffer( vec.clone() ) + Context::parse(&ctx, "<List~Vec EditTree>"), + nested::repr_tree::ReprLeaf::from_vec_buffer( VecBuffer::<Arc<RwLock<EditTree>>>::new() ) ); - - let v2 = VecBuffer::<char>::new(); - rt_string.insert_leaf( - Context::parse(&ctx, "<Vec Char>"), - nested::repr_tree::ReprLeaf::from_vec_buffer( v2.clone() ) - ); - ctx.read().unwrap().morphisms.apply_morphism( - rt_string.clone(), - &Context::parse(&ctx, "<List Char~EditTree> ~ <Vec EditTree>"), - &Context::parse(&ctx, "<List Char> ~ EditTree") + ctx.read().unwrap().apply_morphism( + &rt_string, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<List Char~EditTree>~<Vec EditTree>"), + dst_type: Context::parse(&ctx, "<List Char> ~ EditTree") + } ); /* Setup the Editor-View for this ReprTree @@ -74,10 +69,12 @@ async fn main() { * we apply a morphism that, given the List of Edit-Trees, extracts * the value from each EditTree and shows them in a ListView. */ - ctx.read().unwrap().morphisms.apply_morphism( - rt_string.clone(), - &Context::parse(&ctx, "<List Char>~EditTree"), - &Context::parse(&ctx, "<List Char>") + ctx.read().unwrap().apply_morphism( + &rt_string, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<List Char>~EditTree"), + dst_type: Context::parse(&ctx, "<List Char>") + } ); /* Now, get the ListView that serves our char-values. @@ -91,10 +88,12 @@ async fn main() { /* Lets add another morphism which will store the values * of the character-list in a `Vec<char>` */ - ctx.read().unwrap().morphisms.apply_morphism( - rt_string.clone(), - &Context::parse(&ctx, "<List Char>"), - &Context::parse(&ctx, "<List Char>~<Vec Char>") + ctx.read().unwrap().apply_morphism( + &rt_string, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<List Char>"), + dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>") + } ); /* Access the Vec<char> object (wrapped behind a VecBuffer<char>) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index ed8311f..87ecfc1 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -32,131 +32,25 @@ use { std::sync::{Arc, RwLock}, }; -fn rebuild_projections( - ctx: Arc<RwLock<Context>>, - repr_tree: Arc<RwLock<ReprTree>>, - morph_types: Vec< (laddertypes::TypeTerm, laddertypes::TypeTerm) > -) { - repr_tree.write().unwrap().detach(&ctx); - for (src_type, dst_type) in morph_types.iter() { - ctx.read().unwrap().morphisms.apply_morphism( - repr_tree.clone(), - &src_type, - &dst_type - ); - } -} - -fn setup_hex_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { - rebuild_projections( - ctx.clone(), - rt_int.clone(), - vec![ - // extract values from hex-editor - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" - ), - - // convert to little-endian - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" - ), - // convert digit representation from char to u64 - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>" - ), - // convert radix to decimal - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" - ), - // convert decimal digit representation back to char - ( - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>", - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>" - ), - // convert to big-endian - ( - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>", - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>" - ), - - // decimal editor - ( - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>", - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char ~ EditTree>" - ), - ( - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char ~ EditTree>", - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char ~ EditTree> ~ <Vec EditTree>" - ), - ( - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char ~ EditTree> ~ <Vec EditTree>", - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree" - ), - - ].into_iter() - .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) - .collect() +fn setup_hex_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { + rt_int.write().unwrap().detach( ctx ); + ctx.read().unwrap().apply_morphism( + rt_int, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree") + } ); } fn setup_dec_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { - rebuild_projections( - ctx.clone(), - rt_int.clone(), - vec![ - // extract values from decimal-editor - ( - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree", - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>" - ), - - // convert to little-endian - ( - "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>", - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>" - ), - // convert digit representation to u64 - ( - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char>", - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>" - ), - // convert radix to decimal - ( - "ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>" - ), - // convert back digit representation char - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>", - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" - ), - // convert back to big-endian - ( - "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" - ), - - // hex editor - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" - ), - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>" - ), - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree> ~ <Vec EditTree>", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" - ), - ].into_iter() - .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) - .collect() + rt_int.write().unwrap().detach( ctx ); + ctx.read().unwrap().apply_morphism( + rt_int, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree") + } ); } @@ -177,71 +71,20 @@ async fn main() { /* Add a specific Representation-Path (big-endian hexadecimal) */ - let mut digits_hex = VecBuffer::with_data(vec![ 'c', 'f', 'f' ]); rt_int.insert_leaf( Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>~<Vec Char>"), - nested::repr_tree::ReprLeaf::from_vec_buffer( digits_hex.clone() ) - ); - - let mut digits_dec = VecBuffer::with_data(vec!['3', '2', '1']); - rt_int.insert_leaf( - Context::parse(&ctx, "<PosInt 10 BigEndian>~<Seq <Digit 10>>~<List <Digit 10>>~<List Char>~<Vec Char>"), - nested::repr_tree::ReprLeaf::from_vec_buffer( digits_dec.clone() ) - ); - - let mut digits_hex_editvec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); - rt_int.insert_leaf( - Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16> - ~ Char - ~ EditTree> - ~ <Vec EditTree> - "), - nested::repr_tree::ReprLeaf::from_vec_buffer( digits_hex_editvec.clone() ) - ); - - let mut digits_dec_editvec = VecBuffer::<Arc<RwLock<EditTree>>>::new(); - rt_int.insert_leaf( - Context::parse(&ctx, " - <PosInt 10 BigEndian> - ~ <Seq <Digit 10>> - ~ <List <Digit 10> - ~ Char - ~ EditTree> - ~ <Vec EditTree> - "), - nested::repr_tree::ReprLeaf::from_vec_buffer( digits_dec_editvec.clone() ) - ); + nested::repr_tree::ReprLeaf::from_vec_buffer( + VecBuffer::with_data(vec![ 'c', 'f', 'f' ] + ))); /* initially copy values from Vec to EditTree... */ - rebuild_projections( - ctx.clone(), - rt_int.clone(), - // master representation - vec![ - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <Vec Char>", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>" - ), - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char>", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char ~ EditTree>" - ), - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree>", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree> ~ <Vec EditTree>" - ), - ( - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <List EditTree> ~ <Vec EditTree>", - "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree" - ), - ].into_iter() - .map(|(s,d)| (Context::parse(&ctx, s), Context::parse(&ctx, d))) - .collect() - ); + ctx.read().unwrap().apply_morphism( + &rt_int, + &nested::repr_tree::morphism::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <Vec Char>"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree") + }); setup_hex_master(&ctx, &rt_int); @@ -267,7 +110,6 @@ async fn main() { SingletonBuffer::new(0).get_port() ).unwrap().get(); - let hex_digits_view = rt_int.descend(Context::parse(&ctx, " <PosInt 16 LittleEndian> ~ <Seq <Digit 16> > @@ -278,8 +120,7 @@ async fn main() { .view_list::<u64>() .map(|v| TerminalAtom::from(char::from_digit(*v as u32, 16))) .to_sequence() - .to_grid_horizontal() - ; + .to_grid_horizontal(); let dec_digits_view = rt_int.descend(Context::parse(&ctx, " <PosInt 10 LittleEndian> @@ -291,8 +132,7 @@ async fn main() { .view_list::<u64>() .map(|v| TerminalAtom::from(char::from_digit(*v as u32, 10))) .to_sequence() - .to_grid_horizontal() - ; + .to_grid_horizontal(); /* list of both editors */ diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index fb9abae..3d33efc 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -9,7 +9,7 @@ use { }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt}, + repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt, GenericReprTreeMorphism}, edit_tree::{EditTree, TreeNavResult}, editors::ObjCommander, }, @@ -18,21 +18,16 @@ use { }; pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { - let morphtype = - crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "Char"), - dst_type: Context::parse(&ctx, "Char~EditTree") - }; - ctx.write().unwrap() - .morphisms - .add_morphism( - morphtype, - { - let ctx = ctx.clone(); - move |rt, σ| { - { - let mut b = rt.write().unwrap().singleton_buffer::<char>(); + let char_morph_to_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "Char"), + Context::parse(&ctx, "Char~EditTree"), + { + let ctx = ctx.clone(); + move |rt, σ| { + + { + let mut b = rt.write().unwrap().singleton_buffer::<char>(); if let Some(buf) = b { // buffer already exists } else { @@ -56,7 +51,11 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { rt.insert_leaf( Context::parse(&ctx, "EditTree"), - ReprLeaf::from_singleton_buffer(SingletonBuffer::new(Arc::new(RwLock::new(edittree)))) + ReprLeaf::from_singleton_buffer( + SingletonBuffer::new( + Arc::new(RwLock::new(edittree)) + ) + ) ); ctx.read().unwrap().setup_edittree( @@ -64,8 +63,11 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { SingletonBuffer::new(0).get_port() ); } - } - ); + + } + ); + + ctx.write().unwrap().morphisms.add_morphism( char_morph_to_edittree ); } pub struct CharEditor { diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index 40a7826..d2d22ae 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -9,28 +9,21 @@ use { } }, crate::{ - repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, + repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf, GenericReprTreeMorphism}, editors::digit::DigitEditor, }, std::sync::{Arc, RwLock} }; pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { - // todo: proper scoping of Radix variable ctx.write().unwrap().add_varname("Radix"); - let morphtype = - crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<Digit Radix>~Char"), - dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree") - }; + let digit_morph_char_to_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<Digit Radix>~Char"), + Context::parse(&ctx, "<Digit Radix>~EditTree"), - ctx.write().unwrap() - .morphisms - .add_morphism( - morphtype, - { + { let ctx = ctx.clone(); move |src_rt, σ| { let radix = @@ -39,32 +32,14 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { _ => 0 }; - /* get char representation or create it if not available - */ - let char_rt = - if let Some(crt) = src_rt.descend(Context::parse(&ctx, "Char")) { - crt - } else { - /* TODO: replace this with some formal specification - * of "required representations" - */ - let crt = ReprTree::from_singleton_buffer( - Context::parse(&ctx, "Char"), - SingletonBuffer::new('\0') - ); - src_rt.insert_branch(crt.clone()); - crt - }; - /* Create EditTree object */ let mut edittree = DigitEditor::new( ctx.clone(), radix, - src_rt.descend( - Context::parse(&ctx, "Char") - ).unwrap() - .singleton_buffer::<char>() + src_rt + .descend( Context::parse(&ctx, "Char") ).unwrap() + .singleton_buffer::<char>() ).into_node( r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() ); @@ -77,22 +52,16 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { ) ); } - } - ); + } + ); - let morphtype = - crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<Digit Radix>~Char"), - dst_type: Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64") - }; + let digit_morph_char_to_u64 = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<Digit Radix>~Char"), + Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64"), - ctx.write().unwrap() - .morphisms - .add_morphism( - morphtype, - { - let ctx = ctx.clone(); - move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| { + { + let ctx = ctx.clone(); + move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| { /* infer radix from type */ let radix_typeid = ctx.read().unwrap().get_var_typeid("Radix").unwrap(); @@ -123,19 +92,15 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { } else { eprintln!("radix too large ({})", radix); } - } } - ); + } + ); - let morphtype = - crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64"), - dst_type: Context::parse(&ctx, "<Digit Radix>~Char") - }; - - ctx.write().unwrap().morphisms - .add_morphism(morphtype, { + let digit_morph_u64_to_char = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64"), + Context::parse(&ctx, "<Digit Radix>~Char"), + { let ctx = ctx.clone(); move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| { /* infer radix from type @@ -163,7 +128,13 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { eprintln!("radix too large ({})", radix); } } - }); + } + ); + + + ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_to_edittree ); + ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_to_u64 ); + ctx.write().unwrap().morphisms.add_morphism( digit_morph_u64_to_char ); } diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 868acec..dc6aa61 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -3,9 +3,9 @@ use { r3vi::{ view::{OuterViewPort, singleton::*, list::*} }, - laddertypes::{TypeTerm}, + laddertypes::{TypeTerm, MorphismType}, crate::{ - repr_tree::{ReprTree, ReprTreeExt, ReprLeaf, Context, MorphismType}, + repr_tree::{ReprTree, ReprTreeExt, ReprLeaf, Context, GenericReprTreeMorphism}, editors::{ list::*, integer::* @@ -20,312 +20,93 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.write().unwrap().add_varname("DstRadix"); - /* - * MACHINE INT, SEQ - */ - let morphism_type = - MorphismType { - src_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix BigEndian> - ~ <Seq <Digit Radix> - ~ ℤ_2^64 - ~ machine.UInt64 >"), - dst_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix> - ~ ℤ_2^64 - ~ machine.UInt64 >") - }; - ctx.write().unwrap().morphisms.add_morphism( - morphism_type, { + let posint_seq_morph_big_to_little = GenericReprTreeMorphism::new( + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> + ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"), + Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> + ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"), + { let ctx = ctx.clone(); move |src_rt, σ| { - let src_digits = src_rt.descend( - Context::parse(&ctx, " + let src_digits = src_rt + .descend(Context::parse(&ctx, " <PosInt Radix BigEndian> - ~ <Seq <Digit Radix> - ~ ℤ_2^64 - ~ machine.UInt64 > - ") + ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > + ") .apply_substitution(&|k|σ.get(k).cloned()) .clone() - ).expect("cant descend") - .view_seq::< u64 >(); + ).expect("cant descend") + .view_seq::< u64 >(); src_rt.attach_leaf_to(Context::parse(&ctx, " <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix> - ~ ℤ_2^64 - ~ machine.UInt64 > + ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > ").apply_substitution(&|k|σ.get(k).cloned()).clone(), src_digits.reverse() - ); + ); } } ); - /* MACHINE INT, LIST - */ - let morphism_type = MorphismType { - src_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List ℤ_2^64> - ~ <List machine.UInt64> - "), - dst_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List ℤ_2^64> - ~ <List machine.UInt64> - ") - }; - - ctx.write().unwrap().morphisms.add_morphism( - morphism_type, + let posint_list_morph_big_to_little = GenericReprTreeMorphism::new( + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> + ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"), + Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> + ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"), { let ctx = ctx.clone(); move |src_rt, σ| { - let src_digits = src_rt.descend(Context::parse(&ctx, " - <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > + let src_digits = src_rt + .descend(Context::parse(&ctx, " + <PosInt Radix BigEndian> + ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > ") - .apply_substitution(&|k|σ.get(k).cloned()).clone() - ).expect("cant descend") - .get_port::< dyn ListView<u64> >().unwrap(); + .apply_substitution(&|k|σ.get(k).cloned()) + .clone() + ).expect("cant descend") + .view_list::< u64 >(); - src_rt.attach_leaf_to( - Context::parse(&ctx, " - <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64> - ").apply_substitution(&|k| σ.get(k).cloned()).clone(), + src_rt.attach_leaf_to(Context::parse(&ctx, " + <PosInt Radix LittleEndian> + ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > + ").apply_substitution(&|k|σ.get(k).cloned()).clone(), src_digits.reverse() - ); + ); } } ); - - let mt = MorphismType { - src_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List Char> - "), - dst_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List Char> - ") - }; - ctx.write().unwrap().morphisms.add_morphism( - mt, + let posint_list_morph_little_to_big = GenericReprTreeMorphism::new( + Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> + ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"), + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> + ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"), { let ctx = ctx.clone(); move |src_rt, σ| { - let radix = σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ); - let src_digits = src_rt.descend(Context::parse(&ctx, " - <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>~Char > - ").apply_substitution(&|k|σ.get(k).cloned()).clone() - ).expect("cant descend") - .get_port::< dyn ListView<char> >().unwrap(); - - let rev_port = src_digits.reverse(); - src_rt.attach_leaf_to( - Context::parse(&ctx, " - < PosInt Radix LittleEndian > - ~ < Seq <Digit Radix> > - ~ < List <Digit Radix>~Char > - ").apply_substitution(&|k| σ.get(k).cloned()).clone(), - rev_port - ); - } - } - ); - - - - - - - let morphism_type = MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>") - }; - - ctx.write().unwrap().morphisms.add_morphism( - morphism_type, - { - let ctx = ctx.clone(); - move |src_rt, σ| { - let src_digits = ReprTree::descend( - &src_rt, - Context::parse(&ctx, " - <PosInt Radix LittleEndian> - ~<Seq <Digit Radix>~ℤ_2^64~machine.UInt64 > + let src_digits = src_rt + .descend(Context::parse(&ctx, " + <PosInt Radix LittleEndian> + ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > ") - .apply_substitution(&|k|σ.get(k).cloned()).clone() - ).expect("cant descend") - .view_seq::< u64 >(); + .apply_substitution(&|k|σ.get(k).cloned()) + .clone() + ).expect("cant descend") + .view_list::< u64 >(); src_rt.attach_leaf_to(Context::parse(&ctx, " <PosInt Radix BigEndian> - ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64> - ").apply_substitution(&|k|σ.get(k).cloned()).clone(), - src_digits.reverse() - ); - } - } - ); - - let morphism_type = - MorphismType { - src_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List ℤ_2^64> - ~ <List machine.UInt64> - "), - dst_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List ℤ_2^64> - ~ <List machine.UInt64> - ") - }; - ctx.write().unwrap().morphisms.add_morphism( - morphism_type, { - let ctx = ctx.clone(); - move |src_rt, σ| - { - let src_digits = src_rt.descend( - Context::parse(&ctx, " - <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>~ℤ_2^64~machine.UInt64 > - ").apply_substitution(&|k|σ.get(k).cloned()).clone() - ) - .expect("cant descend") - .view_list::<u64>(); - - src_rt.attach_leaf_to( - Context::parse(&ctx, " - <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>~ℤ_2^64~machine.UInt64 > + ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 > ").apply_substitution(&|k|σ.get(k).cloned()).clone(), src_digits.reverse() - ); + ); } } ); - let mt = MorphismType { - src_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List Char> - "), - dst_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List Char> - ") - }; - - ctx.write().unwrap().morphisms.add_morphism( - mt, - { - let ctx = ctx.clone(); - move |src_rt, σ| { - let src_digits = src_rt.descend(Context::parse(&ctx, " - <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>~Char > - ").apply_substitution(&|k|σ.get(k).cloned()).clone() - ).expect("cant descend") - .view_list::<char>(); - - src_rt.attach_leaf_to( - Context::parse(&ctx, " - < PosInt Radix BigEndian > - ~ < Seq <Digit Radix> > - ~ < List <Digit Radix>~Char > - ").apply_substitution(&|k| σ.get(k).cloned()).clone(), - src_digits.reverse() - ); - } - } - ); -/* - let mt = MorphismType { - src_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List Char> - "), - dst_type: Context::parse(&ctx, " - ℕ - ~ <PosInt Radix LittleEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>> - ~ <List Char> - ") - }; - - ctx.write().unwrap().morphisms.add_morphism( - mt, - { - let ctx = ctx.clone(); - move |src_rt, σ| { - let src_digits = src_rt.descend(Context::parse(&ctx, " - <PosInt Radix BigEndian> - ~ <Seq <Digit Radix>> - ~ <List <Digit Radix>~Char > - ").apply_substitution(&|k|σ.get(k).cloned()).clone() - ).expect("cant descend") - .view_list::<char>(); - - src_rt.attach_leaf_to( - Context::parse(&ctx, " - < PosInt Radix LittleEndian > - ~ < Seq <Digit Radix> > - ~ < List <Digit Radix>~Char > - ").apply_substitution(&|k| σ.get(k).cloned()).clone(), - src_digits.reverse() - ); - } - } - ); -*/ - - let morphism_type = MorphismType { - src_type: Context::parse(&ctx, " + let posint_list_morph_radix = GenericReprTreeMorphism::new( + Context::parse(&ctx, " ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>> @@ -333,18 +114,14 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ~ ℤ_2^64 ~ machine.UInt64> "), - dst_type: Context::parse(&ctx, " + Context::parse(&ctx, " ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix>> ~ <List <Digit DstRadix> ~ ℤ_2^64 ~ machine.UInt64> - ") - }; - - ctx.write().unwrap().morphisms.add_morphism( - morphism_type, + "), { let ctx = ctx.clone(); move |src_rt, σ| { @@ -389,7 +166,13 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { dst_digits_port ); } + } ); + + ctx.write().unwrap().morphisms.add_morphism( posint_seq_morph_big_to_little ); + ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_big_to_little ); + ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_little_to_big ); + ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_radix ); } diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 93a47a5..56f0cf5 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -10,11 +10,11 @@ use { }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt}, + repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt, GenericReprTreeMorphism}, edit_tree::{EditTree}, editors::{ char::{CharEditor}, - list::{ListEditor}//, PTYListController, PTYListStyle} + list::{ListEditor} } }, std::sync::{Arc, RwLock} @@ -25,49 +25,46 @@ use { pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.write().unwrap().add_varname("Item"); - let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"), - dst_type: Context::parse(&ctx, "<List Item>~EditTree") - }; + let list_morph_editsetup1 = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"), + Context::parse(&ctx, "<List Item>~EditTree"), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); + if let Some( item_type ) = σ.get( &item_id ) { + let mut item_vec_rt = src_rt + .descend( + Context::parse(&ctx, "<List Item~EditTree>~<Vec EditTree>") + .apply_substitution(&|id| σ.get(id).cloned()).clone() + ) + .expect("cant descend src repr"); - ctx.write().unwrap().morphisms.add_morphism(mt, { - let ctx = ctx.clone(); - move |src_rt, σ| { - let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); - if let Some( item_type ) = σ.get( &item_id ) { - let mut item_vec_rt = src_rt - .descend( - Context::parse(&ctx, "<List Item~EditTree>~<Vec EditTree>") - .apply_substitution(&|id| σ.get(id).cloned()).clone() - ) - .expect("cant descend src repr"); + let item_vec_buffer = item_vec_rt.vec_buffer::< Arc<RwLock<EditTree>> >(); - let item_vec_buffer = item_vec_rt.vec_buffer::< Arc<RwLock<EditTree>> >(); + let mut list_editor = ListEditor::with_data(ctx.clone(), item_type.clone(), item_vec_buffer); + let edittree_list = list_editor.into_node( + SingletonBuffer::<usize>::new(0).get_port() + ); + src_rt.insert_leaf( + Context::parse(&ctx, "<List Item> ~ EditTree") + .apply_substitution(&|id| σ.get(id).cloned()).clone(), - let mut list_editor = ListEditor::with_data(ctx.clone(), item_type.clone(), item_vec_buffer); - let edittree_list = list_editor.into_node( - SingletonBuffer::<usize>::new(0).get_port() - ); - src_rt.insert_leaf( - Context::parse(&ctx, "<List Item> ~ EditTree") - .apply_substitution(&|id| σ.get(id).cloned()).clone(), - - ReprLeaf::from_singleton_buffer( - SingletonBuffer::new(Arc::new(RwLock::new(edittree_list))) - ) - ); - } else { - eprintln!("no item type"); + ReprLeaf::from_singleton_buffer( + SingletonBuffer::new(Arc::new(RwLock::new(edittree_list))) + ) + ); + } else { + eprintln!("no item type"); + } } } - }); + ); - let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List Char>~EditTree"), - dst_type: Context::parse(&ctx, "<List Char>") - }; - ctx.write().unwrap().morphisms.add_morphism( - mt, + + let list_morph_editsetup2 = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<List Char>~EditTree"), + Context::parse(&ctx, "<List Char>"), { let ctx = ctx.clone(); move |src_rt, σ| { @@ -93,54 +90,43 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ) ); } + } ); - - /* todo : unify the following two morphims with generic item parameter ? - */ - let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List Char>"), - dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>") - }; - ctx.write().unwrap().morphisms.add_morphism( - mt, + let list_morph_to_vec_char = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<List Char>"), + Context::parse(&ctx, "<List Char>~<Vec Char>"), { let ctx = ctx.clone(); move |src_rt, σ| { - let list_view = src_rt.view_list::<char>(); - - src_rt - .attach_leaf_to( - Context::parse(&ctx, "<Vec Char>"), - list_view - ); + src_rt.attach_leaf_to( + Context::parse(&ctx, "<Vec Char>"), + src_rt.view_list::<char>() + ); } } ); - let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List Char>~<Vec Char>"), - dst_type: Context::parse(&ctx, "<List Char>") - }; - ctx.write().unwrap().morphisms.add_morphism( - mt, + let list_morph_from_vec_char = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<List Char>~<Vec Char>"), + Context::parse(&ctx, "<List Char>"), { let ctx = ctx.clone(); move |src_rt, σ| { let src_port = src_rt.descend(Context::parse(&ctx, "<List Char>~<Vec Char>")).expect("descend") .get_port::<RwLock<Vec<char>>>().unwrap(); - src_rt.attach_leaf_to( Context::parse(&ctx, "<List Char>"), src_port.to_list() ); + + src_rt.attach_leaf_to( Context::parse(&ctx, "<List Char>"), src_port.to_list() ); } } ); - let mt = crate::repr_tree::MorphismType { - src_type: Context::parse(&ctx, "<List EditTree>"), - dst_type: Context::parse(&ctx, "<List EditTree>~<Vec EditTree>") - }; - ctx.write().unwrap().morphisms.add_morphism( - mt, + + let list_morph_to_vec_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<List EditTree>"), + Context::parse(&ctx, "<List EditTree> ~ <Vec EditTree>"), + { let ctx = ctx.clone(); move |src_rt, σ| { @@ -156,5 +142,11 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } } ); + + ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup1 ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup2 ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_from_vec_char ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_char ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_edittree ); } diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 71add2a..6bbff0b 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -1,8 +1,8 @@ use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, - laddertypes::{TypeDict, TypeTerm, TypeID}, + laddertypes::{TypeDict, TypeTerm, TypeID, MorphismType, MorphismBase, Morphism}, crate::{ - repr_tree::{ReprTree, ReprTreeExt, MorphismType, GenericReprTreeMorphism, MorphismBase}, + repr_tree::{ReprTree, ReprTreeExt, GenericReprTreeMorphism}, edit_tree::EditTree }, std::{ @@ -18,7 +18,7 @@ pub struct Context { /// assigns a name to every type pub type_dict: Arc<RwLock<TypeDict>>, - pub morphisms: MorphismBase, + pub morphisms: laddertypes::morphism::MorphismBase< GenericReprTreeMorphism >, /// named vertices of the graph nodes: HashMap< String, Arc<RwLock<ReprTree>> >, @@ -39,12 +39,15 @@ impl Context { pub fn with_parent( parent: Option<Arc<RwLock<Context>>> ) -> Self { + let mut dict = TypeDict::new(); + let list_typeid = dict.add_typename("List".into()); + Context { type_dict: match parent.as_ref() { Some(p) => p.read().unwrap().type_dict.clone(), - None => Arc::new(RwLock::new(TypeDict::new())) + None => Arc::new(RwLock::new(dict)) }, - morphisms: MorphismBase::new(), + morphisms: MorphismBase::new( list_typeid ), nodes: HashMap::new(), list_types: match parent.as_ref() { Some(p) => p.read().unwrap().list_types.clone(), @@ -75,9 +78,35 @@ impl Context { } } + pub fn apply_morphism( &self, rt: &Arc<RwLock<ReprTree>>, ty: &MorphismType ) { + if let Some(path) + = self.morphisms.find_morphism_path( ty.clone().normalize() ) + { + let mut path = path.into_iter(); + if let Some(mut src_type) = path.next() { + for dst_type in path { + if let Some(( m, mut τ, σ )) = + self.morphisms.find_morphism_with_subtyping( + &laddertypes::MorphismType { + src_type: src_type.clone(), + dst_type: dst_type.clone() + } + ) { + let mut rt = rt.descend( τ ).expect("descend src repr"); + (m.setup_projection)( &mut rt, &σ ); + } + + src_type = dst_type; + } + } + } else { + eprintln!("no path found"); + } + } + pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> { let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() ))); - ctx.read().unwrap().morphisms.apply_morphism( rt.clone(), &TypeTerm::unit(), t ); + ctx.read().unwrap().apply_morphism( &rt, &MorphismType{ src_type: TypeTerm::unit(), dst_type: t.clone() } ); rt } diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index c2b71d4..5d05bf0 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -10,7 +10,7 @@ pub use { context::{Context}, leaf::ReprLeaf, node::ReprTree, - morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase} + morphism::{GenericReprTreeMorphism} }; use { diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index 1607d6a..d8eaf3d 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -1,5 +1,5 @@ use { - laddertypes::{TypeTerm, TypeID}, + laddertypes::{TypeTerm, TypeID, morphism::Morphism}, r3vi::view::{AnyOuterViewPort, port::UpdateTask}, crate::{ repr_tree::{ReprTree, ReprTreeExt, ReprLeaf}, @@ -10,248 +10,144 @@ use { } }; -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +pub use laddertypes::morphism::MorphismType; -#[derive(Clone, Hash, PartialEq, Eq, Debug)] -pub struct MorphismType { - pub src_type: TypeTerm, - pub dst_type: TypeTerm, -} +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] pub struct GenericReprTreeMorphism { - morph_type: MorphismType, - setup_projection: Arc< + pub(super) morph_type: MorphismType, + pub(super) setup_projection: Arc< dyn Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) // -> Result< ReprLeaf, () > + Send + Sync > } -#[derive(Clone)] -pub struct MorphismBase { - morphisms: Vec< GenericReprTreeMorphism > +impl Morphism for GenericReprTreeMorphism { + fn get_type(&self) -> MorphismType { + self.morph_type.clone() + } + + fn list_map_morphism(&self, list_typeid: TypeID) -> Option< GenericReprTreeMorphism > { + self.into_list_map_dyn(list_typeid) + } } -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +impl GenericReprTreeMorphism { + pub fn new( + src_type: TypeTerm, + dst_type: TypeTerm, -impl MorphismBase { - pub fn new() -> Self { - MorphismBase { - morphisms: Vec::new() + setup: impl Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + + Send + Sync + 'static + ) -> Self { + GenericReprTreeMorphism { + morph_type: MorphismType { + src_type, dst_type + }.normalize(), + + setup_projection: Arc::new(setup) } } - pub fn add_morphism( - &mut self, - morph_type: MorphismType, - setup_projection: - impl Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) -// -> Result< ReprLeaf, () /* TODO: error */ > - + Send + Sync + 'static - ) { - self.morphisms.push( - GenericReprTreeMorphism { - morph_type: MorphismType { - src_type: morph_type.src_type.normalize(), - dst_type: morph_type.dst_type.normalize() - }, - setup_projection: Arc::new(setup_projection) - } - ); - } - - pub fn find_morphism( - &self, - src_type: &TypeTerm, - dst_type: &TypeTerm - ) -> Option<(GenericReprTreeMorphism, HashMap<TypeID, TypeTerm>)> { - - // try list-map morphism - if let Ok(σ) = laddertypes::UnificationProblem::new(vec![ - (src_type.clone().param_normalize(), TypeTerm::App(vec![ TypeTerm::TypeID(TypeID::Fun(10)), TypeTerm::TypeID(TypeID::Var(100)) ])), - (dst_type.clone().param_normalize(), TypeTerm::App(vec![ TypeTerm::TypeID(TypeID::Fun(10)), TypeTerm::TypeID(TypeID::Var(101)) ])), - ]).solve() { - let src_item_type = σ.get(&TypeID::Var(100)).unwrap().clone(); - let dst_item_type = σ.get(&TypeID::Var(101)).unwrap().clone(); -/* - eprintln!("Got a List- Type, check if we find a list-map morphism"); - eprintln!("src-item-type : {:?}", src_item_type); - eprintln!("dst-item-type : {:?}", dst_item_type); -*/ - let src_item_type_lnf = src_item_type.clone().get_lnf_vec(); - let dst_item_type_lnf = dst_item_type.clone().get_lnf_vec(); - - /* if src_item_type ~== "Char", - dst_item_type ~== "machine.UInt64" - */ - if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(0))) && - dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(4))) - { - if let Some((m, σ)) = self.find_list_map_morphism::< char, u64 >( src_item_type, dst_item_type ) { - return Some((m, σ)); - } - } - - /* if src_item_type ~== "machine.UInt64", - dst_item_type ~== "Char" - */ - else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(4))) && - dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(0))) - { - if let Some((m, σ)) = self.find_list_map_morphism::< u64, char >( src_item_type, dst_item_type ) { - return Some((m, σ)); - } - } - - /* if src_item_type ~== "Char" - dst_item_type ~== "EditTree" - */ - else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(0))) && - dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TypeID::Fun(1))) - { - if let Some((m, σ)) = self.find_list_map_morphism::< char, Arc<RwLock<crate::edit_tree::EditTree>> >( src_item_type, dst_item_type ) { - return Some((m, σ)); - } - } - } - - // otherwise - for m in self.morphisms.iter() { - let unification_problem = laddertypes::UnificationProblem::new( - vec![ - ( src_type.clone().normalize(), m.morph_type.src_type.clone() ), - ( dst_type.clone().normalize(), m.morph_type.dst_type.clone() ) - ] - ); - - let unification_result = unification_problem.solve(); - if let Ok(σ) = unification_result { - return Some((m.clone(), σ)); - } - } - - None - } - - - pub fn find_morphism_ladder( - &self, - src_type: &TypeTerm, - dst_type: &TypeTerm, - ) -> Option<( - GenericReprTreeMorphism, - TypeTerm, - HashMap<TypeID, TypeTerm> - )> { - let mut src_lnf = src_type.clone().get_lnf_vec(); - let mut dst_lnf = dst_type.clone().get_lnf_vec(); - let mut halo = vec![]; - - while src_lnf.len() > 0 && dst_lnf.len() > 0 { - if let Some((m, σ)) = self.find_morphism( &TypeTerm::Ladder(src_lnf.clone()), &TypeTerm::Ladder(dst_lnf.clone()) ) { - return Some((m, TypeTerm::Ladder(halo), σ)); - } else { - if src_lnf[0] == dst_lnf[0] { - src_lnf.remove(0); - halo.push(dst_lnf.remove(0)); - } else { - return None; - } - } - } - - None - } - - pub fn apply_morphism( - &self, - repr_tree: Arc<RwLock<ReprTree>>, - src_type: &TypeTerm, - dst_type: &TypeTerm - ) { - if let Some((m, s, σ)) = self.find_morphism_ladder( &src_type, dst_type ) { - //eprintln!("apply morphism on subtree {:?}", s); - let mut rt = repr_tree.descend( s ).expect("descend"); - (m.setup_projection)( &mut rt, &σ ); - } else { - eprintln!("could not find morphism\n {:?}\n ====>\n {:?}", src_type, dst_type); - } - } - - pub fn find_list_map_morphism< + pub fn into_list_map< SrcItem, DstItem >(&self, list_typeid: TypeID) + -> GenericReprTreeMorphism + where SrcItem: Clone + Send + Sync + 'static, DstItem: Clone + Send + Sync + 'static - >( - &self, - mut src_item_type: TypeTerm, - mut dst_item_type: TypeTerm - ) -> Option< - ( GenericReprTreeMorphism, HashMap< TypeID, TypeTerm > ) - > { - if let Some((item_morphism, σ)) = self.find_morphism( &src_item_type, &dst_item_type ) { - (&mut src_item_type).apply_substitution( &|v| σ.get(v).clone().cloned() ); - (&mut dst_item_type).apply_substitution( &|v| σ.get(v).clone().cloned() ); - - let src_lst_type = - TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(10 /* FIXME: remove magic */)), - src_item_type.clone() - ]); - let dst_lst_type = - TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(10 /* FIXME: remove magic */)), - dst_item_type.clone() - ]); + let mut lst_map_type = MorphismType { + src_type: TypeTerm::App(vec![ + TypeTerm::TypeID(list_typeid), + self.morph_type.src_type.clone() + ]), + dst_type: TypeTerm::App(vec![ + TypeTerm::TypeID(list_typeid), + self.morph_type.dst_type.clone() + ]) + }.normalize(); - let sigmalol = σ.clone(); - let m = GenericReprTreeMorphism{ - morph_type: MorphismType { - src_type: src_lst_type.clone(), - dst_type: dst_lst_type.clone(), - }, - setup_projection: Arc::new(move |repr_tree, subst| { - let src_port = repr_tree.descend( src_lst_type.clone() ).expect("descend src seq") - .view_list::<SrcItem>(); + let item_morph = self.clone(); - let src_item_type = src_item_type.clone(); - let dst_item_type = dst_item_type.clone(); - let item_morphism = item_morphism.clone(); - let subst = subst.clone(); + GenericReprTreeMorphism{ + morph_type: lst_map_type.clone(), + setup_projection: Arc::new(move |repr_tree, subst| { + let mut lst_map_type = lst_map_type.clone(); + lst_map_type.src_type.apply_substitution( &|x| subst.get(x).cloned() ); + lst_map_type.dst_type.apply_substitution( &|x| subst.get(x).cloned() ); - let dst_view = src_port.map( + eprintln!( + "lst map type : {:?}", lst_map_type + ); + + let src_port = repr_tree + .descend( lst_map_type.src_type.clone() ) + .expect("descend src seq") + .view_list::<SrcItem>(); + + let subst = subst.clone(); + let item_morph = item_morph.clone(); + + let dst_view = src_port.map( move |x| { - let mut item_ladder = src_item_type.clone().get_lnf_vec(); + let mut item_ladder = item_morph.morph_type.src_type.clone().get_lnf_vec(); let mut item_rt = ReprTree::from_singleton_buffer( item_ladder.remove( item_ladder.len() - 1 ), r3vi::buffer::singleton::SingletonBuffer::new(x.clone()) ); + // TODO: required? while item_ladder.len() > 0 { let mut n = ReprTree::new_arc( item_ladder.remove( item_ladder.len() - 1) ); n.insert_branch( item_rt ); item_rt = n; } - (item_morphism.setup_projection)( &mut item_rt, &subst ); - item_rt.descend( dst_item_type.clone() ).expect("descend to item rt") + (item_morph.setup_projection)( &mut item_rt, &subst ); + item_rt.descend( item_morph.morph_type.dst_type.clone() ).expect("descend to item rt") .view_singleton::< DstItem >() .get_view().unwrap() .get() } - ); + ); - repr_tree.attach_leaf_to( - dst_lst_type.clone(), - dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> > - ); - }) - }; + repr_tree.attach_leaf_to( + lst_map_type.dst_type.clone(), + dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> > + ); + }) + } + } - Some((m, σ)) - } else { -// eprintln!("could not find item morphism\n"); + pub fn into_list_map_dyn(&self, typeid_list: TypeID) + -> Option< GenericReprTreeMorphism > + { + let typeid_char = TypeID::Fun(1); + let typeid_u64 = TypeID::Fun(5); + let typeid_edittree = TypeID::Fun(2); + + let src_item_type_lnf = self.morph_type.src_type.clone().get_lnf_vec(); + let dst_item_type_lnf = self.morph_type.dst_type.clone().get_lnf_vec(); + + if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_u64)) + { + Some( self.into_list_map::< char, u64 >(typeid_list) ) + } + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_u64)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char)) + { + Some( self.into_list_map::< u64, char >(typeid_list) ) + } + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_edittree)) + { + Some( self.into_list_map::< char, Arc<RwLock<crate::edit_tree::EditTree>> >(typeid_list) ) + } + else + { + eprintln!("no list map type for {:?}", dst_item_type_lnf.last()); None } } diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs index 6cb0e2a..d6c3f99 100644 --- a/lib-nested-core/src/repr_tree/node.rs +++ b/lib-nested-core/src/repr_tree/node.rs @@ -13,7 +13,7 @@ use { }, buffer::{singleton::*, vec::*} }, - laddertypes::{TypeTerm}, + laddertypes::{TypeTerm, TypeID}, std::{ collections::HashMap, sync::{Arc, RwLock}, @@ -197,12 +197,23 @@ impl ReprTree { >::new() ); + leaf.attach_to(src_port); + self.leaf = Some(leaf); + } + else if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TypeID::Fun(11)), + TypeTerm::TypeID(TypeID::Fun(1)) + ]) { + let mut leaf = ReprLeaf::from_vec_buffer( + VecBuffer::<char>::new() + ); + leaf.attach_to(src_port); self.leaf = Some(leaf); } else { self.leaf = Some(ReprLeaf::from_view(src_port)); } - } + } } pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { diff --git a/lib-nested-core/src/repr_tree/tests.rs b/lib-nested-core/src/repr_tree/tests.rs index 4e6aa21..8663cb7 100644 --- a/lib-nested-core/src/repr_tree/tests.rs +++ b/lib-nested-core/src/repr_tree/tests.rs @@ -83,10 +83,12 @@ fn digit_projection_char_to_u64() { //<><><><> // add another representation - ctx.read().unwrap().morphisms.apply_morphism( + ctx.read().unwrap().apply_morphism( rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~Char"), - &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64") + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<Digit 16>~Char"), + dst_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64") + } ); let digit_u64_view = rt_digit @@ -121,10 +123,12 @@ fn digit_projection_u64_to_char() { //<><><><> // add another representation - ctx.read().unwrap().morphisms.apply_morphism( + ctx.read().unwrap().apply_morphism( rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64"), - &Context::parse(&ctx, "<Digit 16>~Char") + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64"), + dst_type: Context::parse(&ctx, "<Digit 16>~Char") + } ); let digit_u64_view = rt_digit @@ -170,10 +174,12 @@ fn char_buffered_projection() { assert_eq!( digit_char_view.get_view().unwrap().get(), '5' ); // now we attach the char-repr to the u64-repr - ctx.read().unwrap().morphisms.apply_morphism( + ctx.read().unwrap().apply_morphism( rt_digit.clone(), - &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64"), - &Context::parse(&ctx, "<Digit 16>~Char") + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64"), + dst_type: Context::parse(&ctx, "<Digit 16>~Char") + } ); // char buffer and view should now follow the u64-buffer diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index f3ae4ee..c9fc849 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -228,10 +228,12 @@ impl PTYListController { rt.read().unwrap().get_type().clone(), ctx.type_term_from_str("EditTree").expect("") ]); - ctx.morphisms.apply_morphism( - rt.clone(), - &rt.get_type(), - &ladder + ctx.apply_morphism( + &rt, + &laddertypes::MorphismType { + src_type: rt.get_type(), + dst_type: ladder + } ); let new_edittree = ctx.setup_edittree( From 8d637a6f325a0c42d7303a487457f65f4fca121c Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Tue, 6 Aug 2024 16:29:28 +0200 Subject: [PATCH 52/75] add ReprTree::from_str() to simplify creation of initial representation nodes --- examples/tty-03-string/src/main.rs | 18 +++++++++++------- examples/tty-04-posint/src/main.rs | 22 ++++++++++++++-------- lib-nested-core/src/repr_tree/context.rs | 2 +- lib-nested-core/src/repr_tree/node.rs | 21 +++++++++++++++++++++ 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs index c0b1bfc..3cdc66e 100644 --- a/examples/tty-03-string/src/main.rs +++ b/examples/tty-03-string/src/main.rs @@ -43,20 +43,24 @@ async fn main() { /* Create a Representation-Tree of type <List Char> */ - let mut rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); - - rt_string.insert_leaf( - Context::parse(&ctx, "<List~Vec EditTree>"), - nested::repr_tree::ReprLeaf::from_vec_buffer( VecBuffer::<Arc<RwLock<EditTree>>>::new() ) + let mut rt_string = ReprTree::from_str( + Context::parse(&ctx, "<List Char>~<Vec Char>"), + "hello world" ); + + /* create EditTree + */ ctx.read().unwrap().apply_morphism( &rt_string, &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "<List Char~EditTree>~<Vec EditTree>"), + src_type: Context::parse(&ctx, "<List~Vec Char>"), dst_type: Context::parse(&ctx, "<List Char> ~ EditTree") } ); + // .. avoid cycle of projections.. + rt_string.write().unwrap().detach(&ctx); + /* Setup the Editor-View for this ReprTree */ let edittree_list = ctx.read().unwrap() @@ -65,7 +69,7 @@ async fn main() { SingletonBuffer::new(0).get_port() ).unwrap(); - /* In order to get acces to the values that are modified by the Editor, + /* In order to get access to the values that are modified by the Editor, * we apply a morphism that, given the List of Edit-Trees, extracts * the value from each EditTree and shows them in a ListView. */ diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index 87ecfc1..b03bdd1 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -66,16 +66,22 @@ async fn main() { nested_tty::setup_edittree_hook(&ctx); /* Create a Representation-Tree of type `ℕ` + * with a specific representation-path (big-endian hexadecimal string) */ - let mut rt_int = ReprTree::new_arc( Context::parse(&ctx, "ℕ") ); + let mut rt_int = nested::repr_tree::ReprTree::from_str( + /* TYPE */ + Context::parse(&ctx, " + ℕ + ~ <PosInt 16 BigEndian> + ~ <Seq <Digit 16>> + ~ <List <Digit 16>> + ~ <List Char> + ~ <Vec Char> + "), - /* Add a specific Representation-Path (big-endian hexadecimal) - */ - rt_int.insert_leaf( - Context::parse(&ctx, "<PosInt 16 BigEndian>~<Seq <Digit 16>>~<List <Digit 16>>~<List Char>~<Vec Char>"), - nested::repr_tree::ReprLeaf::from_vec_buffer( - VecBuffer::with_data(vec![ 'c', 'f', 'f' ] - ))); + /* VALUE */ + "cff" + ); /* initially copy values from Vec to EditTree... */ diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 6bbff0b..5e93f51 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -91,7 +91,7 @@ impl Context { src_type: src_type.clone(), dst_type: dst_type.clone() } - ) { + ) { let mut rt = rt.descend( τ ).expect("descend src repr"); (m.setup_projection)( &mut rt, &σ ); } diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs index d6c3f99..6882b7d 100644 --- a/lib-nested-core/src/repr_tree/node.rs +++ b/lib-nested-core/src/repr_tree/node.rs @@ -139,6 +139,27 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } + + pub fn from_str( + type_tag: impl Into<TypeTerm>, + val: &str + ) -> Arc<RwLock<Self>> { + let mut lnf = type_tag.into().get_lnf_vec(); + + let mut rt = ReprTree::from_vec_buffer( + lnf.pop().unwrap(), + VecBuffer::with_data( val.chars().collect() ) + ); + + while let Some(t) = lnf.pop() { + let mut new_rt = ReprTree::new_arc(t); + new_rt.insert_branch(rt); + rt = new_rt; + } + + rt + } + pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> Arc<RwLock<Self>> where T: Clone + Send + Sync + 'static { From 786866746c049746ab1515a3454d7a60858f6345 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 9 Aug 2024 02:31:26 +0200 Subject: [PATCH 53/75] integer radix convert: insert one zero digit in case value is zero --- lib-nested-core/src/editors/integer/radix.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib-nested-core/src/editors/integer/radix.rs b/lib-nested-core/src/editors/integer/radix.rs index 4c5cf31..36213a9 100644 --- a/lib-nested-core/src/editors/integer/radix.rs +++ b/lib-nested-core/src/editors/integer/radix.rs @@ -113,9 +113,13 @@ impl RadixProjection { if let Some(src) = self.src.as_ref() { let mut val = src.get_value(); - while val > 0 { - self.dst_digits.push(val % self.dst_radix); - val /= self.dst_radix; + if val == 0 { + self.dst_digits.push(0); + } else { + while val > 0 { + self.dst_digits.push(val % self.dst_radix); + val /= self.dst_radix; + } } } From 7762fa4b128ad1e685e356a0de275842f0d43676 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 9 Aug 2024 02:33:48 +0200 Subject: [PATCH 54/75] simplify posint example remove setup_hex_master() / setup_dec_master() functions and instead directly call apply_morphism() --- examples/tty-04-posint/src/main.rs | 47 ++++++++++++++---------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index b03bdd1..011ea32 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -32,28 +32,6 @@ use { std::sync::{Arc, RwLock}, }; -fn setup_hex_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { - rt_int.write().unwrap().detach( ctx ); - ctx.read().unwrap().apply_morphism( - rt_int, - &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree") - } - ); -} - -fn setup_dec_master(ctx: &Arc<RwLock<Context>>, rt_int: &Arc<RwLock<ReprTree>>) { - rt_int.write().unwrap().detach( ctx ); - ctx.read().unwrap().apply_morphism( - rt_int, - &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree") - } - ); -} - #[async_std::main] async fn main() { /* setup context @@ -92,7 +70,16 @@ async fn main() { dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree") }); - setup_hex_master(&ctx, &rt_int); + /* set Hex-editor to be master + */ + rt_int.write().unwrap().detach( &ctx ); + ctx.read().unwrap().apply_morphism( + &rt_int, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree") + } + ); let edittree_hex_be_list = ctx.read().unwrap() .setup_edittree( @@ -174,14 +161,24 @@ async fn main() { 0 => { let mut li = last_idx.write().unwrap(); if *li != 0 { - setup_hex_master(&ctx, &rt_int); + rt_int.write().unwrap().detach( &ctx ); + ctx.read().unwrap().apply_morphism(&rt_int, &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char> ~ EditTree"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char> ~ EditTree") + }); + *li = 0; } } 1 => { let mut li = last_idx.write().unwrap(); if *li != 1 { - setup_dec_master(&ctx, &rt_int); + rt_int.write().unwrap().detach( &ctx ); + ctx.read().unwrap().apply_morphism(&rt_int, &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char> ~ EditTree"), + dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char> ~ EditTree") + }); + *li = 1; } } From 0bcfd7a65aeb8696c79530df49f29fc520f93bf1 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 9 Aug 2024 23:00:31 +0200 Subject: [PATCH 55/75] call edittree_hook in morphisms already, add edittree() getter in ReprTreeExt to further simplify application code --- examples/tty-02-digit/src/main.rs | 46 +++++++--------------- examples/tty-03-string/src/main.rs | 12 +----- examples/tty-04-posint/src/main.rs | 42 +++++++++----------- lib-nested-core/src/editors/digit/ctx.rs | 2 + lib-nested-core/src/editors/list/ctx.rs | 2 + lib-nested-core/src/editors/list/editor.rs | 4 +- lib-nested-core/src/repr_tree/context.rs | 4 +- lib-nested-core/src/repr_tree/mod.rs | 5 +++ lib-nested-tty/src/editors/list.rs | 5 +-- 9 files changed, 49 insertions(+), 73 deletions(-) diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs index 60f6032..ad50898 100644 --- a/examples/tty-02-digit/src/main.rs +++ b/examples/tty-02-digit/src/main.rs @@ -84,30 +84,15 @@ async fn main() { } ); - /* setup TTY-Display for DigitEditor - * and call the hook defined above with `set_edittree_hook()` - * - */ - let edittree_digit = ctx.read().unwrap() - .setup_edittree( - rt_digit.clone(), - SingletonBuffer::new(0).get_port() - ).unwrap(); - - let mut digit_u64_buffer = rt_digit - .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap() - .singleton_buffer::<u64>(); - /* setup terminal */ let app = TTYApplication::new({ /* event handler */ let ctx = ctx.clone(); - - let mut edittree_digit = edittree_digit.clone(); + let digit_edittree = rt_digit.edittree( &ctx ); move |ev| { - edittree_digit.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); + digit_edittree.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -124,27 +109,26 @@ async fn main() { .map_item(|p, a| { a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) }) - .offset(Vector2::new(5, 0)), - ); + .offset(Vector2::new(5, 0))); let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); comp.push( nested_tty::make_label(&label_str) .map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) - .offset(Vector2::new(1, 1)) - ); - comp.push( - edittree_digit.get().read().unwrap().display_view() - .offset(Vector2::new(3,2)) - ); - comp.push( - digit_u64_buffer.get_port().map( - |d| nested_tty::make_label(&format!("Digit value={}", d)) - ) + .offset(Vector2::new(1, 1))); + + comp.push(rt_digit + .edittree( &ctx ).get().read().unwrap() + .display_view() + .offset(Vector2::new(3,2))); + + comp.push(rt_digit + .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap() + .view_u64() + .map(|d| nested_tty::make_label(&format!("Digit value={}", d))) .to_grid() .flatten() - .offset(Vector2::new(5,3)) - ); + .offset(Vector2::new(5,3))); } /* write the changes in the view of `term_port` to the terminal diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs index 3cdc66e..d5f8ff9 100644 --- a/examples/tty-03-string/src/main.rs +++ b/examples/tty-03-string/src/main.rs @@ -61,14 +61,6 @@ async fn main() { // .. avoid cycle of projections.. rt_string.write().unwrap().detach(&ctx); - /* Setup the Editor-View for this ReprTree - */ - let edittree_list = ctx.read().unwrap() - .setup_edittree( - rt_string.clone(), - SingletonBuffer::new(0).get_port() - ).unwrap(); - /* In order to get access to the values that are modified by the Editor, * we apply a morphism that, given the List of Edit-Trees, extracts * the value from each EditTree and shows them in a ListView. @@ -117,7 +109,7 @@ async fn main() { /* setup terminal */ let app = TTYApplication::new({ - let edittree_list = edittree_list.clone(); + let edittree_list = rt_string.edittree(&ctx).clone(); /* event handler */ @@ -145,7 +137,7 @@ async fn main() { .offset(Vector2::new(1,1))); comp.push( - edittree_list.get() + rt_string.edittree(&ctx).get() .read().unwrap() .display_view() .offset(Vector2::new(3,2))); diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index 011ea32..906791e 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -81,27 +81,21 @@ async fn main() { } ); - let edittree_hex_be_list = ctx.read().unwrap() - .setup_edittree( - rt_int.descend(Context::parse(&ctx," - <PosInt 16 BigEndian> - ~ <Seq <Digit 16>> - ~ <List <Digit 16>> - ~ <List Char> - ")).expect("descend"), - SingletonBuffer::new(0).get_port() - ).unwrap().get(); + let edittree_hex_be_list = + rt_int + .descend(Context::parse(&ctx, " + <PosInt 16 BigEndian> + ~ <Seq~List <Digit 16>~Char> + ")).unwrap() + .edittree( &ctx ); - let edittree_dec_be_list = ctx.read().unwrap() - .setup_edittree( - rt_int.descend(Context::parse(&ctx," - <PosInt 10 BigEndian> - ~ <Seq <Digit 10>> - ~ <List <Digit 10>> - ~ <List Char> - ")).expect("descend"), - SingletonBuffer::new(0).get_port() - ).unwrap().get(); + let edittree_dec_be_list = + rt_int + .descend(Context::parse(&ctx, " + <PosInt 10 BigEndian> + ~ <Seq~List <Digit 10>~Char> + ")).unwrap() + .edittree( &ctx ); let hex_digits_view = rt_int.descend(Context::parse(&ctx, " <PosInt 16 LittleEndian> @@ -130,15 +124,15 @@ async fn main() { /* list of both editors */ let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); - list_editor.data.push( edittree_hex_be_list.clone() ); - list_editor.data.push( edittree_dec_be_list.clone() ); + list_editor.data.push( edittree_hex_be_list.get() ); + list_editor.data.push( edittree_dec_be_list.get() ); let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); /* cursors are a bit screwed initially so fix them up * TODO: how to fix this generally? */ - edittree_hex_be_list.write().unwrap().goto(TreeCursor::none()); - edittree_dec_be_list.write().unwrap().goto(TreeCursor::none()); + edittree_hex_be_list.get().write().unwrap().goto(TreeCursor::none()); + edittree_dec_be_list.get().write().unwrap().goto(TreeCursor::none()); edittree.goto(TreeCursor{ leaf_mode: nested::editors::list::ListCursorMode::Insert, tree_addr: vec![0,0] diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index d2d22ae..c62b297 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -51,6 +51,8 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { SingletonBuffer::new(Arc::new(RwLock::new(edittree))) ) ); + + ctx.read().unwrap().setup_edittree( src_rt ); } } ); diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 56f0cf5..e4c35fa 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -54,6 +54,8 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { SingletonBuffer::new(Arc::new(RwLock::new(edittree_list))) ) ); + + ctx.read().unwrap().setup_edittree( &src_rt ); } else { eprintln!("no item type"); } diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 04cc63b..64c931f 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -321,8 +321,8 @@ impl ListEditor { let rt = ReprTree::new_arc(self.typ.clone()); let mut et = self.ctx.read().unwrap() .setup_edittree( - rt, - self.depth.map(|d| d+1) + &rt +// , self.depth.map(|d| d+1) ); if let Some(edittree) = et.as_mut(){ diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 5e93f51..cca1894 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -206,8 +206,8 @@ impl Context { pub fn setup_edittree( &self, - rt: Arc<RwLock<ReprTree>>, - depth: OuterViewPort<dyn SingletonView<Item = usize>> + rt: &Arc<RwLock<ReprTree>> +// depth: OuterViewPort<dyn SingletonView<Item = usize>> ) -> Option<SingletonBuffer<Arc<RwLock<EditTree>>>> { if let Some(new_edittree) = rt.descend(self.type_term_from_str("EditTree").unwrap()) diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 5d05bf0..8af48f8 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -58,6 +58,11 @@ pub trait ReprTreeExt { fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>; fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>; + + fn edittree(&self, ctx: &Arc<RwLock<Context>>) -> SingletonBuffer< Arc<RwLock<crate::edit_tree::EditTree>> > { + self.descend(Context::parse(&ctx, "EditTree")).unwrap() + .singleton_buffer() + } } impl ReprTreeExt for Arc<RwLock<ReprTree>> { diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index c9fc849..189125c 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -236,10 +236,7 @@ impl PTYListController { } ); - let new_edittree = ctx.setup_edittree( - rt, - self.depth.map(|d| d+1) - ); + let new_edittree = ctx.setup_edittree( &rt ); if let Some(new_edittree) = new_edittree { From e7331b36aedf6cff5f614b0b4d91e2d81ada262f Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 22 Aug 2024 17:39:02 +0200 Subject: [PATCH 56/75] radix convert: accept radix=0 for native digit radix (2^64) --- lib-nested-core/src/editors/integer/radix.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib-nested-core/src/editors/integer/radix.rs b/lib-nested-core/src/editors/integer/radix.rs index 36213a9..685452b 100644 --- a/lib-nested-core/src/editors/integer/radix.rs +++ b/lib-nested-core/src/editors/integer/radix.rs @@ -116,9 +116,13 @@ impl RadixProjection { if val == 0 { self.dst_digits.push(0); } else { - while val > 0 { - self.dst_digits.push(val % self.dst_radix); - val /= self.dst_radix; + if self.dst_radix == 0 { + self.dst_digits.push(val); + } else { + while val > 0 { + self.dst_digits.push(val % self.dst_radix); + val /= self.dst_radix; + } } } } From fb796cda04169f168bde76cc03ca1fb5da869b65 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Thu, 22 Aug 2024 17:41:57 +0200 Subject: [PATCH 57/75] add static TypeIDs to create basic types without context --- lib-nested-core/src/repr_tree/context.rs | 26 +++++++-- lib-nested-core/src/repr_tree/morphism.rs | 70 +++++++++++++++++------ lib-nested-core/src/repr_tree/node.rs | 28 ++++++--- 3 files changed, 95 insertions(+), 29 deletions(-) diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index cca1894..a9ed8ec 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -13,6 +13,14 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +pub static TYPEID_edittree : TypeID = TypeID::Fun(0); +pub static TYPEID_char : TypeID = TypeID::Fun(1); +pub static TYPEID_u64 : TypeID = TypeID::Fun(2); +pub static TYPEID_list : TypeID = TypeID::Fun(3); +pub static TYPEID_vec : TypeID = TypeID::Fun(4); + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + #[derive(Clone)] pub struct Context { /// assigns a name to every type @@ -35,19 +43,27 @@ pub struct Context { parent: Option<Arc<RwLock<Context>>>, } +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + impl Context { pub fn with_parent( parent: Option<Arc<RwLock<Context>>> ) -> Self { - let mut dict = TypeDict::new(); - let list_typeid = dict.add_typename("List".into()); - Context { type_dict: match parent.as_ref() { Some(p) => p.read().unwrap().type_dict.clone(), - None => Arc::new(RwLock::new(dict)) + None => { + let mut dict = TypeDict::new(); + assert_eq!( TYPEID_edittree, dict.add_typename("EditTree".into()) ); + assert_eq!( TYPEID_char, dict.add_typename("Char".into()) ); + assert_eq!( TYPEID_u64, dict.add_typename("machine.UInt64".into()) ); + assert_eq!( TYPEID_list, dict.add_typename("List".into()) ); + assert_eq!( TYPEID_vec, dict.add_typename("Vec".into()) ); + + Arc::new(RwLock::new(dict)) + } }, - morphisms: MorphismBase::new( list_typeid ), + morphisms: MorphismBase::new( TYPEID_list ), nodes: HashMap::new(), list_types: match parent.as_ref() { Some(p) => p.read().unwrap().list_types.clone(), diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index d8eaf3d..fe59b6f 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -1,8 +1,11 @@ use { laddertypes::{TypeTerm, TypeID, morphism::Morphism}, - r3vi::view::{AnyOuterViewPort, port::UpdateTask}, + r3vi::view::{AnyOuterViewPort, port::*, list::*}, crate::{ - repr_tree::{ReprTree, ReprTreeExt, ReprLeaf}, + repr_tree::{ + ReprTree, ReprTreeExt, ReprLeaf, + context::{*} + }, }, std::{ sync::{Arc, RwLock}, @@ -122,29 +125,64 @@ impl GenericReprTreeMorphism { pub fn into_list_map_dyn(&self, typeid_list: TypeID) -> Option< GenericReprTreeMorphism > - { - let typeid_char = TypeID::Fun(1); - let typeid_u64 = TypeID::Fun(5); - let typeid_edittree = TypeID::Fun(2); - + { let src_item_type_lnf = self.morph_type.src_type.clone().get_lnf_vec(); let dst_item_type_lnf = self.morph_type.dst_type.clone().get_lnf_vec(); - if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char)) && - dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_u64)) + eprintln!("into list map dyn"); + + if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) { - Some( self.into_list_map::< char, u64 >(typeid_list) ) + Some( self.into_list_map::< char, char >(TYPEID_list) ) } - else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_u64)) && - dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char)) + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_u64)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_u64)) { - Some( self.into_list_map::< u64, char >(typeid_list) ) + Some( self.into_list_map::< u64, u64 >(TYPEID_list) ) } - else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char)) && - dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_edittree)) + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_u64)) { - Some( self.into_list_map::< char, Arc<RwLock<crate::edit_tree::EditTree>> >(typeid_list) ) + Some( self.into_list_map::< char, u64 >(TYPEID_list) ) } + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_u64)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) + { + Some( self.into_list_map::< u64, char >(TYPEID_list) ) + } + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_edittree)) + { + Some( self.into_list_map::< char, Arc<RwLock<crate::edit_tree::EditTree>> >(TYPEID_list) ) + } + else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_edittree)) && + dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) + { + Some( self.into_list_map::< Arc<RwLock<crate::edit_tree::EditTree>>, char >(TYPEID_list) ) + } +/* + else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ])) && + dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ])) + { + Some( self.into_list_map::< char, char >(typeid_list) ) + } + else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ])) && + dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ])) + { + Some( self.into_list_map::< u64, u64 >(typeid_list) ) + } + else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ])) && + dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ])) + { + Some( self.into_list_map::< OuterViewPort<dyn ListView<char>>, OuterViewPort<dyn ListView<u64>> >(typeid_list) ) + } + else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ])) && + dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ])) + { + Some( self.into_list_map::< OuterViewPort<dyn ListView<u64>>, OuterViewPort<dyn ListView<char>> >(typeid_list) ) + } +*/ else { eprintln!("no list map type for {:?}", dst_item_type_lnf.last()); diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs index 6882b7d..efb52fb 100644 --- a/lib-nested-core/src/repr_tree/node.rs +++ b/lib-nested-core/src/repr_tree/node.rs @@ -19,7 +19,7 @@ use { sync::{Arc, RwLock}, any::Any }, - super::{Context, ReprLeaf, ReprTreeExt} + super::{Context, ReprLeaf, ReprTreeExt, context::{TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -139,7 +139,6 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } - pub fn from_str( type_tag: impl Into<TypeTerm>, val: &str @@ -204,13 +203,13 @@ impl ReprTree { return; } } - + if let Some(leaf) = self.leaf.as_mut() { leaf.attach_to(src_port); } else { if self.type_tag == TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(11)), - TypeTerm::TypeID(TypeID::Fun(2)) + TypeTerm::TypeID(TYPEID_vec), + TypeTerm::TypeID(TYPEID_edittree) ]) { let mut leaf = ReprLeaf::from_vec_buffer( VecBuffer::< @@ -222,8 +221,8 @@ impl ReprTree { self.leaf = Some(leaf); } else if self.type_tag == TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(11)), - TypeTerm::TypeID(TypeID::Fun(1)) + TypeTerm::TypeID(TYPEID_vec), + TypeTerm::TypeID(TYPEID_char) ]) { let mut leaf = ReprLeaf::from_vec_buffer( VecBuffer::<char>::new() @@ -231,13 +230,25 @@ impl ReprTree { leaf.attach_to(src_port); self.leaf = Some(leaf); - } else { + } + else if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TYPEID_vec), + TypeTerm::TypeID(TYPEID_u64) + ]) { + let mut leaf = ReprLeaf::from_vec_buffer( + VecBuffer::<u64>::new() + ); + + leaf.attach_to(src_port); + self.leaf = Some(leaf); + } else { self.leaf = Some(ReprLeaf::from_view(src_port)); } } } pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { +// eprintln!("DETACH {:?}", self.get_type()); if let Some(leaf) = self.leaf.as_mut() { if self.type_tag == Context::parse(&ctx, "Char") { leaf.detach::<dyn SingletonView<Item = char>>(); @@ -392,3 +403,4 @@ impl ReprTree { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + From b3d0e4f03ca05bf4149ac9e0e1695d5fa958ea61 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 23 Aug 2024 13:57:10 +0200 Subject: [PATCH 58/75] add more types to detach --- lib-nested-core/src/repr_tree/node.rs | 69 ++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs index efb52fb..bc51906 100644 --- a/lib-nested-core/src/repr_tree/node.rs +++ b/lib-nested-core/src/repr_tree/node.rs @@ -19,7 +19,7 @@ use { sync::{Arc, RwLock}, any::Any }, - super::{Context, ReprLeaf, ReprTreeExt, context::{TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}} + super::{Context, ReprLeaf, ReprTreeExt, context::{TYPEID_list, TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -192,7 +192,7 @@ impl ReprTree { V::Msg: Clone { while let Some(rung_type) = type_ladder.next() { - if &rung_type != self.get_type() { + if &rung_type != self.get_type() { if let Some(next_repr) = self.branches.get(&rung_type) { next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); } else { @@ -241,23 +241,70 @@ impl ReprTree { leaf.attach_to(src_port); self.leaf = Some(leaf); - } else { + } else { self.leaf = Some(ReprLeaf::from_view(src_port)); } - } + } } pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) { -// eprintln!("DETACH {:?}", self.get_type()); if let Some(leaf) = self.leaf.as_mut() { - if self.type_tag == Context::parse(&ctx, "Char") { - leaf.detach::<dyn SingletonView<Item = char>>(); + if self.type_tag == + TypeTerm::TypeID(TYPEID_edittree) + { + leaf.detach::< dyn SingletonView< + Item = Arc<RwLock< crate::edit_tree::EditTree >> + > >(); } - if self.type_tag == Context::parse(&ctx, "<Vec Char>") { - leaf.detach_vec::<char>(); + else if self.type_tag == + TypeTerm::TypeID(TYPEID_char) + { + leaf.detach::< dyn SingletonView<Item = char> >(); } - if self.type_tag == Context::parse(&ctx, "<List Char>") { - leaf.detach::<dyn ListView<char>>(); + else if self.type_tag == TypeTerm::TypeID(TYPEID_u64) + { + leaf.detach::< dyn SingletonView<Item = u64> >(); + } + else if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TYPEID_vec), + TypeTerm::TypeID(TYPEID_edittree), + ]) { + leaf.detach_vec::< + Arc<RwLock< crate::edit_tree::EditTree >> + >(); + } + else if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TYPEID_vec), + TypeTerm::TypeID(TYPEID_char), + ]) { + leaf.detach_vec::< char >(); + } + else if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TYPEID_vec), + TypeTerm::TypeID(TYPEID_u64), + ]) { + leaf.detach_vec::< u64 >(); + } + else if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TYPEID_list), + TypeTerm::TypeID(TYPEID_edittree), + ]) { + leaf.detach::< dyn ListView<Arc<RwLock<crate::edit_tree::EditTree>>> >(); + } + else if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TYPEID_list), + TypeTerm::TypeID(TYPEID_char), + ]) { + leaf.detach::< dyn ListView<char> >(); + } + else if self.type_tag == TypeTerm::App(vec![ + TypeTerm::TypeID(TYPEID_list), + TypeTerm::TypeID(TYPEID_u64), + ]) { + leaf.detach::< dyn ListView<u64> >(); + } + else { + eprintln!("cant detach type {}", ctx.read().unwrap().type_term_to_str(&self.type_tag)); } } From aed4cad1e4649bf42ef4846020a2fd657c1b002b Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 1 Sep 2024 23:20:57 +0200 Subject: [PATCH 59/75] add morphisms to create edittree from/to digit/char and generic lists --- lib-nested-core/src/editors/char/mod.rs | 70 ++++++++++++--------- lib-nested-core/src/editors/digit/ctx.rs | 63 +++++++++++++++++++ lib-nested-core/src/editors/digit/editor.rs | 4 ++ lib-nested-core/src/editors/list/ctx.rs | 45 ++++--------- lib-nested-core/src/editors/list/editor.rs | 9 +-- 5 files changed, 125 insertions(+), 66 deletions(-) diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index 3d33efc..f9f97c0 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -25,49 +25,63 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { { let ctx = ctx.clone(); move |rt, σ| { - { let mut b = rt.write().unwrap().singleton_buffer::<char>(); - if let Some(buf) = b { - // buffer already exists - } else { - // create char buffer - rt.write().unwrap().insert_leaf( - vec![].into_iter(), - ReprLeaf::from_singleton_buffer( - SingletonBuffer::new('\0') - ) - ); - } + if let Some(buf) = b { + // buffer already exists + } else { + // create char buffer + rt.write().unwrap().insert_leaf( + vec![].into_iter(), + ReprLeaf::from_singleton_buffer(SingletonBuffer::new('\0')) + ); } + } + + let char_buf = rt.singleton_buffer::<char>(); + let mut edittree = CharEditor::new_edit_tree( + ctx.clone(), + char_buf, + SingletonBuffer::<usize>::new(0).get_port() + ); - let char_buf = rt.singleton_buffer::<char>(); - - let mut edittree = CharEditor::new_edit_tree( - ctx.clone(), - char_buf, - SingletonBuffer::<usize>::new(0).get_port() - ); - - rt.insert_leaf( + rt.insert_leaf( Context::parse(&ctx, "EditTree"), ReprLeaf::from_singleton_buffer( SingletonBuffer::new( Arc::new(RwLock::new(edittree)) ) ) - ); + ); - ctx.read().unwrap().setup_edittree( - rt.clone(), - SingletonBuffer::new(0).get_port() - ); - } - + ctx.read().unwrap().setup_edittree(rt); + } } ); + let char_morph_from_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "Char~EditTree"), + Context::parse(&ctx, "Char"), + { + let ctx = ctx.clone(); + move |rt, σ| + { + let mut b = rt + .descend(Context::parse(&ctx, "EditTree")).unwrap() + .view_singleton::<Arc<RwLock<EditTree>>>(); + + rt.attach_leaf_to( + Context::parse(&ctx, "Char"), + b.map(|x| + x.read().unwrap() + .get_edit::<CharEditor>().unwrap() + .read().unwrap() + .get()) + ); + } + }); ctx.write().unwrap().morphisms.add_morphism( char_morph_to_edittree ); + ctx.write().unwrap().morphisms.add_morphism( char_morph_from_edittree ); } pub struct CharEditor { diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs index c62b297..f78b962 100644 --- a/lib-nested-core/src/editors/digit/ctx.rs +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -19,6 +19,43 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { // todo: proper scoping of Radix variable ctx.write().unwrap().add_varname("Radix"); + let digit_make_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<Digit Radix>"), + Context::parse(&ctx, "<Digit Radix>~EditTree"), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let radix = + match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + Some(TypeTerm::Num(n)) => *n as u32, + _ => 0 + }; + + let char_buf = SingletonBuffer::<char>::new('?'); + + /* Create EditTree object + */ + let mut edittree = DigitEditor::new( + ctx.clone(), + radix, + char_buf + ).into_node( + r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port() + ); + + src_rt.write().unwrap() + .insert_branch( + ReprTree::from_singleton_buffer( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new(Arc::new(RwLock::new(edittree))) + ) + ); + + ctx.read().unwrap().setup_edittree( src_rt ); + } + } + ); + let digit_morph_char_to_edittree = GenericReprTreeMorphism::new( Context::parse(&ctx, "<Digit Radix>~Char"), Context::parse(&ctx, "<Digit Radix>~EditTree"), @@ -57,6 +94,30 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { } ); + let digit_morph_char_from_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<Digit Radix>~EditTree"), + Context::parse(&ctx, "<Digit Radix>~Char"), + + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let edittree = src_rt.edittree( &ctx ); + let port = + edittree + .get() + .read().unwrap() + .get_edit::<DigitEditor>().unwrap() + .read().unwrap() + .get_char_port(); + + src_rt.insert_leaf( + Context::parse(&ctx, "Char"), + ReprLeaf::from_view( port ) + ) + } + } + ); + let digit_morph_char_to_u64 = GenericReprTreeMorphism::new( Context::parse(&ctx, "<Digit Radix>~Char"), Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64"), @@ -134,7 +195,9 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { ); + ctx.write().unwrap().morphisms.add_morphism( digit_make_edittree ); ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_to_edittree ); + ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_from_edittree ); ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_to_u64 ); ctx.write().unwrap().morphisms.add_morphism( digit_morph_u64_to_char ); } diff --git a/lib-nested-core/src/editors/digit/editor.rs b/lib-nested-core/src/editors/digit/editor.rs index 125d2a3..2f80d5d 100644 --- a/lib-nested-core/src/editors/digit/editor.rs +++ b/lib-nested-core/src/editors/digit/editor.rs @@ -59,6 +59,10 @@ impl DigitEditor { */ } + pub fn get_char_port(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { + self.data.get_port() + } + pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Result<u32, char>>> { let radix = self.radix; self.data.get_port().map(move |c| diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index e4c35fa..0d38e7a 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -63,36 +63,24 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } ); - - let list_morph_editsetup2 = GenericReprTreeMorphism::new( - Context::parse(&ctx, "<List Char>~EditTree"), - Context::parse(&ctx, "<List Char>"), + let list_morph_editsetup3 = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<List Item> ~ EditTree"), + Context::parse(&ctx, "<List Item> ~ <List EditTree>"), { let ctx = ctx.clone(); move |src_rt, σ| { - let edittree = - src_rt - .descend(Context::parse(&ctx, "<List Char>~EditTree")).unwrap() - .singleton_buffer::<Arc<RwLock<EditTree>>>(); - + let edittree = src_rt.edittree( &ctx ); let list_edit = edittree.get().read().unwrap().get_edit::< ListEditor >().unwrap(); let edittree_items = list_edit.read().unwrap().data.get_port().to_list(); - src_rt.insert_leaf( - Context::parse(&ctx, "<List Char>"), - ReprLeaf::from_view( - edittree_items - .map(|edittree_char| - edittree_char - .read().unwrap() - .get_edit::<CharEditor>().unwrap() - .read().unwrap() - .get() - ) - ) + eprintln!("edittree_items.len() = {:?}", edittree_items.get_view().unwrap().len()); + + src_rt.attach_leaf_to( + Context::parse(&ctx, "<List Item> ~ <List EditTree>") + .apply_substitution(&|x| σ.get(x).cloned()).clone(), + edittree_items ); } - } ); @@ -132,21 +120,14 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { { let ctx = ctx.clone(); move |src_rt, σ| { - let p = - src_rt - .descend(Context::parse(&ctx, "<List EditTree>")).expect("descend") - .get_port::<dyn ListView< Arc<RwLock<EditTree>> >>().unwrap(); - - src_rt.attach_leaf_to( - Context::parse(&ctx, "<List EditTree> ~ <Vec EditTree>"), - p - ); + let list_port = src_rt.get_port::<dyn ListView< Arc<RwLock<EditTree>> >>().unwrap(); + src_rt.attach_leaf_to( Context::parse(&ctx, "<Vec EditTree>"), list_port ); } } ); ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup1 ); - ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup2 ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup3 ); ctx.write().unwrap().morphisms.add_morphism( list_morph_from_vec_char ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_char ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_edittree ); diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 64c931f..575f6eb 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -1,7 +1,8 @@ use { r3vi::{ view::{OuterViewPort, singleton::*, sequence::*}, - buffer::{singleton::*, vec::*} + buffer::{singleton::*, vec::*}, + projection::* }, laddertypes::{TypeTerm}, crate::{ @@ -319,11 +320,7 @@ impl ListEditor { let mut b = item.ctrl.spillbuf.write().unwrap(); let rt = ReprTree::new_arc(self.typ.clone()); - let mut et = self.ctx.read().unwrap() - .setup_edittree( - &rt -// , self.depth.map(|d| d+1) - ); + let mut et = self.ctx.read().unwrap().setup_edittree(&rt); if let Some(edittree) = et.as_mut(){ From 6ed456e3ff303234bfbcbe3408002ff39ab6a782 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 1 Sep 2024 23:21:49 +0200 Subject: [PATCH 60/75] add morphisms between machine.UInt64 and PosInt --- lib-nested-core/src/editors/integer/ctx.rs | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index dc6aa61..d7df660 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -170,9 +170,52 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } ); + let posint_list_morph_from_u64 = GenericReprTreeMorphism::new( + Context::parse(&ctx, "ℕ ~ machine.UInt64"), + Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64>"), + { + let ctx = ctx.clone(); + move |rt, σ| { + let digits = rt + .descend(Context::parse(&ctx, "ℕ ~ machine.UInt64")).unwrap() + .view_u64() + .to_sequence() + .to_list(); + + rt.attach_leaf_to( + Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64>"), + digits + ); + } + } + ); + let posint_list_morph_to_u64 = GenericReprTreeMorphism::new( + Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64> ~ <Vec machine.UInt64>"), + Context::parse(&ctx, "ℕ ~ machine.UInt64"), + { + let ctx = ctx.clone(); + move |rt, σ| { + let u64_view = rt + .descend(Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64> ~ <Vec machine.UInt64>")).unwrap() + .get_port::< RwLock<Vec< u64 >> >().unwrap() + .to_singleton() + .map(|digits| { + digits.get(0).cloned().unwrap_or(0) + }); + + rt.attach_leaf_to( + Context::parse(&ctx, "ℕ ~ machine.UInt64"), + u64_view + ); + } + } + ); + ctx.write().unwrap().morphisms.add_morphism( posint_seq_morph_big_to_little ); ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_big_to_little ); ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_little_to_big ); ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_radix ); + ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_from_u64 ); + ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_to_u64 ); } From 7f18fd775523edf03a4460df32b5e72da24f829a Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 1 Sep 2024 23:34:52 +0200 Subject: [PATCH 61/75] list editor: get_data_port() make map on list instead of seq --- lib-nested-core/src/editors/list/editor.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 575f6eb..92fa436 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -162,9 +162,9 @@ impl ListEditor { } pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> { - self.data.get_port().to_sequence().map( + self.data.get_port().to_list().map( |x| x.read().unwrap().clone() - ) + ).to_sequence() } /* pub fn get_data(&self) -> Arc<RwLock<ReprTree>> { @@ -186,7 +186,7 @@ impl ListEditor { } else { None } - } + } pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<EditTree>>>> { if let Some(idx) = self.cursor.get().idx { From 0a6405b08e40b83dec2e17c9f118b56b4b5f31fc Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 1 Sep 2024 23:56:04 +0200 Subject: [PATCH 62/75] minor stuff & style --- examples/tty-02-digit/src/main.rs | 6 ++-- lib-nested-core/src/editors/list/editor.rs | 23 ++++++------- lib-nested-core/src/editors/list/segment.rs | 5 +-- lib-nested-core/src/repr_tree/context.rs | 1 - lib-nested-tty/src/editors/list.rs | 36 ++++++++++----------- 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs index ad50898..9279cc5 100644 --- a/examples/tty-02-digit/src/main.rs +++ b/examples/tty-02-digit/src/main.rs @@ -47,7 +47,7 @@ async fn main() { * / | \ * / | \ * / | \ - * u32 EditTree Char + * u64 EditTree Char * - Editor \ * - Display EditTree * / | \ - Editor @@ -109,13 +109,13 @@ async fn main() { .map_item(|p, a| { a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) }) - .offset(Vector2::new(5, 0))); + .offset(Vector2::new(5,0))); let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); comp.push( nested_tty::make_label(&label_str) .map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) - .offset(Vector2::new(1, 1))); + .offset(Vector2::new(1,1))); comp.push(rt_digit .edittree( &ctx ).get().read().unwrap() diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 92fa436..6773891 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -124,23 +124,18 @@ impl ListEditor { .set_editor(editor.clone()) .set_nav(editor.clone()) .set_cmd(editor.clone()) - .set_diag(e - .get_data_port() + .set_diag(e.get_data_port() .enumerate() .map(|(idx, item_editor)| { - let idx = *idx; - item_editor - .get_msg_port() - .map( - move |msg| { - let mut msg = msg.clone(); - msg.addr.insert(0, idx); - msg - } - ) + let idx = *idx; + item_editor.get_msg_port() + .map(move |msg| { + let mut msg = msg.clone(); + msg.addr.insert(0, idx); + msg + }) }) - .flatten() - ); + .flatten()); node.ctrl.spillbuf = e.spillbuf.clone(); node diff --git a/lib-nested-core/src/editors/list/segment.rs b/lib-nested-core/src/editors/list/segment.rs index f8dbdc7..4cd495b 100644 --- a/lib-nested-core/src/editors/list/segment.rs +++ b/lib-nested-core/src/editors/list/segment.rs @@ -42,11 +42,12 @@ impl SequenceView for ListSegmentSequence { type Item = ListSegment; fn len(&self) -> Option<usize> { + let l = self.data.len()?; match self.cur_cursor.mode { ListCursorMode::Insert => { - Some(self.data.len()? + if self.cur_cursor.idx.is_some() { 1 } else { 0 }) + Some(l + if self.cur_cursor.idx.is_some() { 1 } else { 0 }) } - _ => self.data.len(), + _ => Some(l), } } diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index a9ed8ec..c39da1e 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -223,7 +223,6 @@ impl Context { pub fn setup_edittree( &self, rt: &Arc<RwLock<ReprTree>> -// depth: OuterViewPort<dyn SingletonView<Item = usize>> ) -> Option<SingletonBuffer<Arc<RwLock<EditTree>>>> { if let Some(new_edittree) = rt.descend(self.type_term_from_str("EditTree").unwrap()) diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 189125c..e55172c 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -224,37 +224,37 @@ impl PTYListController { ListCursorMode::Insert => { let rt = ReprTree::new_arc(e.typ.clone()); - let ladder = laddertypes::TypeTerm::Ladder(vec![ + let src_ladder = laddertypes::TypeTerm::Ladder(vec![ + rt.read().unwrap().get_type().clone() + ]); + let dst_ladder = laddertypes::TypeTerm::Ladder(vec![ rt.read().unwrap().get_type().clone(), ctx.type_term_from_str("EditTree").expect("") ]); ctx.apply_morphism( &rt, &laddertypes::MorphismType { - src_type: rt.get_type(), - dst_type: ladder + src_type: src_ladder, + dst_type: dst_ladder } ); let new_edittree = ctx.setup_edittree( &rt ); if let Some(new_edittree) = new_edittree { - - let mut ne = new_edittree.get(); - let mut ne = ne.write().unwrap(); - match ne.send_cmd_obj(cmd_obj.clone()) { - TreeNavResult::Continue => { - drop(ne); - e.insert(new_edittree.value.read().unwrap().clone()); - TreeNavResult::Continue + let mut ne = new_edittree.get(); + let mut ne = ne.write().unwrap(); + match ne.send_cmd_obj(cmd_obj.clone()) { + TreeNavResult::Continue => { + drop(ne); + e.insert(new_edittree.value.read().unwrap().clone()); + TreeNavResult::Continue + } + TreeNavResult::Exit => { + TreeNavResult::Exit + } } - TreeNavResult::Exit => { - TreeNavResult::Exit - } - } - } else { - panic!("cant get edit tree"); TreeNavResult::Continue } @@ -301,7 +301,7 @@ impl ObjCommander for PTYListController { let cmd_type = cmd_obj.read().unwrap().get_type().clone(); if cmd_type == Context::parse(&e.ctx, "ListCmd").into() - || cmd_type == Context::parse(&e.ctx, "NestedNode").into() + || cmd_type == Context::parse(&e.ctx, "EditTree").into() { e.send_cmd_obj( cmd_obj ) } From 38c772389f87e23de6e8269f21213956b4af8efd Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 1 Sep 2024 23:56:37 +0200 Subject: [PATCH 63/75] build repr tree --- lib-nested-core/src/repr_tree/context.rs | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index c39da1e..b592ae0 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -120,6 +120,32 @@ impl Context { } } + pub fn build_repr_tree( + &self, + rt: &Arc<RwLock<ReprTree>>, + root: TypeTerm, + leaves: Vec< TypeTerm > + ) { + let mut st_problem = laddertypes::steiner_tree::PathApproxSteinerTreeSolver::new( + root, + leaves + ); + + if let Some( steiner_tree ) = st_problem.solve( &self.morphisms ) { + for morphism_type in steiner_tree.into_edges() { + eprintln!("--> apply morph to {}", self.type_term_to_str(&morphism_type.dst_type)); + if let Some(( morphism, mut τ, σ )) = + self.morphisms.find_morphism_with_subtyping( &morphism_type ) + { + let mut rt = rt.descend( τ ).expect("descend src repr"); + (morphism.setup_projection)( &mut rt, &σ ); + } + } + } else { + eprintln!("could not find steiner tree to build the requested repr tree"); + } + } + pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> { let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() ))); ctx.read().unwrap().apply_morphism( &rt, &MorphismType{ src_type: TypeTerm::unit(), dst_type: t.clone() } ); From 4b7d929abca67df5a99e076719f2679159f4c44a Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 2 Sep 2024 00:01:25 +0200 Subject: [PATCH 64/75] morphisms to copy edittree from <List Digit> to <PosInt ..> --- lib-nested-core/src/editors/integer/ctx.rs | 83 +++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index d7df660..1165543 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -1,7 +1,8 @@ use { r3vi::{ - view::{OuterViewPort, singleton::*, list::*} + view::{OuterViewPort, singleton::*, list::*}, + buffer::singleton::SingletonBuffer }, laddertypes::{TypeTerm, MorphismType}, crate::{ @@ -211,6 +212,86 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } ); + let posint_make_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>> ~ EditTree"), + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ EditTree"), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let mut list_edittree = src_rt.descend( + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>>") + .apply_substitution(&|x| σ.get(x).cloned()).clone() + ) + .unwrap() + .edittree( &ctx ) + .get().clone() + .read().unwrap() + .clone(); + + // clear display + list_edittree.disp.view = ReprTree::new_arc(Context::parse(&ctx, "Display")); + + src_rt.insert_leaf( + Context::parse(&ctx, "<PosInt Radix BigEndian> ~ EditTree") + .apply_substitution(&|x| σ.get(x).cloned()).clone(), + ReprLeaf::from_singleton_buffer( + SingletonBuffer::new( + Arc::new(RwLock::new(list_edittree)) + ) + ) + ); + + ctx.read().unwrap().setup_edittree( + &src_rt.descend( + Context::parse(&ctx, "<PosInt Radix BigEndian>") + .apply_substitution(&|x| σ.get(x).cloned()).clone() + ).unwrap() + ); + } + } + ); + + let posint_edittree_to_list = GenericReprTreeMorphism::new( + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ EditTree"), + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>> ~ EditTree"), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let mut list_edittree = src_rt.descend( + Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian>") + .apply_substitution(&|x| σ.get(x).cloned()).clone()) + .unwrap() + .edittree( &ctx ) + .get().clone() + .read().unwrap() + .clone(); + + // clear display + list_edittree.disp.view = ReprTree::new_arc(Context::parse(&ctx, "Display")); + + src_rt.insert_leaf( + Context::parse(&ctx, "<PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>>~EditTree") + .apply_substitution(&|x| σ.get(x).cloned()).clone(), + ReprLeaf::from_singleton_buffer( + SingletonBuffer::new( + Arc::new(RwLock::new(list_edittree)) + ) + ) + ); + + ctx.read().unwrap().setup_edittree( + &src_rt.descend( + Context::parse(&ctx, "<PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>>") + .apply_substitution(&|x| σ.get(x).cloned()).clone() + ).unwrap() + ); + } + } + ); + + ctx.write().unwrap().morphisms.add_morphism( posint_make_edittree ); + ctx.write().unwrap().morphisms.add_morphism( posint_edittree_to_list ); + ctx.write().unwrap().morphisms.add_morphism( posint_seq_morph_big_to_little ); ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_big_to_little ); ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_little_to_big ); From 9f53b65074d7f5e653ea23534339f24cf7d9b5fe Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 2 Sep 2024 00:02:38 +0200 Subject: [PATCH 65/75] tty backend: hooks to setup display for binary, octal, decimal \& hex notations of PosInt --- lib-nested-tty/src/lib.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index 2bc1138..0e12095 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -121,7 +121,10 @@ pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) { let char_type = Context::parse(&ctx, "Char"); let digit_type = Context::parse(&ctx, "<Digit Radix>"); let list_type = Context::parse(&ctx, "<List Item>"); - let posint_type = Context::parse(&ctx, "<PosInt Radix>"); + let posint_bin_type = Context::parse(&ctx, "<PosInt 2 BigEndian>"); + let posint_oct_type = Context::parse(&ctx, "<PosInt 8 BigEndian>"); + let posint_dec_type = Context::parse(&ctx, "<PosInt 10 BigEndian>"); + let posint_hex_type = Context::parse(&ctx, "<PosInt 16 BigEndian>"); let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap(); ctx.write().unwrap().meta_chars.push(','); @@ -134,18 +137,28 @@ pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) { ctx.write().unwrap().set_edittree_hook( Arc::new( move |et: &mut nested::edit_tree::EditTree, t: laddertypes::TypeTerm| { -// let mut et = et.write().unwrap(); - if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) { *et = crate::editors::edittree_make_char_view(et.clone()); } else if let Ok(σ) = laddertypes::unify(&t, &digit_type) { *et = crate::editors::edittree_make_digit_view(et.clone()); } - else if let Ok(σ) = laddertypes::unify(&t, &posint_type) { + else if let Ok(σ) = laddertypes::unify(&t, &posint_bin_type) { + crate::editors::list::PTYListStyle::for_node( &mut *et, ("0b", "", "")); + crate::editors::list::PTYListController::for_node( &mut *et, None, None ); + } + else if let Ok(σ) = laddertypes::unify(&t, &posint_oct_type) { + crate::editors::list::PTYListStyle::for_node( &mut *et, ("0o", "", "")); + crate::editors::list::PTYListController::for_node( &mut *et, None, None ); + } + else if let Ok(σ) = laddertypes::unify(&t, &posint_dec_type) { crate::editors::list::PTYListStyle::for_node( &mut *et, ("0d", "", "")); crate::editors::list::PTYListController::for_node( &mut *et, None, None ); } + else if let Ok(σ) = laddertypes::unify(&t, &posint_hex_type) { + crate::editors::list::PTYListStyle::for_node( &mut *et, ("0x", "", "")); + crate::editors::list::PTYListController::for_node( &mut *et, None, None ); + } else if let Ok(σ) = laddertypes::unify(&t, &list_type) { let item_type = σ.get( &laddertypes::TypeID::Var(item_tyid) ).unwrap(); From 9b5dfc9ccae2f6d51a7e948e45a93509836e13e2 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 2 Sep 2024 00:05:36 +0200 Subject: [PATCH 66/75] posint example: switch between synced editors based on list of editor types --- examples/tty-04-posint/src/main.rs | 169 ++++++++++++----------------- 1 file changed, 68 insertions(+), 101 deletions(-) diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index 906791e..4c91ee5 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -63,76 +63,66 @@ async fn main() { /* initially copy values from Vec to EditTree... */ - ctx.read().unwrap().apply_morphism( + ctx.read().unwrap().build_repr_tree( &rt_int, - &nested::repr_tree::morphism::MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <Vec Char>"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree") - }); + Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char> ~ <Vec Char>"), + vec![ + Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>> ~ EditTree"), + Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"), + ]); - /* set Hex-editor to be master - */ - rt_int.write().unwrap().detach( &ctx ); - ctx.read().unwrap().apply_morphism( - &rt_int, - &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree") + fn set_master( + ctx: &Arc<RwLock<Context>>, + rt: &Arc<RwLock<ReprTree>>, + mut leaves: Vec< laddertypes::TypeTerm >, + master_idx: usize + ) { + eprintln!("set master to {}", master_idx); + if master_idx < leaves.len() { + let master = leaves.remove( master_idx ); + rt.write().unwrap().detach( &ctx ); + ctx.read().unwrap().build_repr_tree( + rt, + master, + leaves + ); } - ); + } - let edittree_hex_be_list = - rt_int - .descend(Context::parse(&ctx, " - <PosInt 16 BigEndian> - ~ <Seq~List <Digit 16>~Char> - ")).unwrap() - .edittree( &ctx ); + let editor_types = vec![ + Context::parse(&ctx, + "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>> ~ EditTree"), + Context::parse(&ctx, + "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"), + Context::parse(&ctx, + "ℕ ~ <PosInt 16 BigEndian> ~ EditTree"), + Context::parse(&ctx, + "ℕ ~ <PosInt 8 BigEndian> ~ EditTree"), + Context::parse(&ctx, + "ℕ ~ <PosInt 2 BigEndian> ~ EditTree"), + ]; - let edittree_dec_be_list = - rt_int - .descend(Context::parse(&ctx, " - <PosInt 10 BigEndian> - ~ <Seq~List <Digit 10>~Char> - ")).unwrap() - .edittree( &ctx ); + set_master(&ctx, &rt_int, editor_types.clone(), 0); - let hex_digits_view = rt_int.descend(Context::parse(&ctx, " - <PosInt 16 LittleEndian> - ~ <Seq <Digit 16> > - ~ <List <Digit 16> - ~ ℤ_2^64 - ~ machine.UInt64 > - ")).expect("descend") - .view_list::<u64>() - .map(|v| TerminalAtom::from(char::from_digit(*v as u32, 16))) - .to_sequence() - .to_grid_horizontal(); - - let dec_digits_view = rt_int.descend(Context::parse(&ctx, " - <PosInt 10 LittleEndian> - ~ <Seq <Digit 10>> - ~ <List <Digit 10> - ~ ℤ_2^64 - ~ machine.UInt64 > - ")).expect("descend") - .view_list::<u64>() - .map(|v| TerminalAtom::from(char::from_digit(*v as u32, 10))) - .to_sequence() - .to_grid_horizontal(); - - /* list of both editors + /* list of editors */ let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); - list_editor.data.push( edittree_hex_be_list.get() ); - list_editor.data.push( edittree_dec_be_list.get() ); + + // add all desired editors to the list + for leaf in editor_types.iter() { + let et = + rt_int + .descend(leaf.clone()).unwrap() + .edittree(&ctx).get(); + et.write().unwrap().goto(TreeCursor::none()); + list_editor.data.push(et); + } + let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); /* cursors are a bit screwed initially so fix them up * TODO: how to fix this generally? */ - edittree_hex_be_list.get().write().unwrap().goto(TreeCursor::none()); - edittree_dec_be_list.get().write().unwrap().goto(TreeCursor::none()); edittree.goto(TreeCursor{ leaf_mode: nested::editors::list::ListCursorMode::Insert, tree_addr: vec![0,0] @@ -146,37 +136,23 @@ async fn main() { */ let ctx = ctx.clone(); let rt_int = rt_int.clone(); - let last_idx = RwLock::new(1); + let last_idx = RwLock::new(0); + let editor_types = editor_types.clone(); move |ev| { - let cur = edittree.read().unwrap().get_cursor(); if cur.tree_addr.len() > 0 { - match cur.tree_addr[0] { - 0 => { - let mut li = last_idx.write().unwrap(); - if *li != 0 { - rt_int.write().unwrap().detach( &ctx ); - ctx.read().unwrap().apply_morphism(&rt_int, &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char> ~ EditTree"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char> ~ EditTree") - }); + let mut li = last_idx.write().unwrap(); + let ci = cur.tree_addr[0]; - *li = 0; - } - } - 1 => { - let mut li = last_idx.write().unwrap(); - if *li != 1 { - rt_int.write().unwrap().detach( &ctx ); - ctx.read().unwrap().apply_morphism(&rt_int, &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char> ~ EditTree"), - dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char> ~ EditTree") - }); - - *li = 1; - } - } - _=>{} + if *li != ci { + eprintln!("----------------------------------"); + set_master( + &ctx, + &rt_int, + editor_types.clone(), + ci as usize + ); + *li = ci; } } @@ -189,7 +165,7 @@ async fn main() { * so it will be displayed on TTY-output. */ let compositor = TerminalCompositor::new(app.port.inner()); - + /* Now add some views to our compositor */ { @@ -199,30 +175,21 @@ async fn main() { { let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend"); let halo_type = rt_edittree.read().unwrap().get_halo_type().clone(); - let edittree = rt_edittree.read().unwrap().get_view::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>>>>().unwrap().get().read().unwrap().clone(); + let edittree = rt_edittree.edittree( &ctx ); comp.push( nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) .offset(Vector2::new(1,y))); - comp.push( edittree.display_view() + comp.push( edittree.get().read().unwrap().display_view() .offset(Vector2::new(1,y+1))); } - show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>")).expect(""), 1); - show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char>")).expect(""), 4); - - /* project the seq of u64 representations to a view - */ - comp.push(nested_tty::make_label("dec: ").offset(Vector2::new(3,7))); - comp.push(dec_digits_view.offset(Vector2::new(8,7)).map_item(|_,a| { - a.add_style_back(TerminalStyle::fg_color((30,90,200))) - })); - - comp.push(nested_tty::make_label("hex: ").offset(Vector2::new(3,8))); - comp.push(hex_digits_view.offset(Vector2::new(8,8)).map_item(|_,a| { - a.add_style_back(TerminalStyle::fg_color((200, 200, 30))) - })); + let mut y = 1; + for t in editor_types.iter() { + show_edit_tree(&ctx, &mut comp, &rt_int.descend(t.clone()).expect(""), y); + y += 3; + } } /* write the changes in the view of `term_port` to the terminal From 689ac95486208bc6d77174f9d4afb3e6fd6bc8c0 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 2 Sep 2024 00:07:57 +0200 Subject: [PATCH 67/75] posint get_value() : ignore invalid digits --- lib-nested-core/src/editors/integer/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib-nested-core/src/editors/integer/mod.rs b/lib-nested-core/src/editors/integer/mod.rs index b7cd6df..c0d59d4 100644 --- a/lib-nested-core/src/editors/integer/mod.rs +++ b/lib-nested-core/src/editors/integer/mod.rs @@ -35,8 +35,10 @@ pub trait PositionalUInt : SequenceView<Item = u64> { let mut val = 0; let mut r = 1; for i in 0..self.len().unwrap_or(0) { - val += r * self.get(&i).unwrap(); - r *= self.get_radix(); + if let Some(digit_val) = self.get(&i) { + val += r * digit_val; + r *= self.get_radix(); + } } val From af34fc99762dea44b74d51cf55291f528d985335 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 28 Oct 2024 21:17:54 +0100 Subject: [PATCH 68/75] add more seq->list & list->vec morphisms --- lib-nested-core/src/editors/list/ctx.rs | 45 +++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 0d38e7a..0107124 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -84,6 +84,20 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } ); + let seq_morph_to_list_char = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<Seq Char>"), + Context::parse(&ctx, "<Seq Char>~<List Char>"), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + src_rt.attach_leaf_to( + Context::parse(&ctx, "<List Char>"), + src_rt.view_seq::<char>().to_list() + ); + } + } + ); + let list_morph_to_vec_char = GenericReprTreeMorphism::new( Context::parse(&ctx, "<List Char>"), Context::parse(&ctx, "<List Char>~<Vec Char>"), @@ -98,6 +112,34 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { } ); + let seq_morph_to_list_u64 = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<Seq machine.UInt64>"), + Context::parse(&ctx, "<Seq machine.UInt64>~<List machine.UInt64>"), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + src_rt.attach_leaf_to( + Context::parse(&ctx, "<List machine.UInt64>"), + src_rt.view_seq::<u64>().to_list() + ); + } + } + ); + + let list_morph_to_vec_u64 = GenericReprTreeMorphism::new( + Context::parse(&ctx, "<List machine.UInt64>"), + Context::parse(&ctx, "<List machine.UInt64>~<Vec machine.UInt64>"), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + src_rt.attach_leaf_to( + Context::parse(&ctx, "<Vec machine.UInt64>"), + src_rt.view_list::<u64>() + ); + } + } + ); + let list_morph_from_vec_char = GenericReprTreeMorphism::new( Context::parse(&ctx, "<List Char>~<Vec Char>"), Context::parse(&ctx, "<List Char>"), @@ -129,7 +171,10 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) { ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup1 ); ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup3 ); ctx.write().unwrap().morphisms.add_morphism( list_morph_from_vec_char ); + ctx.write().unwrap().morphisms.add_morphism( seq_morph_to_list_char ); + ctx.write().unwrap().morphisms.add_morphism( seq_morph_to_list_u64 ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_char ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_u64 ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_edittree ); } From 50fe43df97dec33779168e62eef4eac489479ff1 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 28 Oct 2024 21:27:20 +0100 Subject: [PATCH 69/75] context: switch to BimapTypeDict --- lib-nested-core/src/repr_tree/context.rs | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index b592ae0..e7cad72 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -1,9 +1,15 @@ use { - r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, - laddertypes::{TypeDict, TypeTerm, TypeID, MorphismType, MorphismBase, Morphism}, crate::{ - repr_tree::{ReprTree, ReprTreeExt, GenericReprTreeMorphism}, - edit_tree::EditTree + edit_tree::EditTree, + repr_tree::{GenericReprTreeMorphism, ReprTree, ReprTreeExt}, + }, + laddertypes::{ + parser::ParseLadderType, sugar::SugaredTypeTerm, unparser::UnparseLadderType, + BimapTypeDict, Morphism, MorphismBase, MorphismType, TypeDict, TypeID, TypeTerm, + }, + r3vi::{ + buffer::singleton::*, + view::{singleton::*, OuterViewPort}, }, std::{ collections::HashMap, @@ -24,7 +30,7 @@ pub static TYPEID_vec : TypeID = TypeID::Fun(4); #[derive(Clone)] pub struct Context { /// assigns a name to every type - pub type_dict: Arc<RwLock<TypeDict>>, + pub type_dict: Arc<RwLock<BimapTypeDict>>, pub morphisms: laddertypes::morphism::MorphismBase< GenericReprTreeMorphism >, @@ -53,12 +59,12 @@ impl Context { type_dict: match parent.as_ref() { Some(p) => p.read().unwrap().type_dict.clone(), None => { - let mut dict = TypeDict::new(); - assert_eq!( TYPEID_edittree, dict.add_typename("EditTree".into()) ); - assert_eq!( TYPEID_char, dict.add_typename("Char".into()) ); - assert_eq!( TYPEID_u64, dict.add_typename("machine.UInt64".into()) ); - assert_eq!( TYPEID_list, dict.add_typename("List".into()) ); - assert_eq!( TYPEID_vec, dict.add_typename("Vec".into()) ); + let mut dict = BimapTypeDict::new(); + assert_eq!(TYPEID_edittree, dict.add_typename("EditTree".into())); + assert_eq!(TYPEID_char, dict.add_typename("Char".into())); + assert_eq!(TYPEID_u64, dict.add_typename("machine.UInt64".into())); + assert_eq!(TYPEID_list, dict.add_typename("List".into())); + assert_eq!(TYPEID_vec, dict.add_typename("Vec".into())); Arc::new(RwLock::new(dict)) } From b2083aec4cae5b7031c6928611bd6101d3ec6410 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 28 Oct 2024 21:32:38 +0100 Subject: [PATCH 70/75] add dictionary example --- Cargo.toml | 1 + examples/tty-05-dictionary/Cargo.toml | 19 ++ examples/tty-05-dictionary/src/main.rs | 299 +++++++++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 examples/tty-05-dictionary/Cargo.toml create mode 100644 examples/tty-05-dictionary/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 44403c7..38b4295 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,5 +10,6 @@ members = [ "examples/tty-02-digit", "examples/tty-03-string", "examples/tty-04-posint", + "examples/tty-05-dictionary", ] diff --git a/examples/tty-05-dictionary/Cargo.toml b/examples/tty-05-dictionary/Cargo.toml new file mode 100644 index 0000000..fef954f --- /dev/null +++ b/examples/tty-05-dictionary/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "tty-05-dictionary" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +laddertypes = { path = "../../../lib-laddertypes" } +r3vi = { path = "../../../lib-r3vi" } +nested = { path = "../../lib-nested-core" } +nested-tty = { path = "../../lib-nested-tty" } +termion = "*" +cgmath = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] + diff --git a/examples/tty-05-dictionary/src/main.rs b/examples/tty-05-dictionary/src/main.rs new file mode 100644 index 0000000..d6daefc --- /dev/null +++ b/examples/tty-05-dictionary/src/main.rs @@ -0,0 +1,299 @@ +extern crate cgmath; +extern crate nested; +extern crate nested_tty; +extern crate r3vi; +extern crate termion; + +use { + cgmath::Vector2, + nested::{ + editors::{ + ObjCommander + }, + repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, + edit_tree::{EditTree, TreeNav, TreeCursor} + }, + laddertypes::{ + bimap::Bimap, + sugar::SugaredTypeTerm + }, + nested_tty::{ + DisplaySegment, TTYApplication, + TerminalCompositor, TerminalStyle, TerminalView, + TerminalAtom, TerminalEvent + }, + r3vi::{ + buffer::{singleton::*, vec::*}, + view::{port::UpdateTask, singleton::*, list::*, sequence::*}, + projection::* + }, + std::sync::{Arc, RwLock}, +}; + +#[async_std::main] +async fn main() { + /* setup context + */ + let ctx = Arc::new(RwLock::new(Context::new())); + nested::editors::char::init_ctx( ctx.clone() ); + nested::editors::digit::init_ctx( ctx.clone() ); + nested::editors::integer::init_ctx( ctx.clone() ); + nested::editors::list::init_ctx( ctx.clone() ); + nested_tty::setup_edittree_hook(&ctx); + + let dict = Arc::new(RwLock::new(Bimap::<String, u64>::new())); + dict.write().unwrap().insert( "Nop".into(), 0 ); + dict.write().unwrap().insert( "Jmp".into(), 1 ); + dict.write().unwrap().insert( "Call".into(), 2 ); + dict.write().unwrap().insert( "Branch".into(), 3 ); + dict.write().unwrap().insert( "Ret".into(), 4 ); + dict.write().unwrap().insert( "Lit".into(), 5 ); + dict.write().unwrap().insert( "Pick".into(), 6 ); + dict.write().unwrap().insert( "Roll".into(), 7 ); + dict.write().unwrap().insert( "Dup".into(), 8 ); + dict.write().unwrap().insert( "Drop".into(), 9 ); + dict.write().unwrap().insert( "Swap".into(), 10 ); + dict.write().unwrap().insert( "Rot".into(), 11 ); + dict.write().unwrap().insert( "Fetch".into(), 13 ); + dict.write().unwrap().insert( "Store".into(), 14 ); + dict.write().unwrap().insert( "Accept".into(), 15 ); + dict.write().unwrap().insert( "Emit".into(), 16 ); + dict.write().unwrap().insert( "IntAdd".into(), 17 ); + dict.write().unwrap().insert( "IntSub".into(), 18 ); + dict.write().unwrap().insert( "IntMul".into(), 19 ); + dict.write().unwrap().insert( "IntDiv".into(), 20 ); + dict.write().unwrap().insert( "IntRem".into(), 21 ); + dict.write().unwrap().insert( "FltAdd".into(), 22 ); + dict.write().unwrap().insert( "FltSub".into(), 23 ); + dict.write().unwrap().insert( "FltMul".into(), 24 ); + dict.write().unwrap().insert( "FltDiv".into(), 25 ); + dict.write().unwrap().insert( "FltRem".into(), 26 ); + dict.write().unwrap().insert( "BitNeg".into(), 28 ); + dict.write().unwrap().insert( "BitAnd".into(), 29 ); + dict.write().unwrap().insert( "BitOr".into(), 30 ); + dict.write().unwrap().insert( "BitXor".into(), 31 ); + dict.write().unwrap().insert( "BitShl".into(), 32 ); + dict.write().unwrap().insert( "BitShr".into(), 33 ); + + let symbol_morph_str_to_u64 = nested::repr_tree::GenericReprTreeMorphism::new( + Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List~Vec Char>"), + Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ machine.UInt64"), + + { + let ctx = ctx.clone(); + let dict = dict.clone(); + + move |rt, σ| { + let str_view = rt + .descend(Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List~Vec Char>")).unwrap() + .vec_buffer::<char>() + .get_port(); + + let u64_view = str_view + .to_singleton() + .map({ + let old_value = Arc::new(RwLock::new(0)); + let dict = dict.clone(); + move |chars| { + let str_val = chars.iter().collect::<String>(); + let dict = &dict.read().unwrap().mλ; + + let mut old_value = old_value.write().unwrap(); + if let Some( new_value ) = dict.get( &str_val ) { + *old_value = new_value.clone(); + new_value.clone() + } else { + old_value.clone() + } + } + }); + + rt.attach_leaf_to( + Context::parse(&ctx, "Opcode ~ ℕ ~ machine.UInt64"), + u64_view + ); + } + } + ); + + let symbol_morph_u64_to_str = nested::repr_tree::GenericReprTreeMorphism::new( + Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ machine.UInt64"), + Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq Char>"), + + { + let ctx = ctx.clone(); + let dict = dict.clone(); + + move |rt, σ| { + let u64_view = rt + .descend(Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ machine.UInt64")).unwrap() + .view_u64(); + + let str_view = + u64_view + .map({ + let dict = dict.clone(); + let old_value = Arc::new(RwLock::new( VecBuffer::<char>::new() )); + move |idx| { + let dict = &dict.read().unwrap().my; + let mut old_value = old_value.write().unwrap(); + if let Some( new_value ) = dict.get( &idx ) { + *old_value = VecBuffer::<char>::with_data( + new_value.chars().collect::<Vec<char>>() + ); + } + + old_value.get_port().to_sequence() + } + }) + .to_sequence() + .flatten(); + + rt.attach_leaf_to( + Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq Char>"), + str_view + ); + } + } + ); + + ctx.write().unwrap().morphisms.add_morphism( symbol_morph_u64_to_str ); + ctx.write().unwrap().morphisms.add_morphism( symbol_morph_str_to_u64 ); + + let mut symbol_rt = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, " + Instruction ~ Mnemonic ~ <Seq~List~Vec Char> + "), + "Call" + ); + + // this is required to initialize the <Vec EditTree> representation, + // and to take the value from <Vec Char> + ctx.read().unwrap().build_repr_tree( + &symbol_rt, + Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List~Vec Char>"), + vec![ + Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ <PosInt 10 BigEndian> ~ EditTree"), + Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List Char> ~ EditTree"), + ]); + + symbol_rt.write().unwrap().detach( &ctx ); + + fn set_master( + ctx: &Arc<RwLock<Context>>, + rt: &Arc<RwLock<ReprTree>>, + mut leaves: Vec< laddertypes::TypeTerm >, + master_idx: usize + ) { + eprintln!("set master to {}", master_idx); + if master_idx < leaves.len() { + let master = leaves.remove( master_idx ); + rt.write().unwrap().detach( &ctx ); + ctx.read().unwrap().build_repr_tree( + rt, + master, + leaves + ); + } + } + + let editor_types = vec![ + Context::parse(&ctx, + "Instruction ~ Mnemonic ~ <Seq~List Char> ~ EditTree"), + Context::parse(&ctx, + "Instruction ~ Opcode ~ ℕ ~ <PosInt 10 BigEndian> ~ EditTree"), + Context::parse(&ctx, + "Instruction ~ Opcode ~ ℕ ~ <PosInt 16 BigEndian> ~ EditTree"), + ]; + + set_master(&ctx, &symbol_rt, editor_types.clone(), 0); + let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); + + // add all desired editors to the list + for leaf in editor_types.iter() { + let et = + symbol_rt + .descend(leaf.clone()).unwrap() + .edittree(&ctx).get(); + et.write().unwrap().goto(TreeCursor::none()); + list_editor.data.push(et); + } + + let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); + edittree.goto(TreeCursor{ + leaf_mode: nested::editors::list::ListCursorMode::Insert, + tree_addr: vec![0, 0] + }); + let edittree = Arc::new(RwLock::new(edittree)); + + /* setup terminal + */ + let app = TTYApplication::new({ + /* event handler + */ + let ctx = ctx.clone(); + let symbol_rt = symbol_rt.clone(); + let last_idx = RwLock::new(0); + let editor_types = editor_types.clone(); + move |ev| { + let cur = edittree.read().unwrap().get_cursor(); + if cur.tree_addr.len() > 0 { + let mut li = last_idx.write().unwrap(); + let ci = cur.tree_addr[0]; + + if *li != ci { + eprintln!("----------------------------------"); + set_master( + &ctx, + &symbol_rt, + editor_types.clone(), + ci as usize + ); + *li = ci; + } + } + + edittree.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); + } + }); + + /* Setup the compositor to serve as root-view + * by routing it to the `app.port` Viewport, + * so it will be displayed on TTY-output. + */ + let compositor = TerminalCompositor::new(app.port.inner()); + + /* Now add some views to our compositor + */ + { + let mut comp = compositor.write().unwrap(); + + fn show_edit_tree( + ctx: &Arc<RwLock<Context>>, + comp: &mut TerminalCompositor, + rt: &Arc<RwLock<ReprTree>>, + y: i16 + ) { + let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend"); + let halo_type = rt_edittree.read().unwrap().get_halo_type().clone(); + let edittree = rt_edittree.read().unwrap().get_view::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>>>>().unwrap().get().read().unwrap().clone(); + + comp.push( nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) + .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) + .offset(Vector2::new(1,y))); + + comp.push( edittree.display_view() + .map_item(|_pt, atom| + atom.add_style_front(TerminalStyle::bg_color((80,80,80))) + ) + .offset(Vector2::new(1,y+1))); + } + + show_edit_tree( &ctx, &mut comp, &symbol_rt.descend(Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List Char>")).unwrap(), 1 ); + show_edit_tree( &ctx, &mut comp, &symbol_rt.descend(Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ <PosInt 10 BigEndian>")).unwrap(), 3 ); + show_edit_tree( &ctx, &mut comp, &symbol_rt.descend(Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ <PosInt 16 BigEndian>")).unwrap(), 5 ); + } + + /* write the changes in the view of `term_port` to the terminal + */ + app.show().await.expect("output error!"); +} From e09f3e565622c5a565e09eb457f04a5d5d9b937f Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 2 Nov 2024 19:19:38 +0100 Subject: [PATCH 71/75] add lines exapmle --- Cargo.toml | 2 +- examples/tty-06-lines/Cargo.toml | 19 ++ examples/tty-06-lines/README.md | 8 + examples/tty-06-lines/src/main.rs | 418 ++++++++++++++++++++++++++++++ 4 files changed, 446 insertions(+), 1 deletion(-) create mode 100644 examples/tty-06-lines/Cargo.toml create mode 100644 examples/tty-06-lines/README.md create mode 100644 examples/tty-06-lines/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 38b4295..c3f2dbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,5 @@ members = [ "examples/tty-03-string", "examples/tty-04-posint", "examples/tty-05-dictionary", + "examples/tty-06-lines", ] - diff --git a/examples/tty-06-lines/Cargo.toml b/examples/tty-06-lines/Cargo.toml new file mode 100644 index 0000000..47c4391 --- /dev/null +++ b/examples/tty-06-lines/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "tty-06-lines" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +laddertypes = { path = "../../../lib-laddertypes" } +r3vi = { path = "../../../lib-r3vi" } +nested = { path = "../../lib-nested-core" } +nested-tty = { path = "../../lib-nested-tty" } +iterate-text = "0.0.1" +termion = "*" +cgmath = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] diff --git a/examples/tty-06-lines/README.md b/examples/tty-06-lines/README.md new file mode 100644 index 0000000..85305aa --- /dev/null +++ b/examples/tty-06-lines/README.md @@ -0,0 +1,8 @@ +# tty-03-string + +Similarly to `tty-02-digit`, a editor is created +but of type <List Char>. +The contents of the editor can be retrieved by +a morphism from the `EditTree` node. +To demonstrate that, the values are are mapped +to the TTY-display in different form. diff --git a/examples/tty-06-lines/src/main.rs b/examples/tty-06-lines/src/main.rs new file mode 100644 index 0000000..701c26c --- /dev/null +++ b/examples/tty-06-lines/src/main.rs @@ -0,0 +1,418 @@ +extern crate cgmath; +extern crate nested; +extern crate nested_tty; +extern crate r3vi; +extern crate termion; + +use { + cgmath::{Vector2, Point2}, + nested::{ + editors::{ObjCommander, char::CharEditor, list::{ListEditor, ListSegment, ListSegmentSequence}}, + repr_tree::{Context, ReprLeaf, ReprTree, ReprTreeExt, GenericReprTreeMorphism}, + edit_tree::{EditTree, TreeNav, TreeCursor} + }, + nested_tty::{ + DisplaySegment, TTYApplication, + TerminalCompositor, TerminalStyle, TerminalView, + TerminalAtom, TerminalEvent, + edit_tree::cursor_widget::TreeNavExt, + TerminalProjections + }, + r3vi::{ + buffer::{singleton::*, vec::*}, + view::{ObserverBroadcast, Observer, ObserverExt, View, ViewPort, OuterViewPort, port::UpdateTask, list::*, sequence::*, singleton::*, index::*, grid::*}, + projection::projection_helper::ProjectionHelper + }, + std::sync::{Arc, RwLock}, +}; + +#[derive(Clone)] +struct LineDiagnostic { + range: (u32, u32), + msg: String +} + +struct LineView { + line_num: Arc< dyn SingletonView<Item = u64> >, + segments: Arc< dyn SequenceView<Item = ListSegment> >, + diagnostics: Arc< dyn SequenceView<Item = LineDiagnostic> >, + + diag_buf: VecBuffer< LineDiagnostic >, + + cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>, + out_port: OuterViewPort<dyn TerminalView>, + proj_helper: ProjectionHelper<usize, Self> +} + +impl View for LineView { + type Msg = IndexArea<Point2<i16>>; +} + +impl IndexView<Point2<i16>> for LineView { + type Item = TerminalAtom; + + fn get(&self, pos: &Point2<i16>) -> Option< TerminalAtom > { + let xoff = 6; + + let mut pos = pos.clone(); + pos.x -= xoff; + if pos.y == 0 { + // main line + if pos.x >= 0 { + match self.segments.get(&(pos.x as usize)) { + Some(ListSegment::InsertCursor) => { + Some(TerminalAtom::new('|', TerminalStyle::fg_color((220, 80, 40)))) + } + Some(ListSegment::Item { editor, cur_dist }) => { + if let Some(e) = editor.get_edit::<CharEditor>() { + let c = e.read().unwrap().get(); + let mut style = TerminalStyle::default(); + let i = if cur_dist >= 0 { pos.x as u32 } else { pos.x as u32 - 1 }; + for d in self.diagnostics.iter() { + if d.range.0 <= i && d.range.1 > i { + style = TerminalStyle::bg_color((110, 80, 30)) + } + } + Some(TerminalAtom::new(c, style)) + } else { + Some(TerminalAtom::from('?')) + } + } + None => None + } + } else if pos.x <= -2 { + // line number + let mut n = self.line_num.get(); + let digit_idx = -(pos.x+2); + for _ in 0..digit_idx { n /= 10; } + Some( + TerminalAtom::new( + char::from_digit((n % 10) as u32, 10).unwrap_or('?'), + TerminalStyle::fg_color((120,120,120)) + ) + ) + } else { + None + } + } else if pos.y > 0 { + // optional diagnostic message + let diag_idx = pos.y as usize - 1; + if let Some(diag) = self.diagnostics.get(&diag_idx) { + if let Some(c) = diag.msg.chars().nth( pos.x as usize ) { + Some(TerminalAtom::new(c, + TerminalStyle::bg_color((20,20,0)) + .add(TerminalStyle::fg_color((220, 40, 40))) + )) + } else { + None + } + } else { + None + } + } else { + None + } + } + + fn area(&self) -> IndexArea<Point2<i16>> { + let xoff = 6; + let mut n = self.line_num.get(); + let mut n_digits = 0 as i16; + while n > 0 { n_digits += 1; n /= 10; } + let diag_len = self.diagnostics.iter().map(|d| d.msg.chars().count() as i16).max().unwrap_or(0); + IndexArea::Range( + Point2::new( xoff -1-n_digits , 0) ..= + Point2::new( + xoff+ + i16::max( + self.segments.len().unwrap_or(i16::MAX as usize) as i16, + diag_len + ), + self.diagnostics.len().unwrap_or(i16::MAX as usize) as i16, + ) + ) + } +} + +impl LineView { + pub fn new( + n: u64, + le: &ListEditor, + ) -> Arc<RwLock<Self>> { + let line_num_buf = SingletonBuffer::new(n); + let diag_buf = VecBuffer::new(); + let seg_seq = ListSegmentSequence::new(le.get_cursor_port(), le.get_data_port()) + .read().unwrap().get_view(); + + let out_port = ViewPort::new(); + let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone()); + + let lv = Arc::new(RwLock::new(LineView{ + line_num: proj_helper.new_singleton_arg(0, line_num_buf.get_port(), + |s: &mut LineView, _msg|{ + s.cast.write().unwrap() + .notify(&IndexArea::Range( + (Point2::new(-100, 0) ..= Point2::new(0, 0)) + )); + }), + segments: proj_helper.new_sequence_arg(1, seg_seq, + |s: &mut LineView, idx| { + s.cast.write().unwrap() + .notify(&IndexArea::Range( + (Point2::new(0, *idx as i16 - 1) ..= Point2::new(100, *idx as i16)) + )); + }), + diagnostics: proj_helper.new_sequence_arg(2, diag_buf.get_port().to_sequence(), + |s: &mut LineView, idx| { + s.cast.write().unwrap() + .notify(&IndexArea::Range( + (Point2::new(-100, 1+*idx as i16) ..= Point2::new(100, 1+*idx as i16)) + )); + }), + + diag_buf, + + cast: out_port.inner().get_broadcast(), + proj_helper, + out_port: out_port.outer() + })); + + lv.write().unwrap().proj_helper.set_proj(&lv); + out_port.inner().set_view(Some(lv.clone())); + + lv + } + + pub fn get_port(&self) -> OuterViewPort<dyn TerminalView> { + self.out_port.clone() + } +} + +struct LinesEditor { + ctx: Arc<RwLock<Context>>, + edit: Arc<RwLock<EditTree>> +} + +impl LinesEditor { + pub fn new(ctx: Arc<RwLock<Context>>) -> Self { + let typ = Context::parse(&ctx, "<List Char>"); + let depth_port = SingletonBuffer::<usize>::new(0).get_port(); + + let list_edit = ListEditor::new(ctx.clone(), typ); + + let line_to_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "Line ~ <Seq~List Char>"), + Context::parse(&ctx, "Line ~ EditTree"), + |rt, σ| { + eprintln!("LINE EDITOR CONSTRUCT"); + } + ); + ctx.write().unwrap().morphisms.add_morphism( line_to_edittree ); + + let lines_segments = nested::editors::list::ListSegmentSequence::new( + list_edit.get_cursor_port(), + list_edit.get_data_port() + ).read().unwrap().get_view(); + let lines_view = lines_segments + .map({ + let ctx = ctx.clone(); + move |segment| match segment { + nested::editors::list::ListSegment::InsertCursor => { + nested_tty::make_label("..... |") + .with_fg_color((220, 80, 40)) + }, + nested::editors::list::ListSegment::Item { editor, cur_dist } => { + if *cur_dist == 0 { + editor.display_view() + .map_item(|x,a| a + .add_style_back(TerminalStyle::bg_color((50, 50, 50))) + ) + } else { + editor.display_view() + } + } + } + }) + .to_grid_vertical() + .flatten(); + + let mut list_edit = list_edit.into_node( depth_port ); + nested_tty::editors::list::PTYListController::for_node( &mut list_edit, Some('\n'), None ); + list_edit.disp.view + .write().unwrap() + .insert_branch(ReprTree::from_view( + Context::parse(&ctx, "TerminalView"), + lines_view + )); + + LinesEditor { + // lines, + edit: Arc::new(RwLock::new(list_edit)), + ctx + } + } + + pub fn add_line(&mut self, line_value: &str) { + let n = self.edit.write().unwrap() + .get_edit::< ListEditor >().unwrap() + .read().unwrap() + .data.len() as u64; + + let line = + self.make_line(line_value) + .descend(Context::parse(&self.ctx, "EditTree")).unwrap() + .edittree(&self.ctx).get(); + + let le = line.read().unwrap().get_edit::<ListEditor>().unwrap(); + le.write().unwrap().goto(TreeCursor::none()); + + let lvport = LineView::new( n, &*le.read().unwrap() ).read().unwrap().get_port(); + line.write().unwrap().disp.view + .insert_leaf( + Context::parse(&self.ctx, "TerminalView"), + ReprLeaf::from_view( lvport ) + ); + + self.edit.write().unwrap() + .get_edit::< ListEditor >().unwrap() + .write().unwrap() + .data + .push(line); + } + + pub fn make_line(&self, line_value: &str) -> Arc<RwLock<ReprTree>> { + let ctx = &self.ctx; + let mut rt_line = ReprTree::from_str( + Context::parse(&ctx, "<List Char>~<Vec Char>"), + line_value + ); + + ctx.read().unwrap().apply_morphism( + &rt_line, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<List~Vec Char>"), + dst_type: Context::parse(&ctx, "<List Char> ~ EditTree") + } + ); + + // .. avoid cycle of projections.. + rt_line.write().unwrap().detach(&ctx); + + ctx.read().unwrap().apply_morphism( + &rt_line, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<List Char>~EditTree"), + dst_type: Context::parse(&ctx, "<List Char>") + } + ); + ctx.read().unwrap().apply_morphism( + &rt_line, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "<List Char>"), + dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>") + } + ); + + rt_line + } + + pub fn add_diagnostic(&mut self, line_num: usize, diag: LineDiagnostic) { + /* + let mut line = self.edit.write().unwrap() + .get_edit::< ListEditor >().expect("cant get list edit") + .write().unwrap() + .data + .get(line_num) + .get_edit::< LineEditor >().expect("cant get line edit"); + + line.write().unwrap().diag_buf.push(diag); + */ + } +/* + pub fn get_lines(&self) -> Vec<String> { + // TODO + let lines = self.edit.read().unwrap().get_edit::< ListEditor >().expect("cant get list edit") + .read().unwrap().data + .clone().into_inner() + .read().unwrap() + .iter() + .map(|line_edittree_arc| { + let line_edittree = line_edittree_arc.read().unwrap(); + line_edittree. + }) + } + + pub fn get(&self) -> String { + self.get_lines().iter() + .map(|l| + l.chars().chain(std::iter::once('\n')) + ).flatten() + .collect() + } +*/ +} + + +#[async_std::main] +async fn main() { + /* setup context + */ + let ctx = Arc::new(RwLock::new(Context::new())); + nested::editors::char::init_ctx( ctx.clone() ); + nested::editors::digit::init_ctx( ctx.clone() ); + nested::editors::integer::init_ctx( ctx.clone() ); + nested::editors::list::init_ctx( ctx.clone() ); + nested_tty::setup_edittree_hook(&ctx); + + let args: Vec<String> = std::env::args().collect(); + let path = String::from(args.get(1).expect("no filename given")); + let mut lines_edit = LinesEditor::new(ctx.clone()); + + let iter_lines = iterate_text::file::lines::IterateFileLines::new(path.clone()); + for line in iter_lines { + let mut sanitized_line = String::new(); + for c in line.chars() { + if c == '\t' { + for _ in 0..4 { sanitized_line.push(' '); } + } else if c != '\n' { + sanitized_line.push(c); + } + } + lines_edit.add_line(&sanitized_line); + } + + lines_edit.edit.write().unwrap().goto(TreeCursor::home()); + lines_edit.add_diagnostic( 5, LineDiagnostic{ range: (0, 10), msg: "test diagnostic".into() } ); + + /* setup terminal + */ + let app = TTYApplication::new({ + let edittree = lines_edit.edit.clone(); + + /* event handler + */ + let ctx = ctx.clone(); + move |ev| { + edittree.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); + } + }); + + /* Setup the compositor to serve as root-view + * by routing it to the `app.port` Viewport, + * so it will be displayed on TTY-output. + */ + let compositor = TerminalCompositor::new(app.port.inner()); + + /* Now add some views to our compositor + */ + { + let mut comp = compositor.write().unwrap(); + let edit = lines_edit.edit.read().unwrap(); + comp.push(edit.get_cursor_widget()); + comp.push(edit.display_view().offset(Vector2::new(0, 1))); + } + + /* write the changes in the view of `term_port` to the terminal + */ + app.show().await.expect("output error!"); +} From fe4b571b8cdb70305113e8e972763af8198e3cae Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 2 Nov 2024 19:21:10 +0100 Subject: [PATCH 72/75] lib-nested-tty: reactivate list-cursor widget via new TreeNavExt trait --- lib-nested-tty/src/edit_tree/cursor_widget.rs | 25 +++++++++++++++++-- lib-nested-tty/src/edit_tree/mod.rs | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib-nested-tty/src/edit_tree/cursor_widget.rs b/lib-nested-tty/src/edit_tree/cursor_widget.rs index 2504428..4c2fa1f 100644 --- a/lib-nested-tty/src/edit_tree/cursor_widget.rs +++ b/lib-nested-tty/src/edit_tree/cursor_widget.rs @@ -1,5 +1,27 @@ +use { + r3vi::{ + view::{ + OuterViewPort + }, + buffer::vec::*, + projection::decorate_sequence::Separate + }, + nested::{ + edit_tree::{ + TreeNav + }, + editors::list::{ + ListCursorMode + } + }, + crate::{TerminalView, make_label, TerminalProjections} +}; -impl TreeNav { +pub trait TreeNavExt { + fn get_cursor_widget(&self) -> OuterViewPort<dyn TerminalView>; +} + +impl<T: TreeNav> TreeNavExt for T { fn get_cursor_widget(&self) -> OuterViewPort<dyn TerminalView> { VecBuffer::with_data( vec![ @@ -30,4 +52,3 @@ impl TreeNav { .flatten() } } - diff --git a/lib-nested-tty/src/edit_tree/mod.rs b/lib-nested-tty/src/edit_tree/mod.rs index fdf1de4..fa78d3f 100644 --- a/lib-nested-tty/src/edit_tree/mod.rs +++ b/lib-nested-tty/src/edit_tree/mod.rs @@ -1,4 +1,4 @@ pub mod color; pub mod keymap; - +pub mod cursor_widget; From 2c2268c918c7895b66f5fcb3827277a8a8e90bc5 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 3 Nov 2024 01:39:57 +0100 Subject: [PATCH 73/75] repr tree: create reprtree with a single path from type ladder --- lib-nested-core/src/repr_tree/node.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs index bc51906..837092e 100644 --- a/lib-nested-core/src/repr_tree/node.rs +++ b/lib-nested-core/src/repr_tree/node.rs @@ -50,15 +50,19 @@ impl std::fmt::Debug for ReprTree { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> impl ReprTree { - pub fn new(type_tag: impl Into<TypeTerm>) -> Self { - let type_tag = type_tag.into(); + pub fn new(typ: impl Into<TypeTerm>) -> Self { + let mut lnf = typ.into().get_lnf_vec(); + let head_type = lnf.remove(0); + + let mut branches = HashMap::new(); + if lnf.len() > 0 { + branches.insert( lnf[0].clone(), ReprTree::new_arc(TypeTerm::Ladder(lnf)) ); + } - assert!(type_tag.is_flat()); - ReprTree { halo: TypeTerm::unit(), - type_tag: type_tag.clone(), - branches: HashMap::new(), + type_tag: head_type, + branches, leaf: None } } From dad789227c44968a7b53387332f951eb33070ca3 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sat, 16 Nov 2024 22:21:41 +0100 Subject: [PATCH 74/75] char editor: move ctx to separate file --- lib-nested-core/src/editors/char/ctx.rs | 88 +++++++++++++++++++++++++ lib-nested-core/src/editors/char/mod.rs | 69 +------------------ 2 files changed, 90 insertions(+), 67 deletions(-) create mode 100644 lib-nested-core/src/editors/char/ctx.rs diff --git a/lib-nested-core/src/editors/char/ctx.rs b/lib-nested-core/src/editors/char/ctx.rs new file mode 100644 index 0000000..8b04f4d --- /dev/null +++ b/lib-nested-core/src/editors/char/ctx.rs @@ -0,0 +1,88 @@ +use { + r3vi::{ + view::{ + OuterViewPort, + singleton::*, + port::UpdateTask + }, + buffer::singleton::* + }, + laddertypes::{TypeTerm}, + crate::{ + repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt, GenericReprTreeMorphism}, + edit_tree::{EditTree, TreeNavResult}, + editors::{ + char::CharEditor, + ObjCommander + }, + }, + std::sync::Arc, + std::sync::RwLock +}; + +pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { + + let char_morph_to_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "Char"), + Context::parse(&ctx, "Char~EditTree"), + { + let ctx = ctx.clone(); + move |rt, σ| { + { + let mut b = rt.write().unwrap().singleton_buffer::<char>(); + if let Some(buf) = b { + // buffer already exists + } else { + // create char buffer + rt.write().unwrap().insert_leaf( + vec![].into_iter(), + ReprLeaf::from_singleton_buffer(SingletonBuffer::new('\0')) + ); + } + } + + let char_buf = rt.singleton_buffer::<char>(); + let mut edittree = CharEditor::new_edit_tree( + ctx.clone(), + char_buf, + SingletonBuffer::<usize>::new(0).get_port() + ); + + rt.insert_leaf( + Context::parse(&ctx, "EditTree"), + ReprLeaf::from_singleton_buffer( + SingletonBuffer::new( + Arc::new(RwLock::new(edittree)) + ) + ) + ); + + ctx.read().unwrap().setup_edittree(rt); + } + } + ); + + let char_morph_from_edittree = GenericReprTreeMorphism::new( + Context::parse(&ctx, "Char~EditTree"), + Context::parse(&ctx, "Char"), + { + let ctx = ctx.clone(); + move |rt, σ| + { + let mut b = rt + .descend(Context::parse(&ctx, "EditTree")).unwrap() + .view_singleton::<Arc<RwLock<EditTree>>>(); + + rt.attach_leaf_to( + Context::parse(&ctx, "Char"), + b.map(|x| + x.read().unwrap() + .get_edit::<CharEditor>().unwrap() + .read().unwrap() + .get()) + ); + } + }); + ctx.write().unwrap().morphisms.add_morphism( char_morph_to_edittree ); + ctx.write().unwrap().morphisms.add_morphism( char_morph_from_edittree ); +} diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index f9f97c0..26e3eaf 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -17,72 +17,8 @@ use { std::sync::RwLock }; -pub fn init_ctx( ctx: Arc<RwLock<Context>> ) { - - let char_morph_to_edittree = GenericReprTreeMorphism::new( - Context::parse(&ctx, "Char"), - Context::parse(&ctx, "Char~EditTree"), - { - let ctx = ctx.clone(); - move |rt, σ| { - { - let mut b = rt.write().unwrap().singleton_buffer::<char>(); - if let Some(buf) = b { - // buffer already exists - } else { - // create char buffer - rt.write().unwrap().insert_leaf( - vec![].into_iter(), - ReprLeaf::from_singleton_buffer(SingletonBuffer::new('\0')) - ); - } - } - - let char_buf = rt.singleton_buffer::<char>(); - let mut edittree = CharEditor::new_edit_tree( - ctx.clone(), - char_buf, - SingletonBuffer::<usize>::new(0).get_port() - ); - - rt.insert_leaf( - Context::parse(&ctx, "EditTree"), - ReprLeaf::from_singleton_buffer( - SingletonBuffer::new( - Arc::new(RwLock::new(edittree)) - ) - ) - ); - - ctx.read().unwrap().setup_edittree(rt); - } - } - ); - - let char_morph_from_edittree = GenericReprTreeMorphism::new( - Context::parse(&ctx, "Char~EditTree"), - Context::parse(&ctx, "Char"), - { - let ctx = ctx.clone(); - move |rt, σ| - { - let mut b = rt - .descend(Context::parse(&ctx, "EditTree")).unwrap() - .view_singleton::<Arc<RwLock<EditTree>>>(); - - rt.attach_leaf_to( - Context::parse(&ctx, "Char"), - b.map(|x| - x.read().unwrap() - .get_edit::<CharEditor>().unwrap() - .read().unwrap() - .get()) - ); - } - }); - ctx.write().unwrap().morphisms.add_morphism( char_morph_to_edittree ); - ctx.write().unwrap().morphisms.add_morphism( char_morph_from_edittree ); -} +pub mod ctx; +pub use crate::editors::char::ctx::init_ctx; pub struct CharEditor { ctx: Arc<RwLock<Context>>, @@ -146,4 +82,3 @@ impl CharEditor { .set_editor( editor.clone() ) } } - From 41c02465bed42bb2350a30cce4144b6816525c2f Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 17 Nov 2024 14:15:17 +0100 Subject: [PATCH 75/75] repr tree: add type alias ReprTreeArc --- lib-nested-core/src/repr_tree/context.rs | 6 +++--- lib-nested-core/src/repr_tree/mod.rs | 6 +++--- lib-nested-core/src/repr_tree/node.rs | 24 +++++++++++++----------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index e7cad72..37f16ae 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -1,7 +1,7 @@ use { crate::{ edit_tree::EditTree, - repr_tree::{GenericReprTreeMorphism, ReprTree, ReprTreeExt}, + repr_tree::{GenericReprTreeMorphism, ReprTree, ReprTreeExt, ReprTreeArc}, }, laddertypes::{ parser::ParseLadderType, sugar::SugaredTypeTerm, unparser::UnparseLadderType, @@ -152,7 +152,7 @@ impl Context { } } - pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> { + pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> ReprTreeArc { let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() ))); ctx.read().unwrap().apply_morphism( &rt, &MorphismType{ src_type: TypeTerm::unit(), dst_type: t.clone() } ); rt @@ -242,7 +242,7 @@ impl Context { */ } - pub fn get_obj(&self, name: &String) -> Option< Arc<RwLock<ReprTree>> > { + pub fn get_obj(&self, name: &String) -> Option< ReprTreeArc > { if let Some(obj) = self.nodes.get(name) { Some(obj.clone()) } else if let Some(parent) = self.parent.as_ref() { diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 8af48f8..e77774f 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -9,7 +9,7 @@ mod tests; pub use { context::{Context}, leaf::ReprLeaf, - node::ReprTree, + node::{ReprTree, ReprTreeArc}, morphism::{GenericReprTreeMorphism} }; @@ -42,7 +42,7 @@ pub trait ReprTreeExt { fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf); fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>); fn create_branch(&mut self, rung: impl Into<TypeTerm>); - fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>; + fn descend(&self, target_type: impl Into<TypeTerm>) -> Option< ReprTreeArc >; fn attach_leaf_to<V: View + ?Sized + 'static>(&self, t: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone; fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone; @@ -100,7 +100,7 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> { self.write().unwrap().attach_leaf_to::<V>(type_ladder.into().get_lnf_vec().into_iter(), v) } - fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + fn descend(&self, target_type: impl Into<TypeTerm>) -> Option< ReprTreeArc > { ReprTree::descend( self, target_type ) } diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs index 837092e..bef682b 100644 --- a/lib-nested-core/src/repr_tree/node.rs +++ b/lib-nested-core/src/repr_tree/node.rs @@ -28,10 +28,12 @@ use { pub struct ReprTree { halo: TypeTerm, type_tag: TypeTerm, - branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>, + branches: HashMap<TypeTerm, ReprTreeArc>, leaf: Option< ReprLeaf > } +pub type ReprTreeArc = Arc<RwLock<ReprTree>>; + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> impl std::fmt::Debug for ReprTree { @@ -67,7 +69,7 @@ impl ReprTree { } } - pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> { + pub fn new_arc(type_tag: impl Into<TypeTerm>) -> ReprTreeArc { Arc::new(RwLock::new(Self::new(type_tag))) } @@ -106,7 +108,7 @@ impl ReprTree { leaf_types } - pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) { + pub fn insert_branch(&mut self, repr: ReprTreeArc) { let branch_type = repr.read().unwrap().get_type().clone(); assert!(branch_type.is_flat()); @@ -119,14 +121,14 @@ impl ReprTree { self.branches.insert(branch_type, repr.clone()); } - pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char ) -> Arc<RwLock<Self>> { + pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char ) -> ReprTreeArc { ReprTree::from_singleton_buffer( Context::parse(ctx, "Char"), SingletonBuffer::new(c) ) } - pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> Arc<RwLock<Self>> + pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> ReprTreeArc where V: View + ?Sized + 'static, V::Msg: Clone { @@ -135,7 +137,7 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } - pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> Arc<RwLock<Self>> + pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> ReprTreeArc where T: Clone + Send + Sync + 'static { let mut rt = ReprTree::new(type_tag); @@ -146,7 +148,7 @@ impl ReprTree { pub fn from_str( type_tag: impl Into<TypeTerm>, val: &str - ) -> Arc<RwLock<Self>> { + ) -> ReprTreeArc { let mut lnf = type_tag.into().get_lnf_vec(); let mut rt = ReprTree::from_vec_buffer( @@ -163,7 +165,7 @@ impl ReprTree { rt } - pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> Arc<RwLock<Self>> + pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> ReprTreeArc where T: Clone + Send + Sync + 'static { let mut rt = ReprTree::new(type_tag); @@ -340,13 +342,13 @@ impl ReprTree { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option< ReprTreeArc > { let dst_type = dst_type.into(); assert!( dst_type.is_flat() ); self.branches.get(&dst_type).cloned() } - pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option< ReprTreeArc > { if let Some(first) = repr_ladder.next() { let rt = rt.read().unwrap(); repr_ladder.fold( @@ -357,7 +359,7 @@ impl ReprTree { } } - pub fn descend(rt: &Arc<RwLock<Self>>, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> { + pub fn descend(rt: &Arc<RwLock<Self>>, dst_type: impl Into<TypeTerm>) -> Option< ReprTreeArc > { let mut lnf = dst_type.into().get_lnf_vec(); if lnf.len() > 0 { if lnf[0] == rt.get_type() {