166 lines
6.2 KiB
Rust
166 lines
6.2 KiB
Rust
|
||
use {
|
||
laddertypes::TypeTerm,
|
||
r3vi::{
|
||
buffer::singleton::SingletonBuffer,
|
||
view::{
|
||
AnyOuterViewPort,
|
||
singleton::*
|
||
}
|
||
},
|
||
crate::{
|
||
repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf},
|
||
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 morphtype =
|
||
crate::repr_tree::MorphismType {
|
||
src_type: Context::parse(&ctx, "<Digit Radix>"),
|
||
dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree")
|
||
};
|
||
|
||
ctx.write().unwrap()
|
||
.morphisms
|
||
.add_morphism(
|
||
morphtype,
|
||
{
|
||
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
|
||
};
|
||
|
||
/* get char representation or create it if not available
|
||
*/
|
||
let char_rt =
|
||
if let Some(crt) = src_rt.descend(Context::parse(&ctx, "Char")) {
|
||
crt
|
||
} else {
|
||
let crt = ReprTree::from_singleton_buffer(
|
||
Context::parse(&ctx, "Char"),
|
||
SingletonBuffer::new('\0')
|
||
);
|
||
src_rt.insert_branch(crt.clone());
|
||
crt
|
||
};
|
||
|
||
/* 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(edittree)
|
||
)
|
||
);
|
||
}
|
||
}
|
||
);
|
||
|
||
let morphtype =
|
||
crate::repr_tree::MorphismType {
|
||
src_type: Context::parse(&ctx, "<Digit Radix>~Char"),
|
||
dst_type: Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64")
|
||
};
|
||
|
||
ctx.write().unwrap()
|
||
.morphisms
|
||
.add_morphism(
|
||
morphtype,
|
||
{
|
||
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 morphtype =
|
||
crate::repr_tree::MorphismType {
|
||
src_type: Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64"),
|
||
dst_type: Context::parse(&ctx, "<Digit Radix>~Char")
|
||
};
|
||
|
||
ctx.write().unwrap().morphisms
|
||
.add_morphism(morphtype, {
|
||
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);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
|