diff --git a/math/radix_transform/src/main.rs b/math/radix_transform/src/main.rs index 1440884..220a6cf 100644 --- a/math/radix_transform/src/main.rs +++ b/math/radix_transform/src/main.rs @@ -8,7 +8,9 @@ use { Observer, ObserverBroadcast, InnerViewPort, - OuterViewPort + OuterViewPort, + TypeTerm, + TypeDict }, sequence::{SequenceView, VecBuffer}, integer::{RadixProjection} @@ -17,6 +19,23 @@ use { #[async_std::main] async fn main() { + let mut td = TypeDict::new(); + for tn in vec![ + "MachineWord", "MachineInt", "MachineSlab", + "Vec", "NullTerminatedString", + "Sequence", "Ascii", + "PositionalInt", "Digit", "LittleEndian", "BigEndian", + "DiffStream", "ℕ" + ] { td.add_typename(tn.into()); } + + let radix_types = vec![ + td.type_term_from_str("( ℕ )").unwrap(), + td.type_term_from_str("( PositionalInt 10 LittleEndian )").unwrap(), + td.type_term_from_str("( Sequence ( Digit 10 ) )").unwrap(), + td.type_term_from_str("( Sequence Ascii )").unwrap(), + td.type_term_from_str("( Sequence MachineSlab )").unwrap() + ]; + nested::magic_header(); eprintln!(" Convert Radix of Positional Integer"); nested::magic_header(); @@ -24,50 +43,69 @@ async fn main() { let mut args = std::env::args(); args.next().expect("Arg $0 missing!"); - eprintln!(" -$1: src_radix - ( ℕ ) - ( PositionalInt 10 LittleEndian ) - ( Sequence (Digit 10) ) - ( Sequence Ascii ) - ( ArgString ) -"); + eprintln!("\n$1: src_radix"); + for t in radix_types.iter() { + eprintln!(" {}", td.type_term_to_str(t)); + } + + eprintln!("\n$2: dst_radix"); + for t in radix_types.iter() { + eprintln!(" {}", td.type_term_to_str(t)); + } + let src_radix_str = args.next().expect("Arg $1 required!"); - - - eprintln!(" -$2: dst_radix - ( ℕ ) - ( PositionalInt 10 LittleEndian ) - ( Sequence (Digit 10) ) - ( Sequence Ascii ) - ( ArgString ) -"); let dst_radix_str = args.next().expect("Arg $2 required!"); - - eprintln!(" ->0: n - ( ℕ ) ~~ <1 - ( PositionalInt src_radix LittleEndian ) - ( Sequence (Digit src_radix) ) - ( Sequence MachineInt ) - ( PipeStream bincode (SequenceDiff MachineInt) ) -"); - - eprintln!(" -<1: n - ( ℕ ) ~~ >0 - ( PositionalInt dst_radix LittleEndian ) - ( Sequence (Digit dst_radix) ) - ( Sequence MachineInt ) - ( PipeStream bincode (SequenceDiff MachineInt) ) -"); - - nested::magic_header(); let src_radix = usize::from_str_radix(&src_radix_str, 10).expect("could not parse src_radix"); let dst_radix = usize::from_str_radix(&dst_radix_str, 10).expect("could not parse dst_radix"); + let in_types = vec![ + td.type_term_from_str("( ℕ )").unwrap(), + td.type_term_from_str("( PositionalInt )").unwrap() + .num_arg(src_radix as i64) + .arg(td.type_term_from_str("( LittleEndian )").unwrap()) + .clone(), + + td.type_term_from_str("( Sequence )").unwrap() + .arg( + td.type_term_from_str("( Digit )").unwrap() + .num_arg(src_radix as i64).clone() + ) + .clone(), + + td.type_term_from_str("( Sequence MachineInt )").unwrap(), + td.type_term_from_str("( DiffStream ( Vec MachineInt ) )").unwrap(), + ]; + + let out_types = vec![ + td.type_term_from_str("( ℕ )").unwrap(), + td.type_term_from_str("( PositionalInt )").unwrap() + .num_arg(dst_radix as i64) + .arg(td.type_term_from_str("( LittleEndian )").unwrap()).clone(), + + td.type_term_from_str("( Sequence )").unwrap() + .arg( + td.type_term_from_str("( Digit )").unwrap() + .num_arg(dst_radix as i64).clone() + ) + .clone(), + + td.type_term_from_str("( Sequence MachineInt )").unwrap(), + td.type_term_from_str("( DiffStream ( Vec MachineInt ) )").unwrap(), + ]; + + eprintln!("\n>0: n"); + for t in in_types.iter() { + eprintln!(" {}", td.type_term_to_str(t)); + } + + eprintln!("\n<1: n"); + for t in out_types.iter() { + eprintln!(" {}", td.type_term_to_str(t)); + } + + nested::magic_header(); + let src_digits_port = ViewPort::new(); let dst_digits_port = ViewPort::new(); diff --git a/nested/src/bimap.rs b/nested/src/bimap.rs new file mode 100644 index 0000000..202df48 --- /dev/null +++ b/nested/src/bimap.rs @@ -0,0 +1,28 @@ +use std::{ + collections::HashMap, + hash::Hash +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct Bimap { + pub mλ: HashMap::, + pub my: HashMap::<Λ, V> +} + +impl Bimap { + pub fn new() -> Self { + Bimap { + mλ: HashMap::new(), + my: HashMap::new() + } + } + + pub fn insert(&mut self, y: V, λ: Λ) { + self.mλ.insert(y.clone(), λ.clone()); + self.my.insert(λ, y); + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + diff --git a/nested/src/core/context.rs b/nested/src/core/context.rs new file mode 100644 index 0000000..47d85d5 --- /dev/null +++ b/nested/src/core/context.rs @@ -0,0 +1,133 @@ +use { + std::{ + collections::HashMap, + sync::{Arc, RwLock}, + any::Any + }, + crate::{ + bimap::Bimap, + core::type_term::{TypeID, TypeTerm} + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub enum ReprTree { + Leaf(Arc), + Branch(HashMap>>) +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone)] +pub struct Object { + type_tag: TypeTerm, + repr: Arc> +} + +impl Object { + fn downcast(&self, repr_type: TypeTerm) -> Option { + match &*self.repr.read().unwrap() { + ReprTree::Leaf(data) => + if self.type_tag == repr_type { + Some(self.clone()) + } else { + None + }, + ReprTree::Branch(reprs) => + Some(Object{ + type_tag: repr_type.clone(), + repr: reprs.get(&repr_type)?.clone() + }) + } + } + + fn downcast_chain<'a>( + &self, + repr_chain: impl Iterator + ) -> Option { + repr_chain.fold( + Some(self.clone()), + |s, t| s?.downcast(t.clone()) + ) + } + + fn get_data(&self) -> Option> { + match &*self.repr.read().unwrap() { + ReprTree::Leaf(data) => Arc::downcast::(data.clone()).ok(), + _ => None + } + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct TypeDict { + typenames: Bimap::, + type_id_counter: u64 +} + +impl TypeDict { + pub fn new() -> Self { + TypeDict { + typenames: Bimap::new(), + type_id_counter: 0 + } + } + + pub fn add_typename(&mut self, tn: String) { + self.typenames.insert(tn, self.type_id_counter); + self.type_id_counter += 1; + } + + pub fn type_term_from_str(&self, typename: &str) -> Option { + TypeTerm::from_str(typename, &self.typenames.mλ) + } + + pub fn type_term_to_str(&self, term: &TypeTerm) -> String { + term.to_str(&self.typenames.my) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct Context { + type_dict: TypeDict, + + // map type_id -> constructor + constructors: HashMap Arc>>, + + objects: HashMap +} + +impl Context { + pub fn add_obj( + &mut self, + name: String, + typename: &str + ) { + self.objects.insert( + name, + Object { + type_tag: self.type_dict.type_term_from_str(typename).unwrap(), + repr: Arc::new(RwLock::new(ReprTree::Branch(HashMap::new()))) + } + ); + } + + pub fn add_repr(&mut self, name: &String, typename: &str, repr: Arc>) { + match &mut *self.objects.get_mut(name).unwrap().repr.write().unwrap() { + ReprTree::Leaf(_) => {/*error*/}, + ReprTree::Branch(repr_map) => { + repr_map.insert(self.type_dict.type_term_from_str(typename).unwrap(), repr.clone()); + } + } + } + + pub fn get_obj(&self, name: &String) -> Option { + self.objects.get(name).cloned() + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + diff --git a/nested/src/core/mod.rs b/nested/src/core/mod.rs index 30c8d6c..a0cb989 100644 --- a/nested/src/core/mod.rs +++ b/nested/src/core/mod.rs @@ -3,6 +3,8 @@ pub mod view; pub mod observer; pub mod channel; pub mod port; +pub mod type_term; +pub mod context; pub use { view::{View}, @@ -24,6 +26,16 @@ pub use { ViewPort, InnerViewPort, OuterViewPort + }, + type_term::{ + TypeID, + TypeTerm + }, + context::{ + ReprTree, + TypeDict, + Context, + Object } }; diff --git a/nested/src/core/type_term.rs b/nested/src/core/type_term.rs new file mode 100644 index 0000000..044413a --- /dev/null +++ b/nested/src/core/type_term.rs @@ -0,0 +1,133 @@ +use std::{ + sync::Arc, + any::Any, + ops::Deref, + collections::HashMap, + iter::Peekable +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub type TypeID = u64; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone, PartialEq, Eq, Hash)] +pub enum TypeTerm { + Type { + id: TypeID, + args: Vec + }, + Num(i64) +} + +impl TypeTerm { + pub fn new(id: TypeID) -> Self { + TypeTerm::Type{ id, args: vec![] } + } + + pub fn arg(&mut self, t: TypeTerm) -> &mut Self { + if let TypeTerm::Type{ id, args } = self { + args.push(t); + } + + self + } + + pub fn num_arg(&mut self, v: i64) -> &mut Self { + self.arg(TypeTerm::Num(v)) + } + + pub fn from_str(s: &str, names: &HashMap) -> Option { + let mut term_stack = Vec::>::new(); + + for token in s.split_whitespace() { + match token { + "(" => { + term_stack.push(None); + }, + ")" => { + let t = term_stack.pop().unwrap(); + if term_stack.len() > 0 { + let mut f = term_stack.last_mut().unwrap(); + if let Some(f) = f { + f.arg(t.unwrap()); + } else { + //error + } + } else { + return t; + } + }, + atom => { + let mut f = term_stack.last_mut().unwrap(); + + match f { + Some(f) => + if atom.chars().nth(0).unwrap().is_numeric() { + f.num_arg(i64::from_str_radix(atom, 10).unwrap()); + } else { + f.arg(TypeTerm::new(*names.get(atom).expect(&format!("invalid atom {}", atom)))); + } + None => { + *f = Some(TypeTerm::new(*names.get(atom).expect(&format!("invalid atom {}", atom)))); + } + } + } + } + } + + None + } + + // only adds parenthesis where args.len > 0 + pub fn to_str1(&self, names: &HashMap) -> String { + match self { + TypeTerm::Type{ id, args } => + if args.len() > 0 { + format!( + "( {} {})", + names[id], + if args.len() > 0 { + args.iter().fold( + String::new(), + |str, term| format!("{}{} ", str, term.to_str1(names) ) + ) + } else { + String::new() + } + ) + } else { + names[id].clone() + }, + + TypeTerm::Num(n) => + format!("{}", n) + } + } + + // always adds an enclosing pair of parenthesis + pub fn to_str(&self, names: &HashMap) -> String { + match self { + TypeTerm::Type{ id, args } => + format!( + "( {} {})", + names[id], + if args.len() > 0 { + args.iter().fold( + String::new(), + |str, term| format!("{}{} ", str, term.to_str1(names) ) + ) + } else { + String::new() + }), + + TypeTerm::Num(n) => + format!("{}", n) + } + } + +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + diff --git a/nested/src/lib.rs b/nested/src/lib.rs index 6d65631..e9c4c1a 100644 --- a/nested/src/lib.rs +++ b/nested/src/lib.rs @@ -1,4 +1,5 @@ #![feature(trait_alias)] +#![feature(non_ascii_idents)] pub mod core; pub mod projection; @@ -13,6 +14,8 @@ pub mod integer; pub mod string_editor; pub mod leveled_term_view; +pub mod bimap; + pub fn magic_header() { eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>"); }