From dc1dc3fe24304595e47dd33b349f556a3630714d Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 15 Aug 2023 23:18:51 +0200
Subject: [PATCH] node: adapt new() to always initialize ctx and data; fix
 get_morphism bug

---
 nested/src/editors/char/mod.rs        |  18 +-
 nested/src/editors/integer/editor.rs  |  37 ++--
 nested/src/editors/list/editor.rs     |   6 +-
 nested/src/editors/list/pty_editor.rs |   2 +-
 nested/src/editors/sum/editor.rs      |  14 +-
 nested/src/tree/node.rs               | 290 +++++++++++++-------------
 nested/src/type_system/context.rs     |  86 +++++---
 nested/src/type_system/editor.rs      |  72 +++++--
 nested/src/type_system/make_editor.rs |  11 +-
 nested/src/type_system/repr_tree.rs   |   4 +
 nested/src/type_system/term.rs        |  53 ++---
 11 files changed, 338 insertions(+), 255 deletions(-)

diff --git a/nested/src/editors/char/mod.rs b/nested/src/editors/char/mod.rs
index d54b60b..6297b3c 100644
--- a/nested/src/editors/char/mod.rs
+++ b/nested/src/editors/char/mod.rs
@@ -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))
diff --git a/nested/src/editors/integer/editor.rs b/nested/src/editors/integer/editor.rs
index d13e25c..f5f9715 100644
--- a/nested/src/editors/integer/editor.rs
+++ b/nested/src/editors/integer/editor.rs
@@ -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
diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs
index 23e9986..802c99f 100644
--- a/nested/src/editors/list/editor.rs
+++ b/nested/src/editors/list/editor.rs
@@ -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(),
diff --git a/nested/src/editors/list/pty_editor.rs b/nested/src/editors/list/pty_editor.rs
index 8fdac59..b3bd245 100644
--- a/nested/src/editors/list/pty_editor.rs
+++ b/nested/src/editors/list/pty_editor.rs
@@ -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() {
diff --git a/nested/src/editors/sum/editor.rs b/nested/src/editors/sum/editor.rs
index 5000772..24c587e 100644
--- a/nested/src/editors/sum/editor.rs
+++ b/nested/src/editors/sum/editor.rs
@@ -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())
diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs
index d2dc585..0f94460 100644
--- a/nested/src/tree/node.rs
+++ b/nested/src/tree/node.rs
@@ -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
-        }
-    }
-}
-
diff --git a/nested/src/type_system/context.rs b/nested/src/type_system/context.rs
index 169ac18..54d5c4e 100644
--- a/nested/src/type_system/context.rs
+++ b/nested/src/type_system/context.rs
@@ -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
         }
     }
diff --git a/nested/src/type_system/editor.rs b/nested/src/type_system/editor.rs
index 32b21cb..5ab137d 100644
--- a/nested/src/type_system/editor.rs
+++ b/nested/src/type_system/editor.rs
@@ -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();
 
diff --git a/nested/src/type_system/make_editor.rs b/nested/src/type_system/make_editor.rs
index 8dcec4e..dde7243 100644
--- a/nested/src/type_system/make_editor.rs
+++ b/nested/src/type_system/make_editor.rs
@@ -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)
             }
diff --git a/nested/src/type_system/repr_tree.rs b/nested/src/type_system/repr_tree.rs
index 87164f3..62f9246 100644
--- a/nested/src/type_system/repr_tree.rs
+++ b/nested/src/type_system/repr_tree.rs
@@ -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
     }
diff --git a/nested/src/type_system/term.rs b/nested/src/type_system/term.rs
index a66b408..c55aa90 100644
--- a/nested/src/type_system/term.rs
+++ b/nested/src/type_system/term.rs
@@ -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(),
-                            ));
-                        }
                     }
                 }
             }