From cea1f36e63fb23197668c10f50e92011ae7e9b82 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 16 Feb 2025 17:08:55 +0100 Subject: [PATCH] read morphism body definitions from morphism-base file and generate instantiations based on type-variable substitutions --- .../{morphisms => array}/length-prefix.h | 14 -- morphisms/include/morphisms/posint.h | 41 ------ morphisms/morphism-base/digit.morphism-base | 67 +++++++++ .../morphism-base/length_prefix.morphism-base | 27 +++- morphisms/morphism-base/posint.morphism-base | 72 ++++++---- morphisms/src/length-prefix.c | 27 +--- morphisms/src/posint.c | 119 ---------------- src/main.rs | 132 ++++++++++++++---- 8 files changed, 244 insertions(+), 255 deletions(-) rename morphisms/include/{morphisms => array}/length-prefix.h (85%) delete mode 100644 morphisms/include/morphisms/posint.h create mode 100644 morphisms/morphism-base/digit.morphism-base delete mode 100644 morphisms/src/posint.c diff --git a/morphisms/include/morphisms/length-prefix.h b/morphisms/include/array/length-prefix.h similarity index 85% rename from morphisms/include/morphisms/length-prefix.h rename to morphisms/include/array/length-prefix.h index d3eb76f..844340c 100644 --- a/morphisms/include/morphisms/length-prefix.h +++ b/morphisms/include/array/length-prefix.h @@ -63,17 +63,3 @@ int length_prefix_array_map_64_to_8( struct LengthPrefixUInt64Array const * restrict src, struct LengthPrefixUInt8Array * restrict dst ); - - -/* - * Morphisms - */ - -int morph_string_as_nullterm_to_length_prefix( - char const * restrict src, - struct LengthPrefixUInt8Array * restrict dst -); -int morph_string_as_length_prefix_to_nullterm( - struct LengthPrefixUInt8Array const * restrict src, - char * restrict dst -); diff --git a/morphisms/include/morphisms/posint.h b/morphisms/include/morphisms/posint.h deleted file mode 100644 index 613333e..0000000 --- a/morphisms/include/morphisms/posint.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include <stdint.h> -#include <morphisms/length-prefix.h> - -int morph_digit_as_char_to_uint8( - //uint64_t const radix, - uint8_t const * restrict src, - uint8_t * restrict dst -); -int morph_digit_as_char_to_uint64( - //uint64_t const radix, - uint8_t const * restrict src, - uint64_t * restrict dst -); -int morph_digit_as_uint8_to_char( - //uint64_t const radix, - uint8_t const * restrict src, - uint8_t * restrict dst -); -int morph_digit_as_uint64_to_char( - //uint64_t const radix, - uint64_t const * restrict src, - uint8_t * restrict dst -); -int morph_posint_endianness( - uint64_t const radix, - struct LengthPrefixUInt64Array const * restrict src, - struct LengthPrefixUInt64Array * restrict dst -); -int morph_posint_radix_le( - uint64_t const src_radix, - uint64_t const dst_radix, - struct LengthPrefixUInt64Array const * restrict src, - struct LengthPrefixUInt64Array * restrict dst -); -int morph_posint_radix_be( - uint64_t const src_radix, - uint64_t const dst_radix, - struct LengthPrefixUInt64Array const * restrict src, - struct LengthPrefixUInt64Array * restrict dst -); diff --git a/morphisms/morphism-base/digit.morphism-base b/morphisms/morphism-base/digit.morphism-base new file mode 100644 index 0000000..0abff91 --- /dev/null +++ b/morphisms/morphism-base/digit.morphism-base @@ -0,0 +1,67 @@ +morph_digit_as_char_to_uint8 (Radix:ℤ) + <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 +--> <Digit Radix> ~ x86.UInt8 +``` + if( *src >= '0' && *src <= '9' ) + *dst = *src - '0'; + else if( *src >= 'a' && *src <= 'f') + *dst = 0xa + *src - 'a'; + else if( *src >= 'A' && *src <= 'F') + *dst = 0xa + *src - 'A'; + else + return -1; + + if( *dst < Radix ) { + return 0; + } else { + return -1; + } +``` + +morph_digit_as_char_to_uint64 (Radix:ℤ) + <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 +--> <Digit Radix> ~ x86.UInt64 +``` + if( *src >= '0' && *src <= '9' ) + *dst = *src - '0'; + else if( *src >= 'a' && *src <= 'f') + *dst = 0xa + *src - 'a'; + else if( *src >= 'A' && *src <= 'F') + *dst = 0xa + *src - 'A'; + else + return -1; + + if( *dst < Radix ) { + return 0; + } else { + return -1; + } +``` + +morph_digit_as_uint8_to_char (Radix:ℤ_16) + <Digit Radix> ~ x86.UInt8 +--> <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 +``` + if ( *src < 10 ) + *dst = *src + '0'; + else if( *dst < 16 ) + *dst = *src - 0xa + 'a'; + else + return -1; + + return 0; +``` + +morph_digit_as_uint64_to_char (Radix:ℤ_16) + <Digit Radix> ~ x86.UInt64 +--> <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 +``` + if ( *src < 10 ) + *dst = *src + '0'; + else if( *dst < 16 ) + *dst = *src - 0xa + 'a'; + else + return -1; + + return 0; +``` diff --git a/morphisms/morphism-base/length_prefix.morphism-base b/morphisms/morphism-base/length_prefix.morphism-base index 290f212..e5ad529 100644 --- a/morphisms/morphism-base/length_prefix.morphism-base +++ b/morphisms/morphism-base/length_prefix.morphism-base @@ -1,9 +1,24 @@ -morph_string_as_nullterm_to_length_prefix () - <Seq~<ValueDelim '\0'> x86.UInt8> +morph_array_as_valterm_to_lenpfx (Terminator:x86.UInt8) + <Seq~<ValueTerminated Terminator> x86.UInt8> --> <Seq~<LengthPrefix x86.UInt64> x86.UInt8> -@lib/libmorph_length-prefix.so:src/length_prefix.c +``` + length_prefix_uint8_array_clear(dst); + while( *src != Terminator ) { + length_prefix_uint8_array_push(dst, *src); + src++; + } -morph_string_as_length_prefix_to_nullterm () + return 0; +``` + +morph_array_as_lenpfx_to_valterm (Terminator:x86.UInt8) <Seq~<LengthPrefix x86.UInt64> x86.UInt8> ---> <Seq~<ValueDelim '\0'> x86.UInt8> -@lib/libmorph_length-prefix.so:src/length_prefix.c +--> <Seq~<ValueTerminated Terminator> x86.UInt8> +``` + for( uint64_t i = 0; i < src->len; ++i ) { + *dst ++ = src->items[i]; + } + *dst = Terminator; + + return 0; +``` diff --git a/morphisms/morphism-base/posint.morphism-base b/morphisms/morphism-base/posint.morphism-base index 7f25f32..81ea945 100644 --- a/morphisms/morphism-base/posint.morphism-base +++ b/morphisms/morphism-base/posint.morphism-base @@ -1,31 +1,27 @@ -morph_digit_as_char_to_uint8 (Radix:ℤ_16) - <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 ---> <Digit Radix> ~ x86.UInt8 -@lib/libmorph-posint.so:src/posint.c - -morph_digit_as_uint8_to_char (Radix:ℤ_16) - <Digit Radix> ~ x86.UInt8 ---> <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 -@lib/libmorph-posint.so:src/posint.c - -morph_digit_as_char_to_uint64 (Radix:ℤ_16) - <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 ---> <Digit Radix> ~ x86.UInt64 -@lib/libmorph-posint.so:src/posint.c - -morph_digit_as_uint64_to_char (Radix:ℤ_16) - <Digit Radix> ~ x86.UInt64 ---> <Digit Radix> ~ Char ~ Ascii ~ x86.UInt8 -@lib/libmorph-posint.so:src/posint.c - morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ) ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq~<LengthPrefix x86.UInt64> <Digit SrcRadix>~x86.UInt64> --> ℕ ~ <PosInt DstRadix LittleEndian> - ~ <Seq~<LengthPrefix x86.UInt64> <Digit DstRadix>~x86.UInt64> -@lib/libmorph-posint.so:src/posint.c + ~ <Seq~<LenghtPrefix x86.UInt64> <Digit DstRadix>~x86.UInt64> +``` + uint64_t value = 0; + + for( uint64_t i = 0; i < src->len; ++i ) { + value *= SrcRadix; + value += src->items[src->len - i - 1]; + } + + length_prefix_uint64_array_clear( dst ); + + while( value > 0 ) { + length_prefix_uint64_array_push( dst, value % DstRadix ); + value /= DstRadix; + } + + return 0; +``` morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ) ℕ @@ -34,7 +30,29 @@ morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ) --> ℕ ~ <PosInt DstRadix BigEndian> ~ <Seq~<LengthPrefix x86.UInt64> <Digit DstRadix>~x86.UInt64> -@lib/libmorph-posint.so:src/posint.c +``` + uint64_t value = 0; + + for( uint64_t i = 0; i < src->len; ++i ) { + value *= SrcRadix; + value += src->items[i]; + } + + 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; + } + + return 0; +``` morph_posint_endianness (Radix:ℤ) ℕ @@ -43,7 +61,9 @@ morph_posint_endianness (Radix:ℤ) --> ℕ ~ <PosInt Radix BigEndian> ~ <Seq~<LengthPrefix x86.UInt64> <Digit Radix> ~ x86.UInt64> -@lib/libmorph-posint.so:src/posint.c +``` + return length_prefix_uint64_array_reverse( src, dst ); +``` morph_posint_endianness (Radix:ℤ) ℕ @@ -52,4 +72,6 @@ morph_posint_endianness (Radix:ℤ) --> ℕ ~ <PosInt Radix LittleEndian> ~ <Seq~<LengthPrefix x86.UInt64> <Digit Radix> ~ x86.UInt64> -@lib/libmorph-posint.so:src/posint.c +``` + return length_prefix_uint64_array_reverse( src, dst ); +``` diff --git a/morphisms/src/length-prefix.c b/morphisms/src/length-prefix.c index 32029bf..4a93bec 100644 --- a/morphisms/src/length-prefix.c +++ b/morphisms/src/length-prefix.c @@ -1,7 +1,7 @@ #include <stdio.h> #include <stdint.h> -#include <morphisms/length-prefix.h> +#include <array/length-prefix.h> void length_prefix_uint64_array_clear( struct LengthPrefixUInt64Array * data @@ -120,28 +120,3 @@ void length_prefix_uint8_array_dump( } printf("]\n"); } - -int morph_string_as_nullterm_to_length_prefix( - char const * restrict src, - struct LengthPrefixUInt8Array * restrict dst -) { - length_prefix_uint8_array_clear(dst); - while( *src ) { - length_prefix_uint8_array_push(dst, *src); - src++; - } - - return 0; -} - -int morph_string_as_length_prefix_to_nullterm( - struct LengthPrefixUInt8Array const * restrict src, - char * restrict dst -) { - for( uint64_t i = 0; i < src->len; ++i ) { - *dst ++ = src->items[i]; - } - *dst = '\0'; - - return 0; -} diff --git a/morphisms/src/posint.c b/morphisms/src/posint.c deleted file mode 100644 index dcc219e..0000000 --- a/morphisms/src/posint.c +++ /dev/null @@ -1,119 +0,0 @@ -#include <stdint.h> -#include <morphisms/length-prefix.h> - -int morph_digit_as_char_to_uint8( - //uint64_t const radix, - uint8_t const * restrict src, - uint8_t * restrict dst -) { - if( *src >= '0' && *src <= '9' ) - *dst = *src - '0'; - else if( *src >= 'a' && *src <= 'f') - *dst = 0xa + *src - 'a'; - else if( *src >= 'A' && *src <= 'F') - *dst = 0xa + *src - 'A'; - else - return -1; - - return 0; -} - -int morph_digit_as_char_to_uint64( - //uint64_t const radix, - uint8_t const * restrict src, - uint64_t * restrict dst -) { - return morph_digit_as_char_to_uint8(src, (void*)dst); -} - -int morph_digit_as_uint8_to_char( - //uint64_t const radix, - uint8_t const * restrict src, - uint8_t * restrict dst -) { - if ( *src < 10 ) - *dst = *src + '0'; - else if( *dst < 16 ) - *dst = *src - 0xa + 'a'; - else - return -1; - - return 0; -} - -int morph_digit_as_uint64_to_char( - //uint64_t const radix, - uint64_t const * restrict src, - uint8_t * restrict dst -) { - return morph_digit_as_uint8_to_char((void*)src, dst); -} - -/* switches endianness by reversing the digit sequence - */ -int morph_posint_endianness( - uint64_t const radix, - - struct LengthPrefixUInt64Array const * restrict src, - struct LengthPrefixUInt64Array * restrict dst -) { - return length_prefix_uint64_array_reverse( src, dst ); -} - -/* morph radix in little endian - */ -int morph_posint_radix_le( - uint64_t const src_radix, - uint64_t const dst_radix, - - struct LengthPrefixUInt64Array const * restrict src, - struct LengthPrefixUInt64Array * restrict dst -) { - uint64_t value = 0; - - for( uint64_t i = 0; i < src->len; ++i ) { - value *= src_radix; - value += src->items[src->len - i - 1]; - } - - length_prefix_uint64_array_clear( dst ); - - while( value > 0 ) { - length_prefix_uint64_array_push( dst, value % dst_radix ); - value /= dst_radix; - } - - return 0; -} - -/* morph radix in little endian - */ -int morph_posint_radix_be( - uint64_t const src_radix, - uint64_t const dst_radix, - - struct LengthPrefixUInt64Array const * restrict src, - struct LengthPrefixUInt64Array * restrict dst -) { - uint64_t value = 0; - - for( uint64_t i = 0; i < src->len; ++i ) { - value *= src_radix; - value += src->items[i]; - } - - uint64_t v = value; - dst->len = 0; - while( v ) { - dst->len++; - v /= dst_radix; - } - - uint64_t i = dst->len; - while( value > 0 ) { - dst->items[--i] = ( dst, value % dst_radix ); - value /= dst_radix; - } - - return 0; -} diff --git a/src/main.rs b/src/main.rs index 6abf52e..268e4de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,7 +51,7 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: laddertypes::TypeTerm, skip_ _ => None } } - else if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"ValueDelim".into()).unwrap()) + else if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"ValueTerminated".into()).unwrap()) { let _delim_val = args[1].clone(); let c_type = get_c_repr_type(dict, args[2].clone(), false)?; @@ -78,7 +78,24 @@ struct LdmcPrimCMorphism { type_args: Vec<(laddertypes::TypeID, String)>, src_type: laddertypes::TypeTerm, dst_type: laddertypes::TypeTerm, - locations: Vec<String> + c_source: String +} + +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) } + } + }, + t => dict.unparse(t) + } +} + +fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm) -> String { + dict.unparse(t) } impl LdmcPrimCMorphism { @@ -89,7 +106,7 @@ impl LdmcPrimCMorphism { if let Some(val_trm) = σ.get(k_id) { if let laddertypes::TypeID::Var(var_id) = k_id { let name = dict.get_varname(*var_id).unwrap(); - let val_str = dict.unparse(val_trm); + let val_str = encode_type_to_symbol(dict, val_trm); s.push_str(&format!("_{}_{}", name, val_str)); } } else { @@ -110,6 +127,34 @@ impl LdmcPrimCMorphism { get_c_repr_type(dict, self.src_type.clone(), true).expect("cant get c-repr type for src type"), get_c_repr_type(dict, self.dst_type.clone(), true).expect("cant get c-repr type for dst type")) } + + pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> Option<String> { + let mut s = String::new(); + + s.push_str(&format!(r#" +int {} ( {} const * restrict src, {} * restrict dst ) {{ +"#, + self.instantiated_symbol_name(dict, &σ), + get_c_repr_type(dict, self.src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr-type"), + get_c_repr_type(dict, self.dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr-type"), + )); + for (ty_id, kind) in self.type_args.iter() { + if let Some(val) = σ.get(ty_id) { + s.push_str(&format!(" #define {} {}\n", dict.get_typename(&ty_id).unwrap(), encode_type_to_value(dict, val))); + } + } + + s.push_str(&self.c_source); + + for (ty_id, kind) in self.type_args.iter() { + s.push_str(&format!("\n #undef {}", dict.get_typename(&ty_id).unwrap())); + } + + s.push_str(&format!(r#" +}} +"#)); + Some(s) + } } #[derive(Clone)] @@ -259,36 +304,45 @@ impl Morphism for LdmcMorphism { * NAME '(' [TYPE-ARG-NAME ':' KIND] ')' * SRC-TYPE * '-->' DST-TYPE - * '@' [ LOCATION ':' ] + * ``` + * TEMPLATE-CODE + * ``` */ fn parser( type_dict: Arc<RwLock< BimapTypeDict >> ) -> impl Parser<char, Vec<LdmcPrimCMorphism>, Error = Simple<char>> { + // morph name ident().padded() + + // type args .then( ident().padded() - .then_ignore(just(':').padded()) + .then_ignore(just(":").padded()) .then(none_of(",)").repeated().padded()) - .separated_by(just(',').padded()) - .delimited_by(just('('), just(')')) + .separated_by(just(",").padded()) + .delimited_by(just("("), just(")")) ) + + // newline .then_ignore(just('\n')) - .then( - take_until(just("-->").ignored()) - .then(take_until(just('@').ignored())) - ) - .then( - none_of(":\n").repeated().separated_by(just(':')) - ) + + // src type + .then(take_until(just("-->").ignored())) + // dst_type + .then(take_until(just("```"))) + + // c sourcecode template + .then(take_until(just("```"))) + .map( - move |(((symbol, type_args), ((src_type, _), (dst_type, _))), locations)| { + move |((((symbol, type_args), (src_type, _)), (dst_type, _)), (c_source, _))| { + let c_source = c_source.iter().collect(); let mut type_dict = type_dict.write().unwrap(); let type_args : Vec<_> = type_args.into_iter().map(|(v,k)| (v,k.into_iter().collect())).collect(); let mut ty_args = Vec::new(); for (var, kind) in type_args.into_iter() { let var_id = type_dict.add_varname(var.clone()); - eprintln!("parser: add varname {} -> {:?}", var, type_dict.get_typeid(&var)); ty_args.push((var_id, kind)); } @@ -300,7 +354,7 @@ fn parser( type_args: ty_args, src_type, dst_type, - locations: locations.into_iter().map(|l| l.into_iter().collect()).collect() + c_source } }) .separated_by(text::newline()) @@ -309,7 +363,7 @@ fn parser( 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~<ValueDelim '\\0'>").expect(""), + type_dict.parse("Seq~<ValueTerminated '\\0'>").expect(""), type_dict.parse("Seq~<LengthPrefix x86.UInt64>").expect("") ]); @@ -345,23 +399,53 @@ fn main() { } - 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(""), - }//, - // &mut *type_dict.write().unwrap() - ); + }); match path { Some(path) => { let mut i = 0; + + /* todo: collect include files from morphism base */ println!(r#" #include <stdio.h> #include <stdint.h> -#include <morphisms/length-prefix.h> -#include <morphisms/posint.h> +#include <array/length-prefix.h> +"#); + let mut existing_instantiations = Vec::new(); + for morph_inst in path.iter() { + match &morph_inst.m { + LdmcMorphism::Primitive( item_morph ) => { + let name = item_morph.instantiated_symbol_name(&mut type_dict, &morph_inst.σ); + if ! existing_instantiations.contains(&name) { + if let Some(s) = item_morph.generate_instantiation(&mut type_dict, &morph_inst.σ) { + println!("{}", s); + } else { + eprintln!("couldnt generate instance {}", name); + } + existing_instantiations.push( name ); + } + } + LdmcMorphism::LengthPrefixMap { length_prefix_type, item_morph } => { + let name = item_morph.instantiated_symbol_name(&mut type_dict, &morph_inst.σ); + if ! existing_instantiations.contains(&name) { + if let Some(s) = item_morph.generate_instantiation(&mut type_dict, &morph_inst.σ) { + println!("{}", s); + } else { + eprintln!("couldnt generate instance {}", name); + } + + existing_instantiations.push( name ); + } + } + _ => {} + } + } + + println!(r#" int main() {{ uint8_t bufA[1024]; uint8_t bufB[1024];