lib-nested/lib-nested-core/src/editors/digit/ctx.rs

205 lines
7.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use {
laddertypes::TypeTerm,
r3vi::{
buffer::singleton::SingletonBuffer,
view::{
AnyOuterViewPort,
singleton::*
}
},
crate::{
repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf, GenericReprTreeMorphism},
editors::digit::DigitEditor,
},
std::sync::{Arc, RwLock}
};
pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
// todo: proper scoping of Radix variable
ctx.write().unwrap().add_varname("Radix");
let digit_make_edittree = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<Digit Radix>"),
Context::parse(&ctx, "<Digit Radix>~EditTree"),
{
let ctx = ctx.clone();
move |src_rt, σ| {
let radix =
match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
Some(TypeTerm::Num(n)) => *n as u32,
_ => 0
};
let char_buf = SingletonBuffer::<char>::new('?');
/* Create EditTree object
*/
let mut edittree = DigitEditor::new(
ctx.clone(),
radix,
char_buf
).into_node(
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
);
src_rt.write().unwrap()
.insert_branch(
ReprTree::from_singleton_buffer(
Context::parse(&ctx, "EditTree"),
SingletonBuffer::new(Arc::new(RwLock::new(edittree)))
)
);
ctx.read().unwrap().setup_edittree( src_rt );
}
}
);
let digit_morph_char_to_edittree = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<Digit Radix>~Char"),
Context::parse(&ctx, "<Digit Radix>~EditTree"),
{
let ctx = ctx.clone();
move |src_rt, σ| {
let radix =
match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
Some(TypeTerm::Num(n)) => *n as u32,
_ => 0
};
/* Create EditTree object
*/
let mut edittree = DigitEditor::new(
ctx.clone(),
radix,
src_rt
.descend( Context::parse(&ctx, "Char") ).unwrap()
.singleton_buffer::<char>()
).into_node(
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
);
src_rt.write().unwrap()
.insert_branch(
ReprTree::from_singleton_buffer(
Context::parse(&ctx, "EditTree"),
SingletonBuffer::new(Arc::new(RwLock::new(edittree)))
)
);
ctx.read().unwrap().setup_edittree( src_rt );
}
}
);
let digit_morph_char_from_edittree = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<Digit Radix>~EditTree"),
Context::parse(&ctx, "<Digit Radix>~Char"),
{
let ctx = ctx.clone();
move |src_rt, σ| {
let edittree = src_rt.edittree( &ctx );
let port =
edittree
.get()
.read().unwrap()
.get_edit::<DigitEditor>().unwrap()
.read().unwrap()
.get_char_port();
src_rt.insert_leaf(
Context::parse(&ctx, "Char"),
ReprLeaf::from_view( port )
)
}
}
);
let digit_morph_char_to_u64 = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<Digit Radix>~Char"),
Context::parse(&ctx, "<Digit Radix>~_2^64~machine.UInt64"),
{
let ctx = ctx.clone();
move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| {
/* infer radix from type
*/
let radix_typeid = ctx.read().unwrap().get_var_typeid("Radix").unwrap();
let radix =
match σ.get( &laddertypes::TypeID::Var(radix_typeid) ) {
Some(TypeTerm::Num(n)) => (*n) as u32,
x => {
eprintln!("invalid radix {:?}", x);
0
}
};
if radix <= 16 {
if let Some(src_rt) = rt.descend(Context::parse(&ctx, "Char")) {
/* insert projected view into ReprTree
*/
let u64_view =
src_rt.view_char()
.map(move |c| c.to_digit(radix).unwrap_or(0) as u64);
rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = u64>>(
Context::parse(&ctx, "_2^64~machine.UInt64").get_lnf_vec().into_iter(),
u64_view
);
} else {
eprintln!("could not find required source representation: <Digit {}>~Char", radix);
}
} else {
eprintln!("radix too large ({})", radix);
}
}
}
);
let digit_morph_u64_to_char = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<Digit Radix>~_2^64~machine.UInt64"),
Context::parse(&ctx, "<Digit Radix>~Char"),
{
let ctx = ctx.clone();
move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| {
/* infer radix from type
*/
let radix =
match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
Some(TypeTerm::Num(n)) => (*n) as u32,
_ => 0
};
if radix <= 16 {
/* insert projected view into ReprTree
*/
let char_view =
rt.descend(Context::parse(&ctx, "_2^64~machine.UInt64"))
.unwrap()
.view_u64()
.map(move |digit| char::from_digit((digit%radix as u64) as u32, radix).unwrap_or('?'));
rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = char>>(
Context::parse(&ctx, "Char").get_lnf_vec().into_iter(),
char_view
);
} else {
eprintln!("radix too large ({})", radix);
}
}
}
);
ctx.write().unwrap().morphisms.add_morphism( digit_make_edittree );
ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_to_edittree );
ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_from_edittree );
ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_to_u64 );
ctx.write().unwrap().morphisms.add_morphism( digit_morph_u64_to_char );
}