diff --git a/Cargo.toml b/Cargo.toml index bf945fc..8eace12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2024" chumsky = "0.9.0" ariadne = "0.2" laddertypes = { path = "../lib-laddertypes", features = ["pretty"] } +tiny-ansi = { version = "0.1.0" } diff --git a/morphisms/.gitignore b/morphisms/.gitignore deleted file mode 100644 index 82f5cc4..0000000 --- a/morphisms/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.so -posint-dec-to-hex-generated-gcc -posint-dec-to-hex-generated-clang -posint-dec-to-hex-optimal-gcc -posint-dec-to-hex-optimal-clang - diff --git a/morphisms/digit.morphism-base b/morphisms/digit.morphism-base index 0abff91..54b9d9f 100644 --- a/morphisms/digit.morphism-base +++ b/morphisms/digit.morphism-base @@ -1,3 +1,6 @@ +``` +``` + morph_digit_as_char_to_uint8 (Radix:ℤ) <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 --> <Digit Radix> ~ x86.UInt8 diff --git a/morphisms/include/array/length-prefix.h b/morphisms/include/array/length-prefix.h index 844340c..6831aad 100644 --- a/morphisms/include/array/length-prefix.h +++ b/morphisms/include/array/length-prefix.h @@ -63,3 +63,8 @@ int length_prefix_array_map_64_to_8( struct LengthPrefixUInt64Array const * restrict src, struct LengthPrefixUInt8Array * restrict dst ); +int length_prefix_array_map_8_to_8( + int (*f) ( uint8_t const * restrict, uint8_t * restrict ), + struct LengthPrefixUInt8Array const * restrict src, + struct LengthPrefixUInt8Array * restrict dst +); diff --git a/morphisms/length_prefix.morphism-base b/morphisms/length_prefix.morphism-base index e5ad529..f8b48aa 100644 --- a/morphisms/length_prefix.morphism-base +++ b/morphisms/length_prefix.morphism-base @@ -1,24 +1,63 @@ +``` +#include <array/length-prefix.h> +``` + morph_array_as_valterm_to_lenpfx (Terminator:x86.UInt8) <Seq~<ValueTerminated Terminator> x86.UInt8> --> <Seq~<LengthPrefix x86.UInt64> x86.UInt8> ``` length_prefix_uint8_array_clear(dst); - while( *src != Terminator ) { - length_prefix_uint8_array_push(dst, *src); - src++; - } + while( *src != Terminator ) + length_prefix_uint8_array_push(dst, *src++); return 0; ``` + morph_array_as_lenpfx_to_valterm (Terminator:x86.UInt8) <Seq~<LengthPrefix x86.UInt64> x86.UInt8> --> <Seq~<ValueTerminated Terminator> x86.UInt8> ``` - for( uint64_t i = 0; i < src->len; ++i ) { - *dst ++ = src->items[i]; - } + for( uint64_t i = 0; i < src->len; ++i ) + *dst++ = src->items[i]; + *dst = Terminator; return 0; ``` + +morph_array_as_lenpfx_to_continuation_bit_8 () + <Seq~<LengthPrefix x86.UInt64> x86.UInt8> +--> <Seq~MsbCont x86.UInt8> +``` + for( uint64_t i = 0; i < src->len; ++i ) { + if( src->items[i] & (1<<7) ) { + fprintf(stderr, "error: value to high for MsbContinuation\n"); + return -1; + } + + dst[i] = src->items[i]; + if( i+1 < src->len ) + dst[i] |= (1<<7); + } + + return 0; +``` + +morph_array_as_lenpfx_to_continuation_bit_16 () + <Seq~<LengthPrefix x86.UInt64> x86.UInt16> +--> <Seq~MsbCont x86.UInt16> +``` + for( uint64_t i = 0; i < src->len; ++i ) { + if( src->items[i] & (1<<15) ) { + fprintf(stderr, "error: value to high for MsbContinuation\n"); + return -1; + } + + dst[i] = src->items[i]; + if( i+1 < src->len ) + dst[i] |= (1<<15); + } + + return 0; +``` diff --git a/morphisms/posint.morphism-base b/morphisms/posint.morphism-base index 81ea945..d8838e0 100644 --- a/morphisms/posint.morphism-base +++ b/morphisms/posint.morphism-base @@ -1,3 +1,30 @@ +``` +#include <array/length-prefix.h> +``` + +morph_nat_as_u64_to_pos () + ℕ + ~ x86.UInt64 +--> ℕ + ~ <PosInt 0 LittleEndian> + ~ <Seq~<LengthPrefix x86.UInt64> <Digit 0>~x86.UInt64> +``` + dst->len = 1; + dst->items[0] = *src; + return 0; +``` + +morph_nat_as_u64_to_pos () + ℕ + ~ <PosInt 0 LittleEndian> + ~ <Seq~<LengthPrefix x86.UInt64> <Digit 0>~x86.UInt64> +--> ℕ + ~ x86.UInt64 +``` + *dst = src->items[0]; + return 0; +``` + morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ) ℕ ~ <PosInt SrcRadix LittleEndian> @@ -15,9 +42,13 @@ morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ) length_prefix_uint64_array_clear( dst ); - while( value > 0 ) { - length_prefix_uint64_array_push( dst, value % DstRadix ); - value /= DstRadix; + if( DstRadix == 0 ) { + length_prefix_uint64_array_push( dst, value ); + } else if( DstRadix > 0 ) { + while( value > 0 ) { + length_prefix_uint64_array_push( dst, value % DstRadix ); + value /= DstRadix; + } } return 0; @@ -38,17 +69,22 @@ morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ) value += src->items[i]; } - uint64_t v = value; - dst->len = 0; - while( v ) { - dst->len++; - v /= DstRadix; - } + if( DstRadix == 0 ) { + dst->len = 1; + dst->items[0] = value; + } else { + uint64_t v = value; + dst->len = 0; + while( v ) { + dst->len++; + v /= DstRadix; + } - uint64_t i = dst->len; - while( value > 0 ) { - dst->items[--i] = ( dst, value % DstRadix ); - value /= DstRadix; + uint64_t i = dst->len; + while( value > 0 ) { + dst->items[--i] = value % DstRadix; + value /= DstRadix; + } } return 0; diff --git a/morphisms/src/length-prefix.c b/morphisms/src/length-prefix.c index 4a93bec..281a8cb 100644 --- a/morphisms/src/length-prefix.c +++ b/morphisms/src/length-prefix.c @@ -28,6 +28,21 @@ int length_prefix_uint64_array_reverse( return 0; } +int length_prefix_array_map_8_to_8( + int (*f) ( uint8_t const * restrict, uint8_t * restrict ), + struct LengthPrefixUInt8Array const * restrict src, + struct LengthPrefixUInt8Array * restrict dst +) { + dst->len = src->len; + for( uint64_t i = 0; i < src->len; ++i ) { + int result = f( &src->items[i], &dst->items[i] ); + if( result ) { + return result; + } + } + return 0; +} + int length_prefix_array_map_64_to_64( int (*f) ( uint64_t const * restrict, uint64_t * restrict ), struct LengthPrefixUInt64Array const * restrict src, diff --git a/src/main.rs b/src/main.rs index 268e4de..13e5516 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,8 @@ use { laddertypes::{ dict::TypeDict, parser::ParseLadderType, subtype_unify, unparser::UnparseLadderType, BimapTypeDict, Morphism, MorphismType }, - std::{any::Any, sync::{Arc, RwLock}} + std::{any::Any, sync::{Arc, RwLock}}, + tiny_ansi::TinyAnsi }; /* @@ -60,10 +61,21 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: laddertypes::TypeTerm, skip_ } else { Some(format!("{} *", c_type)) } - } else { + } + else if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"MsbCont".into()).unwrap()) + { + let c_type = get_c_repr_type(dict, args[1].clone(), false)?; + if skip_pointer { + Some(c_type) + } else { + Some(format!("{} *", c_type)) + } + } + else { None } } + _ => None } } @@ -84,13 +96,31 @@ struct LdmcPrimCMorphism { fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String { match t { laddertypes::TypeTerm::Char(c) => { - match *c { - '\0' => { "NULL".into() }, - '\t' => { "TAB".into() }, - c => { format!("{}", c) } + match c { + '.' => format!("_dot_"), + _ => + format!("{}", (*c as u64)) } }, - t => dict.unparse(t) + laddertypes::TypeTerm::Num(n) => { + format!("{}", n) + } + laddertypes::TypeTerm::TypeID(ty_id) => { + if let Some(name) = dict.get_typename(ty_id) { + format!("{}", name.replace(".", "_dot_")) + } else { + format!("") + } + } + laddertypes::TypeTerm::Ladder(rs) | + laddertypes::TypeTerm::App(rs) => { + let mut s = String::new(); + for r in rs { + s.push('_'); + s.push_str(&encode_type_to_symbol(dict, r)); + } + s + } } } @@ -174,8 +204,8 @@ impl LdmcMorphism { pub fn generate_call(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>, i: u64) { match self { LdmcMorphism::Primitive(prim_morph) => { - let src_c_type = get_c_repr_type(dict, prim_morph.src_type.clone(), true).expect("cant get c-repr type for src type"); - let dst_c_type = get_c_repr_type(dict, prim_morph.dst_type.clone(), true).expect("cant get c-repr type for dst type"); + let src_c_type = get_c_repr_type(dict, prim_morph.src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr type for src type"); + let dst_c_type = get_c_repr_type(dict, prim_morph.dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr type for dst type"); let src_buf = if i%2 == 0 { "bufA" } else { "bufB" }; let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" }; @@ -193,19 +223,14 @@ impl LdmcMorphism { '}'); } LdmcMorphism::LengthPrefixMap { length_prefix_type, item_morph } => { - let src_c_type = get_c_repr_type(dict, self.get_type().src_type, true).expect("cant get c-repr type for src type"); - let dst_c_type = get_c_repr_type(dict, self.get_type().dst_type, true).expect("cant get c-repr type for dst type"); + let src_c_type = get_c_repr_type(dict, self.get_type().src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr type for src type"); + let dst_c_type = get_c_repr_type(dict, self.get_type().dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr type for dst type"); let map_fn = match (src_c_type.as_str(), dst_c_type.as_str()) { - ("struct LengthPrefixUInt64Array", "struct LengthPrefixUInt64Array") => { - "length_prefix_array_map_64_to_64" - }, - ("struct LengthPrefixUInt8Array", "struct LengthPrefixUInt64Array") => { - "length_prefix_array_map_8_to_64" - }, - ("struct LengthPrefixUInt64Array", "struct LengthPrefixUInt8Array") => { - "length_prefix_array_map_64_to_8" - }, + ("struct LengthPrefixUInt64Array", "struct LengthPrefixUInt64Array") => "length_prefix_array_map_64_to_64", + ("struct LengthPrefixUInt8Array", "struct LengthPrefixUInt64Array") => "length_prefix_array_map_8_to_64", + ("struct LengthPrefixUInt64Array", "struct LengthPrefixUInt8Array") => "length_prefix_array_map_64_to_8", + ("struct LengthPrefixUInt8Array", "struct LengthPrefixUInt8Array") => "length_prefix_array_map_8_to_8", _ => { "{{ ERROR: no map function implemented }}" } @@ -310,10 +335,19 @@ impl Morphism for LdmcMorphism { */ fn parser( type_dict: Arc<RwLock< BimapTypeDict >> -) -> impl Parser<char, Vec<LdmcPrimCMorphism>, Error = Simple<char>> { +) -> impl Parser<char, (String, Vec<LdmcPrimCMorphism>), Error = Simple<char>> { + + just("```") + .then(take_until(just("```"))) + .map( + move |(a, (b, c))| { + b.iter().collect() + } + ) // morph name - ident().padded() + .then( + ident().padded() // type args .then( @@ -358,12 +392,15 @@ fn parser( } }) .separated_by(text::newline()) + + ) } fn main() { let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new())); let mut morphism_base = laddertypes::MorphismBase::<LdmcMorphism>::new(vec![ - type_dict.parse("Seq~<ValueTerminated '\\0'>").expect(""), + //type_dict.parse("Seq~MsbCont").expect(""), + //type_dict.parse("Seq~<ValueTerminated '\\0'>").expect(""), type_dict.parse("Seq~<LengthPrefix x86.UInt64>").expect("") ]); @@ -372,11 +409,12 @@ fn main() { let dst_type_arg = args.next().expect("dst type expected"); for mb_path in args { - let src = std::fs::read_to_string(mb_path).expect("read"); + let src = std::fs::read_to_string(mb_path.clone()).expect("read"); let result = parser(type_dict.clone()).parse(src.clone()); match result { - Ok(morphisms) => { - eprintln!("parse ok."); + Ok((includes, morphisms)) => { + eprintln!("[{}] parse ok.", mb_path.bright_yellow()); + println!("{}", includes); for m in morphisms { morphism_base.add_morphism(LdmcMorphism::Primitive(m)); } @@ -399,9 +437,12 @@ fn main() { } + let src_type = type_dict.parse( src_type_arg.as_str() ).expect(""); + let dst_type = type_dict.parse( dst_type_arg.as_str() ).expect(""); + let path = morphism_base.find_morphism_path(MorphismType { - src_type: type_dict.parse( src_type_arg.as_str() ).expect(""), - dst_type: type_dict.parse( dst_type_arg.as_str() ).expect(""), + src_type: src_type.clone(), + dst_type: dst_type.clone(), }); match path { @@ -411,8 +452,10 @@ fn main() { /* todo: collect include files from morphism base */ println!(r#" #include <stdio.h> +#include <unistd.h> +#include <string.h> #include <stdint.h> -#include <array/length-prefix.h> +#include <stdbool.h> "#); let mut existing_instantiations = Vec::new(); @@ -450,9 +493,18 @@ int main() {{ uint8_t bufA[1024]; uint8_t bufB[1024]; - scanf("%s", bufA); - "#); - for morph_inst in path { + char in_str[] = "read :: {} \n"; + char out_str[]= "write:: {} \n"; + write(2, in_str, strlen(in_str)); + write(2, out_str, strlen(out_str)); + + int l = read(0, bufA, 1024); + fprintf(stderr, "read %d bytes\n", l); + + "#, + type_dict.unparse(&src_type).replace("\\", "\\\\"), + type_dict.unparse(&dst_type).replace("\\", "\\\\") ); + for morph_inst in path.iter() { println!(r#" /* morph to {} @@ -473,15 +525,44 @@ int main() {{ } let out_buf = if i%2==0 { "bufA" } else { "bufB" }; - println!(r#" - printf("%s\n", {}); + let is_string = false; + if let Ok((halo, σ)) = laddertypes::subtype_unify( + &dst_type, + &type_dict.parse("<Seq~<ValueTerminated 0> x86.UInt8>").unwrap() + ) { + println!(r#" + printf("%s\n", {});"#, out_buf); + } else if let Ok((halo, σ)) = laddertypes::subtype_unify( + &dst_type, + &type_dict.parse("<Seq~<LengthPrefix x86.UInt64> x86.UInt8>").unwrap() + ) { + println!(r#" + /* write output + */ + {{ + struct LengthPrefixUInt8Array * buf = (void*){}; + write(1, {}, sizeof(uint64_t) + buf->len); + }}"#, out_buf, out_buf); + } else { + println!(r#" + write(1, {}, {});"#, + out_buf, + 1024 + ); + } + + + println!(r#" return 0; }} - "#, out_buf); + "#); + + eprintln!("Success: generated C code"); } None => { eprintln!("Error: could not find morphism path"); + std::process::exit(-1); } } }