diff --git a/nested/src/core/context.rs b/nested/src/core/context.rs index afafeee..07964e4 100644 --- a/nested/src/core/context.rs +++ b/nested/src/core/context.rs @@ -226,13 +226,13 @@ pub struct MorphismType { pub struct Context { /// assigns a name to every type - type_dict: TypeDict, + type_dict: Arc>, /// objects objects: HashMap>>, /// editors - editor_ctors: HashMap Option>> + Send + Sync>>, + editor_ctors: HashMap>, TypeTerm, usize) -> Option>> + Send + Sync>>, /// morphisms default_constructors: HashMap Arc> + Send + Sync>>, @@ -245,7 +245,10 @@ pub struct Context { impl Context { pub fn with_parent(parent: Option>>) -> Self { Context { - type_dict: TypeDict::new(), + type_dict: match parent.as_ref() { + Some(p) => p.read().unwrap().type_dict.clone(), + None => Arc::new(RwLock::new(TypeDict::new())) + }, editor_ctors: HashMap::new(), default_constructors: HashMap::new(), morphism_constructors: HashMap::new(), @@ -259,33 +262,41 @@ impl Context { } pub fn add_typename(&mut self, tn: String) { - self.type_dict.add_typename(tn); + self.type_dict.write().unwrap().add_typename(tn); } pub fn type_term_from_str(&self, tn: &str) -> Option { - self.type_dict.type_term_from_str(&tn) + self.type_dict.read().unwrap().type_term_from_str(&tn) } pub fn type_term_to_str(&self, t: &TypeTerm) -> String { - self.type_dict.type_term_to_str(&t) + self.type_dict.read().unwrap().type_term_to_str(&t) } - pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Box Option>> + Send + Sync>) { - if let Some(tid) = self.type_dict.get_typeid(&tn.into()) { - self.editor_ctors.insert(tid, mk_editor); - } else { - println!("invalid type name"); - } + pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc>, TypeTerm, usize) -> Option>> + Send + Sync>) { + let mut dict = self.type_dict.write().unwrap(); + let tyid = dict.get_typeid(&tn.into()).unwrap_or( dict.add_typename(tn.into()) ); + self.editor_ctors.insert(tyid, mk_editor); } - pub fn make_editor(&self, type_term: TypeTerm, depth: usize) -> Option>> { - if let TypeTerm::Type{ id, args } = type_term.clone() { - let mk_editor = self.editor_ctors.get(&id)?; - mk_editor(self, type_term, depth) + pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option>, TypeTerm, usize) -> Option>> + Send + Sync>> { + if let TypeTerm::Type{ id, args } = ty.clone() { + if let Some(m) = self.editor_ctors.get(&id).cloned() { + Some(m) + } else { + self.parent.as_ref()? + .read().unwrap() + .get_editor_ctor(&ty) + } } else { None } } + pub fn make_editor(ctx: Arc>, type_term: TypeTerm, depth: usize) -> Option>> { + let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?; + mk_editor(ctx, type_term, depth) + } + pub fn add_morphism( &mut self, morph_type: MorphismType, @@ -296,7 +307,7 @@ impl Context { /// adds an object without any representations pub fn add_obj(&mut self, name: String, typename: &str) { - let type_tag = self.type_dict.type_term_from_str(typename).unwrap(); + let type_tag = self.type_dict.read().unwrap().type_term_from_str(typename).unwrap(); self.objects.insert( name, diff --git a/nested/src/core/type_term.rs b/nested/src/core/type_term.rs index da064a8..28de52b 100644 --- a/nested/src/core/type_term.rs +++ b/nested/src/core/type_term.rs @@ -137,9 +137,11 @@ impl TypeDict { } } - pub fn add_typename(&mut self, tn: String) { - self.typenames.insert(tn, self.type_id_counter); + pub fn add_typename(&mut self, tn: String) -> u64 { + let tyid = self.type_id_counter; + self.typenames.insert(tn, tyid); self.type_id_counter += 1; + tyid } pub fn get_typeid(&self, tn: &String) -> Option { diff --git a/nested/src/make_editor.rs b/nested/src/make_editor.rs index 27115cd..b7822a8 100644 --- a/nested/src/make_editor.rs +++ b/nested/src/make_editor.rs @@ -49,77 +49,22 @@ struct GrammarRuleEditor { rhs: Arc>> } - -pub fn init_ctx() -> Arc> { - let mut ctx = Arc::new(RwLock::new(Context::new())); - for tn in vec![ - "MachineWord", "MachineInt", "MachineSyllab", "Bits", - "Vec", "Stream", "Json", - "Sequence", "AsciiString", "UTF-8-String", "Char", "String", "Symbol", - "PosInt", "Digit", "LittleEndian", "BigEndian", - "DiffStream", "ℕ", "List", "PathSegment", "Path", "Term", "RGB", "Vec3i" - ] { ctx.write().unwrap().add_typename(tn.into()); } +pub fn init_editor_ctx(parent: Arc>) -> Arc> { + let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); ctx.write().unwrap().add_editor_ctor( - "Char", Box::new( - |ctx: &Context, ty: TypeTerm, _depth: usize| { + "Char", Arc::new( + |ctx: Arc>, ty: TypeTerm, _depth: usize| { Some( Arc::new(RwLock::new(CharEditor::new())) as Arc>) } ) ); + ctx.write().unwrap().add_editor_ctor( - "Symbol", Box::new( - |ctx: &Context, ty: TypeTerm, depth: usize| { - ctx.make_editor( - ctx.type_term_from_str("( List Char 0 )").unwrap(), - depth - ) - } - ) - ); - ctx.write().unwrap().add_editor_ctor( - "String", Box::new( - |ctx: &Context, ty: TypeTerm, depth: usize| { - ctx.make_editor( - ctx.type_term_from_str("( List Char 3 )").unwrap(), - depth - ) - } - ) - ); - ctx.write().unwrap().add_editor_ctor( - "PosInt", Box::new( - |ctx: &Context, ty: TypeTerm, _depth: usize| { - match ty { - TypeTerm::Type { - id, args - } => { - if args.len() > 0 { - match args[0] { - TypeTerm::Num(radix) => { - Some( - Arc::new(RwLock::new(PosIntEditor::new(radix as u32))) - as Arc> - ) - }, - _ => None - } - } else { - None - } - } - _ => None - } - } - ) - ); - - ctx.write().unwrap().add_editor_ctor( - "List", Box::new({ - let ctx = ctx.clone(); - move |c_: &Context, ty: TypeTerm, depth: usize| { + "List", Arc::new( + |ctx: Arc>, ty: TypeTerm, depth: usize| { match ty { TypeTerm::Type { id, args @@ -159,9 +104,8 @@ pub fn init_ctx() -> Arc> { Some( Arc::new(RwLock::new(PTYListEditor::new( Box::new({ - let ctx = ctx.clone(); move || { - ctx.read().unwrap().make_editor(args[0].clone(), depth + 1).unwrap() + Context::make_editor(ctx.clone(), args[0].clone(), depth + 1).unwrap() } }), style, @@ -177,55 +121,41 @@ pub fn init_ctx() -> Arc> { _ => None } } - } - )); + ) + ); ctx.write().unwrap().add_editor_ctor( - "RGB", Box::new({ - let c = ctx.clone(); - move |ctx: &Context, ty: TypeTerm, depth: usize| { - Some(Arc::new(RwLock::new(ProductEditor::new(depth, c.clone()) - .with_t(Point2::new(0, 0), "{ ") - .with_t(Point2::new(1, 1), "r: ") - .with_n(Point2::new(2, 1), vec![ ctx.type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - .with_t(Point2::new(1, 2), "g: ") - .with_n(Point2::new(2, 2), vec![ ctx.type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - .with_t(Point2::new(1, 3), "b: ") - .with_n(Point2::new(2, 3), vec![ ctx.type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - .with_t(Point2::new(0, 4), "} ") - )) as Arc>) - } - })); - - ctx.write().unwrap().add_editor_ctor( - "PathSegment", Box::new( - |ctx: &Context, ty: TypeTerm, depth: usize| { - ctx.make_editor( - ctx.type_term_from_str("( List Char 0 )").unwrap(), + "Symbol", Arc::new( + |ctx: Arc>, ty: TypeTerm, depth: usize| { + Context::make_editor( + ctx.clone(), + ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(), depth ) } ) ); + ctx.write().unwrap().add_editor_ctor( - "Path", Box::new( - |ctx: &Context, ty: TypeTerm, depth: usize| { - ctx.make_editor( - ctx.type_term_from_str("( List PathSegment 6 )").unwrap(), - depth+1 + "String", Arc::new( + |ctx: Arc>, ty: TypeTerm, depth: usize| { + Context::make_editor( + ctx.clone(), + ctx.read().unwrap().type_term_from_str("( List Char 3 )").unwrap(), + depth ) } ) ); - + ctx.write().unwrap().add_editor_ctor( - "Term", Box::new( - |ctx: &Context, ty: TypeTerm, depth: usize| { + "TypeTerm", Arc::new( + |ctx: Arc>, ty: TypeTerm, depth: usize| { let mut s = SumEditor::new( vec![ - ctx.make_editor(ctx.type_term_from_str("( Symbol )").unwrap(), depth+1).unwrap(), - ctx.make_editor(ctx.type_term_from_str("( PosInt 10 )").unwrap(), depth+1).unwrap(), - ctx.make_editor(ctx.type_term_from_str("( List Term )").unwrap(), depth+1).unwrap(), + Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth+1).unwrap(), + Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth+1).unwrap(), + Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( List TypeTerm )").unwrap(), depth+1).unwrap(), ] ); s.select(0); @@ -237,9 +167,72 @@ pub fn init_ctx() -> Arc> { } ) ); + + ctx +} + +pub fn init_math_ctx(parent: Arc>) -> Arc> { + let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); + + ctx.write().unwrap().add_typename("BigEndian".into()); + ctx.write().unwrap().add_editor_ctor( + "PosInt", Arc::new( + |ctx: Arc>, ty: TypeTerm, _depth: usize| { + match ty { + TypeTerm::Type { + id, args + } => { + if args.len() > 0 { + match args[0] { + TypeTerm::Num(radix) => { + Some( + Arc::new(RwLock::new(PosIntEditor::new(radix as u32))) + as Arc> + ) + }, + _ => None + } + } else { + None + } + } + _ => None + } + } + ) + ); + + ctx +} + +pub fn init_os_ctx(parent: Arc>) -> Arc> { + let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); + + ctx.write().unwrap().add_editor_ctor( + "PathSegment", Arc::new( + |ctx: Arc>, ty: TypeTerm, depth: usize| { + Context::make_editor( + ctx.clone(), + ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(), + depth + ) + } + ) + ); + + ctx.write().unwrap().add_editor_ctor( + "Path", Arc::new( + |ctx: Arc>, ty: TypeTerm, depth: usize| { + Context::make_editor( + ctx.clone(), + ctx.read().unwrap().type_term_from_str("( List PathSegment 6 )").unwrap(), + depth+1 + ) + } + ) + ); ctx } - diff --git a/nested/src/product/editor.rs b/nested/src/product/editor.rs index ec75e3f..b5971ce 100644 --- a/nested/src/product/editor.rs +++ b/nested/src/product/editor.rs @@ -217,7 +217,7 @@ impl TerminalEditor for ProductEditor { } } } else { - let e = self.ctx.read().unwrap().make_editor(t[0].clone(), *ed_depth+1).unwrap(); + let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap(); *editor = Some(e.clone()); update_segment = true; diff --git a/nested/src/product/nav.rs b/nested/src/product/nav.rs index 8d8dd49..ed7d41f 100644 --- a/nested/src/product/nav.rs +++ b/nested/src/product/nav.rs @@ -1,5 +1,6 @@ use { crate::{ + core::Context, list::ListCursorMode, tree::{TreeNav, TreeNavResult, TreeCursor}, product::{segment::ProductEditorSegment, ProductEditor}, @@ -71,7 +72,7 @@ impl TreeNav for ProductEditor { e.write().unwrap().goto(c.clone()); } else if c.tree_addr.len() > 0 { // create editor - let e = self.ctx.read().unwrap().make_editor(t[0].clone(), *ed_depth+1).unwrap(); + let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap(); *editor = Some(e.clone()); let mut e = e.write().unwrap(); e.goto(c.clone()); @@ -130,7 +131,7 @@ impl TreeNav for ProductEditor { } else { // create editor - let e = self.ctx.read().unwrap().make_editor(t[0].clone(), *ed_depth+1).unwrap(); + let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap(); *editor = Some(e.clone()); let mut e = e.write().unwrap(); e.goby(direction); diff --git a/shell/src/command.rs b/shell/src/command.rs index ea5b836..b2828a1 100644 --- a/shell/src/command.rs +++ b/shell/src/command.rs @@ -109,29 +109,16 @@ impl Action for ActNum { } } -pub struct ActColor {} -impl Action for ActColor { - fn make_editor(&self, ctx: Arc>) -> Arc> { - let depth = 1; - Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_t(Point2::new(1, 1), " RGB") - .with_n(Point2::new(0, 1), vec![ ctx.read().unwrap().type_term_from_str("( RGB )").unwrap() ] ) - .with_t(Point2::new(1, 2), " HSV") - .with_n(Point2::new(0, 2), vec![ ctx.read().unwrap().type_term_from_str("( RGB )").unwrap() ] ) - .with_t(Point2::new(1, 3), " HSL") - .with_n(Point2::new(0, 3), vec![ ctx.read().unwrap().type_term_from_str("( RGB )").unwrap() ] ) - )) as Arc> - } -} - pub struct ActLet {} impl Action for ActLet { fn make_editor(&self, ctx: Arc>) -> Arc> { let depth = 1; Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) .with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap() ] ) - .with_t(Point2::new(1, 0), " := ") - .with_n(Point2::new(2, 0), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] ) + .with_t(Point2::new(1, 0), " : ") + .with_n(Point2::new(2, 0), vec![ ctx.read().unwrap().type_term_from_str("( TypeTerm )").unwrap() ] ) + .with_t(Point2::new(3, 0), " := ") + .with_n(Point2::new(4, 0), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) )) as Arc> } } @@ -189,7 +176,6 @@ impl Commander { cmds.insert("ls".into(), Arc::new(ActLs{}) as Arc); cmds.insert("cp".into(), Arc::new(ActCp{}) as Arc); cmds.insert("num".into(), Arc::new(ActNum{}) as Arc); - cmds.insert("color".into(), Arc::new(ActColor{}) as Arc); let m_buf = VecBuffer::new(); let mut c = Commander { diff --git a/shell/src/main.rs b/shell/src/main.rs index 2c9a3bc..ad9737e 100644 --- a/shell/src/main.rs +++ b/shell/src/main.rs @@ -53,8 +53,11 @@ async fn main() { }); // Type Context // - let ctx = nested::make_editor::init_ctx(); - + let ctx = Arc::new(RwLock::new(Context::new())); + let ctx = nested::make_editor::init_editor_ctx(ctx); + let ctx = nested::make_editor::init_math_ctx(ctx); + let ctx = nested::make_editor::init_os_ctx(ctx); + let c = ctx.clone(); let mut process_list_editor = PTYListEditor::new(