node: adapt new() to always initialize ctx and data; fix get_morphism bug
This commit is contained in:
parent
fa8b80678e
commit
dc1dc3fe24
11 changed files with 338 additions and 255 deletions
|
@ -70,15 +70,15 @@ impl CharEditor {
|
|||
let ctx = ctx0.clone();
|
||||
|
||||
let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() }));
|
||||
|
||||
NestedNode::new(0)
|
||||
.set_ctx(ctx0.clone())
|
||||
.set_data(
|
||||
ReprTree::new_leaf(
|
||||
ctx0.read().unwrap().type_term_from_str("( Char )").unwrap(),
|
||||
data.get_port().into()
|
||||
)
|
||||
)
|
||||
|
||||
NestedNode::new(
|
||||
ctx0.clone(),
|
||||
ReprTree::new_leaf(
|
||||
ctx0.read().unwrap().type_term_from_str("( Char )").unwrap(),
|
||||
data.get_port().into()
|
||||
),
|
||||
0 // fixme
|
||||
)
|
||||
.set_view(data
|
||||
.get_port()
|
||||
.map(move |c| TerminalAtom::from(c))
|
||||
|
|
|
@ -90,10 +90,9 @@ impl DigitEditor {
|
|||
let ed = editor.write().unwrap();
|
||||
let r = ed.radix;
|
||||
|
||||
NestedNode::new(depth)
|
||||
.set_ctx(ed.ctx.clone())
|
||||
NestedNode::new(ed.ctx.clone(), data, depth)
|
||||
|
||||
.set_cmd(editor.clone())
|
||||
.set_data(data)
|
||||
.set_view(
|
||||
ed.data
|
||||
.get_port()
|
||||
|
@ -125,11 +124,10 @@ impl DigitEditor {
|
|||
}
|
||||
|
||||
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
|
||||
let data_view = self.get_data_port();
|
||||
ReprTree::ascend(
|
||||
&ReprTree::new_leaf(
|
||||
self.ctx.read().unwrap().type_term_from_str("( u32 )").unwrap(),
|
||||
data_view.into()
|
||||
self.ctx.read().unwrap().type_term_from_str("( Seq u32 )").unwrap(),
|
||||
self.get_data_port().into()
|
||||
),
|
||||
self.get_type()
|
||||
)
|
||||
|
@ -143,7 +141,21 @@ pub struct PosIntEditor {
|
|||
|
||||
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).unwrap();
|
||||
let mut node = Context::make_node(
|
||||
&ctx,
|
||||
(&ctx, format!("( List ( Digit {} ) )", radix).as_str()).into(),
|
||||
0
|
||||
).unwrap();
|
||||
|
||||
// Set Type
|
||||
node.data = ReprTree::ascend(
|
||||
&node.data.clone(),
|
||||
TypeTerm::App(vec![
|
||||
TypeTerm::TypeID(ctx.read().unwrap().get_typeid("PosInt").unwrap()),
|
||||
TypeTerm::Num(radix as i64).into(),
|
||||
TypeTerm::TypeID(ctx.read().unwrap().get_typeid("BigEndian").unwrap())
|
||||
]
|
||||
));
|
||||
|
||||
PTYListController::for_node( &mut node, Some(' '), None );
|
||||
PTYListStyle::for_node( &mut node,
|
||||
|
@ -158,17 +170,6 @@ impl PosIntEditor {
|
|||
)
|
||||
);
|
||||
|
||||
// Set Type
|
||||
let data = node.data.clone().unwrap();
|
||||
node = node.set_data(ReprTree::ascend(
|
||||
&data,
|
||||
TypeTerm::App(vec![
|
||||
TypeTerm::TypeID(ctx.read().unwrap().get_typeid("PosInt").unwrap()),
|
||||
TypeTerm::Num(radix as i64).into(),
|
||||
TypeTerm::TypeID(ctx.read().unwrap().get_typeid("BigEndian").unwrap())
|
||||
]
|
||||
)));
|
||||
|
||||
PosIntEditor {
|
||||
radix,
|
||||
digits: node
|
||||
|
|
|
@ -126,9 +126,7 @@ impl ListEditor {
|
|||
|
||||
let e = editor.read().unwrap();
|
||||
|
||||
NestedNode::new(depth)
|
||||
.set_ctx(ctx)
|
||||
.set_data(data)
|
||||
NestedNode::new(ctx, data, depth)
|
||||
.set_editor(editor.clone())
|
||||
.set_nav(editor.clone())
|
||||
.set_cmd(editor.clone())
|
||||
|
@ -277,7 +275,7 @@ impl ListEditor {
|
|||
|
||||
eprintln!("send items to new tail");
|
||||
le_node.cmd.get().unwrap().write().unwrap().send_cmd_obj(
|
||||
self.data.get(idx).read().unwrap().data.clone().unwrap()
|
||||
self.data.get(idx).read().unwrap().data.clone()
|
||||
/*
|
||||
ReprTree::new_leaf(
|
||||
self.ctx.read().unwrap().type_term_from_str("( NestedNode )").unwrap(),
|
||||
|
|
|
@ -103,7 +103,7 @@ impl PTYListController {
|
|||
close_char: Option<char>
|
||||
) {
|
||||
{
|
||||
let mut ctx = node.ctx.as_ref().unwrap();
|
||||
let mut ctx = node.ctx.as_ref();
|
||||
let mut ctx = ctx.write().unwrap();
|
||||
|
||||
if let Some(c) = split_char.as_ref() {
|
||||
|
|
|
@ -9,7 +9,7 @@ use {
|
|||
crate::{
|
||||
terminal::TerminalView,
|
||||
editors::list::ListCursorMode,
|
||||
type_system::{Context, ReprTree},
|
||||
type_system::{Context, TypeTerm, ReprTree},
|
||||
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||
diagnostics::{Diagnostics, Message},
|
||||
tree::NestedNode,
|
||||
|
@ -49,11 +49,19 @@ impl SumEditor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init_ctx(ctx: &Arc<RwLock<Context>>) {
|
||||
ctx.write().unwrap().add_typename("Sum".into());
|
||||
}
|
||||
|
||||
pub fn into_node(self, ctx: Arc<RwLock<Context>>) -> NestedNode {
|
||||
let view = self.pty_view();
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
NestedNode::new(0)
|
||||
.set_ctx(ctx)
|
||||
|
||||
NestedNode::new(
|
||||
ctx.clone(),
|
||||
ReprTree::new_arc(TypeTerm::TypeID(ctx.read().unwrap().get_typeid("Sum").unwrap())),
|
||||
0
|
||||
)
|
||||
.set_view(view)
|
||||
.set_editor(editor.clone())
|
||||
.set_cmd(editor.clone())
|
||||
|
|
|
@ -18,10 +18,10 @@ use {
|
|||
#[derive(Clone)]
|
||||
pub struct NestedNode {
|
||||
/// context
|
||||
pub ctx: Option< Arc<RwLock<Context>> >,
|
||||
pub ctx: Arc<RwLock<Context>>,
|
||||
|
||||
/// abstract data view
|
||||
pub data: Option< Arc<RwLock<ReprTree>> >,
|
||||
pub data: Arc<RwLock<ReprTree>>,
|
||||
|
||||
/// display view
|
||||
pub view: Option< OuterViewPort<dyn TerminalView> >,
|
||||
|
@ -49,13 +49,134 @@ pub struct NestedNode {
|
|||
>,
|
||||
}
|
||||
|
||||
impl ObjCommander for NestedNode {
|
||||
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
||||
if let Some(cmd) = self.cmd.get() {
|
||||
// todo: filter out tree-nav cmds and send them to tree_nav
|
||||
cmd.write().unwrap().send_cmd_obj(cmd_obj)
|
||||
impl NestedNode {
|
||||
pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: usize) -> Self {
|
||||
NestedNode {
|
||||
ctx,
|
||||
data,
|
||||
view: None,
|
||||
diag: None,
|
||||
depth: SingletonBuffer::new(depth),
|
||||
editor: SingletonBuffer::new(None),
|
||||
cmd: SingletonBuffer::new(None),
|
||||
close_char: SingletonBuffer::new(None),
|
||||
tree_nav: SingletonBuffer::new(None)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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(
|
||||
(&ctx, "( Char )"),
|
||||
buf.get_port().into()
|
||||
),
|
||||
0
|
||||
)
|
||||
.set_view(buf.get_port()
|
||||
.map(|c| TerminalAtom::from(c))
|
||||
.to_index()
|
||||
.map_key(
|
||||
|_x| {
|
||||
Point2::new(0, 0)
|
||||
},
|
||||
|p| {
|
||||
if *p == Point2::new(0,0) { Some(()) } else { None }
|
||||
})
|
||||
)
|
||||
.set_editor(Arc::new(RwLock::new(buf)))
|
||||
}
|
||||
|
||||
|
||||
//\\//\\
|
||||
|
||||
pub fn morph(self, ty: TypeTerm) -> NestedNode {
|
||||
Context::morph_node(self, ty)
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> TypeTerm {
|
||||
self.data.read().unwrap().get_type().clone()
|
||||
}
|
||||
|
||||
//\\//\\
|
||||
|
||||
pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self {
|
||||
self.editor.set(Some(editor));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_view(mut self, view: OuterViewPort<dyn TerminalView>) -> Self {
|
||||
self.view = Some(view);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
|
||||
self.cmd.set(Some(cmd));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
|
||||
self.tree_nav.set(Some(nav));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self {
|
||||
self.diag = Some(diag);
|
||||
self
|
||||
}
|
||||
|
||||
//\\//\\
|
||||
|
||||
pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
||||
self.diag.clone().unwrap_or(ViewPort::new().into_outer())
|
||||
}
|
||||
|
||||
pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.view.clone().unwrap_or(ViewPort::new().into_outer())
|
||||
}
|
||||
|
||||
pub fn get_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 repr_tree = ReprTree::descend_ladder(&self.data, type_ladder)?;
|
||||
repr_tree.clone().read().unwrap()
|
||||
.get_port::<V>().clone()
|
||||
}
|
||||
|
||||
pub fn get_data_view<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<Arc<V>>
|
||||
where V::Msg: Clone {
|
||||
self.get_data_port::<V>(type_str)?.get_view()
|
||||
}
|
||||
|
||||
|
||||
/* TODO
|
||||
|
||||
pub fn get_seq_view<'a, T: Clone>(&self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<dyn SingletonView<Item = T>>> {
|
||||
self.get_data_view::<dyn SequenceView<Item = NestedNode>>(type_str)
|
||||
.unwrap()
|
||||
.map({
|
||||
move |node| {
|
||||
node.get_data_view::<dyn SingletonView<Item = T>>().get()
|
||||
}
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> {
|
||||
if let Some(edit) = self.editor.get() {
|
||||
if let Ok(edit) = edit.downcast::<RwLock<T>>() {
|
||||
Some(edit)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
TreeNavResult::Exit
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,8 +191,10 @@ impl TreeType for NestedNode {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* TODO: remove that at some point
|
||||
*/
|
||||
// todo: remove that at some point
|
||||
impl TerminalEditor for NestedNode {
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.get_view()
|
||||
|
@ -80,10 +203,10 @@ impl TerminalEditor for NestedNode {
|
|||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||
let buf = SingletonBuffer::new(event.clone());
|
||||
|
||||
if let (Some(cmd),Some(ctx)) = (self.cmd.get(),self.ctx.as_ref()) {
|
||||
if let Some(cmd) = self.cmd.get() {
|
||||
cmd.write().unwrap().send_cmd_obj(
|
||||
ReprTree::new_leaf(
|
||||
ctx.read().unwrap().type_term_from_str("( TerminalEvent )").unwrap(),
|
||||
self.ctx.read().unwrap().type_term_from_str("( TerminalEvent )").unwrap(),
|
||||
AnyOuterViewPort::from(buf.get_port())
|
||||
));
|
||||
}
|
||||
|
@ -146,143 +269,20 @@ impl TreeNav for NestedNode {
|
|||
}
|
||||
}
|
||||
|
||||
impl ObjCommander for NestedNode {
|
||||
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
||||
if let Some(cmd) = self.cmd.get() {
|
||||
// todo: filter out tree-nav cmds and send them to tree_nav
|
||||
cmd.write().unwrap().send_cmd_obj(cmd_obj)
|
||||
} else {
|
||||
TreeNavResult::Exit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Diagnostics for NestedNode {
|
||||
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
||||
self.get_diag()
|
||||
}
|
||||
}
|
||||
|
||||
impl NestedNode {
|
||||
pub fn new(depth: usize) -> Self {
|
||||
NestedNode {
|
||||
ctx: None,
|
||||
data: None,
|
||||
view: None,
|
||||
diag: None,
|
||||
depth: SingletonBuffer::new(depth),
|
||||
editor: SingletonBuffer::new(None),
|
||||
cmd: SingletonBuffer::new(None),
|
||||
close_char: SingletonBuffer::new(None),
|
||||
tree_nav: SingletonBuffer::new(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_char(ctx: Arc<RwLock<Context>>, c: char) -> NestedNode {
|
||||
let buf = r3vi::buffer::singleton::SingletonBuffer::<char>::new(c);
|
||||
|
||||
NestedNode::new(0)
|
||||
.set_view(buf.get_port()
|
||||
.map(|c| TerminalAtom::from(c))
|
||||
.to_index()
|
||||
.map_key(
|
||||
|_x| {
|
||||
Point2::new(0, 0)
|
||||
},
|
||||
|p| {
|
||||
if *p == Point2::new(0,0) { Some(()) } else { None }
|
||||
})
|
||||
)
|
||||
.set_data(
|
||||
ReprTree::new_leaf(
|
||||
(&ctx, "( Char )"),
|
||||
buf.get_port().into()
|
||||
)
|
||||
)
|
||||
.set_editor(Arc::new(RwLock::new(buf)))
|
||||
.set_ctx(ctx)
|
||||
}
|
||||
|
||||
pub fn set_ctx(mut self, ctx: Arc<RwLock<Context>>) -> Self {
|
||||
self.ctx = Some(ctx);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_data(mut self, data: Arc<RwLock<ReprTree>>) -> Self {
|
||||
self.data = Some(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self {
|
||||
self.editor.set(Some(editor));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_view(mut self, view: OuterViewPort<dyn TerminalView>) -> Self {
|
||||
self.view = Some(view);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
|
||||
self.cmd.set(Some(cmd));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
|
||||
self.tree_nav.set(Some(nav));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self {
|
||||
self.diag = Some(diag);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
||||
self.diag.clone().unwrap_or(ViewPort::new().into_outer())
|
||||
}
|
||||
|
||||
pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.view.clone().unwrap_or(ViewPort::new().into_outer())
|
||||
}
|
||||
|
||||
pub fn morph(self, ty: TypeTerm) -> NestedNode {
|
||||
Context::morph_node(self, ty)
|
||||
}
|
||||
|
||||
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 {
|
||||
if let Some(ctx) = self.ctx.clone() {
|
||||
if let Some(data) = self.data.clone() {
|
||||
let type_ladder = type_str.map(|s| ((&ctx, s)).into());
|
||||
|
||||
let repr_tree = ReprTree::descend_ladder(&data, type_ladder)?;
|
||||
repr_tree.clone().read().unwrap()
|
||||
.get_port::<V>().clone()
|
||||
} else {
|
||||
eprintln!("get_data(): no data port");
|
||||
None
|
||||
}
|
||||
} else {
|
||||
eprintln!("get_data(): no ctx");
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
/*
|
||||
pub fn get_seq_view<'a, T: Clone>(&self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<dyn SingletonView<Item = T>>> {
|
||||
self.get_data_view::<dyn SequenceView<Item = NestedNode>>(type_str)
|
||||
.unwrap()
|
||||
.map({
|
||||
move |node| {
|
||||
node.get_data_view::<dyn SingletonView<Item = T>>().get()
|
||||
}
|
||||
})
|
||||
}
|
||||
*/
|
||||
pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> {
|
||||
if let Some(edit) = self.editor.get() {
|
||||
if let Ok(edit) = edit.downcast::<RwLock<T>>() {
|
||||
Some(edit)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,21 +31,45 @@ pub enum MorphismMode {
|
|||
Any,
|
||||
}
|
||||
|
||||
#[derive(Clone, Hash, PartialEq, Eq)]
|
||||
#[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, Debug)]
|
||||
#[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!("src_tyid = {:?}, dst_tyid = {:?}",
|
||||
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!("src_tyid = {:?}, dst_tyid = {:?}",
|
||||
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 from(mut value: MorphismType) -> MorphismTypePattern {
|
||||
fn strip( x: &TypeTerm ) -> TypeID {
|
||||
match x {
|
||||
TypeTerm::TypeID(id) => id.clone(),
|
||||
|
@ -54,13 +78,9 @@ impl From<MorphismType> for MorphismTypePattern {
|
|||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
MorphismTypePattern {
|
||||
src_tyid: match value.src_type {
|
||||
Some(TypeTerm::TypeID(id)) => Some(id),
|
||||
_ => None,
|
||||
},
|
||||
|
||||
MorphismTypePattern {
|
||||
src_tyid: value.src_type.map(|x| strip(&x)),
|
||||
dst_tyid: strip(&value.dst_type)
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +102,7 @@ pub struct Context {
|
|||
pub meta_chars: Vec< char >,
|
||||
|
||||
/// graph constructors
|
||||
/// TODO: move into separate struct MorphismMap or something
|
||||
morphisms: HashMap<
|
||||
MorphismTypePattern,
|
||||
Arc<
|
||||
|
@ -96,7 +117,7 @@ pub struct Context {
|
|||
|
||||
impl Into<TypeTerm> for (&Arc<RwLock<Context>>, &str) {
|
||||
fn into(self) -> TypeTerm {
|
||||
self.0.read().unwrap().type_term_from_str(self.1).unwrap()
|
||||
self.0.read().unwrap().type_term_from_str(self.1).expect("could not parse type term")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +205,7 @@ impl Context {
|
|||
pub fn add_node_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, 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
|
||||
|
@ -196,10 +218,10 @@ impl Context {
|
|||
dst_tyid: tyid
|
||||
};
|
||||
|
||||
drop(dict);
|
||||
|
||||
self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| {
|
||||
let ctx = node.ctx.clone().unwrap();
|
||||
let depth = node.depth;
|
||||
mk_editor(ctx, dst_type, depth.get())
|
||||
mk_editor(node.ctx.clone(), dst_type, node.depth.get())
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -216,6 +238,7 @@ impl Context {
|
|||
|
||||
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 {
|
||||
|
@ -231,29 +254,29 @@ impl Context {
|
|||
dst_type: type_term.clone()
|
||||
}).expect("morphism");
|
||||
|
||||
mk_node(NestedNode::new(depth).set_ctx(
|
||||
Arc::new(RwLock::new(
|
||||
Context::with_parent(Some(ctx.clone()))))
|
||||
), 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()))));
|
||||
let new_depth = depth;
|
||||
|
||||
mk_node(
|
||||
NestedNode::new(new_ctx, ReprTree::new_arc(type_term.clone()), 0),
|
||||
type_term
|
||||
)
|
||||
}
|
||||
|
||||
pub fn morph_node(mut node: NestedNode, dst_type: TypeTerm) -> NestedNode {
|
||||
let ctx = node.ctx.clone().unwrap();
|
||||
let mut src_type = None;
|
||||
|
||||
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()
|
||||
)
|
||||
let mut 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 pattern = MorphismType { src_type, dst_type: dst_type.clone() }.into();
|
||||
|
||||
let m = ctx.read().unwrap().get_morphism(pattern);
|
||||
let m = node.ctx.read().unwrap().get_morphism(pattern);
|
||||
if let Some(transform) = m {
|
||||
if let Some(new_node) = transform(node.clone(), dst_type) {
|
||||
new_node
|
||||
|
@ -261,6 +284,7 @@ impl Context {
|
|||
node.clone()
|
||||
}
|
||||
} else {
|
||||
eprintln!("could not find morphism");
|
||||
node
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use {
|
|||
},
|
||||
crate::{
|
||||
type_system::{Context, TypeID, TypeTerm, ReprTree, MorphismTypePattern},
|
||||
terminal::{TerminalEvent},
|
||||
terminal::{TerminalEvent, TerminalStyle},
|
||||
editors::{sum::*, list::{ListCursorMode, ListEditor, PTYListStyle, PTYListController}},
|
||||
tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
|
||||
commander::ObjCommander,
|
||||
|
@ -33,6 +33,8 @@ pub struct TypeTermEditor {
|
|||
ctx: Arc<RwLock<Context>>,
|
||||
|
||||
data: Arc<RwLock<ReprTree>>,
|
||||
|
||||
// forward the editor to the node that references TypeTermEditor
|
||||
editor: SingletonBuffer<
|
||||
Option< Arc<dyn Any + Send + Sync> >
|
||||
>,
|
||||
|
@ -47,6 +49,49 @@ impl TypeTermEditor {
|
|||
ctx.add_list_typename("TypeSymbol".into());
|
||||
ctx.add_list_typename("TypeSymbol::Function".into());
|
||||
ctx.add_list_typename("TypeSymbol::Variable".into());
|
||||
|
||||
let pattern = MorphismTypePattern {
|
||||
src_tyid: ctx.get_typeid("List"),
|
||||
dst_tyid: ctx.get_typeid("TypeSymbol::Function").unwrap()
|
||||
};
|
||||
|
||||
ctx.add_morphism(pattern,
|
||||
Arc::new(
|
||||
|mut node, _dst_type:_| {
|
||||
PTYListController::for_node( &mut node, None, None );
|
||||
PTYListStyle::for_node( &mut node, ("","","") );
|
||||
|
||||
if let Some(v) = node.view {
|
||||
node.view = Some(
|
||||
v.map_item(|i,p| p.add_style_front(TerminalStyle::fg_color((220, 220, 0)))));
|
||||
}
|
||||
|
||||
Some(node)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
let pattern = MorphismTypePattern {
|
||||
src_tyid: ctx.get_typeid("List"),
|
||||
dst_tyid: ctx.get_typeid("TypeSymbol::Variable").unwrap()
|
||||
};
|
||||
|
||||
ctx.add_morphism(pattern,
|
||||
Arc::new(
|
||||
|mut node, _dst_type:_| {
|
||||
PTYListController::for_node( &mut node, None, None );
|
||||
PTYListStyle::for_node( &mut node, ("","","") );
|
||||
|
||||
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)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ctx.add_node_ctor(
|
||||
"TypeTerm", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
|
@ -54,6 +99,7 @@ impl TypeTermEditor {
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
/*
|
||||
ctx.add_list_typename("TypeLadder".into());
|
||||
ctx.add_node_ctor(
|
||||
|
@ -75,13 +121,19 @@ impl TypeTermEditor {
|
|||
eprintln!("morphism to typeterm");
|
||||
PTYListController::for_node( &mut node, Some(' '), None );
|
||||
PTYListStyle::for_node( &mut node, ("","","") );
|
||||
let mut new_node = TypeTermEditor::with_node( node.ctx.clone().unwrap(), node.depth.get(), node.clone(), State::Any );
|
||||
let mut new_node = TypeTermEditor::with_node( node.ctx.clone(), node.depth.get(), node.clone(), State::Any );
|
||||
Some(new_node)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
fn from_type_term(term: TypeTerm) -> TypeTermEditor {
|
||||
match term {
|
||||
TypeTerm::
|
||||
}
|
||||
}
|
||||
*/
|
||||
fn set_state(&mut self, new_state: State) {
|
||||
let old_node = self.cur_node.get();
|
||||
let mut node = match new_state {
|
||||
|
@ -105,7 +157,7 @@ impl TypeTermEditor {
|
|||
|
||||
self.data.write().unwrap().insert_leaf(
|
||||
vec![].into_iter(),
|
||||
node.data.clone().unwrap().read().unwrap()
|
||||
node.data.read().unwrap()
|
||||
.get_port::<dyn SingletonView<Item = char>>().unwrap()
|
||||
.map(
|
||||
|c| TypeTerm::Char(c)
|
||||
|
@ -123,11 +175,11 @@ impl TypeTermEditor {
|
|||
|
||||
self.data.write().unwrap().insert_leaf(
|
||||
vec![].into_iter(),
|
||||
node.data.clone().unwrap().read().unwrap()
|
||||
node.data.read().unwrap()
|
||||
.get_port::<dyn SequenceView<Item = NestedNode>>().unwrap()
|
||||
.map(
|
||||
|node| {
|
||||
node.data.as_ref().unwrap().read().unwrap().get_port::<dyn SingletonView<Item = TypeTerm>>().unwrap()
|
||||
node.data.read().unwrap().get_port::<dyn SingletonView<Item = TypeTerm>>().unwrap()
|
||||
}
|
||||
)
|
||||
.into()
|
||||
|
@ -192,10 +244,8 @@ impl TypeTermEditor {
|
|||
let cc = editor.cur_node.get().close_char;
|
||||
let editor = Arc::new(RwLock::new(editor));
|
||||
|
||||
let mut node = NestedNode::new(depth)
|
||||
.set_ctx(ctx)
|
||||
let mut node = NestedNode::new(ctx, data, depth)
|
||||
.set_view(view)
|
||||
.set_data(data)
|
||||
.set_nav(editor.clone())
|
||||
.set_cmd(editor.clone())
|
||||
.set_editor(editor.clone());
|
||||
|
@ -283,9 +333,7 @@ impl ObjCommander for TypeTermEditor {
|
|||
let cmd_obj = cmd_obj.read().unwrap();
|
||||
let cmd_type = cmd_obj.get_type().clone();
|
||||
|
||||
let char_type = (&self.ctx, "( Char )").into();
|
||||
|
||||
if cmd_type == char_type {
|
||||
if cmd_type == (&self.ctx, "( Char )").into() {
|
||||
if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
|
||||
let c = cmd_view.get();
|
||||
|
||||
|
|
|
@ -31,9 +31,7 @@ pub fn init_mem_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
);
|
||||
|
||||
Some(
|
||||
NestedNode::new(depth)
|
||||
.set_ctx(ctx)
|
||||
.set_data(data)
|
||||
NestedNode::new(ctx, data, depth)
|
||||
.set_editor(Arc::new(RwLock::new(buf)))
|
||||
)
|
||||
} else {
|
||||
|
@ -51,10 +49,12 @@ pub fn init_mem_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
|
||||
pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||
let ctx0 = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
|
||||
|
||||
ListEditor::init_ctx( &ctx0 );
|
||||
|
||||
|
||||
let mut ctx = ctx0.write().unwrap();
|
||||
|
||||
// TODO:: CharEditor::init_ctx( &ctx );
|
||||
ctx.add_node_ctor(
|
||||
"Char", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| {
|
||||
|
@ -63,7 +63,6 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
)
|
||||
);
|
||||
|
||||
|
||||
ctx.add_list_typename("Seq".into());
|
||||
ctx.add_list_typename("Sequence".into());
|
||||
ctx.add_list_typename("SepSeq".into());
|
||||
|
@ -95,7 +94,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
depth+1
|
||||
).expect("nested node");
|
||||
|
||||
//node = node.morph(dst_typ);
|
||||
node = node.morph(dst_typ);
|
||||
|
||||
Some(node)
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ impl ReprTree {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> {
|
||||
Arc::new(RwLock::new(Self::new(type_tag)))
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> &TypeTerm {
|
||||
&self.type_tag
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use {
|
||||
crate::{
|
||||
type_system::{TypeID}
|
||||
},
|
||||
crate::{type_system::{TypeID}},
|
||||
std::collections::HashMap
|
||||
};
|
||||
|
||||
|
@ -241,6 +239,9 @@ impl TypeTerm {
|
|||
}
|
||||
}
|
||||
|
||||
/* 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();
|
||||
|
||||
|
@ -263,36 +264,36 @@ impl TypeTerm {
|
|||
}
|
||||
}
|
||||
atom => {
|
||||
let f = term_stack.last_mut().unwrap();
|
||||
if let Some(f) = term_stack.last_mut() {
|
||||
match f {
|
||||
Some(f) => {
|
||||
let mut chars = atom.chars();
|
||||
let first = chars.next().unwrap();
|
||||
|
||||
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';
|
||||
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);
|
||||
}
|
||||
f.char_arg(c);
|
||||
} else {
|
||||
f.arg(TypeTerm::new(
|
||||
names.get(atom)
|
||||
.expect(&format!("invalid atom {}", atom)).clone()
|
||||
));
|
||||
}
|
||||
} 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 => {
|
||||
*f = Some(TypeTerm::new(
|
||||
names.get(atom).expect(&format!("invalid atom {}", atom)).clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue