use { r3vi::{ view::{ ViewPort, OuterViewPort, AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, port::UpdateTask, View, Observer, singleton::*, sequence::*, list::* }, buffer::{singleton::*, vec::*} }, laddertypes::{TypeTerm, TypeID}, std::{ collections::HashMap, sync::{Arc, RwLock}, any::Any }, super::{Context, ReprLeaf, ReprTreeExt, context::{TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] pub struct ReprTree { halo: TypeTerm, type_tag: TypeTerm, branches: HashMap>>, 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) -> 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) -> Arc> { 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) { 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>) { 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>, c: char ) -> Arc> { ReprTree::from_singleton_buffer( Context::parse(ctx, "Char"), SingletonBuffer::new(c) ) } pub fn from_view( type_tag: impl Into, view: OuterViewPort ) -> Arc> 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( type_tag: impl Into, buf: SingletonBuffer ) -> Arc> 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_str( type_tag: impl Into, val: &str ) -> Arc> { 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( type_tag: impl Into, buf: VecBuffer ) -> Arc> 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( &mut self, src_port: OuterViewPort ) 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( &mut self, mut type_ladder: impl Iterator, src_port: OuterViewPort ) 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 { if self.type_tag == TypeTerm::App(vec![ TypeTerm::TypeID(TYPEID_vec), TypeTerm::TypeID(TYPEID_edittree) ]) { let mut leaf = ReprLeaf::from_vec_buffer( VecBuffer::< Arc> >::new() ); leaf.attach_to(src_port); self.leaf = Some(leaf); } else if self.type_tag == TypeTerm::App(vec![ TypeTerm::TypeID(TYPEID_vec), TypeTerm::TypeID(TYPEID_char) ]) { let mut leaf = ReprLeaf::from_vec_buffer( VecBuffer::::new() ); leaf.attach_to(src_port); self.leaf = Some(leaf); } else if self.type_tag == TypeTerm::App(vec![ TypeTerm::TypeID(TYPEID_vec), TypeTerm::TypeID(TYPEID_u64) ]) { let mut leaf = ReprLeaf::from_vec_buffer( VecBuffer::::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>) { // eprintln!("DETACH {:?}", self.get_type()); if let Some(leaf) = self.leaf.as_mut() { if self.type_tag == Context::parse(&ctx, "Char") { leaf.detach::>(); } if self.type_tag == Context::parse(&ctx, "") { leaf.detach_vec::(); } if self.type_tag == Context::parse(&ctx, "") { leaf.detach::>(); } } for (t,b) in self.branches.iter_mut() { b.write().unwrap().detach(&ctx); } } pub fn insert_leaf( &mut self, mut type_ladder: impl Iterator, 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) -> Option>> { let dst_type = dst_type.into(); assert!( dst_type.is_flat() ); self.branches.get(&dst_type).cloned() } pub fn descend_ladder(rt: &Arc>, mut repr_ladder: impl Iterator) -> Option>> { 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>, dst_type: impl Into) -> Option>> { 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>, type_term: impl Into) -> Arc> { let mut n = Self::new(type_term); n.insert_branch(rt.clone()); Arc::new(RwLock::new(n)) } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub fn singleton_buffer(&mut self) -> Option> { if let Some(leaf) = self.leaf.as_mut() { leaf.as_singleton_buffer::() } else { // create new singleton buffer /* // default value?? let buf = SingletonBuffer::::default(); self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone())); Some(buf) */ None } } pub fn vec_buffer(&mut self) -> Option> { if let Some(leaf) = self.leaf.as_mut() { leaf.as_vec_buffer::() } else { None } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub fn get_port(&self) -> Option> where V::Msg: Clone, { if let Some(leaf) = self.leaf.as_ref() { leaf.get_port::() } else { None } } pub fn get_view(&self) -> Option> where V::Msg: Clone, { self.get_port::()? .get_view() } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub fn view_singleton(&self) -> OuterViewPort> { self.get_port::>().expect("no singleton-view available") } pub fn view_seq(&self) -> OuterViewPort> { self.get_port::>().expect("no sequence-view available") } pub fn view_list(&self) -> OuterViewPort> { self.get_port::>().expect("no list-view available") } pub fn view_char(&self) -> OuterViewPort> { self.get_port::>().expect("no char-view available") } pub fn view_u8(&self) -> OuterViewPort> { self.get_port::>().expect("no u8-view available") } pub fn view_u64(&self) -> OuterViewPort> { self.get_port::>().expect("no u64-view available") } pub fn view_usize(&self) -> OuterViewPort> { self.get_port::>().expect("no usize-view available") } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>