diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs index 43b8656..e3668e1 100644 --- a/nested/src/editors/list/editor.rs +++ b/nested/src/editors/list/editor.rs @@ -103,7 +103,7 @@ impl ListEditor { pub fn get_seq_type(&self) -> TypeTerm { TypeTerm::Type { - id: self.ctx.read().unwrap().get_typeid("Sequence").unwrap(), + id: self.ctx.read().unwrap().get_typeid("List").unwrap(), args: vec![ self.get_item_type() ] } } @@ -277,4 +277,24 @@ impl ListEditor { } } } +/* +use crate::{ + type_system::TypeLadder, + tree::{TreeType, TreeAddr} +}; +impl TreeType for ListEditor { + fn get_type(&self, addr: &TreeAddr) -> TypeLadder { + let idx = crate::utils::modulo::modulo(addr.0[0] as isize, self.data.len() as isize) as usize; + + let mut addr = addr.clone(); + + if self.data.len() > 0 { + addr.0.remove(0); + self.data.get(idx).get_type(addr) + } else { + vec![] + } + } +} +*/ diff --git a/nested/src/editors/list/pty_editor.rs b/nested/src/editors/list/pty_editor.rs index 3e81118..c12c237 100644 --- a/nested/src/editors/list/pty_editor.rs +++ b/nested/src/editors/list/pty_editor.rs @@ -19,7 +19,7 @@ use { make_label }, tree::{TreeCursor, TreeNav}, - diagnostics::{Diagnostics, make_error}, + diagnostics::{Diagnostics}, tree::NestedNode, commander::Commander, PtySegment @@ -179,7 +179,6 @@ impl PTYListEditor { let ed = editor.read().unwrap(); let edd = ed.editor.read().unwrap(); - NestedNode::new() .set_data(edd.get_data()) @@ -354,7 +353,7 @@ impl Commander for PTYListEditor { e.delete_nexd(); } _ => { - let mut new_edit = Context::make_editor(&e.ctx, e.typ.clone(), self.depth).unwrap(); + let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap(); new_edit.goto(TreeCursor::home()); new_edit.handle_terminal_event(event); diff --git a/nested/src/editors/product/editor.rs b/nested/src/editors/product/editor.rs index 0f69cfd..64ab5c6 100644 --- a/nested/src/editors/product/editor.rs +++ b/nested/src/editors/product/editor.rs @@ -235,7 +235,7 @@ impl TerminalEditor for ProductEditor { } } } else { - let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap(); + let mut e = Context::make_node(&self.ctx, t[0].clone(), *ed_depth+1).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 ac855e7..89354d2 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_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap(); + let mut e = Context::make_node(&self.ctx, t[0].clone(), *ed_depth+1).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_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap(); + let mut e = Context::make_node(&self.ctx, t[0].clone(), *ed_depth+1).unwrap(); *editor = Some(e.clone()); e.goby(direction); } diff --git a/nested/src/editors/sum/editor.rs b/nested/src/editors/sum/editor.rs index bb4d432..1261616 100644 --- a/nested/src/editors/sum/editor.rs +++ b/nested/src/editors/sum/editor.rs @@ -3,9 +3,6 @@ use { view::{ ViewPort, OuterViewPort, sequence::*, - }, - buffer::{ - vec::* } }, crate::{ diff --git a/nested/src/tree/addr.rs b/nested/src/tree/addr.rs index 62210a1..6af5dcd 100644 --- a/nested/src/tree/addr.rs +++ b/nested/src/tree/addr.rs @@ -1,5 +1,5 @@ -pub struct TreeAddr(Vec); +pub struct TreeAddr(pub Vec); impl From> for TreeAddr { fn from(v: Vec) -> TreeAddr { diff --git a/nested/src/tree/mod.rs b/nested/src/tree/mod.rs index 94fbb14..27f9c5b 100644 --- a/nested/src/tree/mod.rs +++ b/nested/src/tree/mod.rs @@ -2,11 +2,13 @@ pub mod addr; pub mod cursor; pub mod nav; pub mod node; +pub mod treetype; pub use { addr::TreeAddr, cursor::TreeCursor, nav::{TreeNav, TreeNavResult}, + treetype::{TreeType}, node::NestedNode }; diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs index 709d28c..8ed3f6a 100644 --- a/nested/src/tree/node.rs +++ b/nested/src/tree/node.rs @@ -52,6 +52,17 @@ impl ObjCommander for NestedNode { } } +/* +impl TreeType for NestedNode { + fn get_type(&self, addr: &TreeAddr) -> TypeLadder { + if let Some(editor) = self.editor { + editor.read().unwrap().get_type(addr) + } else { + vec![] + } + } +} +*/ // todo: remove that at some point impl TerminalEditor for NestedNode { fn get_term_view(&self) -> OuterViewPort { diff --git a/nested/src/tree/treetype.rs b/nested/src/tree/treetype.rs new file mode 100644 index 0000000..975dbc4 --- /dev/null +++ b/nested/src/tree/treetype.rs @@ -0,0 +1,14 @@ + +use { + crate::{ + type_system::TypeLadder, + tree::{TreeAddr} + } +}; + +pub trait TreeType { + fn get_type(&self, _addr: &TreeAddr) -> TypeLadder { + vec![] + } +} + diff --git a/nested/src/type_system/context.rs b/nested/src/type_system/context.rs index a15cad4..1dd6679 100644 --- a/nested/src/type_system/context.rs +++ b/nested/src/type_system/context.rs @@ -35,29 +35,50 @@ pub enum MorphismMode { #[derive(Clone, Hash, PartialEq, Eq)] pub struct MorphismType { - pub mode: MorphismMode, - pub src_type: TypeTerm, +// pub mode: MorphismMode, + pub src_type: Option, pub dst_type: TypeTerm, } +#[derive(Hash, Eq, PartialEq, Debug)] +pub struct MorphismTypePattern { + pub src_type: Option, + pub dst_tyid: TypeID +} + +impl From for MorphismTypePattern { + fn from(value: MorphismType) -> MorphismTypePattern { + MorphismTypePattern { + src_type: value.src_type, + dst_tyid: match value.dst_type { + TypeTerm::Type { id, args: _ } => id, + _ => unreachable!() + } + } + } +} + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct Context { /// assigns a name to every type type_dict: Arc>, - /// objects - objects: HashMap>>, + /// vertices of the graph + nodes: HashMap< String, NestedNode >, + /// todo: beautify /// types that can be edited as lists - list_types: Vec, + list_types: Vec< TypeID >, - /// editors - editor_ctors: HashMap>, TypeTerm, usize) -> Option + Send + Sync>>, - - /// morphisms - default_constructors: HashMap Arc> + Send + Sync>>, - morphism_constructors: HashMap>) -> Arc> + Send + Sync>>, + /// graph constructors + morphisms: HashMap< + MorphismTypePattern, + Arc< + dyn Fn( NestedNode, TypeTerm, usize ) -> Option + + Send + Sync + > + >, /// recursion parent: Option>>, @@ -70,10 +91,8 @@ impl Context { Some(p) => p.read().unwrap().type_dict.clone(), None => Arc::new(RwLock::new(TypeDict::new())) }, - editor_ctors: HashMap::new(), - default_constructors: HashMap::new(), - morphism_constructors: HashMap::new(), - objects: HashMap::new(), + morphisms: HashMap::new(), + nodes: HashMap::new(), list_types: match parent.as_ref() { Some(p) => p.read().unwrap().list_types.clone(), None => Vec::new() @@ -86,6 +105,14 @@ impl Context { Context::with_parent(None) } + pub fn depth(&self) -> usize { + if let Some(parent) = self.parent.as_ref() { + parent.read().unwrap().depth() + 1 + } else { + 0 + } + } + pub fn add_typename(&mut self, tn: String) -> TypeID { self.type_dict.write().unwrap().add_typename(tn) } @@ -116,73 +143,97 @@ impl Context { self.type_dict.read().unwrap().type_term_to_str(&t) } - pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc>, TypeTerm, usize) -> Option + Send + Sync>) { - let mut dict = self.type_dict.write().unwrap(); + pub fn add_node_ctor(&mut self, tn: &str, mk_editor: Arc>, TypeTerm, usize) -> Option + 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()) }; - self.editor_ctors.insert(tyid, mk_editor); + + let morphism_pattern = MorphismTypePattern { + src_type: None, + dst_tyid: tyid + }; + + self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type, depth| { + let ctx = node.ctx.clone().unwrap(); + mk_editor(ctx, dst_type, depth) + })); } - pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option>, TypeTerm, usize) -> Option + Send + Sync>> { - if let TypeTerm::Type{ id, args: _ } = ty.clone() { - if let Some(m) = self.editor_ctors.get(&id).cloned() { - Some(m) - } else { - self.parent.as_ref()? - .read().unwrap() - .get_editor_ctor(&ty) - } + pub fn add_morphism( + &mut self, + morph_type_pattern: MorphismTypePattern, + morph_fn: Arc< + dyn Fn( NestedNode, TypeTerm, usize ) -> Option + + Send + Sync + > + ) { + self.morphisms.insert(morph_type_pattern, morph_fn); + } + + pub fn get_morphism(&self, ty: MorphismType) -> Option Option + Send + Sync>> { + + let pattern = MorphismTypePattern::from(ty.clone()); + if let Some(morphism) = self.morphisms.get( &pattern ) { + Some(morphism.clone()) } else { - None + self.parent.as_ref()? + .read().unwrap() + .get_morphism(ty) } } - pub fn make_editor(ctx: &Arc>, type_term: TypeTerm, depth: usize) -> Option { - let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?; - mk_editor(ctx.clone(), type_term, depth) + pub fn make_node(ctx: &Arc>, type_term: TypeTerm, depth: usize) -> Option { + let mk_node = ctx.read().unwrap().get_morphism(MorphismType { + src_type: None, + dst_type: type_term.clone() + })?; + + mk_node(NestedNode::new().set_ctx(ctx.clone()), type_term, depth) } -/* - pub fn enrich_editor( - node: NestedNode, - typ: TypeTerm - ) -> NestedNode { - - // create view + pub fn morph_node(ctx: Arc>, mut node: NestedNode, dst_type: TypeTerm) -> NestedNode { + let mut src_type = None; - // create commander - + if let Some(data) = node.data.clone() { + src_type = Some(data.read().unwrap().get_type().clone()); + node = node.set_data( + ReprTree::ascend( + &data, + dst_type.clone() + ) + ); + } - } -*/ - pub fn add_morphism( - &mut self, - morph_type: MorphismType, - morph_fn: Box>) -> Arc> + Send + Sync>, - ) { - self.morphism_constructors.insert(morph_type, morph_fn); + let pattern = MorphismType { src_type, dst_type: dst_type.clone() }.into(); + if let Some(transform) = ctx.read().unwrap().get_morphism(pattern) { + if let Some(new_node) = transform(node.clone(), dst_type, 0) { + new_node + } else { + node.clone() + } + } else { + node + } } /// adds an object without any representations - pub fn add_obj(&mut self, name: String, typename: &str) { - let type_tag = self.type_dict.read().unwrap().type_term_from_str(typename).unwrap(); + pub fn add_obj(ctx: Arc>, name: String, typename: &str) { + let type_tag = ctx.read().unwrap() + .type_dict.read().unwrap() + .type_term_from_str(typename).unwrap(); - self.objects.insert( - name, - if let Some(ctor) = self.default_constructors.get(&type_tag) { - ctor() - } else { - Arc::new(RwLock::new(ReprTree::new(type_tag))) - }, - ); + if let Some(node) = Context::make_node(&ctx, type_tag, 0) { + ctx.write().unwrap().nodes.insert(name, node); + } } - pub fn get_obj(&self, name: &String) -> Option>> { - if let Some(obj) = self.objects.get(name) { + pub fn get_obj(&self, name: &String) -> Option { + if let Some(obj) = self.nodes.get(name) { Some(obj.clone()) } else if let Some(parent) = self.parent.as_ref() { parent.read().unwrap().get_obj(name) diff --git a/nested/src/type_system/make_editor.rs b/nested/src/type_system/make_editor.rs index 05e1eea..0f926d1 100644 --- a/nested/src/type_system/make_editor.rs +++ b/nested/src/type_system/make_editor.rs @@ -11,7 +11,7 @@ use { tree::{NestedNode}, terminal::{TerminalEditor}, diagnostics::{Diagnostics}, - type_system::TypeTermEditor, + type_system::{TypeTermEditor, MorphismTypePattern}, }, std::sync::{Arc, RwLock}, cgmath::Point2 @@ -28,7 +28,7 @@ pub fn init_mem_ctx(parent: Arc>) -> Arc> { pub fn init_editor_ctx(parent: Arc>) -> Arc> { let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "Char", Arc::new( |ctx: Arc>, _ty: TypeTerm, _depth: usize| { Some(CharEditor::new_node(&ctx)) @@ -38,7 +38,7 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { ctx.write().unwrap().add_list_typename("Sequence".into()); ctx.write().unwrap().add_list_typename("List".into()); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "List", Arc::new( |ctx: Arc>, ty: TypeTerm, depth: usize| { match ty { @@ -65,20 +65,44 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { ); ctx.write().unwrap().add_list_typename("Symbol".into()); - ctx.write().unwrap().add_editor_ctor( - "Symbol", Arc::new( - |ctx: Arc>, _ty: TypeTerm, depth: usize| { - let mut node = PTYListEditor::new( - ctx.clone(), - ctx.read().unwrap().type_term_from_str("( Char )").unwrap(), - ListStyle::Plain, - depth + 1 - ).into_node(); - node.data = Some(ReprTree::ascend( - &node.data.unwrap(), - ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap() - )); + let pattern = MorphismTypePattern { + src_type: ctx.read().unwrap().type_term_from_str("( List Char )"), + dst_tyid: ctx.read().unwrap().get_typeid("Symbol").unwrap() + }; + + ctx.write().unwrap().add_morphism(pattern, + Arc::new( + |mut node, dst_type:_, depth| { + let editor = node.editor.clone().unwrap().downcast::>().unwrap(); + let pty_editor = PTYListEditor::from_editor( + editor, + ListStyle::Plain, + depth + ); + + node.view = Some(pty_editor.pty_view()); + node.cmd = Some(Arc::new(RwLock::new(pty_editor))); + Some(node) + } + ) + ); + + ctx.write().unwrap().add_node_ctor( + "Symbol", Arc::new( + |ctx: Arc>, dst_typ: TypeTerm, depth: usize| { + let mut node = Context::make_node( + &ctx, + TypeTerm::Type { + id: ctx.read().unwrap().get_typeid("List").unwrap(), + args: vec![ + TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap()) + ] + }, + depth + ).unwrap(); + + node = Context::morph_node(ctx, node, dst_typ); Some(node) } @@ -86,7 +110,7 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { ); ctx.write().unwrap().add_list_typename("String".into()); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "String", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { let mut node = PTYListEditor::new( @@ -107,7 +131,7 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { ); ctx.write().unwrap().add_list_typename("TypeTerm".into()); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "TypeTerm", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { Some(TypeTermEditor::new(ctx, depth).into_node()) @@ -126,7 +150,7 @@ pub fn init_math_ctx(parent: Arc>) -> Arc> { ctx.write().unwrap().add_typename("u32".into()); ctx.write().unwrap().add_typename("BigEndian".into()); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "Digit", Arc::new( |ctx: Arc>, ty: TypeTerm, _depth: usize| { match ty { @@ -154,7 +178,7 @@ pub fn init_math_ctx(parent: Arc>) -> Arc> { ); ctx.write().unwrap().add_list_typename("PosInt".into()); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "PosInt", Arc::new( |ctx: Arc>, ty: TypeTerm, _depth: usize| { match ty { @@ -181,9 +205,9 @@ pub fn init_math_ctx(parent: Arc>) -> Arc> { ); ctx.write().unwrap().add_list_typename("RGB".into()); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "RGB", Arc::new( - |ctx: Arc>, ty: TypeTerm, depth: usize| { + |ctx: Arc>, _ty: TypeTerm, depth: usize| { let editor = ProductEditor::new(depth, ctx.clone()) .with_t(Point2::new(0, 0), "r: ") .with_n(Point2::new(1, 0), @@ -225,7 +249,7 @@ pub fn init_os_ctx(parent: Arc>) -> Arc> { let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); ctx.write().unwrap().add_list_typename("PathSegment".into()); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "PathSegment", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { let mut node = PTYListEditor::new( @@ -246,7 +270,7 @@ pub fn init_os_ctx(parent: Arc>) -> Arc> { ); ctx.write().unwrap().add_list_typename("Path".into()); - ctx.write().unwrap().add_editor_ctor( + ctx.write().unwrap().add_node_ctor( "Path", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { let mut node = PTYListEditor::new( diff --git a/nested/src/type_system/mod.rs b/nested/src/type_system/mod.rs index 27dc2fa..2db9051 100644 --- a/nested/src/type_system/mod.rs +++ b/nested/src/type_system/mod.rs @@ -8,7 +8,7 @@ pub mod type_term_editor; pub use { repr_tree::{ReprTree}, type_term::{TypeDict, TypeID, TypeTerm, TypeLadder}, - context::{Context, MorphismMode, MorphismType}, + context::{Context, MorphismMode, MorphismType, MorphismTypePattern}, type_term_editor::TypeTermEditor, make_editor::* }; diff --git a/nested/src/type_system/type_term.rs b/nested/src/type_system/type_term.rs index 41f5f17..de2281d 100644 --- a/nested/src/type_system/type_term.rs +++ b/nested/src/type_system/type_term.rs @@ -7,7 +7,7 @@ pub type TypeLadder = Vec; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum TypeTerm { Type { id: TypeID, args: Vec }, Num(i64), diff --git a/nested/src/type_system/type_term_editor.rs b/nested/src/type_system/type_term_editor.rs index 86e9250..6f2807e 100644 --- a/nested/src/type_system/type_term_editor.rs +++ b/nested/src/type_system/type_term_editor.rs @@ -1,26 +1,15 @@ use { - r3vi::{ - view::{ - OuterViewPort, - sequence::* - } - }, crate::{ type_system::{Context}, - terminal::{TerminalEvent, TerminalView, TerminalEditor, TerminalEditorResult}, + terminal::{TerminalEvent}, editors::{ - list::*, sum::*, - char::CharEditor, - integer::PosIntEditor, }, - tree::{TreeNav, TreeCursor, TreeNavResult}, - diagnostics::{Diagnostics, Message}, + tree::{TreeNav}, tree::NestedNode, commander::Commander, PtySegment }, - cgmath::{Vector2}, termion::event::{Key}, std::{ sync::{Arc, RwLock} @@ -48,9 +37,9 @@ impl TypeTermEditor { ty: TypeTermVar::Any, sum_edit: Arc::new(RwLock::new(SumEditor::new( vec![ - Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( List TypeTerm )").unwrap(), depth + 1).unwrap(), - Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth + 1 ).unwrap(), - Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth + 1 ).unwrap() + Context::make_node( &ctx, ctx.read().unwrap().type_term_from_str("( List TypeTerm )").unwrap(), depth + 1).unwrap(), + Context::make_node( &ctx, ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth + 1 ).unwrap(), + Context::make_node( &ctx, ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth + 1 ).unwrap() ]))) } }