implement MorphismBase, remove data
from NestedNode
This commit is contained in:
parent
834bb49b5e
commit
193b8c8cac
9 changed files with 309 additions and 546 deletions
|
@ -7,87 +7,36 @@ extern crate termion;
|
||||||
use {
|
use {
|
||||||
cgmath::Vector2,
|
cgmath::Vector2,
|
||||||
nested::{
|
nested::{
|
||||||
edit_tree::{NestedNode, TreeCursor, TreeNav},
|
editors::ObjCommander,
|
||||||
repr_tree::{Context, ReprTree},
|
repr_tree::{Context},
|
||||||
editors::ObjCommander
|
|
||||||
},
|
},
|
||||||
nested_tty::{
|
nested_tty::{
|
||||||
terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor,
|
DisplaySegment, TTYApplication,
|
||||||
TerminalEvent, TerminalStyle, TerminalView,
|
TerminalCompositor, TerminalStyle, TerminalView,
|
||||||
TTYApplication
|
|
||||||
},
|
},
|
||||||
r3vi::{
|
r3vi::{
|
||||||
buffer::singleton::*,
|
buffer::singleton::*,
|
||||||
view::{port::UpdateTask, singleton::*, sequence::*, ViewPort},
|
|
||||||
projection::decorate_sequence::*
|
|
||||||
},
|
},
|
||||||
std::sync::{Arc, Mutex, RwLock},
|
std::sync::{Arc, RwLock},
|
||||||
termion::event::{Event, Key},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn node_make_char_view(
|
struct ParseDigit { radix: u32 };
|
||||||
node: NestedNode
|
impl Morphism for ParseDigit {
|
||||||
) -> NestedNode {
|
fn new(
|
||||||
node.disp.view
|
ctx: &Arc<RwLock<Context>>
|
||||||
.write().unwrap()
|
) -> Self {
|
||||||
.insert_branch(ReprTree::new_leaf(
|
|
||||||
Context::parse(&node.ctx, "TerminalView"),
|
|
||||||
node.data
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.get_port::<dyn SingletonView<Item = char>>()
|
|
||||||
.expect("unable to get Char-view")
|
|
||||||
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
|
|
||||||
.to_grid()
|
|
||||||
.into(),
|
|
||||||
));
|
|
||||||
|
|
||||||
node
|
|
||||||
}
|
|
||||||
|
|
||||||
fn node_make_seq_view(
|
|
||||||
mut node: NestedNode
|
|
||||||
) -> NestedNode {
|
|
||||||
node.disp.view
|
|
||||||
.write().unwrap()
|
|
||||||
.insert_branch(ReprTree::new_leaf(
|
|
||||||
Context::parse(&node.ctx, "TerminalView"),
|
|
||||||
node.data
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.get_port::< dyn SequenceView<Item = NestedNode> >()
|
|
||||||
.expect("unable to get Seq-view")
|
|
||||||
.map(move |char_node| node_make_view(char_node.clone()).display_view() )
|
|
||||||
.wrap(nested_tty::make_label("("), nested_tty::make_label(")"))
|
|
||||||
.to_grid_horizontal()
|
|
||||||
.flatten()
|
|
||||||
.into()
|
|
||||||
));
|
|
||||||
node
|
|
||||||
}
|
|
||||||
|
|
||||||
fn node_make_list_edit(
|
|
||||||
mut node: NestedNode
|
|
||||||
) -> NestedNode {
|
|
||||||
nested_tty::editors::list::PTYListStyle::for_node( &mut node, ("(", ",", ")") );
|
|
||||||
nested_tty::editors::list::PTYListController::for_node( &mut node, None, None );
|
|
||||||
|
|
||||||
node
|
|
||||||
}
|
|
||||||
|
|
||||||
fn node_make_view(
|
|
||||||
node: NestedNode
|
|
||||||
) -> NestedNode {
|
|
||||||
if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") {
|
|
||||||
node_make_char_view( node )
|
|
||||||
} else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") {
|
|
||||||
node_make_seq_view( node )
|
|
||||||
} else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") {
|
|
||||||
node_make_list_edit( node )
|
|
||||||
} else {
|
|
||||||
eprintln!("couldnt add view");
|
|
||||||
node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup_projection(&self, repr_tree: Arc<RwLock<ReprTree>>) {
|
||||||
|
if let Some( char_view ) = repr_tree.get_out(Context::parse(&ctx, "Char~")) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_morphism( ) -> Morphism {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
|
@ -96,19 +45,36 @@ async fn main() {
|
||||||
*/
|
*/
|
||||||
let ctx = Arc::new(RwLock::new(Context::default()));
|
let ctx = Arc::new(RwLock::new(Context::default()));
|
||||||
|
|
||||||
|
|
||||||
/* Create a Char-Node with editor & view
|
/* Create a Char-Node with editor & view
|
||||||
*/
|
*/
|
||||||
let mut node1 = Context::make_node(
|
let mut char_obj = ReprTree::make_leaf(
|
||||||
|
Context::parse(&ctx, "Char"),
|
||||||
|
SingletonBuffer::new('X').get_port().into()
|
||||||
|
);
|
||||||
|
|
||||||
|
char_obj.insert_branch(
|
||||||
|
Context::parse(&ctx, "EditTree"),
|
||||||
|
SingletonBuffer::new(
|
||||||
|
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut vec_obj = ReprTree::make_leaf(
|
||||||
|
Context::parse(&ctx, "<Vec Char>"),
|
||||||
|
VecBuffer::new(vec!['a', 'b', 'c']).get_port().into()
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut char_edit = Context::new_edit_tree(
|
||||||
&ctx,
|
&ctx,
|
||||||
// node type
|
// node type
|
||||||
Context::parse(&ctx, "Char"),
|
Context::parse(&ctx, "Char"),
|
||||||
// depth
|
// depth
|
||||||
SingletonBuffer::new(0).get_port(),
|
SingletonBuffer::new(0).get_port(),
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// add a display view to the node
|
// add a display view to the node
|
||||||
node1 = node_make_view( node1 );
|
node1 = nested_tty::editors::node_make_tty_view(node1);
|
||||||
|
|
||||||
/* Create a <List Char>-Node with editor & view
|
/* Create a <List Char>-Node with editor & view
|
||||||
*/
|
*/
|
||||||
|
@ -118,10 +84,25 @@ async fn main() {
|
||||||
Context::parse(&ctx, "<List Char>"),
|
Context::parse(&ctx, "<List Char>"),
|
||||||
// depth
|
// depth
|
||||||
SingletonBuffer::new(0).get_port(),
|
SingletonBuffer::new(0).get_port(),
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// add a display view to the node
|
// add a display view to the node
|
||||||
node2 = node_make_view( node2 );
|
node2 = nested_tty::editors::node_make_tty_view(node2);
|
||||||
|
|
||||||
|
/* Create a <List Char>-Node with editor & view
|
||||||
|
*/
|
||||||
|
let mut node3 = Context::make_node(
|
||||||
|
&ctx,
|
||||||
|
// node type
|
||||||
|
Context::parse(&ctx, "<List <List Char>>"),
|
||||||
|
// depth
|
||||||
|
SingletonBuffer::new(0).get_port(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// add a display view to the node
|
||||||
|
node3 = nested_tty::editors::node_make_tty_view(node3);
|
||||||
|
|
||||||
/* setup terminal
|
/* setup terminal
|
||||||
*/
|
*/
|
||||||
|
@ -130,13 +111,16 @@ async fn main() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let ctx = ctx.clone();
|
let ctx = ctx.clone();
|
||||||
let mut node1 = node1.clone();
|
let node1 = node1.clone();
|
||||||
let mut node2 = node2.clone();
|
let node2 = node2.clone();
|
||||||
move |ev| {
|
let node3 = node3.clone();
|
||||||
|
move |ev| {
|
||||||
let mut node1 = node1.clone();
|
let mut node1 = node1.clone();
|
||||||
let mut node2 = node2.clone();
|
let mut node2 = node2.clone();
|
||||||
node1.send_cmd_obj( ev.to_repr_tree(&ctx) );
|
let mut node3 = node3.clone();
|
||||||
node2.send_cmd_obj( ev.to_repr_tree(&ctx) );
|
node1.send_cmd_obj(ev.to_repr_tree(&ctx));
|
||||||
|
node2.send_cmd_obj(ev.to_repr_tree(&ctx));
|
||||||
|
node3.send_cmd_obj(ev.to_repr_tree(&ctx));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -144,7 +128,7 @@ async fn main() {
|
||||||
*/
|
*/
|
||||||
let compositor = TerminalCompositor::new(app.port.inner());
|
let compositor = TerminalCompositor::new(app.port.inner());
|
||||||
|
|
||||||
// add some views to the display compositor
|
// add some views to the display compositor
|
||||||
compositor.write().unwrap().push(
|
compositor.write().unwrap().push(
|
||||||
nested_tty::make_label("Hello World")
|
nested_tty::make_label("Hello World")
|
||||||
.map_item(|p, a| {
|
.map_item(|p, a| {
|
||||||
|
@ -153,21 +137,40 @@ async fn main() {
|
||||||
.offset(Vector2::new(5, 0)),
|
.offset(Vector2::new(5, 0)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let label = ctx.read().unwrap().type_term_to_str( &node1.get_type() );
|
let label = ctx.read().unwrap().type_term_to_str(&node1.get_type());
|
||||||
compositor.write().unwrap()
|
compositor
|
||||||
.push(nested_tty::make_label( &label ).offset(Vector2::new(0, 2)));
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.push(nested_tty::make_label(&label).offset(Vector2::new(0, 2)));
|
||||||
|
|
||||||
compositor.write().unwrap()
|
compositor
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.push(node1.display_view().offset(Vector2::new(15, 2)));
|
.push(node1.display_view().offset(Vector2::new(15, 2)));
|
||||||
|
|
||||||
|
let label2 = ctx.read().unwrap().type_term_to_str(&node2.get_type());
|
||||||
|
compositor
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.push(nested_tty::make_label(&label2).offset(Vector2::new(0, 3)));
|
||||||
|
|
||||||
let label2 = ctx.read().unwrap().type_term_to_str( &node2.get_type() );
|
compositor
|
||||||
compositor.write().unwrap()
|
.write()
|
||||||
.push(nested_tty::make_label( &label2 ).offset(Vector2::new(0, 3)));
|
.unwrap()
|
||||||
|
|
||||||
compositor.write().unwrap()
|
|
||||||
.push(node2.display_view().offset(Vector2::new(15, 3)));
|
.push(node2.display_view().offset(Vector2::new(15, 3)));
|
||||||
|
|
||||||
|
|
||||||
|
let label3 = ctx.read().unwrap().type_term_to_str(&node3.get_type());
|
||||||
|
compositor
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.push(nested_tty::make_label(&label3).offset(Vector2::new(0, 4)));
|
||||||
|
|
||||||
|
compositor
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.push(node3.display_view().offset(Vector2::new(25, 4)));
|
||||||
|
|
||||||
/* write the changes in the view of `term_port` to the terminal
|
/* write the changes in the view of `term_port` to the terminal
|
||||||
*/
|
*/
|
||||||
app.show().await.expect("output error!");
|
app.show().await.expect("output error!");
|
||||||
|
|
|
@ -52,9 +52,6 @@ pub struct NestedNode {
|
||||||
/// context
|
/// context
|
||||||
pub ctx: Arc<RwLock<Context>>,
|
pub ctx: Arc<RwLock<Context>>,
|
||||||
|
|
||||||
/// abstract data view
|
|
||||||
pub data: Arc<RwLock<ReprTree>>,
|
|
||||||
|
|
||||||
/// viewports for terminal display
|
/// viewports for terminal display
|
||||||
pub disp: NestedNodeDisplay,
|
pub disp: NestedNodeDisplay,
|
||||||
|
|
||||||
|
@ -63,7 +60,7 @@ pub struct NestedNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedNode {
|
impl NestedNode {
|
||||||
pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self {
|
pub fn new(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self {
|
||||||
NestedNode {
|
NestedNode {
|
||||||
disp: NestedNodeDisplay {
|
disp: NestedNodeDisplay {
|
||||||
view: ReprTree::new_arc(Context::parse(&ctx, "Display")),
|
view: ReprTree::new_arc(Context::parse(&ctx, "Display")),
|
||||||
|
@ -74,43 +71,13 @@ impl NestedNode {
|
||||||
editor: SingletonBuffer::new(None),
|
editor: SingletonBuffer::new(None),
|
||||||
spillbuf: Arc::new(RwLock::new(Vec::new())),
|
spillbuf: Arc::new(RwLock::new(Vec::new())),
|
||||||
cmd: SingletonBuffer::new(None),
|
cmd: SingletonBuffer::new(None),
|
||||||
close_char: SingletonBuffer::new(None),
|
close_char: SingletonBuffer::new(None),
|
||||||
tree_nav: SingletonBuffer::new(None),
|
tree_nav: SingletonBuffer::new(None),
|
||||||
},
|
},
|
||||||
data,
|
|
||||||
ctx
|
ctx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: move into separate file/module
|
|
||||||
*/
|
|
||||||
pub fn from_char(ctx: Arc<RwLock<Context>>, c: char) -> NestedNode {
|
|
||||||
let buf = r3vi::buffer::singleton::SingletonBuffer::<char>::new(c);
|
|
||||||
|
|
||||||
NestedNode::new(
|
|
||||||
ctx.clone(),
|
|
||||||
ReprTree::new_leaf(
|
|
||||||
Context::parse(&ctx, "Char"),
|
|
||||||
buf.get_port().into()
|
|
||||||
),
|
|
||||||
SingletonBuffer::new(0).get_port()
|
|
||||||
)
|
|
||||||
// .set_editor(Arc::new(RwLock::new(buf)))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//\\//\\
|
|
||||||
|
|
||||||
pub fn morph(self, ty: TypeTerm) -> NestedNode {
|
|
||||||
Context::morph_node(self, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_type(&self) -> TypeTerm {
|
|
||||||
self.data.read().unwrap().get_type().clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
//\\//\\
|
|
||||||
|
|
||||||
pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self {
|
pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self {
|
||||||
self.edit.editor.set(Some(editor));
|
self.edit.editor.set(Some(editor));
|
||||||
self
|
self
|
||||||
|
@ -137,33 +104,6 @@ impl NestedNode {
|
||||||
self.disp.diag.clone().unwrap_or(ViewPort::new().into_outer())
|
self.disp.diag.clone().unwrap_or(ViewPort::new().into_outer())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>>
|
|
||||||
where V::Msg: Clone {
|
|
||||||
let ctx = self.ctx.clone();
|
|
||||||
let type_ladder = type_str.map(|s| Context::parse(&ctx, s));
|
|
||||||
|
|
||||||
let repr_tree = ReprTree::descend_ladder(&self.data, type_ladder)?;
|
|
||||||
repr_tree.clone().read().unwrap()
|
|
||||||
.get_port::<V>().clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_data_view<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<Arc<V>>
|
|
||||||
where V::Msg: Clone {
|
|
||||||
self.get_data_port::<V>(type_str)?.get_view()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO
|
|
||||||
pub fn get_seq_view<'a, T: Clone>(&self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<dyn SingletonView<Item = T>>> {
|
|
||||||
self.get_data_view::<dyn SequenceView<Item = NestedNode>>(type_str)
|
|
||||||
.unwrap()
|
|
||||||
.map({
|
|
||||||
move |node| {
|
|
||||||
node.get_data_view::<dyn SingletonView<Item = T>>().get()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> {
|
pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> {
|
||||||
if let Some(edit) = self.edit.editor.get() {
|
if let Some(edit) = self.edit.editor.get() {
|
||||||
if let Ok(edit) = edit.downcast::<RwLock<T>>() {
|
if let Ok(edit) = edit.downcast::<RwLock<T>>() {
|
||||||
|
@ -187,7 +127,7 @@ impl TreeType for NestedNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl TreeNav for NestedNode {
|
impl TreeNav for NestedNode {
|
||||||
fn get_cursor(&self) -> TreeCursor {
|
fn get_cursor(&self) -> TreeCursor {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use {
|
||||||
laddertypes::{TypeTerm},
|
laddertypes::{TypeTerm},
|
||||||
crate::{
|
crate::{
|
||||||
repr_tree::{Context},
|
repr_tree::{Context},
|
||||||
repr_tree::{MorphismTypePattern},
|
repr_tree::{MorphismType},
|
||||||
editors::{
|
editors::{
|
||||||
list::*,
|
list::*,
|
||||||
integer::*
|
integer::*
|
||||||
|
@ -16,6 +16,7 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init_ctx(ctx: &mut Context) {
|
pub fn init_ctx(ctx: &mut Context) {
|
||||||
|
/*
|
||||||
ctx.add_typename("MachineInt".into());
|
ctx.add_typename("MachineInt".into());
|
||||||
ctx.add_typename("u32".into());
|
ctx.add_typename("u32".into());
|
||||||
ctx.add_typename("u64".into());
|
ctx.add_typename("u64".into());
|
||||||
|
@ -126,7 +127,7 @@ pub fn init_ctx(ctx: &mut Context) {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
ctx.add_typename("Date".into());
|
ctx.add_typename("Date".into());
|
||||||
ctx.add_typename("ISO-8601".into());
|
ctx.add_typename("ISO-8601".into());
|
||||||
ctx.add_typename("TimeSince".into());
|
ctx.add_typename("TimeSince".into());
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl ListEditor {
|
||||||
|
|
||||||
let e = editor.read().unwrap();
|
let e = editor.read().unwrap();
|
||||||
|
|
||||||
let mut node = NestedNode::new(ctx, data, depth)
|
let mut node = NestedNode::new(ctx, depth)
|
||||||
.set_editor(editor.clone())
|
.set_editor(editor.clone())
|
||||||
.set_nav(editor.clone())
|
.set_nav(editor.clone())
|
||||||
.set_cmd(editor.clone())
|
.set_cmd(editor.clone())
|
||||||
|
@ -307,6 +307,7 @@ impl ListEditor {
|
||||||
self.nexd();
|
self.nexd();
|
||||||
|
|
||||||
let mut b = item.edit.spillbuf.write().unwrap();
|
let mut b = item.edit.spillbuf.write().unwrap();
|
||||||
|
|
||||||
let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap();
|
let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap();
|
||||||
tail_node.goto(TreeCursor::home());
|
tail_node.goto(TreeCursor::home());
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use {
|
||||||
},
|
},
|
||||||
laddertypes::{TypeTerm},
|
laddertypes::{TypeTerm},
|
||||||
crate::{
|
crate::{
|
||||||
repr_tree::{Context, MorphismTypePattern},
|
repr_tree::{Context, MorphismType},
|
||||||
editors::{
|
editors::{
|
||||||
list::{ListEditor, ListSegmentSequence},
|
list::{ListEditor, ListSegmentSequence},
|
||||||
typeterm::{State, TypeTermEditor}
|
typeterm::{State, TypeTermEditor}
|
||||||
|
@ -26,7 +26,7 @@ pub fn init_ctx(ctx: &mut Context) {
|
||||||
ctx.add_list_typename("Type::Ladder".into()); // = T1~T2~...
|
ctx.add_list_typename("Type::Ladder".into()); // = T1~T2~...
|
||||||
|
|
||||||
ctx.add_morphism(
|
ctx.add_morphism(
|
||||||
MorphismTypePattern { src_tyid: ctx.get_typeid("List"), dst_tyid: ctx.get_typeid("Type").unwrap() },
|
MorphismType { src_tyid: Context::parse(&ctx, "<List T>"), dst_tyid: Context::parse(&ctx, "Type") },
|
||||||
Arc::new(move |node, _dst_type:_| {
|
Arc::new(move |node, _dst_type:_| {
|
||||||
let ctx : Arc<RwLock<Context>> = Arc::new(RwLock::new(Context::with_parent(Some(node.ctx.clone()))));
|
let ctx : Arc<RwLock<Context>> = Arc::new(RwLock::new(Context::with_parent(Some(node.ctx.clone()))));
|
||||||
ctx.write().unwrap().meta_chars.push('~');
|
ctx.write().unwrap().meta_chars.push('~');
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use {
|
use {
|
||||||
r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}},
|
r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}},
|
||||||
laddertypes::{TypeDict, TypeTerm, TypeID},
|
laddertypes::{TypeDict, TypeTerm, TypeID},
|
||||||
crate::{
|
crate::{
|
||||||
repr_tree::{ReprTree},
|
repr_tree::{ReprTree, MorphismType, GenericReprTreeMorphism, MorphismBase},
|
||||||
edit_tree::NestedNode
|
edit_tree::NestedNode
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
|
@ -13,129 +13,26 @@
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
|
||||||
pub enum MorphismMode {
|
|
||||||
/// Isomorphism
|
|
||||||
/// e.g. `( PositionalInteger 10 BigEndian ) <~> ( PositionalInteger 16 LittleEndian )`
|
|
||||||
Iso,
|
|
||||||
|
|
||||||
/// Monomorphism, i.e. injective functions,
|
|
||||||
/// upcast-view, downcast-control, semantic gain
|
|
||||||
/// e.g. `( Sequence ( Digit 16 ) ) ~> ( PositionalInteger 16 LittleEndian )`
|
|
||||||
Mono,
|
|
||||||
|
|
||||||
/// Epimorphsim, i.e. surjective functions,
|
|
||||||
/// upcast-control, downcast-view, possible loss of entropy
|
|
||||||
/// e.g. `( Ascii ) ~> ( Digit 16 )`
|
|
||||||
Epi,
|
|
||||||
|
|
||||||
/// Any other function
|
|
||||||
Any,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
|
|
||||||
pub struct MorphismType {
|
|
||||||
// pub mode: MorphismMode,
|
|
||||||
pub src_type: Option<TypeTerm>,
|
|
||||||
pub dst_type: TypeTerm,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Hash, Eq, PartialEq)]
|
|
||||||
pub struct MorphismTypePattern {
|
|
||||||
pub src_tyid: Option<TypeID>,
|
|
||||||
pub dst_tyid: TypeID
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MorphismType {
|
|
||||||
pub fn to_str(&self, ctx: &Context) -> String {
|
|
||||||
format!("{:?} -> {:?}",
|
|
||||||
if let Some(t) = self.src_type.as_ref() {
|
|
||||||
ctx.type_term_to_str(t)
|
|
||||||
} else {
|
|
||||||
"None".into()
|
|
||||||
},
|
|
||||||
ctx.type_term_to_str(&self.dst_type))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MorphismTypePattern {
|
|
||||||
pub fn to_str(&self, ctx: &Context) -> String {
|
|
||||||
format!("{:?} -> {:?}",
|
|
||||||
if let Some(t) = self.src_tyid.as_ref() {
|
|
||||||
ctx.type_term_to_str(&TypeTerm::TypeID(t.clone()))
|
|
||||||
} else {
|
|
||||||
"None".into()
|
|
||||||
},
|
|
||||||
ctx.type_term_to_str(&TypeTerm::TypeID(self.dst_tyid.clone())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<MorphismType> for MorphismTypePattern {
|
|
||||||
fn from(value: MorphismType) -> MorphismTypePattern {
|
|
||||||
fn strip( x: &TypeTerm ) -> TypeID {
|
|
||||||
match x {
|
|
||||||
TypeTerm::TypeID(id) => id.clone(),
|
|
||||||
TypeTerm::App(args) => strip(&args[0]),
|
|
||||||
TypeTerm::Ladder(args) => strip(&args[0]),
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MorphismTypePattern {
|
|
||||||
src_tyid: value.src_type.map(|x| strip(&x)),
|
|
||||||
dst_tyid: strip(&value.dst_type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
/// assigns a name to every type
|
/// assigns a name to every type
|
||||||
pub type_dict: Arc<RwLock<TypeDict>>,
|
pub type_dict: Arc<RwLock<TypeDict>>,
|
||||||
|
|
||||||
|
pub morphisms: MorphismBase,
|
||||||
|
|
||||||
/// named vertices of the graph
|
/// named vertices of the graph
|
||||||
nodes: HashMap< String, NestedNode >,
|
nodes: HashMap< String, Arc<RwLock<ReprTree>> >,
|
||||||
|
|
||||||
/// todo: beautify
|
/// todo: beautify
|
||||||
/// types that can be edited as lists
|
/// types that can be edited as lists
|
||||||
|
/// do we really need this?
|
||||||
pub list_types: Vec< TypeID >,
|
pub list_types: Vec< TypeID >,
|
||||||
pub meta_chars: Vec< char >,
|
pub meta_chars: Vec< char >,
|
||||||
|
|
||||||
/// graph constructors
|
|
||||||
/// TODO: move into separate struct MorphismMap or something
|
|
||||||
morphisms: HashMap<
|
|
||||||
MorphismTypePattern,
|
|
||||||
Arc<
|
|
||||||
dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
|
|
||||||
+ Send + Sync
|
|
||||||
>
|
|
||||||
>,
|
|
||||||
|
|
||||||
/// recursion
|
/// recursion
|
||||||
parent: Option<Arc<RwLock<Context>>>,
|
parent: Option<Arc<RwLock<Context>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Context {
|
|
||||||
fn default() -> Context {
|
|
||||||
let mut ctx = Context::new();
|
|
||||||
|
|
||||||
ctx.add_list_typename("Sequence");
|
|
||||||
ctx.add_synonym("Seq", "Sequence");
|
|
||||||
ctx.add_list_typename("SepSeq");
|
|
||||||
ctx.add_typename("NestedNode");
|
|
||||||
ctx.add_typename("TerminalEvent");
|
|
||||||
|
|
||||||
crate::editors::list::init_ctx( &mut ctx );
|
|
||||||
crate::editors::char::init_ctx( &mut ctx );
|
|
||||||
crate::editors::integer::init_ctx( &mut ctx );
|
|
||||||
crate::editors::typeterm::init_ctx( &mut ctx );
|
|
||||||
|
|
||||||
ctx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self {
|
pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self {
|
||||||
Context {
|
Context {
|
||||||
|
@ -143,7 +40,7 @@ impl Context {
|
||||||
Some(p) => p.read().unwrap().type_dict.clone(),
|
Some(p) => p.read().unwrap().type_dict.clone(),
|
||||||
None => Arc::new(RwLock::new(TypeDict::new()))
|
None => Arc::new(RwLock::new(TypeDict::new()))
|
||||||
},
|
},
|
||||||
morphisms: HashMap::new(),
|
morphisms: MorphismBase::new(),
|
||||||
nodes: HashMap::new(),
|
nodes: HashMap::new(),
|
||||||
list_types: match parent.as_ref() {
|
list_types: match parent.as_ref() {
|
||||||
Some(p) => p.read().unwrap().list_types.clone(),
|
Some(p) => p.read().unwrap().list_types.clone(),
|
||||||
|
@ -240,105 +137,20 @@ impl Context {
|
||||||
pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
|
pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
|
||||||
self.type_dict.read().unwrap().unparse(&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, OuterViewPort<dyn SingletonView<Item = usize>>) -> Option<NestedNode> + Send + Sync>) {
|
|
||||||
let dict = self.type_dict.clone();
|
|
||||||
let mut dict = dict.write().unwrap();
|
|
||||||
|
|
||||||
let tyid =
|
|
||||||
if let Some(tyid) = dict.get_typeid(&tn.into()) {
|
|
||||||
tyid
|
|
||||||
} else {
|
|
||||||
dict.add_typename(tn.into())
|
|
||||||
};
|
|
||||||
|
|
||||||
let morphism_pattern = MorphismTypePattern {
|
|
||||||
src_tyid: None,
|
|
||||||
dst_tyid: tyid
|
|
||||||
};
|
|
||||||
|
|
||||||
drop(dict);
|
|
||||||
|
|
||||||
self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| {
|
|
||||||
mk_editor(node.ctx.clone(), dst_type, node.disp.depth)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_morphism(
|
|
||||||
&mut self,
|
|
||||||
morph_type_pattern: MorphismTypePattern,
|
|
||||||
morph_fn: Arc<
|
|
||||||
dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
|
|
||||||
+ Send + Sync
|
|
||||||
>
|
|
||||||
) {
|
|
||||||
self.morphisms.insert(morph_type_pattern, morph_fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_morphism(&self, ty: MorphismType) -> Option<Arc<dyn Fn(NestedNode, TypeTerm) -> Option<NestedNode> + Send + Sync>> {
|
|
||||||
let pattern = MorphismTypePattern::from(ty.clone());
|
|
||||||
|
|
||||||
if let Some(morphism) = self.morphisms.get( &pattern ) {
|
|
||||||
Some(morphism.clone())
|
|
||||||
} else {
|
|
||||||
self.parent.as_ref()?
|
|
||||||
.read().unwrap()
|
|
||||||
.get_morphism(ty)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn make_node(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Option<NestedNode> {
|
|
||||||
let mk_node = ctx.read().unwrap().get_morphism(MorphismType {
|
|
||||||
src_type: None,
|
|
||||||
dst_type: type_term.clone()
|
|
||||||
}).expect(&format!("morphism {}", ctx.read().unwrap().type_term_to_str(&type_term)));
|
|
||||||
|
|
||||||
/* create new context per node ?? too heavy.. whats the reason? TODO */
|
|
||||||
|
|
||||||
let new_ctx = Arc::new(RwLock::new(Context::with_parent(Some(ctx.clone()))));
|
|
||||||
|
|
||||||
mk_node(
|
|
||||||
NestedNode::new(new_ctx, ReprTree::new_arc(type_term.clone()), depth),
|
|
||||||
type_term
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn morph_node(mut node: NestedNode, dst_type: TypeTerm) -> NestedNode {
|
|
||||||
let src_type = node.data.read().unwrap().get_type().clone();
|
|
||||||
let pattern = MorphismType { src_type: Some(src_type), dst_type: dst_type.clone() };
|
|
||||||
|
|
||||||
/* it is not univesally true to always use ascend.
|
|
||||||
*/
|
|
||||||
node.data =
|
|
||||||
ReprTree::ascend(
|
|
||||||
&node.data,
|
|
||||||
dst_type.clone()
|
|
||||||
);
|
|
||||||
|
|
||||||
let m = node.ctx.read().unwrap().get_morphism(pattern.clone());
|
|
||||||
if let Some(transform) = m {
|
|
||||||
if let Some(new_node) = transform(node.clone(), dst_type) {
|
|
||||||
new_node
|
|
||||||
} else {
|
|
||||||
node.clone()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// adds an object without any representations
|
/// adds an object without any representations
|
||||||
pub fn add_obj(ctx: Arc<RwLock<Context>>, name: String, typename: &str) {
|
pub fn add_obj(ctx: Arc<RwLock<Context>>, name: String, typename: &str) {
|
||||||
let type_tag = ctx.read().unwrap()
|
let type_tag = ctx.read().unwrap()
|
||||||
.type_dict.write().unwrap()
|
.type_dict.write().unwrap()
|
||||||
.parse(typename).unwrap();
|
.parse(typename).unwrap();
|
||||||
|
|
||||||
|
/*
|
||||||
if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) {
|
if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) {
|
||||||
ctx.write().unwrap().nodes.insert(name, node);
|
ctx.write().unwrap().nodes.insert(name, node);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_obj(&self, name: &String) -> Option<NestedNode> {
|
pub fn get_obj(&self, name: &String) -> Option< Arc<RwLock<ReprTree>> > {
|
||||||
if let Some(obj) = self.nodes.get(name) {
|
if let Some(obj) = self.nodes.get(name) {
|
||||||
Some(obj.clone())
|
Some(obj.clone())
|
||||||
} else if let Some(parent) = self.parent.as_ref() {
|
} else if let Some(parent) = self.parent.as_ref() {
|
||||||
|
@ -347,85 +159,6 @@ impl Context {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn get_obj_port<'a, V: View + ?Sized + 'static>(
|
|
||||||
&self,
|
|
||||||
name: &str,
|
|
||||||
type_ladder: impl Iterator<Item = &'a str>,
|
|
||||||
) -> Option<OuterViewPort<V>>
|
|
||||||
where
|
|
||||||
V::Msg: Clone,
|
|
||||||
{
|
|
||||||
self.get_obj(&name.into())?
|
|
||||||
.downcast_ladder(type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()))?
|
|
||||||
.get_port()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_repr<'a>(
|
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
type_ladder: impl Iterator<Item = &'a str>,
|
|
||||||
port: AnyOuterViewPort,
|
|
||||||
) {
|
|
||||||
self.get_obj(&name.to_string())
|
|
||||||
.unwrap()
|
|
||||||
.repr
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert_leaf(
|
|
||||||
type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()),
|
|
||||||
port,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn epi_cast(&mut self, name: &str, typename: &str) {
|
|
||||||
let dst_type = self.type_dict.type_term_from_str(typename).unwrap();
|
|
||||||
let old_obj = self.objects.get(&name.to_string()).unwrap().clone();
|
|
||||||
let new_obj = if let Some(ctor) = self.morphism_constructors.get(&MorphismType {
|
|
||||||
mode: MorphismMode::Epi,
|
|
||||||
src_type: old_obj.type_tag.clone(),
|
|
||||||
dst_type: dst_type.clone(),
|
|
||||||
}) {
|
|
||||||
ctor(old_obj.clone())
|
|
||||||
} else {
|
|
||||||
Arc::new(RwLock::new(ReprTree::new(dst_type)))
|
|
||||||
};
|
|
||||||
|
|
||||||
new_obj
|
|
||||||
.repr
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert_branch(old_obj.type_tag, old_obj.repr);
|
|
||||||
|
|
||||||
self.objects.insert(name.to_string(), new_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mono_view<'a, V: View + ?Sized + 'static>(
|
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
type_ladder: impl Iterator<Item = &'a str>,
|
|
||||||
) -> Option<OuterViewPort<V>>
|
|
||||||
where
|
|
||||||
V::Msg: Clone,
|
|
||||||
{
|
|
||||||
if let Some(p) = self.get_obj_port(name, type_ladder) {
|
|
||||||
Some(p)
|
|
||||||
} else {
|
|
||||||
// todo : add repr with morphism constructor (if one exists)
|
|
||||||
/*
|
|
||||||
if let Some(ctor) = self.morphism_constructors.get(
|
|
||||||
&MorphismType {
|
|
||||||
mode: MorphismMode::Mono,
|
|
||||||
src_type: old_obj.type_tag.clone(),
|
|
||||||
dst_type:
|
|
||||||
}
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
pub mod context;
|
pub mod context;
|
||||||
|
pub mod morphism;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
context::{Context, MorphismMode, MorphismType, MorphismTypePattern},
|
context::{Context},
|
||||||
|
morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase}
|
||||||
};
|
};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
@ -16,7 +18,7 @@ use {
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ReprTree {
|
pub struct ReprTree {
|
||||||
type_tag: TypeTerm,
|
type_tag: TypeTerm,
|
||||||
port: Option<AnyOuterViewPort>,
|
port: Option<AnyOuterViewPort>,
|
||||||
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
|
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
|
||||||
|
@ -97,6 +99,8 @@ impl ReprTree {
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
|
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
|
||||||
where
|
where
|
||||||
V::Msg: Clone,
|
V::Msg: Clone,
|
||||||
|
@ -137,110 +141,5 @@ impl ReprTree {
|
||||||
n.insert_branch(rt.clone());
|
n.insert_branch(rt.clone());
|
||||||
Arc::new(RwLock::new(n))
|
Arc::new(RwLock::new(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn add_iso_repr(
|
|
||||||
&self,
|
|
||||||
type_ladder: impl Iterator<Item = TypeTerm>,
|
|
||||||
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
|
||||||
) {
|
|
||||||
let mut cur_repr = self.repr.clone();
|
|
||||||
|
|
||||||
for dst_type in type_ladder {
|
|
||||||
if let Some(next_repr) = self.repr.read().unwrap().branches.get(&dst_type) {
|
|
||||||
// go deeper
|
|
||||||
cur_repr = next_repr.clone();
|
|
||||||
} else {
|
|
||||||
// search for morphism constructor and insert new repr
|
|
||||||
let mut obj = None;
|
|
||||||
|
|
||||||
for src_type in cur_repr.read().unwrap().branches.keys() {
|
|
||||||
if let Some(ctor) = morphism_constructors.get(&MorphismType {
|
|
||||||
mode: MorphismMode::Iso,
|
|
||||||
src_type: src_type.clone(),
|
|
||||||
dst_type: dst_type.clone(),
|
|
||||||
}) {
|
|
||||||
let new_obj = ctor(Object {
|
|
||||||
type_tag: src_type.clone(),
|
|
||||||
repr: cur_repr
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.branches
|
|
||||||
.get(&src_type)
|
|
||||||
.unwrap()
|
|
||||||
.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
assert!(new_obj.type_tag == dst_type);
|
|
||||||
|
|
||||||
obj = Some(new_obj);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(obj) = obj {
|
|
||||||
cur_repr
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert_branch(obj.type_tag, obj.repr);
|
|
||||||
} else {
|
|
||||||
panic!("could not find matching isomorphism!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_mono_repr<'a>(
|
|
||||||
&self,
|
|
||||||
type_ladder: impl Iterator<Item = TypeTerm>,
|
|
||||||
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
|
||||||
) {
|
|
||||||
let mut cur_type = self.type_tag.clone();
|
|
||||||
let mut cur_repr = self.repr.clone();
|
|
||||||
|
|
||||||
for dst_type in type_ladder {
|
|
||||||
if let Some(next_repr) = self.repr.read().unwrap().branches.get(&dst_type) {
|
|
||||||
// go deeper
|
|
||||||
cur_type = dst_type;
|
|
||||||
cur_repr = next_repr.clone();
|
|
||||||
} else {
|
|
||||||
if let Some(constructor) = morphism_constructors.get(&MorphismType {
|
|
||||||
mode: MorphismMode::Mono,
|
|
||||||
src_type: cur_type.clone(),
|
|
||||||
dst_type: dst_type.clone(),
|
|
||||||
}) {
|
|
||||||
let new_obj = constructor(Object {
|
|
||||||
type_tag: cur_type.clone(),
|
|
||||||
repr: cur_repr
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.branches
|
|
||||||
.get(&cur_type)
|
|
||||||
.unwrap()
|
|
||||||
.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
assert!(new_obj.type_tag == dst_type);
|
|
||||||
cur_repr
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert_branch(new_obj.type_tag.clone(), new_obj.repr.clone());
|
|
||||||
|
|
||||||
cur_type = new_obj.type_tag;
|
|
||||||
cur_repr = new_obj.repr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace with higher-level type in which self is a repr branch
|
|
||||||
pub fn epi_cast<'a>(
|
|
||||||
&self,
|
|
||||||
_type_ladder: impl Iterator<Item = TypeTerm>,
|
|
||||||
_morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
|
||||||
) {
|
|
||||||
// todo
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
105
lib-nested-core/src/repr_tree/morphism.rs
Normal file
105
lib-nested-core/src/repr_tree/morphism.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
use {
|
||||||
|
laddertypes::{TypeTerm, TypeID},
|
||||||
|
crate::{
|
||||||
|
repr_tree::{ReprTree},
|
||||||
|
},
|
||||||
|
std::{
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
collections::HashMap
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
|
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
|
||||||
|
pub struct MorphismType {
|
||||||
|
pub src_type: TypeTerm,
|
||||||
|
pub dst_type: TypeTerm,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct GenericReprTreeMorphism {
|
||||||
|
morph_type: MorphismType,
|
||||||
|
repr_tree_op: Arc<
|
||||||
|
dyn Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> )
|
||||||
|
+ Send + Sync
|
||||||
|
>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct MorphismBase {
|
||||||
|
morphisms: Vec< GenericReprTreeMorphism >
|
||||||
|
}
|
||||||
|
|
||||||
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
|
impl MorphismBase {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
MorphismBase {
|
||||||
|
morphisms: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_morphism(
|
||||||
|
&mut self,
|
||||||
|
morph_type: MorphismType,
|
||||||
|
repr_tree_op: impl Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + Send + Sync
|
||||||
|
) {
|
||||||
|
self.morphisms.push(
|
||||||
|
GenericReprTreeMorphism {
|
||||||
|
morph_type,
|
||||||
|
repr_tree_op: Arc::new(repr_tree_op)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_morphism(
|
||||||
|
&self,
|
||||||
|
src_type: &TypeTerm,
|
||||||
|
dst_type: &TypeTerm
|
||||||
|
) -> Option<(&GenericReprTreeMorphism, HashMap<TypeID, TypeTerm>)> {
|
||||||
|
for m in self.morphisms.iter() {
|
||||||
|
|
||||||
|
let unification_problem = laddertypes::UnificationProblem::new(
|
||||||
|
vec![
|
||||||
|
( src_type.clone(), m.morph_type.src_type.clone() ),
|
||||||
|
( dst_type.clone(), m.morph_type.dst_type.clone() )
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Ok(σ) = unification_problem.solve() {
|
||||||
|
eprintln!("found matching morphism");
|
||||||
|
return Some((m, σ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn morph(
|
||||||
|
&self,
|
||||||
|
repr_tree: Arc<RwLock<ReprTree>>,
|
||||||
|
target_type: &TypeTerm
|
||||||
|
) {
|
||||||
|
if let Some((m, σ)) = self.find_morphism( repr_tree.read().unwrap().get_type(), target_type ) {
|
||||||
|
(m.repr_tree_op)( repr_tree, &σ );
|
||||||
|
} else {
|
||||||
|
eprintln!("could not find morphism");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
/*
|
||||||
|
impl MorphismType {
|
||||||
|
pub fn to_str(&self, ctx: &Context) -> String {
|
||||||
|
format!("{:?} -> {:?}",
|
||||||
|
if let Some(t) = self.src_type.as_ref() {
|
||||||
|
ctx.type_dict.read().unwrap().unparse(t)
|
||||||
|
} else {
|
||||||
|
"None".into()
|
||||||
|
},
|
||||||
|
ctx.type_dict.read().unwrap().unparse(&self.dst_type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
|
@ -1,3 +1,84 @@
|
||||||
|
|
||||||
pub mod list;
|
pub mod list;
|
||||||
|
|
||||||
|
use {
|
||||||
|
nested::{
|
||||||
|
edit_tree::{NestedNode},
|
||||||
|
repr_tree::{ReprTree, Context}
|
||||||
|
},
|
||||||
|
r3vi::{
|
||||||
|
view::{singleton::*, sequence::*},
|
||||||
|
projection::decorate_sequence::*
|
||||||
|
},
|
||||||
|
crate::{
|
||||||
|
make_label,
|
||||||
|
DisplaySegment,
|
||||||
|
atom::TerminalAtom
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn node_make_char_view(
|
||||||
|
node: NestedNode
|
||||||
|
) -> NestedNode {
|
||||||
|
node.disp.view
|
||||||
|
.write().unwrap()
|
||||||
|
.insert_branch(ReprTree::new_leaf(
|
||||||
|
Context::parse(&node.ctx, "TerminalView"),
|
||||||
|
node.data
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get_port::<dyn SingletonView<Item = char>>()
|
||||||
|
.expect("unable to get Char-view")
|
||||||
|
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
|
||||||
|
.to_grid()
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
|
||||||
|
node
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn node_make_seq_view(
|
||||||
|
mut node: NestedNode
|
||||||
|
) -> NestedNode {
|
||||||
|
node.disp.view
|
||||||
|
.write().unwrap()
|
||||||
|
.insert_branch(ReprTree::new_leaf(
|
||||||
|
Context::parse(&node.ctx, "TerminalView"),
|
||||||
|
node.data
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get_port::<dyn SequenceView<Item = NestedNode>>()
|
||||||
|
.expect("unable to get Seq-view")
|
||||||
|
.map(move |char_node| node_make_tty_view(char_node.clone()).display_view() )
|
||||||
|
.wrap(make_label("("), make_label(")"))
|
||||||
|
.to_grid_horizontal()
|
||||||
|
.flatten()
|
||||||
|
.into()
|
||||||
|
));
|
||||||
|
node
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn node_make_list_edit(
|
||||||
|
mut node: NestedNode
|
||||||
|
) -> NestedNode {
|
||||||
|
list::PTYListStyle::for_node( &mut node, ("(", "", ")") );
|
||||||
|
list::PTYListController::for_node( &mut node, None, None );
|
||||||
|
|
||||||
|
node
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn node_make_tty_view(
|
||||||
|
node: NestedNode
|
||||||
|
) -> NestedNode {
|
||||||
|
if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") {
|
||||||
|
node_make_char_view( node )
|
||||||
|
} else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") {
|
||||||
|
node_make_seq_view( node )
|
||||||
|
} else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") {
|
||||||
|
node_make_list_edit( node )
|
||||||
|
} else {
|
||||||
|
eprintln!("couldnt add view");
|
||||||
|
node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue