diff --git a/nested/Cargo.toml b/nested/Cargo.toml index 6793380..8814165 100644 --- a/nested/Cargo.toml +++ b/nested/Cargo.toml @@ -5,11 +5,12 @@ name = "nested" version = "0.1.0" [dependencies] -#r3vi = { git = "https://git.exobiont.de/senvas/r3vi.git" } -r3vi = { path = "../../r3vi" } +#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"] } -termion = "1.5.5" +termion = "2.0.1" vte = "0.10.1" ansi_colours = "1.0" signal-hook = "0.3.1" diff --git a/nested/src/editors/char/mod.rs b/nested/src/editors/char/mod.rs index 91dc3f4..2521cb1 100644 --- a/nested/src/editors/char/mod.rs +++ b/nested/src/editors/char/mod.rs @@ -6,8 +6,9 @@ use { }, buffer::singleton::* }, + laddertypes::{TypeTerm}, crate::{ - type_system::{Context, ReprTree, TypeTerm}, + type_system::{Context, ReprTree}, terminal::{TerminalAtom}, tree::{NestedNode, TreeNavResult}, commander::{ObjCommander} @@ -19,8 +20,8 @@ use { pub fn init_ctx( ctx: &mut Context ) { ctx.add_node_ctor( "Char", - Arc::new(|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| { - Some(CharEditor::new_node(ctx)) + Arc::new(|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { + Some(CharEditor::new_node(ctx, depth)) })); } @@ -34,7 +35,7 @@ impl ObjCommander for CharEditor { let cmd_obj = cmd_obj.read().unwrap(); let cmd_type = cmd_obj.get_type().clone(); - if cmd_type == (&self.ctx, "( Char )").into() { + if cmd_type == Context::parse(&self.ctx, "Char") { if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() { let value = cmd_view.get(); @@ -69,7 +70,7 @@ impl CharEditor { self.get_port().get_view().unwrap().get() } - pub fn new_node(ctx0: Arc<RwLock<Context>>) -> NestedNode { + pub fn new_node(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() })); @@ -77,14 +78,14 @@ impl CharEditor { NestedNode::new( ctx0.clone(), ReprTree::new_leaf( - ctx0.read().unwrap().type_term_from_str("( Char )").unwrap(), + ctx0.read().unwrap().type_term_from_str("Char").unwrap(), data.get_port().into() ), - 0 // fixme + depth ) .set_view(data .get_port() - .map(move |c| TerminalAtom::from(c)) + .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) .to_grid() ) .set_cmd( editor.clone() ) diff --git a/nested/src/editors/integer/ctx.rs b/nested/src/editors/integer/ctx.rs index b683f3e..99c9aa7 100644 --- a/nested/src/editors/integer/ctx.rs +++ b/nested/src/editors/integer/ctx.rs @@ -1,6 +1,11 @@ + use { + r3vi::{ + view::{OuterViewPort, singleton::*} + }, + laddertypes::{TypeTerm}, crate::{ - type_system::{Context, TypeTerm}, + type_system::{Context}, editors::{ list::*, integer::* @@ -19,7 +24,7 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_node_ctor( "Digit", Arc::new( - |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| { + |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { match ty { TypeTerm::App(args) => { if args.len() > 1 { @@ -50,9 +55,6 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_morphism(pattern, Arc::new( |mut node, dst_type| { - let _depth = node.depth.get(); - let _editor = node.editor.get().unwrap().downcast::<RwLock<ListEditor>>().unwrap(); - // todo: check src_type parameter to be ( Digit radix ) match dst_type { @@ -87,7 +89,7 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_node_ctor( "PosInt", Arc::new( - |ctx0: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: usize| { + |ctx0: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { match dst_typ.clone() { TypeTerm::App(args) => { if args.len() > 1 { @@ -105,7 +107,7 @@ pub fn init_ctx(ctx: &mut Context) { .clone() .into() ]), - depth+1 + depth.map(|d| d+1) ).unwrap(); node = node.morph(dst_typ); diff --git a/nested/src/editors/integer/editor.rs b/nested/src/editors/integer/editor.rs index b2fe84a..3e11b34 100644 --- a/nested/src/editors/integer/editor.rs +++ b/nested/src/editors/integer/editor.rs @@ -10,8 +10,9 @@ use { index_hashmap::* } }, + laddertypes::{TypeTerm}, crate::{ - type_system::{Context, TypeTerm, ReprTree}, + type_system::{Context, ReprTree}, editors::list::{ListCmd, PTYListController, PTYListStyle}, terminal::{ TerminalAtom, TerminalStyle, make_label @@ -40,7 +41,7 @@ impl ObjCommander for DigitEditor { let cmd_obj = cmd_obj.read().unwrap(); let cmd_type = cmd_obj.get_type().clone(); - if cmd_type == (&self.ctx, "( Char )").into() { + 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(); @@ -84,7 +85,7 @@ impl DigitEditor { } } - pub fn into_node(self, depth: usize) -> NestedNode { + pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode { let data = self.get_data(); let editor = Arc::new(RwLock::new(self)); let ed = editor.write().unwrap(); @@ -99,7 +100,7 @@ impl DigitEditor { TerminalAtom::new( c.unwrap_or('?'), if c.unwrap_or('?').to_digit(r).is_some() { - TerminalStyle::fg_color((100, 140, 100)) + TerminalStyle::fg_color((90, 160, 90)) } else { //TerminalStyle::bg_color((90, 10, 10)) TerminalStyle::fg_color((200, 40, 40)) @@ -125,7 +126,7 @@ impl DigitEditor { 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.ctx.read().unwrap().type_term_from_str("<Seq u32>").unwrap(), self.get_data_port().into() ), self.get_type() @@ -145,8 +146,8 @@ impl PosIntEditor { pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self { let mut node = Context::make_node( &ctx, - (&ctx, format!("( List ( Digit {} ) )", radix).as_str()).into(), - 0 + Context::parse(&ctx, format!("<List <Digit {}>>", radix).as_str()), + r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() ).unwrap(); // Set Type diff --git a/nested/src/editors/list/cmd.rs b/nested/src/editors/list/cmd.rs index d7958a5..74c7fee 100644 --- a/nested/src/editors/list/cmd.rs +++ b/nested/src/editors/list/cmd.rs @@ -26,7 +26,7 @@ impl ListCmd { pub fn into_repr_tree(self, ctx: &Arc<RwLock<Context>>) -> Arc<RwLock<ReprTree>> { let buf = r3vi::buffer::singleton::SingletonBuffer::new(self); ReprTree::new_leaf( - (ctx, "( ListCmd )"), + Context::parse(ctx, "ListCmd"), buf.get_port().into() ) } @@ -58,6 +58,8 @@ 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); @@ -71,55 +73,53 @@ impl ObjCommander for ListEditor { match cur.mode { ListCursorMode::Select => { if let Some(mut item) = self.get_item().clone() { - if self.is_listlist() { - let item_cur = item.get_cursor(); - - match cmd.get() { - ListCmd::DeletePxev => { - if idx > 0 - && item_cur.tree_addr.iter().fold( - true, - |is_zero, x| is_zero && (*x == 0) - ) - { - self.listlist_join_pxev(idx); - TreeNavResult::Continue - } else { - item.send_cmd_obj(cmd_obj) - } - } - - ListCmd::DeleteNexd => { - let item_cur = item.get_cursor_warp(); - let next_idx = idx as usize + 1; - - if next_idx < self.data.len() - && item_cur.tree_addr.iter().fold( - true, - |is_end, x| is_end && (*x == -1) - ) - { - self.listlist_join_nexd(idx as usize); - TreeNavResult::Continue - } else { - item.send_cmd_obj(cmd_obj) - } - } - - ListCmd::Split => { - self.listlist_split(); - TreeNavResult::Continue - } - - _ => { - item.send_cmd_obj(cmd_obj); + let item_cur = item.get_cursor(); + + match cmd.get() { + ListCmd::DeletePxev => { + eprintln!("SELECT: delete pxev"); + if idx > 0 + && item_cur.tree_addr.iter().fold( + true, + |is_zero, x| is_zero && (*x == 0) + ) + { + self.listlist_join_pxev(idx); TreeNavResult::Continue + } else { + item.send_cmd_obj(cmd_obj) } } - } else { - TreeNavResult::Exit + + ListCmd::DeleteNexd => { + let item_cur = item.get_cursor_warp(); + let next_idx = idx as usize + 1; + + if next_idx < self.data.len() + && item_cur.tree_addr.iter().fold( + true, + |is_end, x| is_end && (*x == -1) + ) + { + self.listlist_join_nexd(idx as usize); + TreeNavResult::Continue + } else { + item.send_cmd_obj(cmd_obj) + } + } + + ListCmd::Split => { + self.listlist_split(); + TreeNavResult::Continue + } + + _ => { + item.send_cmd_obj(cmd_obj); + TreeNavResult::Continue + } } } else { + eprintln!("ptylist: no item"); TreeNavResult::Exit } }, @@ -127,6 +127,7 @@ impl ObjCommander for ListEditor { ListCursorMode::Insert => { match cmd.get() { ListCmd::DeletePxev => { + eprintln!("INSERT: delete pxev"); self.delete_pxev(); TreeNavResult::Continue } @@ -149,18 +150,19 @@ impl ObjCommander for ListEditor { } } } else { + eprintln!("ptylist: cursor has no idx"); TreeNavResult::Exit } - } } } else { if let Some(cur_item) = self.get_item_mut() { drop(cmd_repr); - cur_item.write().unwrap().send_cmd_obj(cmd_obj) - } else { + cur_item.write().unwrap().send_cmd_obj(cmd_obj); TreeNavResult::Continue + } else { + TreeNavResult::Exit } } } diff --git a/nested/src/editors/list/ctx.rs b/nested/src/editors/list/ctx.rs index d42f9c2..91474f0 100644 --- a/nested/src/editors/list/ctx.rs +++ b/nested/src/editors/list/ctx.rs @@ -1,6 +1,8 @@ use { + r3vi::{view::{OuterViewPort, singleton::*}}, + laddertypes::{TypeTerm}, crate::{ - type_system::{Context, TypeTerm}, + type_system::{Context}, editors::list::{ListEditor, PTYListController, PTYListStyle} }, std::sync::{Arc, RwLock} @@ -9,12 +11,12 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub fn init_ctx(ctx: &mut Context) { - ctx.add_list_typename("ListCmd".into()); + 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: usize| { + |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| { match ty { TypeTerm::App(args) => { if args.len() > 1 { diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs index d234cb3..31c1f1b 100644 --- a/nested/src/editors/list/editor.rs +++ b/nested/src/editors/list/editor.rs @@ -1,10 +1,11 @@ use { r3vi::{ - view::{OuterViewPort, singleton::*, sequence::*}, + view::{ViewPort, OuterViewPort, singleton::*, sequence::*}, buffer::{singleton::*, vec::*} }, + laddertypes::{TypeTerm}, crate::{ - type_system::{Context, TypeTerm, ReprTree}, + type_system::{Context, ReprTree}, editors::list::{ListCursor, ListCursorMode, ListCmd}, tree::{NestedNode, TreeNav, TreeCursor}, diagnostics::Diagnostics, @@ -22,10 +23,12 @@ pub struct ListEditor { pub data: VecBuffer< Arc<RwLock<NestedNode>> >, pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>, - + pub(super) addr_port: OuterViewPort<dyn SequenceView<Item = isize>>, pub(super) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>, + depth: OuterViewPort<dyn SingletonView<Item = usize>>, + pub(crate) ctx: Arc<RwLock<Context>>, /// item type @@ -95,13 +98,16 @@ impl ListEditor { data, spillbuf: Arc::new(RwLock::new(Vec::new())), ctx, - typ + typ, + depth: SingletonBuffer::new(0).get_port() } } - pub fn into_node(self, depth: usize) -> NestedNode { + pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode { let data = self.get_data(); let ctx = self.ctx.clone(); + + self.depth = depth.clone(); let editor = Arc::new(RwLock::new(self)); let e = editor.read().unwrap(); @@ -189,6 +195,7 @@ impl ListEditor { } } + /// is the element-type also a list-like editor (i.e. impls TreeNav) pub fn is_listlist(&self) -> bool { self.ctx.read().unwrap().is_list_type(&self.typ) } @@ -227,6 +234,12 @@ 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() + ); + let mut cur = self.cursor.get(); if let Some(idx) = cur.idx { match cur.mode { @@ -235,7 +248,9 @@ impl ListEditor { if self.is_listlist() { cur.mode = ListCursorMode::Select; } else { - cur.idx = Some(idx + 1); + eprintln!("list insert: is not a listlist ({:?})", self.typ); + item.write().unwrap().goto(TreeCursor::none()); + cur.idx = Some(idx + 1); } } @@ -254,7 +269,8 @@ impl ListEditor { } /// split the list off at the current cursor position and return the second half - pub fn split(&mut self) { + pub fn split(&mut self) { + eprintln!("split"); let cur = self.cursor.get(); if let Some(idx) = cur.idx { let idx = idx as usize; @@ -264,10 +280,32 @@ impl ListEditor { ); self.data.remove(idx); } + + /* in case the split leaves an empty item-list + * as a last element, remove it + */ +/* + if self.is_listlist() { + if idx > 0 && idx < self.data.len()+1 { + /* we are in insert mode, + * get element before cursor + */ + let prev_idx = idx - 1; + let prev_node = self.data.get(prev_idx); + let prev_node = prev_node.read().unwrap(); + + if prev_node.get_data_view::<dyn SequenceView<Item = NestedNode>>(vec![].into_iter()).iter().count() == 0 { + drop(prev_node); + self.data.remove(prev_idx); + } + } + } + */ } } pub fn listlist_split(&mut self) { + eprintln!("listlist split"); let cur = self.get_cursor(); if let Some(mut item) = self.get_item().clone() { @@ -280,14 +318,15 @@ impl ListEditor { self.nexd(); let mut b = item.spillbuf.write().unwrap(); - let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), item.depth.get()).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()); for node in b.iter() { + eprintln!("splid :send to tail node"); tail_node .send_cmd_obj( ReprTree::new_leaf( - (&self.ctx, "( NestedNode )"), + Context::parse(&self.ctx, "NestedNode"), SingletonBuffer::<NestedNode>::new( node.read().unwrap().clone() ).get_port().into() @@ -299,7 +338,7 @@ impl ListEditor { drop(item); tail_node.goto(TreeCursor::home()); - if cur.tree_addr.len() > 2 { + if cur.tree_addr.len() > 1 { tail_node.dn(); } @@ -341,7 +380,7 @@ impl ListEditor { for x in data.iter() { pxv_editor.send_cmd_obj( ReprTree::new_leaf( - (&self.ctx, "( NestedNode )"), + Context::parse(&self.ctx, "NestedNode"), SingletonBuffer::<NestedNode>::new( x.read().unwrap().clone() ).get_port().into() @@ -349,13 +388,15 @@ impl ListEditor { ); } + + // fixme: is it oc0 or old_cur ?? if oc0.tree_addr.len() > 1 { pxv_editor.goto(TreeCursor { tree_addr: vec![ old_cur.tree_addr[0], 0 ], leaf_mode: ListCursorMode::Insert }); pxv_editor.send_cmd_obj(ListCmd::DeletePxev.into_repr_tree( &self.ctx )); - } else { + } else if oc0.tree_addr.len() > 0 { pxv_editor.goto(TreeCursor { tree_addr: vec![ old_cur.tree_addr[0] ], leaf_mode: ListCursorMode::Insert @@ -398,7 +439,7 @@ impl ListEditor { for x in data.iter() { cur_editor.send_cmd_obj( ReprTree::new_leaf( - (&self.ctx, "( NestedNode )"), + Context::parse(&self.ctx, "NestedNode"), SingletonBuffer::<NestedNode>::new( x.read().unwrap().clone() ).get_port().into() @@ -406,17 +447,20 @@ impl ListEditor { ); } + // fixme: is it oc0 or old_cur ?? if oc0.tree_addr.len() > 1 { cur_editor.goto(TreeCursor { tree_addr: vec![ old_cur.tree_addr[0], -1 ], leaf_mode: ListCursorMode::Insert }); cur_editor.send_cmd_obj(ListCmd::DeleteNexd.into_repr_tree( &self.ctx )); - } else { + } else if oc0.tree_addr.len() > 0 { cur_editor.goto(TreeCursor { tree_addr: vec![ old_cur.tree_addr[0] ], leaf_mode: ListCursorMode::Insert }); + } else { + cur_editor.goto(TreeCursor::none()); } } diff --git a/nested/src/editors/list/nav.rs b/nested/src/editors/list/nav.rs index 88bac81..31d0cc2 100644 --- a/nested/src/editors/list/nav.rs +++ b/nested/src/editors/list/nav.rs @@ -195,6 +195,7 @@ 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) @@ -210,6 +211,7 @@ impl TreeNav for ListEditor { 1 => { if direction.y > 0 { // dn + if cur.tree_addr[0] < self.data.len() as isize { if self.data .get_mut(cur.tree_addr[0] as usize) @@ -219,7 +221,8 @@ impl TreeNav for ListEditor { self.cursor.set(ListCursor { mode: ListCursorMode::Select, idx: Some(cur.tree_addr[0]) - }) + }); + self.set_leaf_mode(cur.leaf_mode); } } diff --git a/nested/src/editors/list/pty_editor.rs b/nested/src/editors/list/pty_editor.rs index bc5dc8a..829aef4 100644 --- a/nested/src/editors/list/pty_editor.rs +++ b/nested/src/editors/list/pty_editor.rs @@ -1,6 +1,6 @@ use { r3vi::{ - view::{OuterViewPort, sequence::*}, + view::{ViewPort, OuterViewPort, sequence::*}, projection::decorate_sequence::*, }, crate::{ @@ -18,23 +18,20 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct PTYListStyle { - style: (String, String, String), - depth: usize + style: (String, String, String) } impl PTYListStyle { - pub fn new(style: (&str, &str, &str), depth: usize) -> PTYListStyle { + pub fn new(style: (&str, &str, &str)) -> PTYListStyle { PTYListStyle { - style: (style.0.into(), style.1.into(), style.2.into()), - depth + style: (style.0.into(), style.1.into(), style.2.into()) } } pub fn get_seg_seq_view(&self, editor: &ListEditor) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> { let seg_seq = ListSegmentSequence::new( editor.get_cursor_port(), - editor.get_data_port(), - self.depth + editor.get_data_port() ); let se = seg_seq.read().unwrap(); se.get_view().map(move |segment| segment.pty_view()) @@ -43,8 +40,7 @@ impl PTYListStyle { pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> { let seg_seq = ListSegmentSequence::new( editor.get_cursor_port(), - editor.get_data_port(), - self.depth + editor.get_data_port() ); let seg_seq = seg_seq.read().unwrap(); @@ -59,7 +55,7 @@ impl PTYListStyle { pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) { node.view = Some( - Self::new(style, node.depth.get()) + Self::new(style) .pty_view( &node.get_edit::<ListEditor>().unwrap().read().unwrap() ) @@ -69,13 +65,15 @@ impl PTYListStyle { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +// todo: rename to CharController + pub struct PTYListController { pub editor: Arc<RwLock<ListEditor>>, split_char: Option<char>, close_char: Option<char>, - depth: usize + depth: OuterViewPort<dyn SingletonView<Item = usize>> } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -85,7 +83,7 @@ impl PTYListController { editor: Arc<RwLock<ListEditor>>, split_char: Option<char>, close_char: Option<char>, - depth: usize + depth: OuterViewPort<dyn SingletonView<Item = usize>> ) -> Self { PTYListController { editor, @@ -113,7 +111,7 @@ 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.get() ))); + let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.depth.clone() ))); node.cmd.set(Some(controller.clone())); node.close_char.set(close_char); @@ -131,10 +129,6 @@ impl PTYListController { self.editor.read().unwrap().get_item() } - pub fn set_depth(&mut self, depth: usize) { - self.depth = depth; - } - pub fn handle_term_event(&mut self, event: &TerminalEvent, _cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { let mut e = self.editor.write().unwrap(); match event { @@ -155,6 +149,7 @@ impl PTYListController { // || Some(c) == child_close_char { e.listlist_split(); + eprintln!("done listlist split"); TreeNavResult::Continue } else if Some(c) == child_close_char { e.goto(TreeCursor::none()); @@ -176,12 +171,12 @@ impl PTYListController { match cur.mode { ListCursorMode::Insert => { - let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth+1).unwrap(); + 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()) { TreeNavResult::Continue => { - e.insert(Arc::new(RwLock::new(new_edit))); + e.insert(Arc::new(RwLock::new(new_edit.clone()))); TreeNavResult::Continue } TreeNavResult::Exit => { @@ -194,12 +189,12 @@ impl PTYListController { let res = item.write().unwrap().send_cmd_obj(cmd_obj.clone()); let child_close_char = item.read().unwrap().close_char.get(); - match res { + match res { TreeNavResult::Continue => TreeNavResult::Continue, TreeNavResult::Exit => { // child editor returned control, probably for meta-char handling.. - if cmd_obj.read().unwrap().get_type().clone() == ctx.type_term_from_str("( Char )").unwrap() { + if cmd_obj.read().unwrap().get_type().clone() == ctx.type_term_from_str("Char").unwrap() { let co = cmd_obj.read().unwrap(); if let Some(cmd_view) = co.get_view::<dyn SingletonView<Item = char>>() { drop(co); @@ -230,13 +225,13 @@ impl ObjCommander for PTYListController { let mut e = self.editor.write().unwrap(); let cmd_type = cmd_obj.read().unwrap().get_type().clone(); - if cmd_type == (&e.ctx, "( ListCmd )").into() - || cmd_type == (&e.ctx, "( NestedNode )").into() + if cmd_type == Context::parse(&e.ctx, "ListCmd").into() + || cmd_type == Context::parse(&e.ctx, "NestedNode").into() { e.send_cmd_obj( cmd_obj ) } - else if cmd_type == (&e.ctx, "( TerminalEvent )").into() { + else if cmd_type == Context::parse(&e.ctx, "TerminalEvent").into() { let co = cmd_obj.read().unwrap(); if let Some(view) = co.get_view::<dyn SingletonView<Item = TerminalEvent>>() { drop( co ); diff --git a/nested/src/editors/list/segment.rs b/nested/src/editors/list/segment.rs index aba00c0..4ae0368 100644 --- a/nested/src/editors/list/segment.rs +++ b/nested/src/editors/list/segment.rs @@ -22,7 +22,6 @@ pub enum ListSegment { InsertCursor, Item { editor: NestedNode, - depth: usize, cur_dist: isize, } } @@ -37,9 +36,8 @@ impl PtySegment for ListSegment { .add_style_front(TerminalStyle::bold(true)) }) } - ListSegment::Item{ editor, depth, cur_dist } => { + ListSegment::Item{ editor, cur_dist } => { let e = editor.clone(); - let d = *depth; let cur_dist = *cur_dist; editor.get_view().map_item(move |_pt, atom| { let c = e.get_cursor(); @@ -50,10 +48,11 @@ impl PtySegment for ListSegment { } 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(d)) + .add_style_back(fg_style_from_depth(e.depth.get_view().get())) }) } } @@ -64,7 +63,6 @@ pub struct ListSegmentSequence { data: Arc<dyn SequenceView<Item = NestedNode>>, cursor: Arc<dyn SingletonView<Item = ListCursor>>, - depth: usize, cur_cursor: ListCursor, port: ViewPort<dyn SequenceView<Item = ListSegment>>, @@ -95,7 +93,6 @@ impl SequenceView for ListSegmentSequence { ListCursorMode::Select => { ListSegment::Item { editor: self.data.get(idx)?, - depth: self.depth, cur_dist: cur - *idx as isize } } @@ -103,7 +100,6 @@ impl SequenceView for ListSegmentSequence { if *idx < cur as usize { ListSegment::Item { editor: self.data.get(idx)?, - depth: self.depth, cur_dist: cur - *idx as isize } } else if *idx == cur as usize { @@ -111,7 +107,6 @@ impl SequenceView for ListSegmentSequence { } else { ListSegment::Item { editor: self.data.get(&(*idx - 1))?, - depth: self.depth, cur_dist: cur - *idx as isize } } @@ -120,7 +115,6 @@ impl SequenceView for ListSegmentSequence { } else { ListSegment::Item { editor: self.data.get(&idx)?, - depth: self.depth, cur_dist: *idx as isize + 1 } }) @@ -131,14 +125,12 @@ impl ListSegmentSequence { pub fn new( cursor_port: OuterViewPort<dyn SingletonView<Item = ListCursor>>, data_port: OuterViewPort<dyn SequenceView<Item = NestedNode>>, - depth: usize ) -> Arc<RwLock<Self>> { let out_port = ViewPort::new(); let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone()); let proj = Arc::new(RwLock::new(ListSegmentSequence { cur_cursor: cursor_port.get_view().get(), port: out_port.clone(), - depth, cursor: proj_helper.new_singleton_arg(0, cursor_port, |s: &mut Self, _msg| { let _old_cursor = s.cur_cursor; diff --git a/nested/src/editors/product/editor.rs b/nested/src/editors/product/editor.rs index 790a38d..d3bdd9a 100644 --- a/nested/src/editors/product/editor.rs +++ b/nested/src/editors/product/editor.rs @@ -9,8 +9,9 @@ use { index_hashmap::* } }, + laddertypes::{TypeTerm}, crate::{ - type_system::{Context, TypeTerm}, + type_system::{Context}, terminal::{ TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalView @@ -202,7 +203,7 @@ impl ObjCommander for ProductEditor { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { let co = cmd_obj.read().unwrap(); let cmd_type = co.get_type().clone(); - let term_event_type = (&self.ctx, "( TerminalEvent )").into(); + let term_event_type = Context::parse(&self.ctx, "TerminalEvent").into(); if cmd_type == term_event_type { if let Some(te_view) = co.get_view::<dyn SingletonView<Item = TerminalEvent>>() { @@ -238,7 +239,7 @@ impl ObjCommander for ProductEditor { } } } else { - let mut e = Context::make_node(&self.ctx, t.clone(), *ed_depth+1).unwrap(); + let mut e = Context::make_node(&self.ctx, t.clone(), r3vi::buffer::singleton::SingletonBuffer::new(*ed_depth).get_port()).unwrap(); *editor = Some(e.clone()); update_segment = true; diff --git a/nested/src/editors/product/nav.rs b/nested/src/editors/product/nav.rs index c339c97..e681111 100644 --- a/nested/src/editors/product/nav.rs +++ b/nested/src/editors/product/nav.rs @@ -71,7 +71,7 @@ impl TreeNav for ProductEditor { e.goto(c.clone()); } else if c.tree_addr.len() > 0 { // create editor - let mut e = Context::make_node(&self.ctx, t.clone(), *ed_depth+1).unwrap(); + let mut e = Context::make_node(&self.ctx, t.clone(), r3vi::buffer::singleton::SingletonBuffer::new(*ed_depth+1).get_port()).unwrap(); *editor = Some(e.clone()); e.goto(c.clone()); } @@ -128,7 +128,7 @@ impl TreeNav for ProductEditor { } else { // create editor - let mut e = Context::make_node(&self.ctx, t.clone(), *ed_depth+1).unwrap(); + let mut e = Context::make_node(&self.ctx, t.clone(), r3vi::buffer::singleton::SingletonBuffer::new(*ed_depth+1).get_port()).unwrap(); *editor = Some(e.clone()); e.goby(direction); } diff --git a/nested/src/editors/product/segment.rs b/nested/src/editors/product/segment.rs index 0e20cb9..0b223f5 100644 --- a/nested/src/editors/product/segment.rs +++ b/nested/src/editors/product/segment.rs @@ -4,8 +4,9 @@ use { OuterViewPort } }, + laddertypes::{TypeTerm}, crate::{ - type_system::{Context, TypeTerm}, + type_system::{Context}, terminal::{ TerminalStyle, TerminalView, make_label diff --git a/nested/src/editors/sum/editor.rs b/nested/src/editors/sum/editor.rs index 24c587e..14b7798 100644 --- a/nested/src/editors/sum/editor.rs +++ b/nested/src/editors/sum/editor.rs @@ -6,10 +6,11 @@ use { sequence::*, } }, + laddertypes::{TypeTerm}, crate::{ terminal::TerminalView, editors::list::ListCursorMode, - type_system::{Context, TypeTerm, ReprTree}, + type_system::{Context, ReprTree}, tree::{TreeNav, TreeCursor, TreeNavResult}, diagnostics::{Diagnostics, Message}, tree::NestedNode, @@ -60,7 +61,7 @@ impl SumEditor { NestedNode::new( ctx.clone(), ReprTree::new_arc(TypeTerm::TypeID(ctx.read().unwrap().get_typeid("Sum").unwrap())), - 0 + r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() ) .set_view(view) .set_editor(editor.clone()) diff --git a/nested/src/editors/typeterm/cmd.rs b/nested/src/editors/typeterm/cmd.rs index f5b9aff..e219cc8 100644 --- a/nested/src/editors/typeterm/cmd.rs +++ b/nested/src/editors/typeterm/cmd.rs @@ -3,8 +3,8 @@ use { view::{singleton::*} }, crate::{ - type_system::{ReprTree}, - editors::{list::{ListEditor, ListCmd}}, + type_system::{Context, ReprTree}, + editors::{list::{ListEditor, ListCmd, ListCursorMode}}, tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, commander::ObjCommander }, @@ -20,7 +20,7 @@ impl ObjCommander for TypeTermEditor { let cmd_obj = co.clone(); let cmd_obj = cmd_obj.read().unwrap(); - if cmd_obj.get_type().clone() == (&self.ctx, "( Char )").into() { + if cmd_obj.get_type().clone() == Context::parse(&self.ctx, "Char") { if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() { let c = cmd_view.get(); @@ -44,7 +44,7 @@ impl ObjCommander for TypeTermEditor { TreeNavResult::Exit } _ => { - self.set_state( State::AnySymbol ); + self.set_state( State::FunSymbol ); self.cur_node.get_mut().goto(TreeCursor::home()); self.send_child_cmd( co ) } @@ -52,71 +52,138 @@ impl ObjCommander for TypeTermEditor { } State::Char => { - match c { - '\'' => { - self.cur_node.get_mut().goto(TreeCursor::none()); + match self.send_child_cmd( co ) { + TreeNavResult::Exit => { + match c { + '\'' => { + self.cur_node.get_mut().goto(TreeCursor::none()); + } + _ => {} + } TreeNavResult::Exit - } - _ => { - self.send_child_cmd( co ) - } + }, + TreeNavResult::Continue => TreeNavResult::Continue } } State::Ladder => { - let res = self.send_child_cmd( co.clone() ); - - match res { - TreeNavResult::Continue => { + + match self.get_cursor().tree_addr.len() { + + // entire term is selected + 0 => { + match c { + '<' => { + self.morph_to_list(State::App); + TreeNavResult::Continue + } + _ => { TreeNavResult::Exit } + } + } + + // entire item selected or insert mode + 1 => { match c { '~' => { - self.normalize_nested_ladder(); + // ignore '~' since we are already in a ladder + // and cant split current item + TreeNavResult::Continue + } + _ => { + self.send_child_cmd( co.clone() ) } - _ => {} } - TreeNavResult::Continue } - TreeNavResult::Exit => { + + // some subterm + _ => { match c { - '~' => TreeNavResult::Continue, - _ => TreeNavResult::Exit + '~' => { + let i0 = self.cur_node.get().get_edit::<ListEditor>().unwrap(); + let cur_it = i0.clone().read().unwrap().get_item().clone(); + if let Some(i) = cur_it { + let cur_tte = i.get_edit::<TypeTermEditor>().unwrap(); + if cur_tte.read().unwrap().state == State::App || cur_tte.read().unwrap().get_cursor().tree_addr.len() > 1 { + self.send_child_cmd( co.clone() ) + } else { + drop(cur_tte); + drop(i); + + self.send_child_cmd( + ListCmd::Split.into_repr_tree( &self.ctx ) + ) + } + } else { + self.send_child_cmd( co.clone() ) + } + } + _ => { + self.send_child_cmd( co.clone() ) + } } } } } State::App => { - let res = self.send_child_cmd( co.clone() ); - match res { - TreeNavResult::Exit => { + match self.get_cursor().tree_addr.len() { + + // entire Term is selected + 0 => { + match c { '~' => { - self.previous_item_into_ladder(); + self.morph_to_list(State::Ladder); + self.goto(TreeCursor { + tree_addr: vec![ -1 ], + leaf_mode: ListCursorMode::Insert + }); TreeNavResult::Continue - }, - _ => {TreeNavResult::Exit} + } + '<' => { + self.morph_to_list(State::App); + TreeNavResult::Continue + } + _ => { + TreeNavResult::Exit + } } - }, - TreeNavResult::Continue => { - match c { - '>'| - ' ' => { - let i = self.cur_node.get().get_edit::<ListEditor>().unwrap(); - let i = i.read().unwrap(); - if let Some(i) = i.get_item() { - let tte = i.get_edit::<TypeTermEditor>().unwrap(); - let mut tte = tte.write().unwrap(); - if tte.state == State::Ladder { - tte.normalize_singleton(); - } + }, + + // some item is selected + _ => { + match self.send_child_cmd( co.clone() ) { + TreeNavResult::Exit => { + match c { + '~' => { + self.previous_item_into_ladder(); + TreeNavResult::Continue + }, + _ => {TreeNavResult::Exit} } }, - _ => {} + TreeNavResult::Continue => { + match c { + '>'| + ' ' => { + let i = self.cur_node.get().get_edit::<ListEditor>().unwrap(); + let i = i.read().unwrap(); + if let Some(i) = i.get_item() { + let tte = i.get_edit::<TypeTermEditor>().unwrap(); + let mut tte = tte.write().unwrap(); + + if tte.state == State::Ladder { + tte.normalize_singleton(); + } + } + }, + _ => {} + } + TreeNavResult::Continue + } } - - TreeNavResult::Continue } } } @@ -128,11 +195,19 @@ impl ObjCommander for TypeTermEditor { match res { TreeNavResult::Exit => { match c { + '<' => { + self.goto(TreeCursor::none()); + self.morph_to_list(State::App); + TreeNavResult::Continue + } '~' => { - self.morph_to_ladder(); + self.morph_to_list(State::Ladder); + self.set_addr(0); + self.dn(); self.send_cmd_obj( ListCmd::Split.into_repr_tree( &self.ctx ) - ) + ); + TreeNavResult::Continue } _ => { TreeNavResult::Exit @@ -156,11 +231,11 @@ impl ObjCommander for TypeTermEditor { match &self.state { State::Any => { let cmd_repr = co.read().unwrap(); - if cmd_repr.get_type().clone() == (&self.ctx, "( NestedNode )").into() { + if cmd_repr.get_type().clone() == Context::parse(&self.ctx, "NestedNode") { if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = NestedNode>>() { let node = view.get(); - if node.data.read().unwrap().get_type().clone() == (&self.ctx, "( Char )").into() { + if node.data.read().unwrap().get_type().clone() == Context::parse(&self.ctx, "Char") { self.set_state( State::AnySymbol ); } else { self.set_state( State::Ladder ); @@ -184,7 +259,6 @@ impl ObjCommander for TypeTermEditor { let res = self.send_child_cmd( co.clone() ); self.normalize_empty(); - if let Some(cmd) = co.read().unwrap().get_view::<dyn SingletonView<Item = ListCmd>>() { match cmd.get() { ListCmd::Split => { diff --git a/nested/src/editors/typeterm/ctx.rs b/nested/src/editors/typeterm/ctx.rs index 8036e72..4ad5b55 100644 --- a/nested/src/editors/typeterm/ctx.rs +++ b/nested/src/editors/typeterm/ctx.rs @@ -1,8 +1,16 @@ use { + r3vi::{ + view::{OuterViewPort, singleton::*} + }, + laddertypes::{TypeTerm}, crate::{ - type_system::{Context, TypeTerm, MorphismTypePattern}, + type_system::{Context, MorphismTypePattern}, terminal::{TerminalStyle, TerminalProjections}, - editors::{list::{PTYListStyle, PTYListController}, typeterm::{State, TypeTermEditor}} + editors::{ + list::{PTYListStyle, PTYListController, ListEditor, ListSegmentSequence}, + typeterm::{State, TypeTermEditor} + }, + PtySegment }, std::{sync::{Arc, RwLock}}, cgmath::{Point2} @@ -25,7 +33,7 @@ pub fn init_ctx(ctx: &mut Context) { let ctx : Arc<RwLock<Context>> = Arc::new(RwLock::new(Context::with_parent(Some(node.ctx.clone())))); ctx.write().unwrap().meta_chars.push('~'); - let new_node = TypeTermEditor::with_node( ctx, node.depth.get(), node.clone(), State::Any ); + let new_node = TypeTermEditor::with_node( ctx, node.clone(), State::Any ); Some(new_node) })); @@ -34,14 +42,29 @@ pub fn init_ctx(ctx: &mut Context) { Arc::new(|mut node, _dst_type: _| { PTYListController::for_node( &mut node, Some('~'), None ); - let vertical_view = false; + let vertical_view = true; if vertical_view { let editor = node.get_edit::<crate::editors::list::ListEditor>().unwrap(); let mut e = editor.write().unwrap(); - let seg_view = PTYListStyle::new( ("","~",""), node.depth.get() ).get_seg_seq_view( &mut e ); + let seg_view = PTYListStyle::new( ("","~","") ).get_seg_seq_view( &mut e ); node = node.set_view( - seg_view.to_grid_vertical().flatten() + seg_view.to_grid_vertical() + .map_item( + |pt,x| + if pt.y > 0 { + r3vi::buffer::vec::VecBuffer::with_data(vec![ + crate::terminal::make_label("~"), + x.clone() + ]) + .get_port() + .to_sequence() + .to_grid_horizontal() + .flatten() + } else { + x.clone() + } + ).flatten() ); } else { PTYListStyle::for_node( &mut node, ("","~","") ); @@ -71,6 +94,7 @@ pub fn init_ctx(ctx: &mut Context) { Arc::new(|mut node, _dst_type:_| { PTYListController::for_node( &mut node, Some(' '), None ); PTYListStyle::for_node( &mut node, ("","","") ); + Some(node) })); @@ -80,11 +104,6 @@ pub fn init_ctx(ctx: &mut Context) { PTYListController::for_node( &mut node, Some(' '), None ); PTYListStyle::for_node( &mut node, ("","","") ); - // display variables blue color - if let Some(v) = node.view { - node.view = Some( - v.map_item(|_i,p| p.add_style_front(TerminalStyle::fg_color((5, 120, 240))))); - } Some(node) })); @@ -97,6 +116,7 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_morphism( MorphismTypePattern { src_tyid: ctx.get_typeid("Char"), dst_tyid: ctx.get_typeid("Type::Lit::Char").unwrap() }, Arc::new(|mut node, _dst_type:_| { + node.ctx.write().unwrap().meta_chars = vec![ '\'' ]; let mut grid = r3vi::buffer::index_hashmap::IndexBuffer::new(); grid.insert_iter( @@ -117,7 +137,7 @@ pub fn init_ctx(ctx: &mut Context) { })); ctx.add_node_ctor("Type", Arc::new( - |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| { + |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/nested/src/editors/typeterm/mod.rs index d018c81..d15cbb4 100644 --- a/nested/src/editors/typeterm/mod.rs +++ b/nested/src/editors/typeterm/mod.rs @@ -6,10 +6,12 @@ pub use ctx::init_ctx; use { r3vi::{ + view::{OuterViewPort, singleton::*}, buffer::{singleton::*} }, + laddertypes::{TypeID, TypeTerm}, crate::{ - type_system::{Context, TypeID, TypeTerm, ReprTree}, + type_system::{Context, ReprTree}, editors::{list::{ListCursorMode, ListEditor, ListCmd}}, tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, commander::ObjCommander @@ -36,8 +38,9 @@ pub struct TypeTermEditor { data: Arc<RwLock<ReprTree>>, close_char: SingletonBuffer<Option<char>>, spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>, + depth: OuterViewPort<dyn SingletonView<Item = usize>>, - depth: usize, + buf: SingletonBuffer< TypeTerm >, // editing/parsing state state: State, @@ -47,8 +50,8 @@ pub struct TypeTermEditor { } impl TypeTermEditor { - pub fn from_type_term(ctx: Arc<RwLock<Context>>, depth: usize, term: &TypeTerm) -> NestedNode { - let mut node = TypeTermEditor::new_node(ctx.clone(), depth); + pub fn from_type_term(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>, term: &TypeTerm) -> NestedNode { + let mut node = TypeTermEditor::new_node(ctx.clone(), depth.clone()); node.goto(TreeCursor::home()); match term { @@ -74,11 +77,11 @@ impl TypeTermEditor { let parent_ctx = editor.read().unwrap().cur_node.get().ctx.clone(); for x in args.iter() { - let arg_node = TypeTermEditor::from_type_term( parent_ctx.clone(), depth+1, x ); + let arg_node = TypeTermEditor::from_type_term( parent_ctx.clone(), depth.map(|d| d+1), x ); node.send_cmd_obj( ReprTree::new_leaf( - (&ctx, "( NestedNode )"), + Context::parse(&ctx, "NestedNode"), SingletonBuffer::new(arg_node).get_port().into() ) ); @@ -92,11 +95,11 @@ impl TypeTermEditor { let parent_ctx = editor.read().unwrap().cur_node.get().ctx.clone(); for x in args.iter() { - let arg_node = TypeTermEditor::from_type_term( parent_ctx.clone(), depth+1, x ); + let arg_node = TypeTermEditor::from_type_term( parent_ctx.clone(), depth.map(|d| d+1), x ); node.send_cmd_obj( ReprTree::new_leaf( - (&ctx, "( NestedNode )"), + Context::parse(&ctx, "NestedNode"), SingletonBuffer::new(arg_node).get_port().into() ) ); @@ -122,7 +125,7 @@ impl TypeTermEditor { editor.send_cmd_obj(ReprTree::from_char(&ctx, *c)); } } - + node.goto(TreeCursor::none()); node } @@ -130,38 +133,37 @@ impl TypeTermEditor { fn set_state(&mut self, new_state: State) { let mut node = match new_state { State::Any => { - Context::make_node( &self.ctx, (&self.ctx, "( List Char )").into(), self.depth ).unwrap() - .morph( (&self.ctx, "( Type::Sym )").into() ) - + Context::make_node( &self.ctx, Context::parse(&self.ctx, "<List Char>"), self.depth.map(|x| x) ).unwrap() + .morph( Context::parse(&self.ctx, "Type::Sym") ) } State::App => { - Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), self.depth ).unwrap() - .morph( (&self.ctx, "( Type::App )").into() ) + Context::make_node( &self.ctx, Context::parse(&self.ctx, "<List Type>"), self.depth.map(|x| x) ).unwrap() + .morph( Context::parse(&self.ctx, "Type::App") ) } State::Ladder => { - Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), self.depth ).unwrap() - .morph( (&self.ctx, "( Type::Ladder )").into() ) + Context::make_node( &self.ctx, Context::parse(&self.ctx, "<List Type>"), self.depth.map(|x| x) ).unwrap() + .morph( Context::parse(&self.ctx, "Type::Ladder") ) } State::AnySymbol => { - Context::make_node( &self.ctx, (&self.ctx, "( List Char )").into(), self.depth ).unwrap() - .morph( (&self.ctx, "( Type::Sym )").into() ) + Context::make_node( &self.ctx, Context::parse(&self.ctx, "<List Char>"), self.depth.map(|x| x) ).unwrap() + .morph( Context::parse(&self.ctx, "Type::Sym") ) }, State::FunSymbol => { - Context::make_node( &self.ctx, (&self.ctx, "( List Char )").into(), self.depth ).unwrap() - .morph( (&self.ctx, "( Type::Sym::Fun )").into() ) + Context::make_node( &self.ctx, Context::parse(&self.ctx, "<List Char>"), self.depth.map(|x| x) ).unwrap() + .morph( Context::parse(&self.ctx, "Type::Sym::Fun") ) }, State::VarSymbol => { - Context::make_node( &self.ctx, (&self.ctx, "( List Char )").into(), self.depth ).unwrap() - .morph( (&self.ctx, "( Type::Sym::Var )").into() ) + Context::make_node( &self.ctx, Context::parse(&self.ctx, "<List Char>"), self.depth.map(|x| x) ).unwrap() + .morph( Context::parse(&self.ctx, "Type::Sym::Var") ) } State::Num => { crate::editors::integer::PosIntEditor::new(self.ctx.clone(), 10) .into_node() - .morph( (&self.ctx, "( Type::Lit::Num )").into() ) + .morph( Context::parse(&self.ctx, "Type::Lit::Num") ) } State::Char => { - Context::make_node( &self.ctx, (&self.ctx, "( Char )").into(), self.depth ).unwrap() - .morph( (&self.ctx, "( Type::Lit::Char )").into() ) + Context::make_node( &self.ctx, Context::parse(&self.ctx, "Char"), self.depth.map(|x| x) ).unwrap() + .morph( Context::parse(&self.ctx, "Type::Lit::Char") ) } }; @@ -173,36 +175,37 @@ impl TypeTermEditor { self.state = new_state; } - pub fn new_node(ctx: Arc<RwLock<Context>>, depth: usize) -> NestedNode { + pub fn new_node(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode { let ctx : Arc<RwLock<Context>> = Arc::new(RwLock::new(Context::with_parent(Some(ctx)))); ctx.write().unwrap().meta_chars.push('~'); + ctx.write().unwrap().meta_chars.push('<'); - let mut symb_node = Context::make_node( &ctx, (&ctx, "( List Char )").into(), depth ).unwrap(); - symb_node = symb_node.morph( (&ctx, "( Type::Sym )").into() ); + let mut symb_node = Context::make_node( &ctx, Context::parse(&ctx, "<List Char>"), depth ).unwrap(); + symb_node = symb_node.morph( Context::parse(&ctx, "Type::Sym") ); Self::with_node( ctx.clone(), - depth, symb_node, State::Any ) } - fn with_node(ctx: Arc<RwLock<Context>>, depth: usize, node: NestedNode, state: State) -> NestedNode { - let _buffer = SingletonBuffer::<Option<TypeTerm>>::new( None ); + fn with_node(ctx: Arc<RwLock<Context>>, cur_node: NestedNode, state: State) -> NestedNode { + let buf = SingletonBuffer::<TypeTerm>::new( TypeTerm::unit() ); let data = Arc::new(RwLock::new(ReprTree::new( - (&ctx, "( Type )") + Context::parse(&ctx, "Type") ))); let editor = TypeTermEditor { ctx: ctx.clone(), data: data.clone(), state, - cur_node: SingletonBuffer::new(node), + buf, + cur_node: SingletonBuffer::new(cur_node.clone()), close_char: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())), - depth + depth: cur_node.depth.clone() }; let view = editor.cur_node @@ -215,16 +218,16 @@ impl TypeTermEditor { let _cc = editor.cur_node.get().close_char; let editor = Arc::new(RwLock::new(editor)); - let mut node = NestedNode::new(ctx, data, depth) + let mut super_node = NestedNode::new(ctx, data, cur_node.depth) .set_view(view) .set_nav(editor.clone()) .set_cmd(editor.clone()) .set_editor(editor.clone()); - editor.write().unwrap().close_char = node.close_char.clone(); - node.spillbuf = editor.read().unwrap().spillbuf.clone(); - - node + editor.write().unwrap().close_char = super_node.close_char.clone(); + super_node.spillbuf = editor.read().unwrap().spillbuf.clone(); + + super_node } fn forward_spill(&mut self) { @@ -288,71 +291,34 @@ impl TypeTermEditor { let subladder_list_edit = subladder_list_edit.read().unwrap(); if subladder_list_edit.data.len() == 0 { - self.set_state( State::Any ); } } - /* unwrap a ladder if it only contains one element */ pub fn normalize_singleton(&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(); - let subladder_list_edit = subladder_list_edit.read().unwrap(); - if subladder_list_edit.data.len() == 1 { - let it_node = subladder_list_edit.data.get(0); - let it_node = it_node.read().unwrap(); - if it_node.get_type() == (&self.ctx, "( Type )").into() { - let other_tt = it_node.get_edit::<TypeTermEditor>().unwrap(); + if self.state == State::Ladder { + let subladder_list_node = self.cur_node.get().clone(); + let subladder_list_edit = subladder_list_node.get_edit::<ListEditor>().unwrap(); - let mut other_tt = other_tt.write().unwrap(); + let subladder_list_edit = subladder_list_edit.read().unwrap(); + if subladder_list_edit.data.len() == 1 { + let it_node = subladder_list_edit.data.get(0); + let it_node = it_node.read().unwrap(); + if it_node.get_type() == Context::parse(&self.ctx, "Type") { + let other_tt = it_node.get_edit::<TypeTermEditor>().unwrap(); - other_tt.normalize_singleton(); + let mut other_tt = other_tt.write().unwrap(); - self.close_char.set(other_tt.close_char.get()); - self.cur_node.set(other_tt.cur_node.get()); - self.state = other_tt.state; - } - } else { - } - } + other_tt.normalize_singleton(); + other_tt.depth.0.set_view( self.depth.map(|x| x).get_view() ); - /* flatten ladder of ladders into one ladder editor - */ - pub fn normalize_nested_ladder(&mut self) { - let mut subladder_list_node = self.cur_node.get().clone(); - let subladder_list_edit = subladder_list_node.get_edit::<ListEditor>().unwrap(); - - let item = subladder_list_edit.write().unwrap().get_item().clone(); - - if let Some(it_node) = item { - if it_node.get_type() == (&self.ctx, "( Type )").into() { - let other_tt = it_node.get_edit::<TypeTermEditor>().unwrap(); - - if other_tt.write().unwrap().state == State::Ladder { - let other = other_tt.read().unwrap().cur_node.get().get_edit::<ListEditor>().unwrap(); - let buf = other.read().unwrap().data.clone(); - - subladder_list_edit.write().unwrap().up(); - subladder_list_edit.write().unwrap().up(); - subladder_list_node.send_cmd_obj( - ListCmd::DeleteNexd.into_repr_tree( &self.ctx ) - ); - - if subladder_list_edit.read().unwrap().get_cursor_warp().tree_addr.len() > 0 { - if subladder_list_edit.read().unwrap().get_cursor_warp().tree_addr[0] == -1 { - subladder_list_edit.write().unwrap().delete_nexd(); - } - } - - let l = buf.len(); - for i in 0..l { - subladder_list_edit.write().unwrap().insert( buf.get(i) ); - } - subladder_list_node.dn(); + self.close_char.set(other_tt.close_char.get()); + self.cur_node.set(other_tt.cur_node.get()); + self.state = other_tt.state; } } } @@ -371,96 +337,58 @@ impl TypeTermEditor { app_edit.delete_nexd(); } + // select previous element app_edit.goto(TreeCursor{ tree_addr: vec![ cur.tree_addr[0]-1 ], leaf_mode: ListCursorMode::Select }); - - if let Some(item_node) = app_edit.get_item() { + + // get selected element + if let Some(item_node) = app_edit.get_item() { let item_typterm = item_node.get_edit::<TypeTermEditor>().expect("typetermedit"); let mut item_typterm = item_typterm.write().unwrap(); - match item_typterm.state { - - // if item at cursor is Ladder - State::Ladder => { - drop(item_typterm); - - app_edit.dn(); - app_edit.qnexd(); - } - _ => { - item_typterm.goto(TreeCursor::none()); - drop(item_typterm); - - // else create new ladder - let mut list_node = Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), self.depth ).unwrap(); - list_node = list_node.morph( (&self.ctx, "( Type::Ladder )").into() ); - - let mut new_node = TypeTermEditor::with_node( - self.ctx.clone(), - self.depth, - list_node, - State::Ladder - ); - - // insert old node and split - new_node.goto(TreeCursor::home()); - - new_node.send_cmd_obj( - ReprTree::new_leaf( - (&self.ctx, "( NestedNode )"), - SingletonBuffer::<NestedNode>::new( item_node ).get_port().into() - ) - ); - - *app_edit.get_item_mut().unwrap().write().unwrap() = new_node; - app_edit.dn(); - } + if item_typterm.state != State::Ladder { + item_typterm.morph_to_list( State::Ladder ); } + + item_typterm.goto(TreeCursor { + tree_addr: vec![ -1 ], + leaf_mode: ListCursorMode::Insert + }); } } } - - /* replace with new ladder node with self as first element + + /* replace with new list-node (ladder/app) with self as first element */ - pub fn morph_to_ladder(&mut self) { + pub(super) fn morph_to_list(&mut self, state: State) { eprintln!("morph into ladder"); - let old_node = self.cur_node.get().clone(); - *old_node.depth.get_mut() += 1; + let mut old_node = self.cur_node.get().clone(); + + /* reconfigure current node to display new_node list-editor + */ + self.set_state( state ); /* create a new NestedNode with TerminaltypeEditor, * that has same state & child-node as current node. */ - let old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), self.depth ); + 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() ); + let old_edit_clone = old_edit_node.get_edit::<TypeTermEditor>().unwrap(); old_edit_clone.write().unwrap().set_state( self.state ); - old_edit_clone.write().unwrap().close_char.set( old_node.close_char.get() ); old_edit_clone.write().unwrap().cur_node.set( old_node ); - /* create new list-edit node for the ladder - */ - let mut new_node = Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), self.depth ).unwrap(); - new_node = new_node.morph( (&self.ctx, "( Type::Ladder )").into() ); - - /* reconfigure current node to display new_node list-editor - */ - self.close_char.set(new_node.close_char.get()); - self.cur_node.set(new_node); - self.state = State::Ladder; - /* insert old node and split */ self.goto(TreeCursor::home()); - self.send_cmd_obj( + self.send_child_cmd( ReprTree::new_leaf( - (&self.ctx, "( NestedNode )"), + Context::parse(&self.ctx, "NestedNode"), SingletonBuffer::new( old_edit_node ).get_port().into() ) ); - - self.set_addr(0); - self.dn(); } } diff --git a/nested/src/editors/typeterm/nav.rs b/nested/src/editors/typeterm/nav.rs index 0d3f970..6fb7bf1 100644 --- a/nested/src/editors/typeterm/nav.rs +++ b/nested/src/editors/typeterm/nav.rs @@ -42,4 +42,3 @@ impl TreeNav for TypeTermEditor { self.cur_node.get_mut().goto(new_cur) } } - diff --git a/nested/src/tree/cursor.rs b/nested/src/tree/cursor.rs index 934be6d..9caa659 100644 --- a/nested/src/tree/cursor.rs +++ b/nested/src/tree/cursor.rs @@ -24,6 +24,17 @@ impl TreeCursor { tree_addr: vec![], } } + + pub fn get_subcursor(&self, depth: usize) -> TreeCursor { + TreeCursor { + leaf_mode: self.leaf_mode, + tree_addr: if depth < self.tree_addr.len() { + self.tree_addr[ depth.. ].iter().cloned().collect() + } else { + vec![] + } + } + } } impl Default for TreeCursor { diff --git a/nested/src/tree/nav.rs b/nested/src/tree/nav.rs index 488e26b..9d85cdd 100644 --- a/nested/src/tree/nav.rs +++ b/nested/src/tree/nav.rs @@ -21,10 +21,10 @@ use { cgmath::Vector2, }; -#[derive(Clone, Copy, Eq, PartialEq)] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] pub enum TreeNavResult { Continue, Exit } -#[derive(Clone, Copy, Eq, PartialEq)] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] pub enum TreeHeightOp { P, Q, Max } pub trait TreeNav { @@ -181,3 +181,4 @@ pub trait TreeNav { } } + diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs index 2e81ae3..1406c96 100644 --- a/nested/src/tree/node.rs +++ b/nested/src/tree/node.rs @@ -5,8 +5,9 @@ use { view::{View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*}, buffer::{singleton::*} }, + laddertypes::{TypeTerm}, crate::{ - type_system::{ReprTree, Context, TypeTerm}, + type_system::{ReprTree, Context}, terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult, TerminalAtom}, diagnostics::{Diagnostics, Message}, tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp}, @@ -32,18 +33,15 @@ struct NestedNodeEdit { /// abstract editor pub editor: SingletonBuffer< Option< Arc<dyn Any + Send + Sync> > ->, + >, - pub input_buf:: VecBuffer< NestedNode >, - pub output_buf: VecBuffer< NestedNode >, + pub spillbuf: VecBuffer< NestedNode >, /// commander & navigation pub cmd: SingletonBuffer< Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> > >, - pub close_char: SingletonBuffer< - Option< char > - >, + pub close_char: SingletonBuffer< Option< char > >, // could be replaced by cmd when TreeNav -CmdObjects are used pub tree_nav: SingletonBuffer< @@ -82,16 +80,13 @@ pub struct NestedNode { pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >, /// depth - pub depth: SingletonBuffer< usize >, + pub depth: OuterViewPort< dyn SingletonView<Item = usize> >, /// abstract editor pub editor: SingletonBuffer< Option< Arc<dyn Any + Send + Sync> > >, - /* TODO: - * - spill buffer (contains overflowing elements as well as 'split-off' parts) - */ pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>, /// commander & navigation @@ -107,13 +102,13 @@ pub struct NestedNode { } impl NestedNode { - pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: usize) -> Self { + pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self { NestedNode { ctx, data, view: None, diag: None, - depth: SingletonBuffer::new(depth), + depth, editor: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())), cmd: SingletonBuffer::new(None), @@ -130,10 +125,10 @@ impl NestedNode { NestedNode::new( ctx.clone(), ReprTree::new_leaf( - (&ctx, "( Char )"), + Context::parse(&ctx, "Char"), buf.get_port().into() ), - 0 + SingletonBuffer::new(0).get_port() ) .set_view(buf.get_port() .map(|c| TerminalAtom::from(c)) @@ -200,7 +195,7 @@ impl NestedNode { 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| ((&ctx, s)).into()); + 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() @@ -262,7 +257,7 @@ impl TerminalEditor for NestedNode { 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(), + self.ctx.read().unwrap().type_term_from_str("TerminalEvent").unwrap(), AnyOuterViewPort::from(buf.get_port()) )); } diff --git a/nested/src/tree/treetype.rs b/nested/src/tree/treetype.rs index 9fd9ae3..9f66849 100644 --- a/nested/src/tree/treetype.rs +++ b/nested/src/tree/treetype.rs @@ -1,14 +1,14 @@ use { + laddertypes::{TypeTerm, TypeID}, crate::{ - type_system::{TypeTerm, TypeID}, tree::{TreeAddr} } }; pub trait TreeType { - fn get_type(&self, _addr: &TreeAddr) -> TypeTerm { - TypeTerm::new(TypeID::Var(0)) + fn get_type(&self, addr: &TreeAddr) -> Vec<TypeTerm> { + vec![] } } diff --git a/nested/src/type_system/context.rs b/nested/src/type_system/context.rs index 7e57eb9..bf4f8c4 100644 --- a/nested/src/type_system/context.rs +++ b/nested/src/type_system/context.rs @@ -1,6 +1,8 @@ use { + r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, + laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ - type_system::{TypeDict, TypeTerm, TypeID, ReprTree}, + type_system::{ReprTree}, tree::NestedNode }, std::{ @@ -134,12 +136,6 @@ impl Default for Context { } } -impl Into<TypeTerm> for (&Arc<RwLock<Context>>, &str) { - fn into(self) -> TypeTerm { - self.0.read().unwrap().type_term_from_str(self.1).expect("could not parse type term") - } -} - impl Context { pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self { Context { @@ -173,6 +169,10 @@ impl Context { } } + pub fn parse(ctx: &Arc<RwLock<Self>>, s: &str) -> TypeTerm { + ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term") + } + pub fn add_typename(&mut self, tn: &str) -> TypeID { self.type_dict.write().unwrap().add_typename(tn.to_string()) } @@ -195,6 +195,18 @@ impl Context { TypeTerm::TypeID(id) => { self.list_types.contains(id) } + TypeTerm::Ladder(args) | + TypeTerm::App(args) => { + if args.len() > 0 { + if self.is_list_type(&args[0]) { + true + } else { + false + } + } else { + false + } + } _ => false } } @@ -221,15 +233,15 @@ impl Context { } } - pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> { - self.type_dict.read().unwrap().type_term_from_str(&tn) + pub fn type_term_from_str(&self, tn: &str) -> Result<TypeTerm, laddertypes::parser::ParseError> { + self.type_dict.write().unwrap().parse(&tn) } pub fn type_term_to_str(&self, t: &TypeTerm) -> String { - self.type_dict.read().unwrap().type_term_to_str(&t) + 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, usize) -> Option<NestedNode> + Send + Sync>) { + 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(); @@ -248,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.get()) + mk_editor(node.ctx.clone(), dst_type, node.depth) })); } @@ -275,7 +287,7 @@ impl Context { } } - pub fn make_node(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<NestedNode> { + 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() @@ -284,7 +296,6 @@ impl Context { /* create new context per node ?? too heavy.. whats the reason? TODO */ let new_ctx = Arc::new(RwLock::new(Context::with_parent(Some(ctx.clone())))); - let _new_depth = depth; mk_node( NestedNode::new(new_ctx, ReprTree::new_arc(type_term.clone()), depth), @@ -320,10 +331,10 @@ impl Context { /// 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.read().unwrap() - .type_term_from_str(typename).unwrap(); + .type_dict.write().unwrap() + .parse(typename).unwrap(); - if let Some(node) = Context::make_node(&ctx, type_tag, 0) { + if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) { ctx.write().unwrap().nodes.insert(name, node); } } diff --git a/nested/src/type_system/dict.rs b/nested/src/type_system/dict.rs deleted file mode 100644 index b8fd44c..0000000 --- a/nested/src/type_system/dict.rs +++ /dev/null @@ -1,73 +0,0 @@ -use { - crate::{ - utils::Bimap, - type_system::{TypeTerm} - } -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Eq, PartialEq, Hash, Clone, Debug)] -pub enum TypeID { - Fun(u64), - Var(u64) -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct TypeDict { - typenames: Bimap<String, TypeID>, - type_lit_counter: u64, - type_var_counter: u64, -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl TypeDict { - pub fn new() -> Self { - TypeDict { - typenames: Bimap::new(), - type_lit_counter: 0, - type_var_counter: 0, - } - } - - pub fn add_varname(&mut self, tn: String) -> TypeID { - let tyid = TypeID::Var(self.type_var_counter); - self.type_var_counter += 1; - self.typenames.insert(tn, tyid.clone()); - tyid - } - - pub fn add_typename(&mut self, tn: String) -> TypeID { - let tyid = TypeID::Fun(self.type_lit_counter); - self.type_lit_counter += 1; - self.typenames.insert(tn, tyid.clone()); - tyid - } - - pub fn add_synonym(&mut self, new: String, old: String) { - if let Some(tyid) = self.get_typeid(&old) { - self.typenames.insert(new, tyid); - } - } - - pub fn get_typename(&self, tid: &TypeID) -> Option<String> { - self.typenames.my.get(tid).cloned() - } - - pub fn get_typeid(&self, tn: &String) -> Option<TypeID> { - self.typenames.mλ.get(tn).cloned() - } - - pub fn type_term_from_str(&self, typename: &str) -> Option<TypeTerm> { - TypeTerm::from_str(typename, &self.typenames.mλ) - } - - pub fn type_term_to_str(&self, term: &TypeTerm) -> String { - term.to_str(&self.typenames.my) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - diff --git a/nested/src/type_system/ladder.rs b/nested/src/type_system/ladder.rs deleted file mode 100644 index ca7fef0..0000000 --- a/nested/src/type_system/ladder.rs +++ /dev/null @@ -1,71 +0,0 @@ -use { - crate::type_system::{TypeTerm, TypeID}, - std::collections::HashMap -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone, Eq, PartialEq, Hash, Debug)] -pub struct TypeLadder(pub Vec<TypeTerm>); - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl From<Vec<TypeTerm>> for TypeLadder { - fn from(l: Vec<TypeTerm>) -> Self { - TypeLadder(l) - } -} - -impl From<TypeTerm> for TypeLadder { - fn from(l: TypeTerm) -> Self { - TypeLadder(vec![ l ]) - } -} - -impl TypeLadder { - /// if compatible, returns the number of descents neccesary - pub fn is_compatible_with(&self, other: &TypeLadder) -> Option<usize> { - if let Some(other_top_type) = other.0.first() { - for (i, t) in self.0.iter().enumerate() { - if t == other_top_type { - return Some(i); - } - } - - None - } else { - None - } - } - - pub fn is_matching_repr(&self, other: &TypeLadder) -> Result<usize, Option<(usize, usize)>> { - if let Some(start) = self.is_compatible_with(other) { - for (i, (t1, t2)) in self.0.iter().skip(start).zip(other.0.iter()).enumerate() { - if t1 != t2 { - return Err(Some((start, i))); - } - } - - Ok(start) - } else { - Err(None) - } - } - - pub fn to_str1(&self, names: &HashMap<TypeID, String>) -> String { - let mut s = String::new(); - let mut first = true; - - for t in self.0.iter() { - if !first { - s = s + "~"; - } - first = false; - s = s + &t.to_str(names); - } - s - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - diff --git a/nested/src/type_system/mod.rs b/nested/src/type_system/mod.rs index f52f6ef..6d52a5b 100644 --- a/nested/src/type_system/mod.rs +++ b/nested/src/type_system/mod.rs @@ -1,15 +1,8 @@ pub mod context; - -pub mod dict; -pub mod term; -//pub mod ladder; pub mod repr_tree; pub use { - dict::*, -// ladder::*, - repr_tree::*, - term::*, - context::{Context, MorphismMode, MorphismType, MorphismTypePattern} + context::{Context, MorphismMode, MorphismType, MorphismTypePattern}, + repr_tree::ReprTree }; diff --git a/nested/src/type_system/repr_tree.rs b/nested/src/type_system/repr_tree.rs index eeeb8cf..611565c 100644 --- a/nested/src/type_system/repr_tree.rs +++ b/nested/src/type_system/repr_tree.rs @@ -1,7 +1,8 @@ use { r3vi::view::{AnyOuterViewPort, OuterViewPort, View}, + laddertypes::{TypeTerm}, crate::{ - type_system::{TypeTerm, Context} + type_system::{Context} }, std::{ collections::HashMap, @@ -50,7 +51,7 @@ impl ReprTree { 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( - (ctx, "( Char )"), + Context::parse(ctx, "Char"), buf.get_port().into() ) } diff --git a/nested/src/type_system/term.rs b/nested/src/type_system/term.rs deleted file mode 100644 index cb0cce4..0000000 --- a/nested/src/type_system/term.rs +++ /dev/null @@ -1,351 +0,0 @@ -use { - crate::{type_system::{TypeID}}, - std::collections::HashMap -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub enum TypeTerm { - - /* Atomic Terms */ - - // Base types from dictionary - TypeID(TypeID), - - // Literals - Num(i64), - Char(char), - - - - /* Complex Terms */ - - // Type Parameters - // avoid currying to save space & indirection - App(Vec< TypeTerm >), - - // Type Ladders - Ladder(Vec< TypeTerm >), -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl TypeTerm { - pub fn new(id: TypeID) -> Self { - TypeTerm::TypeID(id) - } - - pub fn arg(&mut self, t: impl Into<TypeTerm>) -> &mut Self { - match self { - TypeTerm::App(args) => { - args.push(t.into()); - } - - _ => { - *self = TypeTerm::App(vec![ - self.clone(), - t.into() - ]) - } - } - - self - } - - pub fn num_arg(&mut self, v: i64) -> &mut Self { - self.arg(TypeTerm::Num(v)) - } - - pub fn char_arg(&mut self, c: char) -> &mut Self { - self.arg(TypeTerm::Char(c)) - } - - /// transform term to have at max 2 entries in Application list - pub fn curry(&self) -> Self { - match self { - TypeTerm::App(head) => { - let mut head = head.clone(); - if head.len() > 2 { - let mut tail = head.split_off(2); - - TypeTerm::App(vec![ - TypeTerm::App(head), - if tail.len() > 1 { - TypeTerm::App(tail).curry() - } else { - tail.remove(0) - } - ]) - } else { - TypeTerm::App(head) - } - } - - TypeTerm::Ladder(l) => { - TypeTerm::Ladder( l.iter().map(|x| x.curry()).collect() ) - } - - atom => { atom.clone() } - } - } - - /// summarize all curried applications into one vec - pub fn decurry(&mut self) -> &mut Self { - match self { - TypeTerm::App(args) => { - if args.len() > 0 { - let mut a0 = args.remove(0); - a0.decurry(); - match a0 { - TypeTerm::App(sub_args) => { - for (i,x) in sub_args.into_iter().enumerate() { - args.insert(i, x); - } - } - other => { args.insert(0, other); } - } - } - } - TypeTerm::Ladder(args) => { - for x in args.iter_mut() { - x.decurry(); - } - } - _ => {} - } - - self - } - - /// does the type contain ladders (false) or is it 'flat' (true) ? - pub fn is_flat(&self) -> bool { - match self { - TypeTerm::TypeID(_) => true, - TypeTerm::Num(_) => true, - TypeTerm::Char(_) => true, - TypeTerm::App(args) => args.iter().fold(true, |s,x| s && x.is_flat()), - TypeTerm::Ladder(_) => false - } - } - - /// transmute self into Ladder-Normal-Form - /// - /// Example: - /// <Seq <Digit 10>~Char> ⇒ <Seq <Digit 10>>~<Seq Char> - pub fn normalize(self) -> Self { - let mut new_ladder = Vec::<TypeTerm>::new(); - - match self { - TypeTerm::Ladder(args) => { - for x in args.into_iter() { - new_ladder.push(x.normalize()); - } - } - - TypeTerm::App(args) => { - let mut args_iter = args.into_iter(); - if let Some(head) = args_iter.next() { - - let mut stage1_args = vec![ head.clone() ]; - let mut stage2_args = vec![ head.clone() ]; - - let mut done = false; - - for x in args_iter { - match x.normalize() { - TypeTerm::Ladder(mut ladder) => { - // normalize this ladder - - if !done { - if ladder.len() > 2 { - stage1_args.push( ladder.remove(0) ); - stage2_args.push( TypeTerm::Ladder(ladder.to_vec()) ); - done = true; - } else if ladder.len() == 1 { - stage1_args.push( ladder[0].clone() ); - stage2_args.push( ladder[0].clone() ); - } else { - // empty type ? - } - - } else { - stage1_args.push( TypeTerm::Ladder(ladder.clone()) ); - stage2_args.push( TypeTerm::Ladder(ladder.clone()) ); - } - }, - _ => { - unreachable!("x is in LNF"); - } - } - } - - new_ladder.push(TypeTerm::Ladder(stage1_args)); - new_ladder.push(TypeTerm::Ladder(stage2_args)); - } - } - - atom => { - new_ladder.push(atom); - } - } - - TypeTerm::Ladder( new_ladder ) - } - - /* - pub fn is_supertype_of(&self, t: &TypeTerm) -> bool { - t.is_semantic_subtype_of(self) - } - */ - - // returns provided syntax-type, - pub fn is_semantic_subtype_of(&self, expected_type: &TypeTerm) -> Option< TypeTerm > { - let provided_lnf = self.clone(); - let expected_lnf = expected_type.clone(); - - match - (provided_lnf.normalize(), - expected_lnf.normalize()) - { - ( TypeTerm::Ladder( provided_ladder ), - TypeTerm::Ladder( expected_ladder ) - ) => { - - for i in 0..provided_ladder.len() { - if provided_ladder[i] == expected_ladder[0] { - return Some(TypeTerm::Ladder( - provided_ladder[i..].into_iter().cloned().collect() - )) - } - } - - None - }, - - _ => { - // both are in LNF! - unreachable!() - } - } - } - - pub fn is_syntactic_subtype_of(&self, expected_type: &TypeTerm) -> bool { - if let Some(provided_type) = self.is_semantic_subtype_of( expected_type ) { - &provided_type == expected_type - } else { - false - } - } - - /* this function is deprecated and only partially working, - wontfix, will be replaced by TypeTerm-Editor - */ - pub fn from_str(s: &str, names: &HashMap<String, TypeID>) -> Option<Self> { - let mut term_stack = Vec::<Option<TypeTerm>>::new(); - - for token in s.split_whitespace() { - match token { - "(" => { - term_stack.push(None); - } - ")" => { - let t = term_stack.pop().unwrap(); - if term_stack.len() > 0 { - let f = term_stack.last_mut().unwrap(); - if let Some(f) = f { - f.arg(t.unwrap()); - } else { - //error - } - } else { - return t; - } - } - atom => { - if let Some(f) = term_stack.last_mut() { - match f { - Some(f) => { - let mut chars = atom.chars(); - let first = chars.next().unwrap(); - - if first.is_numeric() { - f.num_arg(i64::from_str_radix(atom, 10).unwrap()); - } else if first == '\'' { - if let Some(mut c) = chars.next() { - if c == '\\' { - if let Some('n') = chars.next() { - c = '\n'; - } - } - f.char_arg(c); - } - } else { - f.arg(TypeTerm::new( - names.get(atom) - .expect(&format!("invalid atom {}", atom)).clone() - )); - } - } - None => { - *f = Some(TypeTerm::new( - names.get(atom).expect(&format!("invalid atom {}", atom)).clone(), - )); - } - } - } - } - } - } - - None - } - - pub fn to_str(&self, names: &HashMap<TypeID, String>) -> String { - match self { - TypeTerm::App(args) => { - let mut out = String::new(); - - out.push_str(&"<"); - - let mut first = true; - for x in args.iter() { - if !first { - out.push_str(&" "); - } else { - first = false; - } - - out.push_str(&x.to_str(names)); - } - - out.push_str(&">"); - - out - } - - TypeTerm::Ladder(l) => { - let mut out = String::new(); - - let mut first = true; - for x in l.iter() { - if !first { - out.push_str(&"~"); - } else { - first = false; - } - - out.push_str(&x.to_str(names)); - } - - out - } - - TypeTerm::Num(n) => format!("{}", n), - TypeTerm::Char('\n') => format!("'\\n'"), - TypeTerm::Char(c) => format!("'{}'", c), - TypeTerm::TypeID(id) => format!("{}", names[id]), - } - } -} diff --git a/nested/src/utils/color.rs b/nested/src/utils/color.rs index 25772ee..532a7fe 100644 --- a/nested/src/utils/color.rs +++ b/nested/src/utils/color.rs @@ -5,23 +5,27 @@ use { pub fn bg_style_from_depth(depth: usize) -> TerminalStyle { match depth { 0 => TerminalStyle::bg_color((150,80,230)), - 1 => TerminalStyle::bg_color((75,75,75)), - 2 => TerminalStyle::bg_color((40,40,40)), - 3 => TerminalStyle::bg_color((30,30,30)), - 4 => TerminalStyle::bg_color((25,25,25)), - 5 => TerminalStyle::bg_color((20,20,20)), + 1 => TerminalStyle::bg_color((66,66,66)), + 2 => TerminalStyle::bg_color((44,44,44)), + 3 => TerminalStyle::bg_color((33,33,33)), + 4 => TerminalStyle::bg_color((28,28,28)), + 5 => TerminalStyle::bg_color((21,21,21)), _ => TerminalStyle::default(), } } pub fn fg_style_from_depth(depth: usize) -> TerminalStyle { - match depth % 6 { - 0 => TerminalStyle::fg_color((120, 120, 0)), - 1 => TerminalStyle::fg_color((250, 165, 40)), - 2 => TerminalStyle::fg_color((80, 180, 180)), - 3 => TerminalStyle::fg_color((180, 240, 85)), - 4 => TerminalStyle::fg_color((200, 190, 70)), - _ => TerminalStyle::default() - } + if depth == 0 { + TerminalStyle::fg_color((200, 200, 200)) + } else { + match depth % 5 { + 0 => TerminalStyle::fg_color((128, 106, 97)), + 1 => TerminalStyle::fg_color((100, 120, 232)), + 2 => TerminalStyle::fg_color((180, 100, 96)), + 3 => TerminalStyle::fg_color((188, 155, 18)), + 4 => TerminalStyle::fg_color((135, 182, 134)), + _ => TerminalStyle::default() + } + } }