type terms, first parsing & serialization

This commit is contained in:
Michael Sippel 2021-04-30 03:49:53 +02:00
parent 0feaee454c
commit a1b95c5892
Signed by: senvas
GPG key ID: F96CF119C34B64A6
6 changed files with 386 additions and 39 deletions

View file

@ -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();

28
nested/src/bimap.rs Normal file
View file

@ -0,0 +1,28 @@
use std::{
collections::HashMap,
hash::Hash
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct Bimap<V: Eq + Hash, Λ: Eq + Hash> {
pub : HashMap::<V, Λ>,
pub my: HashMap::<Λ, V>
}
impl<V: Eq + Hash + Clone, Λ: Eq + Hash + Clone> Bimap<V, Λ> {
pub fn new() -> Self {
Bimap {
: HashMap::new(),
my: HashMap::new()
}
}
pub fn insert(&mut self, y: V, λ: Λ) {
self..insert(y.clone(), λ.clone());
self.my.insert(λ, y);
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

133
nested/src/core/context.rs Normal file
View file

@ -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<dyn Any + Send + Sync>),
Branch(HashMap<TypeTerm, Arc<RwLock<ReprTree>>>)
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone)]
pub struct Object {
type_tag: TypeTerm,
repr: Arc<RwLock<ReprTree>>
}
impl Object {
fn downcast(&self, repr_type: TypeTerm) -> Option<Object> {
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<Item = &'a TypeTerm>
) -> Option<Object> {
repr_chain.fold(
Some(self.clone()),
|s, t| s?.downcast(t.clone())
)
}
fn get_data<T: Any + Send + Sync>(&self) -> Option<Arc<T>> {
match &*self.repr.read().unwrap() {
ReprTree::Leaf(data) => Arc::downcast::<T>(data.clone()).ok(),
_ => None
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct TypeDict {
typenames: Bimap::<String, u64>,
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> {
TypeTerm::from_str(typename, &self.typenames.)
}
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<u64, Box<Fn() -> Arc<dyn Any + Send + Sync>>>,
objects: HashMap<String, Object>
}
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<RwLock<ReprTree>>) {
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<Object> {
self.objects.get(name).cloned()
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -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
}
};

View file

@ -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<TypeTerm>
},
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<String, u64>) -> Option<Self> {
let mut term_stack = Vec::<Option<TypeTerm>>::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<u64, String>) -> 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<u64, String>) -> 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)
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -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!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
}