allow nested contexts

improve make_editor
This commit is contained in:
Michael Sippel 2022-11-19 01:45:57 +01:00
parent bed4bc329b
commit bcbeb2298a
Signed by: senvas
GPG key ID: F96CF119C34B64A6
7 changed files with 137 additions and 141 deletions

View file

@ -226,13 +226,13 @@ pub struct MorphismType {
pub struct Context { pub struct Context {
/// assigns a name to every type /// assigns a name to every type
type_dict: TypeDict, type_dict: Arc<RwLock<TypeDict>>,
/// objects /// objects
objects: HashMap<String, Arc<RwLock<ReprTree>>>, objects: HashMap<String, Arc<RwLock<ReprTree>>>,
/// editors /// editors
editor_ctors: HashMap<TypeID, Box<dyn Fn(&Self, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested+ Send + Sync>>> + Send + Sync>>, editor_ctors: HashMap<TypeID, Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>>,
/// morphisms /// morphisms
default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Arc<RwLock<ReprTree>> + Send + Sync>>, default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Arc<RwLock<ReprTree>> + Send + Sync>>,
@ -245,7 +245,10 @@ pub struct Context {
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 {
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(), editor_ctors: HashMap::new(),
default_constructors: HashMap::new(), default_constructors: HashMap::new(),
morphism_constructors: HashMap::new(), morphism_constructors: HashMap::new(),
@ -259,33 +262,41 @@ impl Context {
} }
pub fn add_typename(&mut self, tn: String) { 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<TypeTerm> { pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
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 { 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<dyn Fn(&Self, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>) { pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>) {
if let Some(tid) = self.type_dict.get_typeid(&tn.into()) { let mut dict = self.type_dict.write().unwrap();
self.editor_ctors.insert(tid, mk_editor); let tyid = dict.get_typeid(&tn.into()).unwrap_or( dict.add_typename(tn.into()) );
self.editor_ctors.insert(tyid, mk_editor);
}
pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option<Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>> {
if let TypeTerm::Type{ id, args } = ty.clone() {
if let Some(m) = self.editor_ctors.get(&id).cloned() {
Some(m)
} else { } else {
println!("invalid type name"); self.parent.as_ref()?
.read().unwrap()
.get_editor_ctor(&ty)
} }
}
pub fn make_editor(&self, type_term: TypeTerm, depth: usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
if let TypeTerm::Type{ id, args } = type_term.clone() {
let mk_editor = self.editor_ctors.get(&id)?;
mk_editor(self, type_term, depth)
} else { } else {
None None
} }
} }
pub fn make_editor(ctx: Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?;
mk_editor(ctx, type_term, depth)
}
pub fn add_morphism( pub fn add_morphism(
&mut self, &mut self,
morph_type: MorphismType, morph_type: MorphismType,
@ -296,7 +307,7 @@ impl Context {
/// adds an object without any representations /// adds an object without any representations
pub fn add_obj(&mut self, name: String, typename: &str) { 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( self.objects.insert(
name, name,

View file

@ -137,9 +137,11 @@ impl TypeDict {
} }
} }
pub fn add_typename(&mut self, tn: String) { pub fn add_typename(&mut self, tn: String) -> u64 {
self.typenames.insert(tn, self.type_id_counter); let tyid = self.type_id_counter;
self.typenames.insert(tn, tyid);
self.type_id_counter += 1; self.type_id_counter += 1;
tyid
} }
pub fn get_typeid(&self, tn: &String) -> Option<TypeID> { pub fn get_typeid(&self, tn: &String) -> Option<TypeID> {

View file

@ -49,77 +49,22 @@ struct GrammarRuleEditor {
rhs: Arc<RwLock<PTYListEditor<RhsNode>>> rhs: Arc<RwLock<PTYListEditor<RhsNode>>>
} }
pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
pub fn init_ctx() -> Arc<RwLock<Context>> { let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
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()); }
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"Char", Box::new( "Char", Arc::new(
|ctx: &Context, ty: TypeTerm, _depth: usize| { |ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
Some( Some(
Arc::new(RwLock::new(CharEditor::new())) Arc::new(RwLock::new(CharEditor::new()))
as Arc<RwLock<dyn Nested + Send + Sync>>) as Arc<RwLock<dyn Nested + Send + Sync>>)
} }
) )
); );
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<RwLock<dyn Nested + Send + Sync>>
)
},
_ => None
}
} else {
None
}
}
_ => None
}
}
)
);
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"List", Box::new({ "List", Arc::new(
let ctx = ctx.clone(); |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| {
move |c_: &Context, ty: TypeTerm, depth: usize| {
match ty { match ty {
TypeTerm::Type { TypeTerm::Type {
id, args id, args
@ -159,9 +104,8 @@ pub fn init_ctx() -> Arc<RwLock<Context>> {
Some( Some(
Arc::new(RwLock::new(PTYListEditor::new( Arc::new(RwLock::new(PTYListEditor::new(
Box::new({ Box::new({
let ctx = ctx.clone();
move || { move || {
ctx.read().unwrap().make_editor(args[0].clone(), depth + 1).unwrap() Context::make_editor(ctx.clone(), args[0].clone(), depth + 1).unwrap()
} }
}), }),
style, style,
@ -177,55 +121,41 @@ pub fn init_ctx() -> Arc<RwLock<Context>> {
_ => None _ => None
} }
} }
} )
)); );
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"RGB", Box::new({ "Symbol", Arc::new(
let c = ctx.clone(); |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| {
move |ctx: &Context, ty: TypeTerm, depth: usize| { Context::make_editor(
Some(Arc::new(RwLock::new(ProductEditor::new(depth, c.clone()) ctx.clone(),
.with_t(Point2::new(0, 0), "{ ") ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
.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<RwLock<dyn Nested + Send + Sync>>)
}
}));
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(),
depth depth
) )
} }
) )
); );
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"Path", Box::new( "String", Arc::new(
|ctx: &Context, ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| {
ctx.make_editor( Context::make_editor(
ctx.type_term_from_str("( List PathSegment 6 )").unwrap(), ctx.clone(),
depth+1 ctx.read().unwrap().type_term_from_str("( List Char 3 )").unwrap(),
depth
) )
} }
) )
); );
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"Term", Box::new( "TypeTerm", Arc::new(
|ctx: &Context, ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| {
let mut s = SumEditor::new( let mut s = SumEditor::new(
vec![ vec![
ctx.make_editor(ctx.type_term_from_str("( Symbol )").unwrap(), depth+1).unwrap(), Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth+1).unwrap(),
ctx.make_editor(ctx.type_term_from_str("( PosInt 10 )").unwrap(), depth+1).unwrap(), Context::make_editor(ctx.clone(), ctx.read().unwrap().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("( List TypeTerm )").unwrap(), depth+1).unwrap(),
] ]
); );
s.select(0); s.select(0);
@ -241,5 +171,68 @@ pub fn init_ctx() -> Arc<RwLock<Context>> {
ctx ctx
} }
pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
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<RwLock<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<RwLock<dyn Nested + Send + Sync>>
)
},
_ => None
}
} else {
None
}
}
_ => None
}
}
)
);
ctx
}
pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
ctx.write().unwrap().add_editor_ctor(
"PathSegment", Arc::new(
|ctx: Arc<RwLock<Context>>, 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<RwLock<Context>>, ty: TypeTerm, depth: usize| {
Context::make_editor(
ctx.clone(),
ctx.read().unwrap().type_term_from_str("( List PathSegment 6 )").unwrap(),
depth+1
)
}
)
);
ctx
}

View file

@ -217,7 +217,7 @@ impl TerminalEditor for ProductEditor {
} }
} }
} else { } 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()); *editor = Some(e.clone());
update_segment = true; update_segment = true;

View file

@ -1,5 +1,6 @@
use { use {
crate::{ crate::{
core::Context,
list::ListCursorMode, list::ListCursorMode,
tree::{TreeNav, TreeNavResult, TreeCursor}, tree::{TreeNav, TreeNavResult, TreeCursor},
product::{segment::ProductEditorSegment, ProductEditor}, product::{segment::ProductEditorSegment, ProductEditor},
@ -71,7 +72,7 @@ impl TreeNav for ProductEditor {
e.write().unwrap().goto(c.clone()); e.write().unwrap().goto(c.clone());
} else if c.tree_addr.len() > 0 { } else if c.tree_addr.len() > 0 {
// create editor // 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()); *editor = Some(e.clone());
let mut e = e.write().unwrap(); let mut e = e.write().unwrap();
e.goto(c.clone()); e.goto(c.clone());
@ -130,7 +131,7 @@ impl TreeNav for ProductEditor {
} else { } else {
// create editor // 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()); *editor = Some(e.clone());
let mut e = e.write().unwrap(); let mut e = e.write().unwrap();
e.goby(direction); e.goby(direction);

View file

@ -109,29 +109,16 @@ impl Action for ActNum {
} }
} }
pub struct ActColor {}
impl Action for ActColor {
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn Nested + Send + Sync>> {
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<RwLock<dyn Nested + Send + Sync>>
}
}
pub struct ActLet {} pub struct ActLet {}
impl Action for ActLet { impl Action for ActLet {
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn Nested + Send + Sync>> { fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn Nested + Send + Sync>> {
let depth = 1; let depth = 1;
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) 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_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap() ] )
.with_t(Point2::new(1, 0), " := ") .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_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<RwLock<dyn Nested + Send + Sync>> )) as Arc<RwLock<dyn Nested + Send + Sync>>
} }
} }
@ -189,7 +176,6 @@ impl Commander {
cmds.insert("ls".into(), Arc::new(ActLs{}) as Arc<dyn Action + Send + Sync>); cmds.insert("ls".into(), Arc::new(ActLs{}) as Arc<dyn Action + Send + Sync>);
cmds.insert("cp".into(), Arc::new(ActCp{}) as Arc<dyn Action + Send + Sync>); cmds.insert("cp".into(), Arc::new(ActCp{}) as Arc<dyn Action + Send + Sync>);
cmds.insert("num".into(), Arc::new(ActNum{}) as Arc<dyn Action + Send + Sync>); cmds.insert("num".into(), Arc::new(ActNum{}) as Arc<dyn Action + Send + Sync>);
cmds.insert("color".into(), Arc::new(ActColor{}) as Arc<dyn Action + Send + Sync>);
let m_buf = VecBuffer::new(); let m_buf = VecBuffer::new();
let mut c = Commander { let mut c = Commander {

View file

@ -53,7 +53,10 @@ async fn main() {
}); });
// Type Context // // 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 c = ctx.clone();
let mut process_list_editor = let mut process_list_editor =