2021-04-30 03:49:53 +02:00
|
|
|
use {
|
2022-05-08 23:30:49 +02:00
|
|
|
crate::{
|
2023-01-02 13:18:55 +01:00
|
|
|
core::{AnyOuterViewPort, OuterViewPort, View},
|
|
|
|
type_system::{TypeDict, TypeTerm, TypeID, ReprTree},
|
2022-12-19 11:26:07 +01:00
|
|
|
tree::NestedNode
|
2021-11-19 12:19:52 +01:00
|
|
|
},
|
2021-04-30 03:49:53 +02:00
|
|
|
std::{
|
|
|
|
collections::HashMap,
|
2021-11-19 12:19:52 +01:00
|
|
|
sync::{Arc, RwLock},
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
2023-01-02 13:18:55 +01:00
|
|
|
};
|
2021-04-30 03:49:53 +02:00
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
|
|
|
2021-05-22 01:33:58 +02:00
|
|
|
pub struct TypeLadder(Vec<TypeTerm>);
|
|
|
|
|
2021-05-10 01:57:47 +02:00
|
|
|
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
|
|
|
pub enum MorphismMode {
|
|
|
|
/// Isomorphism
|
|
|
|
/// e.g. `( PositionalInteger 10 BigEndian ) <~> ( PositionalInteger 16 LittleEndian )`
|
|
|
|
Iso,
|
2021-04-30 03:49:53 +02:00
|
|
|
|
2021-05-10 01:57:47 +02:00
|
|
|
/// Monomorphism, i.e. injective functions,
|
|
|
|
/// upcast-view, downcast-control, semantic gain
|
|
|
|
/// e.g. `( Sequence ( Digit 16 ) ) ~> ( PositionalInteger 16 LittleEndian )`
|
|
|
|
Mono,
|
|
|
|
|
|
|
|
/// Epimorphsim, i.e. surjective functions,
|
|
|
|
/// upcast-control, downcast-view, possible loss of entropy
|
|
|
|
/// e.g. `( Ascii ) ~> ( Digit 16 )`
|
|
|
|
Epi,
|
|
|
|
|
|
|
|
/// Any other function
|
2021-11-19 12:19:52 +01:00
|
|
|
Any,
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
2021-04-30 03:49:53 +02:00
|
|
|
|
2021-05-10 01:57:47 +02:00
|
|
|
#[derive(Clone, Hash, PartialEq, Eq)]
|
|
|
|
pub struct MorphismType {
|
|
|
|
pub mode: MorphismMode,
|
|
|
|
pub src_type: TypeTerm,
|
2021-11-19 12:19:52 +01:00
|
|
|
pub dst_type: TypeTerm,
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
|
|
|
|
|
|
pub struct Context {
|
2022-05-08 23:30:49 +02:00
|
|
|
/// assigns a name to every type
|
2022-11-19 01:45:57 +01:00
|
|
|
type_dict: Arc<RwLock<TypeDict>>,
|
2022-11-18 00:21:29 +01:00
|
|
|
|
2022-05-08 23:30:49 +02:00
|
|
|
/// objects
|
2022-11-18 00:21:29 +01:00
|
|
|
objects: HashMap<String, Arc<RwLock<ReprTree>>>,
|
2022-05-08 23:30:49 +02:00
|
|
|
|
|
|
|
/// editors
|
2022-12-19 11:26:07 +01:00
|
|
|
editor_ctors: HashMap<TypeID, Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>>,
|
2022-05-08 23:30:49 +02:00
|
|
|
|
|
|
|
/// morphisms
|
2022-11-18 00:21:29 +01:00
|
|
|
default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Arc<RwLock<ReprTree>> + Send + Sync>>,
|
|
|
|
morphism_constructors: HashMap<MorphismType, Box<dyn Fn(Arc<RwLock<ReprTree>>) -> Arc<RwLock<ReprTree>> + Send + Sync>>,
|
2022-05-08 23:30:49 +02:00
|
|
|
|
|
|
|
/// recursion
|
2021-11-19 12:19:52 +01:00
|
|
|
parent: Option<Arc<RwLock<Context>>>,
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Context {
|
2021-05-10 01:57:47 +02:00
|
|
|
pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self {
|
|
|
|
Context {
|
2022-11-19 01:45:57 +01:00
|
|
|
type_dict: match parent.as_ref() {
|
|
|
|
Some(p) => p.read().unwrap().type_dict.clone(),
|
|
|
|
None => Arc::new(RwLock::new(TypeDict::new()))
|
|
|
|
},
|
2022-05-08 23:30:49 +02:00
|
|
|
editor_ctors: HashMap::new(),
|
2021-05-10 01:57:47 +02:00
|
|
|
default_constructors: HashMap::new(),
|
|
|
|
morphism_constructors: HashMap::new(),
|
|
|
|
objects: HashMap::new(),
|
2021-11-19 12:19:52 +01:00
|
|
|
parent,
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
Context::with_parent(None)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add_typename(&mut self, tn: String) {
|
2022-11-19 01:45:57 +01:00
|
|
|
self.type_dict.write().unwrap().add_typename(tn);
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
pub fn get_typeid(&self, tn: &str) -> Option<TypeID> {
|
|
|
|
self.type_dict.read().unwrap().get_typeid(&tn.into())
|
|
|
|
}
|
|
|
|
|
2021-05-10 01:57:47 +02:00
|
|
|
pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
|
2022-11-19 01:45:57 +01:00
|
|
|
self.type_dict.read().unwrap().type_term_from_str(&tn)
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
2022-12-18 01:20:17 +01:00
|
|
|
|
2022-05-08 23:30:49 +02:00
|
|
|
pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
|
2022-11-19 01:45:57 +01:00
|
|
|
self.type_dict.read().unwrap().type_term_to_str(&t)
|
2022-05-08 23:30:49 +02:00
|
|
|
}
|
2021-05-10 01:57:47 +02:00
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>) {
|
2022-11-19 01:45:57 +01:00
|
|
|
let mut dict = self.type_dict.write().unwrap();
|
2022-12-19 11:26:07 +01:00
|
|
|
let tyid = dict
|
|
|
|
.get_typeid(&tn.into())
|
|
|
|
.unwrap_or( dict.add_typename(tn.into()) );
|
2022-11-19 01:45:57 +01:00
|
|
|
self.editor_ctors.insert(tyid, mk_editor);
|
2022-05-08 23:30:49 +02:00
|
|
|
}
|
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option<Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>> {
|
2022-12-18 01:39:01 +01:00
|
|
|
if let TypeTerm::Type{ id, args: _ } = ty.clone() {
|
2022-11-19 01:45:57 +01:00
|
|
|
if let Some(m) = self.editor_ctors.get(&id).cloned() {
|
|
|
|
Some(m)
|
|
|
|
} else {
|
|
|
|
self.parent.as_ref()?
|
|
|
|
.read().unwrap()
|
|
|
|
.get_editor_ctor(&ty)
|
|
|
|
}
|
2022-05-08 23:30:49 +02:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
2022-11-13 15:26:25 +01:00
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
pub fn make_editor(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<NestedNode> {
|
2022-11-19 01:45:57 +01:00
|
|
|
let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?;
|
2022-12-19 11:26:07 +01:00
|
|
|
mk_editor(ctx.clone(), type_term, depth)
|
2022-11-19 01:45:57 +01:00
|
|
|
}
|
|
|
|
|
2021-05-10 01:57:47 +02:00
|
|
|
pub fn add_morphism(
|
|
|
|
&mut self,
|
|
|
|
morph_type: MorphismType,
|
2022-11-18 00:21:29 +01:00
|
|
|
morph_fn: Box<dyn Fn(Arc<RwLock<ReprTree>>) -> Arc<RwLock<ReprTree>> + Send + Sync>,
|
2021-05-10 01:57:47 +02:00
|
|
|
) {
|
|
|
|
self.morphism_constructors.insert(morph_type, morph_fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// adds an object without any representations
|
2021-11-19 12:19:52 +01:00
|
|
|
pub fn add_obj(&mut self, name: String, typename: &str) {
|
2022-11-19 01:45:57 +01:00
|
|
|
let type_tag = self.type_dict.read().unwrap().type_term_from_str(typename).unwrap();
|
2021-05-10 01:57:47 +02:00
|
|
|
|
2021-04-30 03:49:53 +02:00
|
|
|
self.objects.insert(
|
|
|
|
name,
|
2021-05-10 01:57:47 +02:00
|
|
|
if let Some(ctor) = self.default_constructors.get(&type_tag) {
|
|
|
|
ctor()
|
|
|
|
} else {
|
2022-11-18 00:21:29 +01:00
|
|
|
Arc::new(RwLock::new(ReprTree::new(type_tag)))
|
2021-11-19 12:19:52 +01:00
|
|
|
},
|
2021-04-30 03:49:53 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-11-18 00:21:29 +01:00
|
|
|
pub fn get_obj(&self, name: &String) -> Option<Arc<RwLock<ReprTree>>> {
|
2021-05-10 01:57:47 +02:00
|
|
|
if let Some(obj) = self.objects.get(name) {
|
|
|
|
Some(obj.clone())
|
|
|
|
} else if let Some(parent) = self.parent.as_ref() {
|
|
|
|
parent.read().unwrap().get_obj(name)
|
|
|
|
} else {
|
|
|
|
None
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
|
|
|
}
|
2021-11-19 12:19:52 +01:00
|
|
|
|
2022-11-18 00:21:29 +01:00
|
|
|
/*
|
2021-11-19 12:19:52 +01:00
|
|
|
pub fn get_obj_port<'a, V: View + ?Sized + 'static>(
|
2021-05-10 01:57:47 +02:00
|
|
|
&self,
|
|
|
|
name: &str,
|
2021-11-19 12:19:52 +01:00
|
|
|
type_ladder: impl Iterator<Item = &'a str>,
|
2021-05-22 01:33:58 +02:00
|
|
|
) -> Option<OuterViewPort<V>>
|
2021-11-19 12:19:52 +01:00
|
|
|
where
|
|
|
|
V::Msg: Clone,
|
|
|
|
{
|
2021-05-10 01:57:47 +02:00
|
|
|
self.get_obj(&name.into())?
|
2021-11-19 12:19:52 +01:00
|
|
|
.downcast_ladder(type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()))?
|
2021-05-10 01:57:47 +02:00
|
|
|
.get_port()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn insert_repr<'a>(
|
|
|
|
&mut self,
|
|
|
|
name: &str,
|
|
|
|
type_ladder: impl Iterator<Item = &'a str>,
|
2021-11-19 12:19:52 +01:00
|
|
|
port: AnyOuterViewPort,
|
2021-05-10 01:57:47 +02:00
|
|
|
) {
|
2021-11-19 12:19:52 +01:00
|
|
|
self.get_obj(&name.to_string())
|
|
|
|
.unwrap()
|
|
|
|
.repr
|
|
|
|
.write()
|
|
|
|
.unwrap()
|
2021-05-10 01:57:47 +02:00
|
|
|
.insert_leaf(
|
|
|
|
type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()),
|
2021-11-19 12:19:52 +01:00
|
|
|
port,
|
2021-05-10 01:57:47 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-11-19 12:19:52 +01:00
|
|
|
pub fn epi_cast(&mut self, name: &str, typename: &str) {
|
2021-05-10 01:57:47 +02:00
|
|
|
let dst_type = self.type_dict.type_term_from_str(typename).unwrap();
|
2021-05-13 16:22:30 +02:00
|
|
|
let old_obj = self.objects.get(&name.to_string()).unwrap().clone();
|
2021-11-19 12:19:52 +01:00
|
|
|
let new_obj = if let Some(ctor) = self.morphism_constructors.get(&MorphismType {
|
|
|
|
mode: MorphismMode::Epi,
|
|
|
|
src_type: old_obj.type_tag.clone(),
|
|
|
|
dst_type: dst_type.clone(),
|
|
|
|
}) {
|
|
|
|
ctor(old_obj.clone())
|
|
|
|
} else {
|
2022-11-18 00:21:29 +01:00
|
|
|
Arc::new(RwLock::new(ReprTree::new(dst_type)))
|
2021-11-19 12:19:52 +01:00
|
|
|
};
|
2021-04-30 03:49:53 +02:00
|
|
|
|
2021-11-19 12:19:52 +01:00
|
|
|
new_obj
|
|
|
|
.repr
|
|
|
|
.write()
|
|
|
|
.unwrap()
|
|
|
|
.insert_branch(old_obj.type_tag, old_obj.repr);
|
2021-05-10 01:57:47 +02:00
|
|
|
|
|
|
|
self.objects.insert(name.to_string(), new_obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn mono_view<'a, V: View + ?Sized + 'static>(
|
|
|
|
&mut self,
|
|
|
|
name: &str,
|
2021-11-19 12:19:52 +01:00
|
|
|
type_ladder: impl Iterator<Item = &'a str>,
|
2021-05-22 01:33:58 +02:00
|
|
|
) -> Option<OuterViewPort<V>>
|
2021-11-19 12:19:52 +01:00
|
|
|
where
|
|
|
|
V::Msg: Clone,
|
|
|
|
{
|
2021-05-10 01:57:47 +02:00
|
|
|
if let Some(p) = self.get_obj_port(name, type_ladder) {
|
|
|
|
Some(p)
|
|
|
|
} else {
|
|
|
|
// todo : add repr with morphism constructor (if one exists)
|
|
|
|
/*
|
|
|
|
if let Some(ctor) = self.morphism_constructors.get(
|
|
|
|
&MorphismType {
|
|
|
|
mode: MorphismMode::Mono,
|
|
|
|
src_type: old_obj.type_tag.clone(),
|
2021-11-19 12:19:52 +01:00
|
|
|
dst_type:
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
|
|
|
)
|
|
|
|
*/
|
|
|
|
None
|
|
|
|
}
|
2022-11-18 00:21:29 +01:00
|
|
|
}
|
|
|
|
*/
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|