From 21bb33193ab52c87007913f3f93ec802014db2ba Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Mon, 24 Mar 2025 10:14:25 +0100
Subject: [PATCH 01/31] wip struct morphisms

---
 src/c_gen.rs         | 133 ++++++++++++++++++++++++++++------
 src/main.rs          | 119 +++++++++++++++++++++++++-----
 src/morphism.rs      | 116 +++++++++++++++++++++++++++++-
 src/struct_layout.rs | 167 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 496 insertions(+), 39 deletions(-)
 create mode 100644 src/struct_layout.rs

diff --git a/src/c_gen.rs b/src/c_gen.rs
index ac68a93..7f5c7ea 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -1,6 +1,6 @@
 use {
-    laddertypes::{TypeDict, TypeTerm, parser::*, unparser::*, morphism::{Morphism, MorphismInstance}},
-    crate::morphism::{LdmcPrimCMorphism, LdmcMorphism}
+    crate::{morphism::{LdmcMorphism, LdmcPrimCMorphism}, struct_layout::{get_type_size, ObjectSize, StructLayout}},
+    laddertypes::{morphism::{Morphism, MorphismInstance}, parser::*, unparser::*, TypeDict, TypeTerm},
 };
 
 /*
@@ -85,7 +85,23 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: laddertypes::TypeTerm, skip_
                             }
                         }
                         else {
-                            None
+
+                            if let Some(layout) = StructLayout::parse(dict, t.clone()) {
+                                let mut c_type = String::from("struct {\n");
+
+                                for (field_name, field_type) in layout.members.iter() {
+                                    let field_c_type = get_c_repr_type(dict, field_type.clone(), false).expect("");
+                                    c_type.push_str(&format!("    {} {};\n",
+                                        field_c_type,
+                                        field_name
+                                    ));
+                                }
+
+                                c_type.push_str("}");
+                                Some(c_type)
+                            } else {
+                                None
+                            }
                         }
                     }
 
@@ -205,14 +221,17 @@ morph {}
 ---> {},
 subst σ = {:?},
 halo  Ψ = {}
-*/"#,
+*/
+{}
+"#,
             type_dict.unparse(&morph_inst.get_type().dst_type.param_normalize().decurry()),
             type_dict.unparse(&morph_inst.m.get_type().src_type),
             type_dict.unparse(&morph_inst.m.get_type().dst_type),
             morph_inst.σ,
             type_dict.unparse(&morph_inst.halo),
+            morph_inst.m.generate_call(type_dict, &morph_inst.σ, i)
         );
-        morph_inst.m.generate_call(type_dict, &morph_inst.σ, i);
+
         i += 1;
     }
 
@@ -322,7 +341,42 @@ int {} ( {} const * restrict src, {} * restrict dst ) {{
 }
 
 impl LdmcMorphism {
-    pub fn generate_call(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>, i: u64) {
+    pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> LdmcPrimCMorphism {
+
+        let src_type = self.get_type().src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
+        let dst_type = self.get_type().dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
+
+        let src_c_type = get_c_repr_type(dict, src_type.clone(), true).expect("cant get c-repr type for src type");
+        let dst_c_type = get_c_repr_type(dict, dst_type.clone(), true).expect("cant get c-repr type for src type");
+
+        let c_source =
+            format!("
+typedef {} {}_src_t;
+
+typedef {} {}_dst_t;
+
+int {} ( {}_src_t const * restrict src, {}_dst_t * restrict dst )
+{{
+{}
+    return 0;
+}}
+                ",
+                src_c_type, symbol,
+                dst_c_type, symbol,
+                symbol, symbol, symbol,
+                self.generate_call(dict, σ, 0)
+            );
+
+        LdmcPrimCMorphism {
+            symbol,
+            type_args: Vec::new(),
+            src_type,
+            dst_type,
+            c_source
+        }
+    }
+
+    pub fn generate_call(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>, i: u64) -> String {
         match self {
             LdmcMorphism::Primitive(prim_morph) => {
                 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");
@@ -331,17 +385,16 @@ impl LdmcMorphism {
                 let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
                 let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
 
-                println!(r#"
-    {}
+                format!(r#"
+    {{
             {} const * restrict src = (void*) {};
             {} * restrict dst = (void*) {};
             {} ( src, dst );
-    {}"#,
-                    '{',
+    }}"#,
                     src_c_type, src_buf,
                     dst_c_type, dst_buf,
                     prim_morph.instantiated_symbol_name(dict, σ),
-                    '}');
+                )
             }
             LdmcMorphism::LengthPrefixMap { length_prefix_type, item_morph } => {
                 let src_type = self.get_type().src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
@@ -383,18 +436,17 @@ impl LdmcMorphism {
 
                 let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
                 let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
-                println!(r#"
-    {}
+                format!(r#"
+    {{
             {} const * restrict src = (void*) {};
             {} * restrict dst = (void*) {};
             {} ( {}, src, dst );
-    {}"#,
-            '{',
+    }}"#,
                     src_c_type, src_buf,
                     dst_c_type, dst_buf,
                     map_fn,
                     item_morph.instantiated_symbol_name(dict, σ),
-                    '}');
+                )
             }
             LdmcMorphism::ValueDelimMap { delim, item_morph } => {
                 let src_c_type = get_c_repr_type(dict, item_morph.src_type.clone(), false).expect("cant get c-repr type for src type");
@@ -402,17 +454,54 @@ impl LdmcMorphism {
 
                 let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
                 let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
-                println!(r#"
-    {}
+                format!(r#"
+    {{
             {} const * restrict src = (void*) {};
             {} * restrict dst = (void*) {};
             value_delim_array_map_8_to_64( {}, src, dst );
-    {}"#,
-            '{',
+    }}"#,
                     src_c_type, src_buf,
                     dst_c_type, dst_buf,
-                    item_morph.instantiated_symbol_name(dict, σ),
-                    '}');
+                    item_morph.instantiated_symbol_name(dict, σ)
+                )
+            },
+
+            LdmcMorphism::StructMap { src_struct, dst_struct, member_morphisms } => {
+                let mut output = String::new();
+                for member_morph in member_morphisms.iter() {
+                    if let Some(m) = member_morph.item_morph.as_ref() {
+                        //let src_c_type = get_c_repr_type(dict, m.src_type.clone(), false).expect("cant get c-repr type for field member");
+                        //let dst_c_type = get_c_repr_type(dict, m.dst_type.clone(), false).expect("cant get c-repr type for field member");
+
+                        output.push_str(&format!("    {} ( &src->{}, &dst->{} );\n",
+                            m.instantiated_symbol_name(dict, σ),
+                            member_morph.field_name,
+                            member_morph.field_name
+                        ));
+                    } else {
+                        let mut field_type = None;
+                        for (field_name, ft) in src_struct.members.iter() {
+                            if field_name == &member_morph.field_name {
+                                field_type = Some(ft);
+                            }
+                        }
+
+                        let field_type = field_type.expect("cant get field member type");
+                        //if let Some(field_c_type) = get_c_repr_type(dict, field_type.clone(), false).expect("cat get c-repr type for field member");
+
+                        match  get_type_size(dict, field_type.clone()) {
+                            ObjectSize::Static(size) => {
+                                output.push_str(&format!("    memcpy( &dst->{}, &src->{}, sizeof(dst->{}) );\n",
+                                    member_morph.field_name, member_morph.field_name, member_morph.field_name
+                                ));
+                            }
+                            _ => {
+                                eprintln!("cant assign field of unknown size!");
+                            }
+                        }
+                    }
+                }
+                output
             }
         }
     }
diff --git a/src/main.rs b/src/main.rs
index 13b8629..8769384 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,29 +3,25 @@
 mod morphism;
 mod parser;
 mod c_gen;
+mod struct_layout;
 
 use {
-    ariadne::{Color, Label, Report, ReportKind, Source},
-    chumsky::prelude::*,
-    laddertypes::{
-        parser::ParseLadderType, BimapTypeDict, MorphismType
-    },
-    std::sync::{Arc, RwLock},
-    tiny_ansi::TinyAnsi,
-
-
     crate::{
         morphism::LdmcMorphism,
         parser::morphism_base_parser,
-    }
+    }, ariadne::{Color, Label, Report, ReportKind, Source}, chumsky::prelude::*, laddertypes::{
+        parser::ParseLadderType, unparser::*, BimapTypeDict, MorphismType, TypeDict
+    }, std::{collections::HashMap, sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi
 };
 
 fn main() {
     let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
-    let mut morphism_base = laddertypes::MorphismBase::<LdmcMorphism>::new(vec![
+
+    let mut morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcMorphism>::new(vec![
         //type_dict.parse("Seq~MsbCont").expect(""),
         //type_dict.parse("Seq~<ValueTerminated '\\0'>").expect(""),
-        type_dict.parse("Seq~<LengthPrefix native.UInt64>").expect("")
+        type_dict.parse("Seq~<LengthPrefix native.UInt64>").expect(""),
+        type_dict.parse("Struct").expect("")
     ]);
 
     let mut args = std::env::args().skip(1);
@@ -60,14 +56,105 @@ fn main() {
         }
     }
 
+    let mut γ = HashMap::new();
+    γ.insert(
+        type_dict.get_typeid_creat(&"Byte".into()),
+        type_dict.parse("<Seq~<StaticLength 8> Bit>").expect("parse")
+            .apply_substitution(&|k| γ.get(k).cloned())
+            .clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.UInt8".into()),
+        type_dict.parse("ℤ_2^8 ~ <PosInt 2 BigEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>").expect("parse")
+            .apply_substitution(&|k| γ.get(k).cloned())
+            .clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.UInt16".into()),
+        type_dict.parse("ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >").expect("parse")
+            .apply_substitution(&|k| γ.get(k).cloned())
+            .clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.UInt32".into()),
+        type_dict.parse("ℤ_2^32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >").expect("parse")
+            .apply_substitution(&|k| γ.get(k).cloned())
+            .clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.UInt64".into()),
+        type_dict.parse("ℤ_2^64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >").expect("parse")
+            .apply_substitution(&|k| γ.get(k).cloned())
+            .clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.Float".into()),
+        type_dict.parse("ℝ ~ IEEE-754.Float32 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
+            .apply_substitution(&|k| γ.get(k).cloned())
+            .clone()
+    );
 
+    let struct_type1 = type_dict.parse("
+        <Struct
+            <Struct.Field  online-since          TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
+            <Struct.Field  battery-capacity      Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
+            <Struct.Field  battery-charge        Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
+            <Struct.Field  min-sampling-period   Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
+            <Struct.Field  cur-sampling-period   Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
+            <Struct.Field  max-chunk-size        ℕ ~ native.UInt32 >
+            <Struct.Field  cur-chunk-size        ℕ ~ native.UInt32 >
+            <Struct.Field  n-chunks-capacity     ℕ ~ native.UInt32 >
+            <Struct.Field  n-full-data-chunks    ℕ ~ native.UInt32 >
+            <Struct.Field  n-empty-data-chunks   ℕ ~ native.UInt32 >
+        >
+    ").expect("parse struct type");
+
+    eprintln!("{}
+    ",
+    struct_type1.clone().sugar(&mut type_dict).pretty(&type_dict, 0)
+    );
+
+    for m in morphism_base.enum_morphisms( &struct_type1 ) {
+        eprintln!("{:?} -> {:?}",
+            type_dict.read().unwrap().unparse(&m.get_type().src_type),
+            type_dict.read().unwrap().unparse(&m.get_type().dst_type)
+        );
+    }
+    return;
+
+    let struct_type2 = type_dict.parse("
+        <Struct
+
+            <Struct.Field  battery-charge        Energy ~ Wh ~ ℝ ~ native.Double >
+            <Struct.Field  battery-capacity      Energy ~ Wh ~ ℝ ~ native.Double >
+            <Struct.Field  min-sampling-period   Duration ~ Seconds ~ ℝ ~ native.Double >
+            <Struct.Field  cur-sampling-period   Duration ~ Seconds ~ ℝ ~ native.Double >
+            <Struct.Field  max-chunk-size        ℕ ~ native.UInt32 >
+            <Struct.Field  cur-chunk-size        ℕ ~ native.UInt32 >
+            <Struct.Field  n-chunks-capacity     ℕ ~ native.UInt32 >
+            <Struct.Field  n-full-data-chunks    ℕ ~ native.UInt32 >
+            <Struct.Field  n-empty-data-chunks   ℕ ~ native.UInt32 >
+
+            <Struct.Field  online-since          TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ native.Double >
+        >
+    ").expect("parse struct type");
+
+    let m = LdmcMorphism::new_struct_map(&mut type_dict, &morphism_base, struct_type1, struct_type2);
+
+    println!("{}",
+        m.into_prim_c_morphism(&mut type_dict, "morph_my_struct".into(), &HashMap::new())
+            .c_source
+    );
+return;
     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: src_type.clone(),
-        dst_type: dst_type.clone(),
-    });
+    let path = laddertypes::morphism_path::ShortestPathProblem::new(
+        &morphism_base,
+        MorphismType {
+            src_type: src_type.clone(),
+            dst_type: dst_type.clone(),
+        }).solve();
 
     match path {
         Some(path) => {
diff --git a/src/morphism.rs b/src/morphism.rs
index a1f2aab..c5a509f 100644
--- a/src/morphism.rs
+++ b/src/morphism.rs
@@ -1,5 +1,6 @@
 
-use laddertypes::morphism::Morphism;
+use laddertypes::{morphism::Morphism, morphism_base::MorphismBase};
+use crate::{c_gen::encode_type_to_symbol, struct_layout::StructLayout};
 
 #[derive(Clone, Debug)]
 pub struct LdmcPrimCMorphism {
@@ -10,9 +11,18 @@ pub struct LdmcPrimCMorphism {
     pub c_source: String
 }
 
+#[derive(Clone)]
+pub struct StructFieldMorphism {
+    pub field_name: String,
+    pub item_morph: Option<Box<LdmcPrimCMorphism>>,
+    pub src_offset: u64,
+    pub dst_offset: u64,
+}
+
 #[derive(Clone)]
 pub enum LdmcMorphism {
     Primitive( LdmcPrimCMorphism ),
+    //Chain(Vec< LdmcPrimCMorphism >),
     LengthPrefixMap{
         length_prefix_type: laddertypes::TypeTerm,
         item_morph: Box<LdmcPrimCMorphism>
@@ -20,6 +30,104 @@ pub enum LdmcMorphism {
     ValueDelimMap{
         delim: u64,
         item_morph: Box<LdmcPrimCMorphism>
+    },
+    StructMap{
+        src_struct: StructLayout,
+        dst_struct: StructLayout,
+        member_morphisms: Vec<StructFieldMorphism>
+    }
+}
+
+impl LdmcMorphism {
+    /*
+    pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String) -> LdmcPrimCMorphism {
+
+        let src_c_type = ;
+        let dst_c_type = ;
+
+        let c_source =
+            format!("
+                int {} ( {} const * restrict src, {} * restrict dst ) {{
+                    {}
+                    return 0;
+                }}
+                ",
+                symbol, src_c_type, dst_c_type,
+                self.generate_call(dict, &std::collections::HashMap::new(), 0)
+            );
+
+        LdmcPrimCMorphism {
+            symbol,
+            type_args: Vec::new(),
+            src_type,
+            dst_type,
+            c_source
+        }
+    }
+*/
+    pub fn new_struct_map(
+        dict: &mut impl laddertypes::TypeDict,
+        morph_base: &MorphismBase<LdmcMorphism>,
+        src: laddertypes::TypeTerm,
+        dst: laddertypes::TypeTerm,
+    ) -> Self {
+        let src_struct = StructLayout::parse(dict, src).expect("cant parse src struct layout");
+        let dst_struct = StructLayout::parse(dict, dst).expect("cant parse dst struct layout");
+
+        let mut member_morphisms = Vec::new();
+
+        for (field_name, dst_type) in dst_struct.members.iter() {
+            let mut src_type = None;
+            for (src_name, st) in src_struct.members.iter() {
+                if src_name == field_name {
+                    src_type = Some(st.clone());
+                }
+            }
+            let src_type = src_type.expect(&format!("cant find member {} in src struct", field_name));
+
+            if src_type == *dst_type {
+                member_morphisms.push(
+                    StructFieldMorphism {
+                        field_name: field_name.to_string(),
+                        item_morph: None,
+                        src_offset: src_struct.get_offset( field_name ),
+                        dst_offset: dst_struct.get_offset( field_name ),
+                    }
+                );
+            } else {
+                match morph_base.find_morphism(
+                    &laddertypes::MorphismType {
+                        src_type: src_type.clone(),
+                        dst_type: dst_type.clone()
+                    },
+                    dict
+                ) {
+                    Some(item_morph) => {
+                        let morph_symb = format!("morph_{}_to_{}",
+                            encode_type_to_symbol(dict, &src_type),
+                            encode_type_to_symbol(dict, &dst_type)
+                        );
+                        member_morphisms.push(
+                            StructFieldMorphism {
+                                field_name: field_name.to_string(),
+                                item_morph: Some(Box::new(item_morph.m.into_prim_c_morphism(dict, morph_symb, &item_morph.σ))),
+                                src_offset: src_struct.get_offset( field_name ),
+                                dst_offset: dst_struct.get_offset( field_name ),
+                            }
+                        );
+                    },
+
+                    None => {
+                        eprintln!("cant map field {}", field_name);
+                    }
+                }
+            }
+        }
+
+        LdmcMorphism::StructMap {
+            src_struct, dst_struct,
+            member_morphisms
+        }
     }
 }
 
@@ -47,6 +155,12 @@ impl Morphism for LdmcMorphism {
                     src_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.src_type.clone() ]),
                     dst_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.dst_type.clone() ]),
                 }
+            },
+            LdmcMorphism::StructMap { src_struct, dst_struct, member_morphisms } => {
+                laddertypes::MorphismType {
+                    src_type: src_struct.get_type(),
+                    dst_type: dst_struct.get_type()
+                }
             }
         }.normalize()
     }
diff --git a/src/struct_layout.rs b/src/struct_layout.rs
new file mode 100644
index 0000000..d961602
--- /dev/null
+++ b/src/struct_layout.rs
@@ -0,0 +1,167 @@
+
+use laddertypes::{parser::*, unparser::*, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm};
+
+#[derive(Clone, Copy, Debug)]
+pub enum ObjectSize {
+    Static(u64),
+    Dynamic(/* function to get size at runtime */),
+    Unknown
+}
+
+
+pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
+    let ty = ty.clone().get_lnf_vec().last().unwrap().clone();
+
+    if ty == dict.parse("native.UInt8").expect("") {
+        return ObjectSize::Static(1);
+    }
+    if ty == dict.parse("native.UInt16").expect("") {
+        return ObjectSize::Static(2);
+    }
+    if ty == dict.parse("native.UInt32").expect("") ||
+        ty == dict.parse("native.Float").expect("") {
+        return ObjectSize::Static(4);
+    }
+    if ty == dict.parse("native.UInt64").expect("") ||
+       ty == dict.parse("native.Double").expect("") {
+        return ObjectSize::Static(8);
+    }
+
+    if let Some(layout) = StructLayout::parse( dict, ty ) {
+        return layout.get_size();
+    }
+
+    ObjectSize::Unknown
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+enum LayoutType {
+    Natural,
+    Packed
+}
+
+#[derive(Clone, Debug)]
+pub struct StructLayout {
+    ty: laddertypes::TypeTerm,
+    item_type: laddertypes::TypeTerm,
+    pub members: Vec< (String, laddertypes::TypeTerm) >,
+    offsets: std::collections::HashMap< String, u64 >,
+    size: ObjectSize
+}
+
+impl StructLayout {
+    pub fn get_type(&self) -> TypeTerm {
+        self.ty.clone()
+    }
+
+    pub fn get_size(&self) -> ObjectSize {
+        self.size
+    }
+
+    pub fn get_offset(&self, name: &String) -> u64 {
+        *self.offsets.get(name).expect("")
+    }
+
+    pub fn calculate_offsets(&mut self, dict: &mut impl TypeDict) {
+        let layout_type = LayoutType::Natural;
+        let mut offset = 0;
+
+        for (field_name, field_type) in self.members.iter() {
+            //let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
+            match get_type_size( dict, field_type.clone() ) {
+                ObjectSize::Static(field_size) => {
+                    if layout_type == LayoutType::Natural {
+                        // add padding to natural alignment
+                        if offset % field_size > 0 {
+                            offset = field_size * ((offset / field_size)+1);
+                        }
+                    }
+
+                    // take offset
+                    self.offsets.insert(field_name.clone(), offset);
+
+                    // advance by current size
+                    offset += field_size;
+                }
+                ObjectSize::Dynamic() => {
+                    eprintln!("dynamically sized Field in struct!");
+                    self.offsets.insert(field_name.clone(), offset);
+                    self.size = ObjectSize::Dynamic();
+                    return;
+                }
+                ObjectSize::Unknown => {
+                    eprintln!("unknown field size!");
+                    self.offsets.insert(field_name.clone(), offset);
+                    self.size = ObjectSize::Unknown;
+                    return;
+                }
+            }
+        }
+
+        match self.size {
+            ObjectSize::Dynamic() => {
+
+            }
+            _ => {
+                self.size = ObjectSize::Static(offset);
+            }
+        }
+    }
+
+    pub fn generate_members(&self, dict: &mut impl TypeDict, prefix: &str, base_ptr: &str) {
+        let mut offset = 0;
+
+        for (field_name, field_type) in self.members.iter() {
+            let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
+            let offset = self.get_offset(field_name);
+            println!(" {} * restrict {}_{} = {} + {};",
+                field_c_type, prefix, field_name, base_ptr, offset
+            );
+        }
+    }
+
+    pub fn parse(dict: &mut impl TypeDict, struct_type: TypeTerm) -> Option <Self> {
+        match struct_type.sugar(dict) {
+            SugaredTypeTerm::Struct(sugared_members) => {
+                let mut members = Vec::new();
+                let mut item_type = dict.parse("Byte").expect("");
+
+                for SugaredStructMember{ symbol, ty } in sugared_members {
+                    members.push((symbol, ty.desugar(dict)));
+                }
+
+                let mut sl = StructLayout {
+                    ty: TypeTerm::unit(),
+                    item_type,
+                    members,
+                    offsets: std::collections::HashMap::new(),
+                    size: ObjectSize::Unknown
+                };
+
+                sl.calculate_offsets(dict);
+                sl.calculate_type(dict);
+
+                Some(sl)
+            }
+
+            _ => {
+                eprintln!("not a struct");
+                None
+            }
+        }
+    }
+
+    fn calculate_type(&mut self, dict: &mut impl TypeDict) {
+        self.ty =
+            SugaredTypeTerm::Struct(
+                self.members
+                    .iter()
+                    .cloned()
+                    .map(|(symbol,ty)|
+                        SugaredStructMember{ symbol, ty:ty.sugar(dict) })
+                    .collect()
+            )
+                .desugar(dict);
+
+    }
+}

From bce52e9fcfd6712306a2479753d44ee80b3045e3 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 25 Mar 2025 19:38:56 +0100
Subject: [PATCH 02/31] replace native.Float/native.Double with
 native.Float32/native.Float64

---
 morphisms/angle.morphism-base       | 32 ++++++++++++++---------------
 morphisms/real.morphism-base        | 28 ++++++++++++-------------
 morphisms/temperature.morphism-base | 16 +++++++--------
 3 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/morphisms/angle.morphism-base b/morphisms/angle.morphism-base
index 71aba96..5fa3baf 100644
--- a/morphisms/angle.morphism-base
+++ b/morphisms/angle.morphism-base
@@ -3,16 +3,16 @@
 ```
 
 morph_angle_as_degrees_to_turns_float ()
-    Angle ~ Degrees ~ ℝ ~ native.Float
---> Angle ~ Turns ~ ℝ ~ native.Float
+    Angle ~ Degrees ~ ℝ ~ native.Float32
+--> Angle ~ Turns ~ ℝ ~ native.Float32
 ```
     *dst = *src / 360.0;
     return 0;
 ```
 
 morph_angle_as_degrees_to_turns_double ()
-    Angle ~ Degrees ~ ℝ ~ native.Double
---> Angle ~ Turns ~ ℝ ~ native.Double
+    Angle ~ Degrees ~ ℝ ~ native.Float64
+--> Angle ~ Turns ~ ℝ ~ native.Float64
 ```
     *dst = *src / 360.0;
     return 0;
@@ -20,16 +20,16 @@ morph_angle_as_degrees_to_turns_double ()
 
 
 morph_angle_as_turns_to_degrees_float ()
-    Angle ~ Turns ~ ℝ ~ native.Float
---> Angle ~ Degrees ~ ℝ ~ native.Float
+    Angle ~ Turns ~ ℝ ~ native.Float32
+--> Angle ~ Degrees ~ ℝ ~ native.Float32
 ```
     *dst = *src * 360.0;
     return 0;
 ```
 
 morph_angle_as_turns_to_degrees_double ()
-    Angle ~ Turns ~ ℝ ~ native.Double
---> Angle ~ Degrees ~ ℝ ~ native.Double
+    Angle ~ Turns ~ ℝ ~ native.Float64
+--> Angle ~ Degrees ~ ℝ ~ native.Float64
 ```
     *dst = *src * 360.0;
     return 0;
@@ -39,16 +39,16 @@ morph_angle_as_turns_to_degrees_double ()
 
 
 morph_angle_as_radians_to_turns_float ()
-    Angle ~ Radians ~ ℝ ~ native.Float
---> Angle ~ Turns ~ ℝ ~ native.Float
+    Angle ~ Radians ~ ℝ ~ native.Float32
+--> Angle ~ Turns ~ ℝ ~ native.Float32
 ```
     *dst = *src / PHI;
     return 0;
 ```
 
 morph_angle_as_radians_to_turns_double ()
-    Angle ~ Radians ~ ℝ ~ native.Double
---> Angle ~ Turns ~ ℝ ~ native.Double
+    Angle ~ Radians ~ ℝ ~ native.Float64
+--> Angle ~ Turns ~ ℝ ~ native.Float64
 ```
     *dst = *src / PHI;
     return 0;
@@ -56,16 +56,16 @@ morph_angle_as_radians_to_turns_double ()
 
 
 morph_angle_as_turns_to_radians_float ()
-    Angle ~ Turns ~ ℝ ~ native.Float
---> Angle ~ Radians ~ ℝ ~ native.Float
+    Angle ~ Turns ~ ℝ ~ native.Float32
+--> Angle ~ Radians ~ ℝ ~ native.Float32
 ```
     *dst = *src * PHI;
     return 0;
 ```
 
 morph_angle_as_degrees_to_radians_double ()
-    Angle ~ Turns ~ ℝ ~ native.Double
---> Angle ~ Radians ~ ℝ ~ native.Double
+    Angle ~ Turns ~ ℝ ~ native.Float64
+--> Angle ~ Radians ~ ℝ ~ native.Float64
 ```
     *dst = *src * PHI;
     return 0;
diff --git a/morphisms/real.morphism-base b/morphisms/real.morphism-base
index 3302f80..4add278 100644
--- a/morphisms/real.morphism-base
+++ b/morphisms/real.morphism-base
@@ -4,7 +4,7 @@
 
 morph_real_as_decimalstr_to_float ()
     ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
---> ℝ ~ native.Float
+--> ℝ ~ native.Float32
 ```
     sscanf(src, "%f", dst);
     return 0;
@@ -12,14 +12,14 @@ morph_real_as_decimalstr_to_float ()
 
 morph_real_as_decimalstr_to_double ()
     ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
---> ℝ ~ native.Double
+--> ℝ ~ native.Float64
 ```
     sscanf(src, "%lf", dst);
     return 0;
 ```
 
 morph_real_as_float_to_decimalstr ()
-    ℝ ~ native.Float
+    ℝ ~ native.Float32
 --> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
 ```
     sprintf(dst, "%f", *src);
@@ -27,7 +27,7 @@ morph_real_as_float_to_decimalstr ()
 ```
 
 morph_real_as_double_to_decimalstr ()
-    ℝ ~ native.Double
+    ℝ ~ native.Float64
 --> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
 ```
     sprintf(dst, "%f", *src);
@@ -36,16 +36,16 @@ morph_real_as_double_to_decimalstr ()
 
 
 morph_real_as_float_to_double ()
-    ℝ ~ native.Float
---> ℝ ~ native.Double
+    ℝ ~ native.Float32
+--> ℝ ~ native.Float64
 ```
     *dst = *src;
     return 0;
 ```
 
 morph_real_as_double_to_float ()
-    ℝ ~ native.Double
---> ℝ ~ native.Float
+    ℝ ~ native.Float64
+--> ℝ ~ native.Float32
 ```
     fprintf(stderr, "Warning: morphin Double -> Float. Precision loss!");
     *dst = *src;
@@ -54,7 +54,7 @@ morph_real_as_double_to_float ()
 
 morph_real_as_u64_to_float ()
     ℝ ~ ℕ ~ native.UInt64
---> ℝ ~ native.Float
+--> ℝ ~ native.Float32
 ```
     fprintf(stderr, "Warning: morphin UInt64 -> Float. Precision loss!");
     *dst = *src;
@@ -63,7 +63,7 @@ morph_real_as_u64_to_float ()
 
 morph_real_as_u64_to_double ()
     ℝ ~ ℕ ~ native.UInt64
---> ℝ ~ native.Double
+--> ℝ ~ native.Float64
 ```
     fprintf(stderr, "Warning: morphin UInt64 -> Double. Precision loss!");
     *dst = *src;
@@ -72,14 +72,14 @@ morph_real_as_u64_to_double ()
 
 morph_real_as_quantized_linear_to_float (Begin: ℝ, End: ℝ, Steps: ℤ)
     ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
---> ℝ ~ native.Float
+--> ℝ ~ native.Float32
 ```
     *dst = (float)Begin  +  ( *src * ((float)End - (float)Begin) ) / (float)Steps;
     return 0;
 ```
 
 morph_real_as_float_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
-    ℝ ~ native.Float
+    ℝ ~ native.Float32
 --> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
 ```
     *dst = ((*src - (float)Begin) * (float)Steps) / ((float)End - (float)Begin);
@@ -90,14 +90,14 @@ morph_real_as_float_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
 
 morph_real_as_quantized_linear_to_double (Begin: ℝ, End: ℝ, Steps: ℤ)
     ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
---> ℝ ~ native.Double
+--> ℝ ~ native.Float64
 ```
     *dst = (double)Begin  +  ( *src * ((double)End - (double)Begin) ) / (double)Steps;
     return 0;
 ```
 
 morph_real_as_double_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
-    ℝ ~ native.Double
+    ℝ ~ native.Float64
 --> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
 ```
     *dst = ((*src - (double)Begin) * (double)Steps) / ((double)End - (double)Begin);
diff --git a/morphisms/temperature.morphism-base b/morphisms/temperature.morphism-base
index 7831292..6c682bc 100644
--- a/morphisms/temperature.morphism-base
+++ b/morphisms/temperature.morphism-base
@@ -2,32 +2,32 @@
 ```
 
 morph_celsius_to_kelvin ()
-      Temperature ~ Celsius ~ ℝ ~ native.Float
--->   Temperature ~ Kelvin ~ ℝ ~ native.Float
+      Temperature ~ Celsius ~ ℝ ~ native.Float32
+-->   Temperature ~ Kelvin ~ ℝ ~ native.Float32
 ```
     *dst = *src + 273.15;
     return 0;
 ```
 
 morph_kelvin_to_celsius ()
-      Temperature ~ Kelvin ~ ℝ ~ native.Float
--->   Temperature ~ Celsius ~ ℝ ~ native.Float
+      Temperature ~ Kelvin ~ ℝ ~ native.Float32
+-->   Temperature ~ Celsius ~ ℝ ~ native.Float32
 ```
     *dst = *src - 273.15;
     return 0;
 ```
 
 morph_celsius_to_fahrenheit ()
-      Temperature ~ Celsius ~ ℝ ~ native.Float
--->   Temperature ~ Fahrenheit ~ ℝ ~ native.Float
+      Temperature ~ Celsius ~ ℝ ~ native.Float32
+-->   Temperature ~ Fahrenheit ~ ℝ ~ native.Float32
 ```
     *dst = (*src * 9.0 / 5.0) + 32.0;
     return 0;
 ```
 
 morph_fahrenheit_to_celsius ()
-      Temperature ~ Fahrenheit ~ ℝ ~ native.Float
--->   Temperature ~ Celsius ~ ℝ ~ native.Float
+      Temperature ~ Fahrenheit ~ ℝ ~ native.Float32
+-->   Temperature ~ Celsius ~ ℝ ~ native.Float32
 ```
     *dst = (*src - 32.0) * 5.0 / 9.0;
     return 0;

From d98afc294df8b0d3ff6fb1c4b64a221ef86b29ef Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Mon, 31 Mar 2025 10:29:57 +0200
Subject: [PATCH 03/31] exemplaric platform definitions

---
 platforms/json.lt     | 100 ++++++++++++++++++++++++++++++++++++++++++
 platforms/json5.lt    |   0
 platforms/protobuf.lt |   3 ++
 platforms/spapod.lt   |   0
 platforms/x86.lt      |   5 +++
 5 files changed, 108 insertions(+)
 create mode 100644 platforms/json.lt
 create mode 100644 platforms/json5.lt
 create mode 100644 platforms/protobuf.lt
 create mode 100644 platforms/spapod.lt
 create mode 100644 platforms/x86.lt

diff --git a/platforms/json.lt b/platforms/json.lt
new file mode 100644
index 0000000..8e69138
--- /dev/null
+++ b/platforms/json.lt
@@ -0,0 +1,100 @@
+
+type UTF8-String = <Seq Char~Unicode> ~ UTF-8 ~ <Seq~<ValueTerminated 0> native.UInt8> ;
+
+type SerializedJson.Value = json.Value
+    ~ <Enum
+        <Null   json.Null ~ SerializedJson.Null >
+        <String json.String ~ SerializedJson.String >
+        <Number json.Number ~ SerializedJson.Number >
+        <Bool   json.Bool ~ SerializedJson.Bool >
+        <Array  json.Array ~ SerializedJson.Array >
+        <Object json.Object ~ SerializedJson.Object >>
+    ~ <Seq Char> ;
+
+type SerializedJson.Null = < Struct~<Seq Char> "\"null\"" > ;
+
+type SerializedJson.String = <Seq Char>
+                           ~ <Struct~<Seq Char> "\"" <Seq Char> "\"">
+                           ~ <Seq Char> ;
+
+type SerializedJson.Number = ℝ
+                           ~ <PosInt 10 BigEndian>
+                           ~ <Seq <Digit 10> ~ Char> ;
+
+type SerializedJson.Bool   = Bool
+                           ~ <Enum~<Seq Char>
+                                <True~"\"true\"" <>>
+                                <False~"\"false\"" <>>>
+                           ~ <Seq Char> ;
+
+type SerializedJson.Array  = <Struct~<Seq Char>
+                                "["
+                                    <Seq json.Value>
+                                  ~ <ValueSep ',' Char>
+                                  ~ <Seq Char>
+                                "]" >
+                            ~ <Seq Char> ;
+
+type SerializedJson.Object = <Struct~<Seq Char>
+                                "{"
+                                <members <Seq
+                                            <Struct~<Seq Char>
+                                                <key json.String>
+                                                ":"
+                                                <value json.Value>>>>
+                                "}"
+                             >
+                           ~ <Seq Char>;
+
+type parsedJson.Value = json.Value ~ <Enum~native.UInt8
+        < parsedJson_Null~0     <> >
+        < parsedJson_String~1   <Ref UTF8-String> ~ native.Address >
+        < parsedJson_Int~2      ℝ~ℕ~native.UInt64 >
+        < parsedJson_Float~2    ℝ~native.Float64 >
+        < parsedJson_Bool~3     Bool ~ native.UInt8 >
+
+        < parsedJson_Array~4    <Ref <Seq ~ <LengthPrefix native.UInt64>
+                                        parsedJsonValue
+                                     >
+                                >
+                                ~ native.Address >
+
+        < parsedJson_Object~5   <Ref <Seq ~ <LengthPrefix native.UInt64>
+                                        <Struct
+                                            <key <Ref UTF8-String> ~ native.Address>
+                                            <val parsedJsonValue>
+                                        >
+                                >
+                                ~ native.Address >>
+    ~ <Struct
+        <tag native.UInt8>
+        native.UInt64      >;
+
+parse_json_value ()
+    json.Value ~ UTF8-String
+--> json.Value ~ parsedJsonValue
+```
+
+    {
+        dst->tag = PARSED_JSON_NULL;
+        dst->parsedJson_Null;
+    }
+
+    {
+        dst->tag = PARSED_JSON_STRING;
+        dst->parsedJson_String = malloc(len);
+        strncpy(dst->parsedJson_String, src, len);
+        src += len;
+    }
+
+    {
+        dst->tag = PARSED_JSON_NUMBER;
+
+        MORPH(
+            "ℝ ~ ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10> ~ Char> ~ UTF8-String",
+            "ℝ ~ ℕ ~ native.UInt64",
+            src,
+            &dst->parsedJson_Number
+        );
+    }
+```
diff --git a/platforms/json5.lt b/platforms/json5.lt
new file mode 100644
index 0000000..e69de29
diff --git a/platforms/protobuf.lt b/platforms/protobuf.lt
new file mode 100644
index 0000000..ce273f6
--- /dev/null
+++ b/platforms/protobuf.lt
@@ -0,0 +1,3 @@
+
+type protobuf.Varint = ℕ ~ <PosInt 128 LittleEndian> ~ <Seq~MsbCont <Digit 128> ~ ℤ_128 ~ native.UInt8> ;
+type protobuf.String = <Seq Char ~ Unicode> ~ UTF-8 ~ <Seq ~ <LengthPrefix protobuf.Varint> Byte> ;
diff --git a/platforms/spapod.lt b/platforms/spapod.lt
new file mode 100644
index 0000000..e69de29
diff --git a/platforms/x86.lt b/platforms/x86.lt
new file mode 100644
index 0000000..0348efc
--- /dev/null
+++ b/platforms/x86.lt
@@ -0,0 +1,5 @@
+
+type x86.UInt64 = ℤ_2/\64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >;
+type x86.UInt32 = ℤ_2/\32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >;
+type x86.UInt16 = ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >;
+type x86.UInt8 = ℤ_256 ~ <Posint 2 BigEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>;

From 583892f10d6bf153352d0c16af3ca19e52a066a5 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 1 Apr 2025 18:23:18 +0200
Subject: [PATCH 04/31] wip struct morphisms

---
 src/c_gen.rs         | 628 ++++++++++++++++++-------------------------
 src/c_gen_types.rs   | 240 +++++++++++++++++
 src/main.rs          | 143 +++++-----
 src/morphism.rs      |  85 +++---
 src/parser.rs        |  22 +-
 src/struct_layout.rs | 220 ++++++++++-----
 6 files changed, 774 insertions(+), 564 deletions(-)
 create mode 100644 src/c_gen_types.rs

diff --git a/src/c_gen.rs b/src/c_gen.rs
index 7f5c7ea..c64a0f6 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -1,158 +1,286 @@
 use {
-    crate::{morphism::{LdmcMorphism, LdmcPrimCMorphism}, struct_layout::{get_type_size, ObjectSize, StructLayout}},
-    laddertypes::{morphism::{Morphism, MorphismInstance}, parser::*, unparser::*, TypeDict, TypeTerm},
+    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
 };
 
-/*
-*/
-pub fn get_c_repr_kind(kind: String) -> Option<String> {
-    match kind.as_str() {
-        "ℤ" => Some("uint64_t".into()),
-        _ => None
-    }
-}
 
-/* for a given ladder type `t`, get the corresponding C type
- */
-pub fn get_c_repr_type(dict: &mut impl TypeDict, t: laddertypes::TypeTerm, skip_pointer: bool) -> Option<String> {
-    let lnf = t.normalize().decurry().get_lnf_vec();
 
-    match lnf.last() {
-        Some(t) => {
-            if t == &dict.parse("Byte").expect("parse")
-            || t == &dict.parse("native.UInt8").expect("parse")
-            || t == &dict.parse("<StaticLength 8 Bit>").expect("parse")
-            {
-                Some("uint8_t".into())
-            } else if t == &dict.parse("native.UInt16").expect("parse") {
-                Some("uint16_t".into())
-            } else if t == &dict.parse("native.UInt32").expect("parse") {
-                Some("uint32_t".into())
-            } else if t == &dict.parse("native.UInt64").expect("parse") {
-                Some("uint64_t".into())
-            } else if t == &dict.parse("native.Float").expect("parse") {
-                Some("float".into())
-            } else if t == &dict.parse("native.Double").expect("parse") {
-                Some("double".into())
+
+
+
+
+impl LdmcPrimMorph {
+    pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> String {
+        let mut s = self.symbol.clone();
+        for (k_id,v) in self.type_args.iter() {
+            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 = encode_type_to_symbol(dict, &val_trm);
+                    s.push_str(&format!("_{}_{}", name, val_str));
+                }
             } else {
-                match t {
-                    laddertypes::TypeTerm::App(args) => {
-                        if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"LengthPrefix".into()).unwrap())
-                        {
-                            let length_c_type : String = get_c_repr_type(dict, args[1].clone(), false)?;
-                            let item_c_type : String = get_c_repr_type(dict, args[2].clone(), false)?;
-
-                            match length_c_type.as_str() {
-                                "uint8_t" |
-                                "uint16_t" |
-                                "uint32_t" |
-                                "uint64_t" => {}
-                                _ => {
-                                    eprintln!("invalid length type!");
-                                    return None;
-                                }
-                            }
-                            match item_c_type.as_str() {
-                                "uint8_t" |
-                                "uint16_t" |
-                                "uint32_t" |
-                                "uint64_t" => {}
-                                _ => {
-                                    eprintln!("invalid item type!");
-                                    return None;
-                                }
-                            }
-
-                            Some(format!("LengthPrefix_{}_Array_{}", length_c_type, item_c_type))
-                        }
-                        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)?;
-                            if skip_pointer {
-                                Some(c_type)
-                            } else {
-                                Some(format!("{} *", c_type))
-                            }
-                        }
-                        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 {
-
-                            if let Some(layout) = StructLayout::parse(dict, t.clone()) {
-                                let mut c_type = String::from("struct {\n");
-
-                                for (field_name, field_type) in layout.members.iter() {
-                                    let field_c_type = get_c_repr_type(dict, field_type.clone(), false).expect("");
-                                    c_type.push_str(&format!("    {} {};\n",
-                                        field_c_type,
-                                        field_name
-                                    ));
-                                }
-
-                                c_type.push_str("}");
-                                Some(c_type)
-                            } else {
-                                None
-                            }
-                        }
-                    }
-
-                    _ => None
+                if let laddertypes::TypeID::Var(var_id) = k_id {
+                    let k = dict.get_varname(*var_id).unwrap();
+                    s.push_str(&format!("_{:?}_MISSING", k));
+                    eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing type parameter {} ({})", k, var_id);
                 }
             }
         }
-        None => None
+        s
+    }
+
+    pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
+        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::SugaredTypeTerm>
+    ) -> String {
+        format!("int {} ({} const * restrict src, {} * restrict dst);",
+            self.instantiated_symbol_name(dict, σ),
+            get_c_repr_type(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
+            get_c_repr_type(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
+    }
+
+    pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> Option<String> {
+        let mut s = String::new();
+        let src_type = self.ty.src_type.clone().apply_subst(σ).clone();
+        let dst_type = self.ty.dst_type.clone().apply_subst(σ).clone();
+
+        let symbol = encode_morph_type_to_symbol(dict, &self.ty);
+        let src_c_symbol = encode_type_to_symbol(dict, &self.ty.src_type);
+        let dst_c_symbol = encode_type_to_symbol(dict, &self.ty.dst_type);
+
+        let src_c_type = get_c_repr_type(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type");
+        let dst_c_type = get_c_repr_type(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for src type");
+
+        s.push_str(&format!(r#"
+int {} ( {} const * restrict src, {} * restrict dst ) {{
+"#,
+            self.instantiated_symbol_name(dict, σ),
+            get_c_repr_type(dict, src_type, true).expect("cant get c-repr-type"),
+            get_c_repr_type(dict, dst_type, true).expect("cant get c-repr-type"),
+        ));
+        s.push_str(&self.c_source);
+        s.push_str(&format!(r#"
+    return 0;
+}}
+"#));
+        Some(s)
     }
 }
 
 
-pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
-    match t {
-        laddertypes::TypeTerm::Char(c) => {
-            match c {
-                '.' => format!("_dot_"),
-                _ =>
-                format!("{}", (*c as u64))
-            }
-        },
-        laddertypes::TypeTerm::Num(n) => {
-            format!("{}", n)
+
+
+
+pub struct LdmcCTargetMorph {
+    includes: Vec< String >,
+    active_instantiations: Vec< LdmcPrimMorph >,
+}
+
+impl LdmcCTargetMorph {
+    pub fn new() -> Self {
+        LdmcCTargetMorph {
+            includes: Vec::new(),
+            active_instantiations: Vec::new()
         }
-        laddertypes::TypeTerm::TypeID(ty_id) => {
-            if let Some(name) = dict.get_typename(ty_id) {
-                format!("{}", name.replace(".", "_dot_"))
-            } else {
-                format!("")
-            }
+    }
+
+    pub fn add_instantiation(
+        &mut self,
+        dict: &mut impl TypeDict,
+        morph: MorphismInstance2<LdmcPrimMorph>,
+    ) -> Result<LdmcPrimMorph, ()> {
+        let new_inst = self.bake_morphism(dict, morph)?;
+        if ! self.active_instantiations.contains(&new_inst) {
+            self.active_instantiations.push(new_inst.clone());
         }
-        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));
+        Ok(new_inst)
+    }
+
+    pub fn into_c_source(self, dict: &mut impl TypeDict) -> String {
+        let mut source = String::new();
+        for inc in self.includes {
+            source.push_str(&inc);
+        }
+
+        for m in self.active_instantiations {
+            source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
+        }
+
+        source
+    }
+
+    pub fn bake_morphism(
+        &mut self,
+        dict: &mut impl laddertypes::TypeDict,
+        morph_inst: MorphismInstance2<LdmcPrimMorph>,
+    ) -> Result<LdmcPrimMorph, ()> {
+
+        match &morph_inst {
+            MorphismInstance2::Primitive { ψ, σ, morph } => {
+                let mut c_source = String::new();
+                for (ty_id, kind) in morph.type_args.iter() {
+                    if let Some(val) = σ.get(ty_id) {
+                        eprintln!("val = {}", val.pretty(dict, 0));
+                        let type_var_value =
+                            if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
+                                c_repr_type
+                            } else {
+                                encode_type_to_value(dict, &val)
+                            };
+
+                        c_source.push_str(&format!("    #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
+                    }
+                }
+                c_source.push_str(&morph.c_source);
+                for (ty_id, kind) in morph.type_args.iter() {
+                    c_source.push_str(&format!("\n    #undef {}", dict.get_typename(&ty_id).unwrap()));
+                }
+
+                Ok(LdmcPrimMorph{
+                    symbol: morph.instantiated_symbol_name(dict, σ),
+                    type_args: Vec::new(),
+                    ty: morph_inst.get_type(),
+                    c_source
+                })
+            },
+            MorphismInstance2::Chain { path } => {
+                let ty = morph_inst.get_type();
+                let symbol = encode_morph_type_to_symbol(dict, &ty);
+
+                let mut c_source = String::new();
+
+                if path.len() > 1 {
+                    c_source.push_str(r#"
+            uint8_t bufA[128];
+            uint8_t bufB[128];
+    "#);
+                }
+
+                for (i,morph) in path.iter().enumerate() {
+                    if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
+                        let morph_symbol = inst.instantiated_symbol_name(dict, &morph.get_subst());
+
+                        let src_c_type = get_c_repr_type(dict, ty.src_type.clone(), true).expect("cant get c-repr type for src type");
+                        let dst_c_type = get_c_repr_type(dict, ty.dst_type.clone(), true).expect("cant get c-repr type for dst type");
+
+                        let src_buf = if i == 0 { "src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
+                        let dst_buf = if i+1 == path.len() { "dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
+
+                        c_source.push_str(&format!(r#"
+            {{
+                    {} const * restrict src = {};
+                    {} * restrict dst = {};
+                    {} ( src, dst );
+            }}"#,
+                            src_c_type, src_buf,
+                            dst_c_type, dst_buf,
+                            morph_symbol
+                        ));
+                    } else {
+                        eprintln!("failed to add instantiation of item morphism");
+                    }
+                }
+
+                Ok(LdmcPrimMorph {
+                    symbol, type_args: Vec::new(), ty,
+                    c_source
+                })
+            }
+            MorphismInstance2::MapSeq { ψ, seq_repr, item_morph } => {
+                let i = 0; // <--todo
+                self.add_instantiation(dict, item_morph.as_ref().clone());
+                if let Some(seq_repr) = seq_repr {
+
+                    dict.add_varname("LengthType".into());
+                    if let Ok(γ) = laddertypes::unification_sugared::unify(
+                        &dict.parse("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
+                        seq_repr.as_ref()
+                    ) {
+                        let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
+                        let ty = morph_inst.get_type();
+                        let symbol = encode_morph_type_to_symbol(dict, &ty);
+                        let item_morph_symbol = encode_morph_type_to_symbol(dict, &item_morph.get_type());
+
+                        let length_c_type = get_c_repr_type(dict, length_type.clone(), true).expect("cant c-repr type for array length");
+                        let src_item_c_type = get_c_repr_type(dict, item_morph.get_type().src_type, true).expect("cant c-repr type for src item");
+                        let dst_item_c_type = get_c_repr_type(dict, item_morph.get_type().dst_type, true).expect("cant c-repr type for dst item");
+                        let src_c_type = get_c_repr_type(dict, ty.src_type.clone(), true).expect("cant get c-repr type for src type");
+                        let dst_c_type = get_c_repr_type(dict, ty.dst_type.clone(), true).expect("cant get c-repr type for dst type");
+
+                        let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
+                            length_c_type, src_item_c_type, dst_item_c_type
+                        );
+
+                        let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
+                        let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
+                        let c_source = format!(r#"
+            {{
+                    {} const * restrict src = (void*) {};
+                    {} * restrict dst = (void*) {};
+                    {} ( {}, src, dst );
+            }}"#,
+                            src_c_type, src_buf,
+                            dst_c_type, dst_buf,
+                            map_fn,
+                            item_morph_symbol,
+                        );
+
+                        Ok(LdmcPrimMorph{
+                            symbol, type_args: Vec::new(), ty,
+                            c_source
+                        })
+                    } else {
+                        eprintln!("Error: Unknown Seq- Representation!!");
+                        Err(())
+                    }
+                } else {
+                    eprintln!("Error: missing Seq- Representation!!");
+                    Err(())
+                }
+            },
+            MorphismInstance2::MapStruct { ψ, struct_repr, member_morph } => {
+                let ty = morph_inst.get_type();
+                let symbol =encode_morph_type_to_symbol(dict, &ty);
+
+                let mut c_source = String::new();
+
+                for (name, morph) in member_morph.iter() {
+                    if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
+                        c_source.push_str(
+                            &format!("
+                                {} ( &src->{}, &dst->{} );
+                            ",
+                            inst.symbol,
+                            name, name
+                        ));
+                    } else {
+                        eprintln!("failed to create morphism instantiation for struct member");
+                        return Err(());
+                    }
+                }
+
+                Ok(LdmcPrimMorph{
+                    symbol, type_args: Vec::new(), ty,
+                    c_source
+                })
+            }
+            MorphismInstance2::MapEnum { ψ, enum_repr, variant_morph } => {
+                todo!();
             }
-            s
         }
     }
 }
 
-pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm) -> String {
-    dict.unparse(t)
-}
 
-
-pub fn generate_main(type_dict: &mut impl TypeDict, path: Vec<MorphismInstance<LdmcMorphism>>, src_type: TypeTerm, dst_type: TypeTerm) {
+/*
+pub fn generate_main(
+    type_dict: &mut impl TypeDict,
+    morph: MorphismInstance2<LdmcPrimMorph>,
+    src_type: TypeTerm, dst_type: TypeTerm
+) {
     let mut i = 0;
 
+
+
     /* todo: collect include files from morphism base */
     println!(r#"
 #include <stdio.h>
@@ -271,238 +399,4 @@ return 0;
 
     eprintln!("Success: generated C code");
 }
-
-impl LdmcPrimCMorphism {
-    pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict,
-        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> String {
-        let mut s = self.symbol.clone();
-        for (k_id,v) in self.type_args.iter() {
-            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 = encode_type_to_symbol(dict, val_trm);
-                    s.push_str(&format!("_{}_{}", name, val_str));
-                }
-            } else {
-                if let laddertypes::TypeID::Var(var_id) = k_id {
-                    let k = dict.get_varname(*var_id).unwrap();
-                    s.push_str(&format!("_{:?}_MISSING", k));
-                    eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing {} ({})", k, var_id);
-                }
-            }
-        }
-        s
-    }
-
-    pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
-        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> String {
-        format!("int {} ({} const * restrict src, {} * restrict dst);",
-            self.instantiated_symbol_name(dict, σ),
-            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) {
-                eprintln!("val = {}", dict.unparse(&val));
-
-                let type_var_value =
-                    if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
-                        c_repr_type
-                    } else {
-                        encode_type_to_value(dict, val)
-                    };
-
-                s.push_str(&format!("    #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
-            }
-        }
-
-        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)
-    }
-}
-
-impl LdmcMorphism {
-    pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> LdmcPrimCMorphism {
-
-        let src_type = self.get_type().src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
-        let dst_type = self.get_type().dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
-
-        let src_c_type = get_c_repr_type(dict, src_type.clone(), true).expect("cant get c-repr type for src type");
-        let dst_c_type = get_c_repr_type(dict, dst_type.clone(), true).expect("cant get c-repr type for src type");
-
-        let c_source =
-            format!("
-typedef {} {}_src_t;
-
-typedef {} {}_dst_t;
-
-int {} ( {}_src_t const * restrict src, {}_dst_t * restrict dst )
-{{
-{}
-    return 0;
-}}
-                ",
-                src_c_type, symbol,
-                dst_c_type, symbol,
-                symbol, symbol, symbol,
-                self.generate_call(dict, σ, 0)
-            );
-
-        LdmcPrimCMorphism {
-            symbol,
-            type_args: Vec::new(),
-            src_type,
-            dst_type,
-            c_source
-        }
-    }
-
-    pub fn generate_call(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>, i: u64) -> String {
-        match self {
-            LdmcMorphism::Primitive(prim_morph) => {
-                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" };
-
-                format!(r#"
-    {{
-            {} const * restrict src = (void*) {};
-            {} * restrict dst = (void*) {};
-            {} ( src, dst );
-    }}"#,
-                    src_c_type, src_buf,
-                    dst_c_type, dst_buf,
-                    prim_morph.instantiated_symbol_name(dict, σ),
-                )
-            }
-            LdmcMorphism::LengthPrefixMap { length_prefix_type, item_morph } => {
-                let src_type = self.get_type().src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
-                let dst_type = self.get_type().dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
-
-                eprintln!("length prefix type ={:?}", length_prefix_type);
-                eprintln!("src_type ={:?}", src_type);
-                eprintln!("dst_type = {:?}", dst_type);
-
-                dict.add_varname("S".into());
-
-                let γ_src = laddertypes::unify(
-                    &dict.parse("<Seq~<LengthPrefix S> T>").expect("parse template"),
-                    &src_type
-                ).expect("cant get src item type");
-
-                let γ_dst = laddertypes::unify(
-                    &dict.parse("<Seq~<LengthPrefix S> T>").expect("parse template"),
-                    &dst_type
-                ).expect("cant get dst item type");
-
-                let src_length_type = γ_src.get(&dict.get_typeid(&"S".into()).unwrap()).expect("cant get src-length type").clone();
-                let dst_length_type = γ_src.get(&dict.get_typeid(&"S".into()).unwrap()).expect("cant get dst-length type").clone();
-
-                let length_type = src_length_type;
-
-                let src_item_type = γ_src.get(&dict.get_typeid(&"T".into()).unwrap()).expect("cant get src-item type").clone();
-                let dst_item_type = γ_dst.get(&dict.get_typeid(&"T".into()).unwrap()).expect("cant get src-item type").clone();
-
-                let length_c_type = get_c_repr_type(dict, length_type, true).expect("cant c-repr type for array length");
-                let src_item_c_type = get_c_repr_type(dict, src_item_type, true).expect("cant c-repr type for src item");
-                let dst_item_c_type = get_c_repr_type(dict, dst_item_type, true).expect("cant c-repr type for dst item");
-                let src_c_type = get_c_repr_type(dict, src_type, true).expect("cant get c-repr type for src type");
-                let dst_c_type = get_c_repr_type(dict, dst_type, true).expect("cant get c-repr type for dst type");
-
-                let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
-                    length_c_type, src_item_c_type, dst_item_c_type
-                );
-
-                let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
-                let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
-                format!(r#"
-    {{
-            {} const * restrict src = (void*) {};
-            {} * restrict dst = (void*) {};
-            {} ( {}, src, dst );
-    }}"#,
-                    src_c_type, src_buf,
-                    dst_c_type, dst_buf,
-                    map_fn,
-                    item_morph.instantiated_symbol_name(dict, σ),
-                )
-            }
-            LdmcMorphism::ValueDelimMap { delim, item_morph } => {
-                let src_c_type = get_c_repr_type(dict, item_morph.src_type.clone(), false).expect("cant get c-repr type for src type");
-                let dst_c_type = get_c_repr_type(dict, item_morph.dst_type.clone(), false).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" };
-                format!(r#"
-    {{
-            {} const * restrict src = (void*) {};
-            {} * restrict dst = (void*) {};
-            value_delim_array_map_8_to_64( {}, src, dst );
-    }}"#,
-                    src_c_type, src_buf,
-                    dst_c_type, dst_buf,
-                    item_morph.instantiated_symbol_name(dict, σ)
-                )
-            },
-
-            LdmcMorphism::StructMap { src_struct, dst_struct, member_morphisms } => {
-                let mut output = String::new();
-                for member_morph in member_morphisms.iter() {
-                    if let Some(m) = member_morph.item_morph.as_ref() {
-                        //let src_c_type = get_c_repr_type(dict, m.src_type.clone(), false).expect("cant get c-repr type for field member");
-                        //let dst_c_type = get_c_repr_type(dict, m.dst_type.clone(), false).expect("cant get c-repr type for field member");
-
-                        output.push_str(&format!("    {} ( &src->{}, &dst->{} );\n",
-                            m.instantiated_symbol_name(dict, σ),
-                            member_morph.field_name,
-                            member_morph.field_name
-                        ));
-                    } else {
-                        let mut field_type = None;
-                        for (field_name, ft) in src_struct.members.iter() {
-                            if field_name == &member_morph.field_name {
-                                field_type = Some(ft);
-                            }
-                        }
-
-                        let field_type = field_type.expect("cant get field member type");
-                        //if let Some(field_c_type) = get_c_repr_type(dict, field_type.clone(), false).expect("cat get c-repr type for field member");
-
-                        match  get_type_size(dict, field_type.clone()) {
-                            ObjectSize::Static(size) => {
-                                output.push_str(&format!("    memcpy( &dst->{}, &src->{}, sizeof(dst->{}) );\n",
-                                    member_morph.field_name, member_morph.field_name, member_morph.field_name
-                                ));
-                            }
-                            _ => {
-                                eprintln!("cant assign field of unknown size!");
-                            }
-                        }
-                    }
-                }
-                output
-            }
-        }
-    }
-}
+*/
diff --git a/src/c_gen_types.rs b/src/c_gen_types.rs
new file mode 100644
index 0000000..9c0020d
--- /dev/null
+++ b/src/c_gen_types.rs
@@ -0,0 +1,240 @@
+use {
+    crate::{morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::chain::Chain, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}
+};
+
+/*
+*/
+pub fn get_c_repr_kind(kind: String) -> Option<String> {
+    match kind.as_str() {
+        "ℤ" => Some("uint64_t".into()),
+        _ => None
+    }
+}
+
+/* for a given ladder type `t`, get the corresponding C type
+ */
+pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointer: bool) -> Option<String> {
+    eprintln!("get c repr of {}", t.pretty(dict,0));
+
+    match t.get_floor_type().1.strip() {
+        SugaredTypeTerm::TypeID(tyid) => {
+            if tyid == dict.get_typeid_creat("native.UInt8") {
+                Some("uint8_t".into())
+            } else if tyid == dict.get_typeid_creat("native.UInt16") {
+                Some("uint16_t".into())
+            } else if tyid == dict.get_typeid_creat("native.UInt32") {
+                Some("uint32_t".into())
+            } else if tyid == dict.get_typeid_creat("native.UInt64") {
+                Some("uint64_t".into())
+            } else if tyid == dict.get_typeid_creat("native.Address") {
+                Some("void*".into())
+            } else if tyid == dict.get_typeid_creat("native.Float32") {
+                Some("float".into())
+            } else if tyid == dict.get_typeid_creat("native.Float64") {
+                Some("double".into())
+            } else {
+                None
+            }
+        }
+
+        SugaredTypeTerm::Seq{ seq_repr, items } => {
+            if let Some(sr_sugar) = seq_repr {
+                let sr = sr_sugar.desugar(dict);
+
+                let item_type = items.first().expect("no item type specified!").clone();
+                let item_c_type : String = get_c_repr_type(dict, item_type, false).expect("cant get item type representation");
+
+                dict.add_varname("Length".into()); // Kind: Num
+                dict.add_varname("LengthType".into()); // Kind: Type
+                dict.add_varname("TermValue".into()); // Kind: Value of Type ItemType
+
+                if let Ok(σ) = laddertypes::unify(
+                    &sr,
+                    &dict.parse("<StaticLength Length>").expect("parse")
+                ) {
+                    let length = match
+                        σ.get(
+                            &dict.get_typeid(&"Length".into()).expect("no Length ID")
+                        ).expect("no length specified!")
+                    {
+                        TypeTerm::Num(l) => l,
+                        _ => {
+                            eprintln!("invalid Length!");
+                            return None;
+                        }
+                    };
+                    Some(format!("{}[{}]", item_c_type, length))
+                }
+                else if let Ok(σ) = laddertypes::unify(
+                    &sr,
+                    &dict.parse("<LengthPrefix LengthType>").expect("parse")
+                ) {
+                    let length_type = σ.get(
+                            &dict.get_typeid(&"LengthType".into()).expect("no LengthType ID")
+                        ).expect("no length type specified")
+                        .clone()
+                        .sugar(dict);
+                    let length_c_type : String = get_c_repr_type(dict, length_type, false).expect("cant get length type representation");
+
+                    match length_c_type.as_str() {
+                        "uint8_t" |
+                        "uint16_t" |
+                        "uint32_t" |
+                        "uint64_t" => {}
+                        s => {
+                                eprintln!("invalid length type '{}' !", s);
+                                return None;
+                            }
+                        }
+                        match item_c_type.as_str() {
+                            "uint8_t" |
+                            "uint16_t" |
+                            "uint32_t" |
+                            "uint64_t" |
+                            "void*" => {}
+                            s => {
+                                eprintln!("invalid item type '{}'!", s);
+                                return None;
+                        }
+                    }
+
+                    Some(format!("LengthPrefix_{}_Array_{}", length_c_type, item_c_type))
+                }
+                else if let Ok(σ) = laddertypes::unify(
+                    &sr,
+                    &dict.parse("<ValueTerminated TermValue>").expect("")
+                ) {
+                    if skip_pointer {
+                        Some(item_c_type)
+                    } else {
+                        Some(format!("{} *", item_c_type))
+                    }
+                }
+                else {
+                    eprintln!("can't get C-repr for sequence type `{}`!", dict.unparse(&sr));
+                    None
+                }
+            } else {
+                eprintln!("no sequence-representation type specified!");
+                None
+            }
+        }
+
+        SugaredTypeTerm::Struct{ struct_repr, members } => {
+            let c_struct_attribute =
+                if let Some(sr) = struct_repr {
+                    let sr = sr.desugar(dict);
+                    match LayoutType::parse(dict, &sr).expect("layout type") {
+                        LayoutType::Aligned => "",
+                        LayoutType::Packed => "__attribute((packed))__"
+                    }
+                } else {""};
+
+            let mut c_type = format!("struct {} {{\n", c_struct_attribute);
+
+            for SugaredStructMember{ symbol, ty } in members {
+                let field_c_type = get_c_repr_type(dict, ty, false).expect("");
+                c_type.push_str(&format!("    {} {};\n",
+                    field_c_type,
+                    symbol
+                ));
+            }
+
+            c_type.push_str("}");
+            Some(c_type)
+        }
+
+        SugaredTypeTerm::Enum { enum_repr, variants } => {
+            let mut c_type = format!("
+struct {{
+    enum {{
+");
+
+            for (i, SugaredEnumVariant{ symbol, ty }) in variants.iter().enumerate() {
+                c_type.push_str(&format!(
+                    "       {} = {}", symbol.to_uppercase(), i
+                ));
+
+                if i+1 < variants.len() {
+                    c_type.push_str(",\n");
+                }
+            }
+
+            c_type.push_str("
+    } tag;
+
+    union {
+");
+
+            for SugaredEnumVariant{ symbol, ty } in variants {
+                let variant_c_type = get_c_repr_type(dict, ty, false).expect("cant get C-Repr type for variant");
+                c_type.push_str(&format!(
+                    "       {} {};\n", variant_c_type, symbol
+                ));
+            }
+
+            c_type.push_str("
+    };
+}");
+
+            Some(c_type)
+        }
+
+        SugaredTypeTerm::Ladder(rungs) => {
+            if let Some(t) = rungs.last() {
+                get_c_repr_type(dict, t.clone(), false)
+            } else {
+                None
+            }
+        }
+
+        _ => { None }
+    }
+}
+
+pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm)-> String {
+    let t = t.clone().desugar(dict);
+    match t {
+        laddertypes::TypeTerm::Char(c) => {
+            match c {
+                '.' => format!("_dot_"),
+                _ =>
+                format!("{}", (c as u64))
+            }
+        },
+        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('_');
+
+                let r = r.sugar(dict);
+                s.push_str(&encode_type_to_symbol(dict, &r));
+            }
+            s
+        }
+    }
+}
+
+pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &SugaredMorphismType) -> String {
+    format!(
+        "morph_{}__to_{}",
+        encode_type_to_symbol(dict, &t.src_type),
+        encode_type_to_symbol(dict, &t.dst_type)
+    )
+}
+
+pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm) -> String {
+    let t = t.clone().desugar(dict);
+    dict.unparse(&t)
+}
diff --git a/src/main.rs b/src/main.rs
index 8769384..7ee2bad 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,26 +3,22 @@
 mod morphism;
 mod parser;
 mod c_gen;
+mod c_gen_types;
 mod struct_layout;
 
 use {
     crate::{
-        morphism::LdmcMorphism,
+        morphism::LdmcPrimMorph,
         parser::morphism_base_parser,
-    }, ariadne::{Color, Label, Report, ReportKind, Source}, chumsky::prelude::*, laddertypes::{
-        parser::ParseLadderType, unparser::*, BimapTypeDict, MorphismType, TypeDict
+    }, ariadne::{Color, Label, Report, ReportKind, Source}, c_gen::LdmcCTargetMorph, chumsky::prelude::*, laddertypes::{
+        morphism_path_sugared::SugaredShortestPathProblem, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::ParseLadderType, unparser::*, BimapTypeDict, MorphismType, SugaredTypeTerm, TypeDict
     }, std::{collections::HashMap, sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi
 };
 
 fn main() {
     let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
 
-    let mut morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcMorphism>::new(vec![
-        //type_dict.parse("Seq~MsbCont").expect(""),
-        //type_dict.parse("Seq~<ValueTerminated '\\0'>").expect(""),
-        type_dict.parse("Seq~<LengthPrefix native.UInt64>").expect(""),
-        type_dict.parse("Struct").expect("")
-    ]);
+    let mut morphism_base = laddertypes::morphism_base_sugared::SugaredMorphismBase::<LdmcPrimMorph>::new();
 
     let mut args = std::env::args().skip(1);
     let src_type_arg = args.next().expect("src type expected");
@@ -36,7 +32,7 @@ fn main() {
                 eprintln!("[{}] parse ok.", mb_path.bright_yellow());
                 println!("{}", includes);
                 for m in morphisms {
-                    morphism_base.add_morphism(LdmcMorphism::Primitive(m));
+                    morphism_base.add_morphism(m);
                 }
             }
             Err(errs) => {
@@ -58,86 +54,103 @@ fn main() {
 
     let mut γ = HashMap::new();
     γ.insert(
-        type_dict.get_typeid_creat(&"Byte".into()),
+        type_dict.get_typeid_creat(&"Byte"),
         type_dict.parse("<Seq~<StaticLength 8> Bit>").expect("parse")
-            .apply_substitution(&|k| γ.get(k).cloned())
+            .apply_subst(&γ)
             .clone()
     );
     γ.insert(
-        type_dict.get_typeid_creat(&"x86.UInt8".into()),
+        type_dict.get_typeid_creat(&"x86.UInt8"),
         type_dict.parse("ℤ_2^8 ~ <PosInt 2 BigEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>").expect("parse")
-            .apply_substitution(&|k| γ.get(k).cloned())
+            .apply_subst(&γ)
             .clone()
     );
     γ.insert(
-        type_dict.get_typeid_creat(&"x86.UInt16".into()),
+        type_dict.get_typeid_creat(&"x86.UInt16"),
         type_dict.parse("ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >").expect("parse")
-            .apply_substitution(&|k| γ.get(k).cloned())
+            .apply_subst(&γ)
             .clone()
     );
     γ.insert(
-        type_dict.get_typeid_creat(&"x86.UInt32".into()),
+        type_dict.get_typeid_creat(&"x86.UInt32"),
         type_dict.parse("ℤ_2^32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >").expect("parse")
-            .apply_substitution(&|k| γ.get(k).cloned())
-            .clone()
+            .apply_subst(&γ).clone()
     );
     γ.insert(
-        type_dict.get_typeid_creat(&"x86.UInt64".into()),
+        type_dict.get_typeid_creat(&"x86.UInt64"),
         type_dict.parse("ℤ_2^64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >").expect("parse")
-            .apply_substitution(&|k| γ.get(k).cloned())
-            .clone()
+            .apply_subst(&γ).clone()
     );
     γ.insert(
-        type_dict.get_typeid_creat(&"x86.Float".into()),
+        type_dict.get_typeid_creat(&"x86.Float32"),
         type_dict.parse("ℝ ~ IEEE-754.Float32 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
-            .apply_substitution(&|k| γ.get(k).cloned())
-            .clone()
+            .apply_subst(&γ).clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.Float64"),
+        type_dict.parse("ℝ ~ IEEE-754.Float64 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
+            .apply_subst(&γ).clone()
     );
 
+    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 struct_type1 = type_dict.parse("
-        <Struct
-            <Struct.Field  online-since          TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
-            <Struct.Field  battery-capacity      Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
-            <Struct.Field  battery-charge        Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
-            <Struct.Field  min-sampling-period   Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
-            <Struct.Field  cur-sampling-period   Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
-            <Struct.Field  max-chunk-size        ℕ ~ native.UInt32 >
-            <Struct.Field  cur-chunk-size        ℕ ~ native.UInt32 >
-            <Struct.Field  n-chunks-capacity     ℕ ~ native.UInt32 >
-            <Struct.Field  n-full-data-chunks    ℕ ~ native.UInt32 >
-            <Struct.Field  n-empty-data-chunks   ℕ ~ native.UInt32 >
+        <Struct ~ Aligned
+            <online-since          TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
+            <capacity              Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
+            <battery-charge        Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
+            <min-sampling-period   Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
+            <cur-sampling-period   Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
+            <max-chunk-size        ℕ ~ native.UInt32 >
+            <cur-chunk-size        ℕ ~ native.UInt32 >
+            <n-chunks-capacity     ℕ ~ native.UInt32 >
+            <n-full-data-chunks    ℕ ~ native.UInt32 >
+            <n-empty-data-chunks   ℕ ~ native.UInt32 >
         >
     ").expect("parse struct type");
 
-    eprintln!("{}
-    ",
-    struct_type1.clone().sugar(&mut type_dict).pretty(&type_dict, 0)
-    );
-
-    for m in morphism_base.enum_morphisms( &struct_type1 ) {
-        eprintln!("{:?} -> {:?}",
-            type_dict.read().unwrap().unparse(&m.get_type().src_type),
-            type_dict.read().unwrap().unparse(&m.get_type().dst_type)
-        );
-    }
-    return;
-
     let struct_type2 = type_dict.parse("
-        <Struct
-
-            <Struct.Field  battery-charge        Energy ~ Wh ~ ℝ ~ native.Double >
-            <Struct.Field  battery-capacity      Energy ~ Wh ~ ℝ ~ native.Double >
-            <Struct.Field  min-sampling-period   Duration ~ Seconds ~ ℝ ~ native.Double >
-            <Struct.Field  cur-sampling-period   Duration ~ Seconds ~ ℝ ~ native.Double >
-            <Struct.Field  max-chunk-size        ℕ ~ native.UInt32 >
-            <Struct.Field  cur-chunk-size        ℕ ~ native.UInt32 >
-            <Struct.Field  n-chunks-capacity     ℕ ~ native.UInt32 >
-            <Struct.Field  n-full-data-chunks    ℕ ~ native.UInt32 >
-            <Struct.Field  n-empty-data-chunks   ℕ ~ native.UInt32 >
-
-            <Struct.Field  online-since          TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ native.Double >
+        <Struct ~ Packed
+            <battery-charge        Energy ~ Wh ~ ℝ ~ native.Double >
+            <battery-capacity      Energy ~ Wh ~ ℝ ~ native.Double >
+            <min-sampling-period   Duration ~ Seconds ~ ℝ ~ native.Double >
+            <cur-sampling-period   Duration ~ Seconds ~ ℝ ~ native.Double >
+            <max-chunk-size        ℕ ~ native.UInt32 >
+            <cur-chunk-size        ℕ ~ native.UInt32 >
+            <n-chunks-capacity     ℕ ~ native.UInt32 >
+            <n-full-data-chunks    ℕ ~ native.UInt32 >
+            <n-empty-data-chunks   ℕ ~ native.UInt32 >
+            <online-since          TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ native.Double >
         >
     ").expect("parse struct type");
+*/
+
+/*
+    let struct_type1 = type_dict.parse("
+        RGB~<Struct
+            <red ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
+            <green ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
+            <blue ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
+        >
+        ").expect("parse");
+
+    let struct_type2 = type_dict.parse("
+        RGB~<Struct
+            <red ℝ ~ native.Float64>
+            <green ℝ ~ native.Float64>
+            <blue ℝ ~ native.Float64>
+        >
+    ").expect("parse");
+*/
+
+    let ty = SugaredMorphismType{ src_type: src_type.sugar(&mut type_dict), dst_type: dst_type.sugar(&mut type_dict) };
+    let mut target = LdmcCTargetMorph::new();
+    target.add_instantiation(&mut type_dict, morphism_base.get_morphism_instance( &ty ).expect("cant get instance"));
+    println!("{}", target.into_c_source(&mut type_dict));
+/*
+    return;
 
     let m = LdmcMorphism::new_struct_map(&mut type_dict, &morphism_base, struct_type1, struct_type2);
 
@@ -145,10 +158,9 @@ fn main() {
         m.into_prim_c_morphism(&mut type_dict, "morph_my_struct".into(), &HashMap::new())
             .c_source
     );
-return;
-    let src_type = type_dict.parse( src_type_arg.as_str() ).expect("");
-    let dst_type = type_dict.parse( dst_type_arg.as_str() ).expect("");
 
+
+return;
     let path = laddertypes::morphism_path::ShortestPathProblem::new(
         &morphism_base,
         MorphismType {
@@ -165,4 +177,5 @@ return;
             std::process::exit(-1);
         }
     }
+    */
 }
diff --git a/src/morphism.rs b/src/morphism.rs
index c5a509f..1fb4199 100644
--- a/src/morphism.rs
+++ b/src/morphism.rs
@@ -1,44 +1,16 @@
 
-use laddertypes::{morphism::Morphism, morphism_base::MorphismBase};
-use crate::{c_gen::encode_type_to_symbol, struct_layout::StructLayout};
+use laddertypes::{morphism::Morphism, morphism_base::MorphismBase, morphism_path::ShortestPathProblem, morphism_sugared::{SugaredMorphism, SugaredMorphismType}, SugaredStructMember};
+use crate::{c_gen_types::encode_type_to_symbol, struct_layout::StructLayout};
 
-#[derive(Clone, Debug)]
-pub struct LdmcPrimCMorphism {
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct LdmcPrimMorph {
     pub symbol: String,
     pub type_args: Vec<(laddertypes::TypeID, String)>,
-    pub src_type: laddertypes::TypeTerm,
-    pub dst_type: laddertypes::TypeTerm,
+    pub ty: SugaredMorphismType,
     pub c_source: String
 }
 
-#[derive(Clone)]
-pub struct StructFieldMorphism {
-    pub field_name: String,
-    pub item_morph: Option<Box<LdmcPrimCMorphism>>,
-    pub src_offset: u64,
-    pub dst_offset: u64,
-}
-
-#[derive(Clone)]
-pub enum LdmcMorphism {
-    Primitive( LdmcPrimCMorphism ),
-    //Chain(Vec< LdmcPrimCMorphism >),
-    LengthPrefixMap{
-        length_prefix_type: laddertypes::TypeTerm,
-        item_morph: Box<LdmcPrimCMorphism>
-    },
-    ValueDelimMap{
-        delim: u64,
-        item_morph: Box<LdmcPrimCMorphism>
-    },
-    StructMap{
-        src_struct: StructLayout,
-        dst_struct: StructLayout,
-        member_morphisms: Vec<StructFieldMorphism>
-    }
-}
-
-impl LdmcMorphism {
+impl LdmcPrimMorph {
     /*
     pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String) -> LdmcPrimCMorphism {
 
@@ -65,20 +37,22 @@ impl LdmcMorphism {
         }
     }
 */
+/*
+
     pub fn new_struct_map(
         dict: &mut impl laddertypes::TypeDict,
-        morph_base: &MorphismBase<LdmcMorphism>,
+        morph_base: &MorphismBase<LdmcPrimMorph>,
         src: laddertypes::TypeTerm,
         dst: laddertypes::TypeTerm,
     ) -> Self {
-        let src_struct = StructLayout::parse(dict, src).expect("cant parse src struct layout");
-        let dst_struct = StructLayout::parse(dict, dst).expect("cant parse dst struct layout");
+        let src_struct = StructLayout::parse(dict, &src).expect("cant parse src struct layout");
+        let dst_struct = StructLayout::parse(dict, &dst).expect("cant parse dst struct layout");
 
         let mut member_morphisms = Vec::new();
 
-        for (field_name, dst_type) in dst_struct.members.iter() {
+        for SugaredStructMember{ symbol: field_name, ty: dst_type } in dst_struct.members.iter() {
             let mut src_type = None;
-            for (src_name, st) in src_struct.members.iter() {
+            for SugaredStructMember{ symbol: src_name, ty: st } in src_struct.members.iter() {
                 if src_name == field_name {
                     src_type = Some(st.clone());
                 }
@@ -95,14 +69,19 @@ impl LdmcMorphism {
                     }
                 );
             } else {
-                match morph_base.find_morphism(
-                    &laddertypes::MorphismType {
-                        src_type: src_type.clone(),
-                        dst_type: dst_type.clone()
-                    },
-                    dict
-                ) {
-                    Some(item_morph) => {
+                match ShortestPathProblem::new(
+                    &morph_base,
+                    laddertypes::MorphismType {
+                        src_type: src_type.clone().desugar(dict),
+                        dst_type: dst_type.clone().desugar(dict)
+                    }
+                ).solve()
+                {
+                    Some(path) => {
+
+                        let src_type = src_type.clone().desugar(dict);
+                        let dst_type = dst_type.clone().desugar(dict);
+
                         let morph_symb = format!("morph_{}_to_{}",
                             encode_type_to_symbol(dict, &src_type),
                             encode_type_to_symbol(dict, &dst_type)
@@ -110,7 +89,7 @@ impl LdmcMorphism {
                         member_morphisms.push(
                             StructFieldMorphism {
                                 field_name: field_name.to_string(),
-                                item_morph: Some(Box::new(item_morph.m.into_prim_c_morphism(dict, morph_symb, &item_morph.σ))),
+                                item_morph: None,//Some(Box::new(item_morph.m.into_prim_c_morphism(dict, morph_symb, &item_morph.σ))),
                                 src_offset: src_struct.get_offset( field_name ),
                                 dst_offset: dst_struct.get_offset( field_name ),
                             }
@@ -124,13 +103,20 @@ impl LdmcMorphism {
             }
         }
 
-        LdmcMorphism::StructMap {
+        LdmcPrimMorph::StructMap {
             src_struct, dst_struct,
             member_morphisms
         }
     }
+    */
 }
 
+impl SugaredMorphism for LdmcPrimMorph {
+    fn get_type(&self) -> SugaredMorphismType {
+        self.ty.clone()
+    }
+}
+/*
 impl Morphism for LdmcMorphism {
     fn weight(&self) -> u64 {
         1
@@ -188,3 +174,4 @@ impl Morphism for LdmcMorphism {
         }
     }
 }
+*/
diff --git a/src/parser.rs b/src/parser.rs
index f45fddf..49320df 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,11 +1,7 @@
 use {
-    chumsky::{
+    crate::morphism::LdmcPrimMorph, chumsky::{
         prelude::*, text::*
-    },
-    std::sync::{Arc, RwLock},
-
-    laddertypes::{TypeDict, BimapTypeDict, parser::*},
-    crate::morphism::LdmcPrimCMorphism
+    }, laddertypes::{morphism_sugared::SugaredMorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
 };
 
 /* morphism-base text format:
@@ -18,7 +14,7 @@ use {
  */
 pub fn morphism_base_parser(
     type_dict: Arc<RwLock< BimapTypeDict >>
-) -> impl Parser<char, (String, Vec<LdmcPrimCMorphism>), Error = Simple<char>> {
+) -> impl Parser<char, (String, Vec<LdmcPrimMorph>), Error = Simple<char>> {
 
     just("```")
     .then(take_until(just("```")))
@@ -63,14 +59,16 @@ pub fn morphism_base_parser(
                 ty_args.push((var_id, kind));
             }
 
-            let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type");
-            let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type");
+            let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
+            let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
 
-            LdmcPrimCMorphism {
+            LdmcPrimMorph {
                 symbol,
                 type_args: ty_args,
-                src_type,
-                dst_type,
+                ty: SugaredMorphismType{
+                    src_type,
+                    dst_type
+                },
                 c_source
             }
         })
diff --git a/src/struct_layout.rs b/src/struct_layout.rs
index d961602..40be995 100644
--- a/src/struct_layout.rs
+++ b/src/struct_layout.rs
@@ -1,4 +1,6 @@
 
+use std::ops::Deref;
+
 use laddertypes::{parser::*, unparser::*, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm};
 
 #[derive(Clone, Copy, Debug)]
@@ -8,43 +10,137 @@ pub enum ObjectSize {
     Unknown
 }
 
+impl std::ops::Add for ObjectSize {
+    type Output = Self;
 
-pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
-    let ty = ty.clone().get_lnf_vec().last().unwrap().clone();
+    fn add(self, rhs: Self) -> Self {
+        match (self, rhs) {
+            (ObjectSize::Unknown, _) |
+            (_, ObjectSize::Unknown)
+                => ObjectSize::Unknown,
 
-    if ty == dict.parse("native.UInt8").expect("") {
-        return ObjectSize::Static(1);
+            (ObjectSize::Dynamic(), _) |
+            (_, ObjectSize::Dynamic())
+                => ObjectSize::Dynamic(),
+
+            (ObjectSize::Static(s1), ObjectSize::Static(s2)) => ObjectSize::Static(s1 + s2),
+        }
     }
-    if ty == dict.parse("native.UInt16").expect("") {
-        return ObjectSize::Static(2);
+}
+
+impl std::ops::Mul for ObjectSize {
+    type Output = Self;
+
+    fn mul(self, rhs: Self) -> Self {
+        match (self, rhs) {
+            (ObjectSize::Unknown, _) |
+            (_, ObjectSize::Unknown)
+                => ObjectSize::Unknown,
+
+            (ObjectSize::Dynamic(), _) |
+            (_, ObjectSize::Dynamic())
+                => ObjectSize::Dynamic(),
+
+            (ObjectSize::Static(s1), ObjectSize::Static(s2)) => ObjectSize::Static(s1 * s2),
+        }
     }
-    if ty == dict.parse("native.UInt32").expect("") ||
-        ty == dict.parse("native.Float").expect("") {
-        return ObjectSize::Static(4);
-    }
-    if ty == dict.parse("native.UInt64").expect("") ||
-       ty == dict.parse("native.Double").expect("") {
-        return ObjectSize::Static(8);
+}
+
+pub fn get_type_size( dict: &mut impl TypeDict, ty: SugaredTypeTerm ) -> ObjectSize {
+    match &ty {
+        SugaredTypeTerm::TypeID(tyid) => {
+                 if tyid == &dict.get_typeid_creat("native.UInt8") { ObjectSize::Static(1) }
+            else if tyid == &dict.get_typeid_creat("native.UInt16") { ObjectSize::Static(2) }
+            else if tyid == &dict.get_typeid_creat("native.UInt32") { ObjectSize::Static(4) }
+            else if tyid == &dict.get_typeid_creat("native.UInt64") { ObjectSize::Static(8) }
+            else if tyid == &dict.get_typeid_creat("native.Address") { ObjectSize::Static(8) }
+            else if tyid == &dict.get_typeid_creat("native.Float32") { ObjectSize::Static(4) }
+            else if tyid == &dict.get_typeid_creat("native.Float64") { ObjectSize::Static(8) }
+            else {
+                ObjectSize::Unknown
+            }
+        },
+
+        SugaredTypeTerm::Ladder(rungs) => {
+            get_type_size(dict, rungs.last().unwrap().clone() )
+        }
+
+        SugaredTypeTerm::Struct { struct_repr, members } => {
+            let layout = StructLayout::parse_sugared(dict, ty).expect("invalid struct");
+            layout.get_size()
+        }
+
+        SugaredTypeTerm::Seq { seq_repr, items } => {
+            if let Some(seq_repr) = seq_repr {
+                dict.add_typename("Length".into());
+                dict.add_typename("LengthType".into());
+                dict.add_typename("TerminatorValue".into());
+
+                if let Ok(σ) = laddertypes::unify(
+                    &seq_repr.clone().desugar(dict),
+                    &dict.parse("<StaticLength Length>").expect("")
+                ) {
+                    if let Some(TypeTerm::Num(len)) = σ.get(&dict.get_typeid(&"Length".into()).expect("")) {
+                        ObjectSize::Static(*len as u64) * get_type_size(dict, items.first().unwrap().clone())
+                    } else {
+                        ObjectSize::Unknown
+                    }
+                }
+                else if let Ok(σ) = laddertypes::unify(
+                    &seq_repr.clone().desugar(dict),
+                    &dict.parse("<LengthPrefix LengthType>").expect("")
+                ) {
+                    ObjectSize::Dynamic()
+                }
+                else if let Ok(σ) = laddertypes::unify(
+                    &seq_repr.clone().desugar(dict),
+                    &dict.parse("<ValueTerminated TerminatorValue>").expect("")
+                ) {
+                    ObjectSize::Dynamic()
+                }
+                else {
+                    ObjectSize::Unknown
+                }
+            } else {
+                ObjectSize::Unknown
+            }
+        }
+
+        _ => ObjectSize::Unknown
     }
 
-    if let Some(layout) = StructLayout::parse( dict, ty ) {
-        return layout.get_size();
-    }
-
-    ObjectSize::Unknown
 }
 
 #[derive(Clone, Copy, Debug, PartialEq)]
-enum LayoutType {
-    Natural,
+pub enum LayoutType {
+    Aligned,
     Packed
 }
 
-#[derive(Clone, Debug)]
+impl LayoutType {
+    pub fn parse( dict: &mut impl TypeDict, ty: &TypeTerm ) -> Option< LayoutType > {
+        if ty == &dict.parse("Aligned").expect("parse") {
+            Some(LayoutType::Aligned)
+        } else if ty == &dict.parse("Packed").expect("parse") {
+            Some(LayoutType::Packed)
+        } else {
+            None
+        }
+    }
+
+    pub fn unparse(&self, dict: &mut impl TypeDict) -> TypeTerm {
+        match self {
+            LayoutType::Aligned => dict.parse("Aligned").unwrap(),
+            LayoutType::Packed => dict.parse("Packed").unwrap()
+        }
+    }
+}
+
+#[derive(Clone)]
 pub struct StructLayout {
-    ty: laddertypes::TypeTerm,
-    item_type: laddertypes::TypeTerm,
-    pub members: Vec< (String, laddertypes::TypeTerm) >,
+    pub ty: laddertypes::TypeTerm,
+    pub layout: LayoutType,
+    pub members: Vec< SugaredStructMember >,
     offsets: std::collections::HashMap< String, u64 >,
     size: ObjectSize
 }
@@ -62,18 +158,22 @@ impl StructLayout {
         *self.offsets.get(name).expect("")
     }
 
-    pub fn calculate_offsets(&mut self, dict: &mut impl TypeDict) {
-        let layout_type = LayoutType::Natural;
+    pub fn init_offsets(&mut self, dict: &mut impl TypeDict) {
         let mut offset = 0;
 
-        for (field_name, field_type) in self.members.iter() {
+        for SugaredStructMember{symbol: field_name, ty: field_type} in self.members.iter() {
             //let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
             match get_type_size( dict, field_type.clone() ) {
                 ObjectSize::Static(field_size) => {
-                    if layout_type == LayoutType::Natural {
-                        // add padding to natural alignment
-                        if offset % field_size > 0 {
-                            offset = field_size * ((offset / field_size)+1);
+                    match self.layout {
+                        LayoutType::Aligned => {
+                            // add padding to get natural alignment of current member
+                            if offset % field_size > 0 {
+                                offset = field_size * ((offset / field_size)+1);
+                            }
+                        }
+                        LayoutType::Packed => {
+                            // no padding
                         }
                     }
 
@@ -90,7 +190,7 @@ impl StructLayout {
                     return;
                 }
                 ObjectSize::Unknown => {
-                    eprintln!("unknown field size!");
+                    eprintln!("Struct member `{}` has unknown size!", field_name);
                     self.offsets.insert(field_name.clone(), offset);
                     self.size = ObjectSize::Unknown;
                     return;
@@ -108,38 +208,30 @@ impl StructLayout {
         }
     }
 
-    pub fn generate_members(&self, dict: &mut impl TypeDict, prefix: &str, base_ptr: &str) {
-        let mut offset = 0;
-
-        for (field_name, field_type) in self.members.iter() {
-            let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
-            let offset = self.get_offset(field_name);
-            println!(" {} * restrict {}_{} = {} + {};",
-                field_c_type, prefix, field_name, base_ptr, offset
-            );
-        }
+    pub fn parse(dict: &mut impl TypeDict, struct_type: &TypeTerm) -> Option <Self> {
+        let st = struct_type.clone().strip().param_normalize().sugar(dict);
+        Self::parse_sugared(dict, st)
     }
 
-    pub fn parse(dict: &mut impl TypeDict, struct_type: TypeTerm) -> Option <Self> {
-        match struct_type.sugar(dict) {
-            SugaredTypeTerm::Struct(sugared_members) => {
-                let mut members = Vec::new();
-                let mut item_type = dict.parse("Byte").expect("");
-
-                for SugaredStructMember{ symbol, ty } in sugared_members {
-                    members.push((symbol, ty.desugar(dict)));
-                }
-
+    pub fn parse_sugared(dict: &mut impl TypeDict, st: SugaredTypeTerm) -> Option <Self> {
+        eprintln!("{}", st.pretty(dict, 0));
+        match st.clone() {
+            SugaredTypeTerm::Struct{ struct_repr, members } => {
                 let mut sl = StructLayout {
-                    ty: TypeTerm::unit(),
-                    item_type,
+                    ty: st.desugar(dict),
+                    layout: if let Some(sr) = struct_repr {
+                        let sr = sr.desugar(dict);
+                        LayoutType::parse( dict, &sr ).expect("invalid struct layout type")
+                    } else {
+                        eprintln!("choose default struct repr");
+                        LayoutType::Aligned
+                    },
+
                     members,
                     offsets: std::collections::HashMap::new(),
                     size: ObjectSize::Unknown
                 };
-
-                sl.calculate_offsets(dict);
-                sl.calculate_type(dict);
+                sl.init_offsets(dict);
 
                 Some(sl)
             }
@@ -150,18 +242,4 @@ impl StructLayout {
             }
         }
     }
-
-    fn calculate_type(&mut self, dict: &mut impl TypeDict) {
-        self.ty =
-            SugaredTypeTerm::Struct(
-                self.members
-                    .iter()
-                    .cloned()
-                    .map(|(symbol,ty)|
-                        SugaredStructMember{ symbol, ty:ty.sugar(dict) })
-                    .collect()
-            )
-                .desugar(dict);
-
-    }
 }

From 39cba1ee57be010c26f13fe82e7ff95e42054ac8 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 2 Apr 2025 14:11:17 +0200
Subject: [PATCH 05/31] improve symbol names in generated c code

---
 src/c_gen.rs       | 72 ++++++++++++++++++++++++++++------------------
 src/c_gen_types.rs | 13 +++++----
 2 files changed, 51 insertions(+), 34 deletions(-)

diff --git a/src/c_gen.rs b/src/c_gen.rs
index c64a0f6..5677c73 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -1,5 +1,5 @@
 use {
-    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
+    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
 };
 
 
@@ -43,19 +43,14 @@ impl LdmcPrimMorph {
         let src_type = self.ty.src_type.clone().apply_subst(σ).clone();
         let dst_type = self.ty.dst_type.clone().apply_subst(σ).clone();
 
-        let symbol = encode_morph_type_to_symbol(dict, &self.ty);
-        let src_c_symbol = encode_type_to_symbol(dict, &self.ty.src_type);
-        let dst_c_symbol = encode_type_to_symbol(dict, &self.ty.dst_type);
-
-        let src_c_type = get_c_repr_type(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type");
-        let dst_c_type = get_c_repr_type(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for src type");
+        let symbol = self.instantiated_symbol_name(dict, σ);
+        let src_c_symbol = encode_type_to_symbol(dict, &self.ty.strip_halo().src_type);
+        let dst_c_symbol = encode_type_to_symbol(dict, &self.ty.strip_halo().dst_type);
 
         s.push_str(&format!(r#"
 int {} ( {} const * restrict src, {} * restrict dst ) {{
 "#,
-            self.instantiated_symbol_name(dict, σ),
-            get_c_repr_type(dict, src_type, true).expect("cant get c-repr-type"),
-            get_c_repr_type(dict, dst_type, true).expect("cant get c-repr-type"),
+            symbol, src_c_symbol, dst_c_symbol,
         ));
         s.push_str(&self.c_source);
         s.push_str(&format!(r#"
@@ -72,14 +67,18 @@ int {} ( {} const * restrict src, {} * restrict dst ) {{
 
 pub struct LdmcCTargetMorph {
     includes: Vec< String >,
+    active_types: Vec< SugaredTypeTerm >,
     active_instantiations: Vec< LdmcPrimMorph >,
 }
 
 impl LdmcCTargetMorph {
     pub fn new() -> Self {
         LdmcCTargetMorph {
-            includes: Vec::new(),
-            active_instantiations: Vec::new()
+            includes: vec![
+                "#include <stdint.h>".into(),
+            ],
+            active_instantiations: Vec::new(),
+            active_types: Vec::new(),
         }
     }
 
@@ -92,6 +91,15 @@ impl LdmcCTargetMorph {
         if ! self.active_instantiations.contains(&new_inst) {
             self.active_instantiations.push(new_inst.clone());
         }
+
+        let ty = new_inst.get_type().strip_halo();
+        if ! self.active_types.contains(&ty.src_type) {
+            self.active_types.push(ty.src_type);
+        }
+        if ! self.active_types.contains(&ty.dst_type) {
+            self.active_types.push(ty.dst_type);
+        }
+
         Ok(new_inst)
     }
 
@@ -101,6 +109,14 @@ impl LdmcCTargetMorph {
             source.push_str(&inc);
         }
 
+        for ty in self.active_types {
+            source.push_str(&format!("
+    typedef {} {};
+",
+                get_c_repr_type(dict, ty.clone(), false).expect("cant get c-repr type"),
+                encode_type_to_symbol(dict, &ty)));
+        }
+
         for m in self.active_instantiations {
             source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
         }
@@ -119,7 +135,6 @@ impl LdmcCTargetMorph {
                 let mut c_source = String::new();
                 for (ty_id, kind) in morph.type_args.iter() {
                     if let Some(val) = σ.get(ty_id) {
-                        eprintln!("val = {}", val.pretty(dict, 0));
                         let type_var_value =
                             if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
                                 c_repr_type
@@ -138,13 +153,13 @@ impl LdmcCTargetMorph {
                 Ok(LdmcPrimMorph{
                     symbol: morph.instantiated_symbol_name(dict, σ),
                     type_args: Vec::new(),
-                    ty: morph_inst.get_type(),
+                    ty: morph_inst.get_haloless_type(),
                     c_source
                 })
             },
             MorphismInstance2::Chain { path } => {
-                let ty = morph_inst.get_type();
-                let symbol = encode_morph_type_to_symbol(dict, &ty);
+                let ty = morph_inst.get_type().strip_halo();
+                let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
 
                 let mut c_source = String::new();
 
@@ -159,8 +174,8 @@ impl LdmcCTargetMorph {
                     if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
                         let morph_symbol = inst.instantiated_symbol_name(dict, &morph.get_subst());
 
-                        let src_c_type = get_c_repr_type(dict, ty.src_type.clone(), true).expect("cant get c-repr type for src type");
-                        let dst_c_type = get_c_repr_type(dict, ty.dst_type.clone(), true).expect("cant get c-repr type for dst type");
+                        let src_c_type = get_c_repr_type(dict, inst.get_type().strip_halo().src_type, true).expect("cant get c-repr type for src type");
+                        let dst_c_type = get_c_repr_type(dict, inst.get_type().strip_halo().dst_type, true).expect("cant get c-repr type for dst type");
 
                         let src_buf = if i == 0 { "src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
                         let dst_buf = if i+1 == path.len() { "dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
@@ -187,7 +202,7 @@ impl LdmcCTargetMorph {
             }
             MorphismInstance2::MapSeq { ψ, seq_repr, item_morph } => {
                 let i = 0; // <--todo
-                self.add_instantiation(dict, item_morph.as_ref().clone());
+                self.add_instantiation(dict, item_morph.as_ref().clone()).expect("add instantiation");
                 if let Some(seq_repr) = seq_repr {
 
                     dict.add_varname("LengthType".into());
@@ -196,15 +211,15 @@ impl LdmcCTargetMorph {
                         seq_repr.as_ref()
                     ) {
                         let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
-                        let ty = morph_inst.get_type();
-                        let symbol = encode_morph_type_to_symbol(dict, &ty);
-                        let item_morph_symbol = encode_morph_type_to_symbol(dict, &item_morph.get_type());
+                        let ty = morph_inst.get_type().strip_halo();
+                        let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
+                        let item_morph_symbol = encode_morph_type_to_symbol(dict, &item_morph.get_haloless_type());
 
                         let length_c_type = get_c_repr_type(dict, length_type.clone(), true).expect("cant c-repr type for array length");
-                        let src_item_c_type = get_c_repr_type(dict, item_morph.get_type().src_type, true).expect("cant c-repr type for src item");
-                        let dst_item_c_type = get_c_repr_type(dict, item_morph.get_type().dst_type, true).expect("cant c-repr type for dst item");
-                        let src_c_type = get_c_repr_type(dict, ty.src_type.clone(), true).expect("cant get c-repr type for src type");
-                        let dst_c_type = get_c_repr_type(dict, ty.dst_type.clone(), true).expect("cant get c-repr type for dst type");
+                        let src_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().src_type, true).expect("cant c-repr type for src item");
+                        let dst_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().dst_type, true).expect("cant c-repr type for dst item");
+                        let src_c_type = encode_type_to_symbol(dict, &ty.strip_halo().src_type);
+                        let dst_c_type = encode_type_to_symbol(dict, &ty.strip_halo().dst_type);
 
                         let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
                             length_c_type, src_item_c_type, dst_item_c_type
@@ -238,13 +253,14 @@ impl LdmcCTargetMorph {
                 }
             },
             MorphismInstance2::MapStruct { ψ, struct_repr, member_morph } => {
-                let ty = morph_inst.get_type();
-                let symbol =encode_morph_type_to_symbol(dict, &ty);
+                let ty = morph_inst.get_type().strip_halo();
+                let symbol =encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
 
                 let mut c_source = String::new();
 
                 for (name, morph) in member_morph.iter() {
                     if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
+                        let name = name.replace("-", "_").replace(".","_dot_");
                         c_source.push_str(
                             &format!("
                                 {} ( &src->{}, &dst->{} );
diff --git a/src/c_gen_types.rs b/src/c_gen_types.rs
index 9c0020d..8490ba7 100644
--- a/src/c_gen_types.rs
+++ b/src/c_gen_types.rs
@@ -14,8 +14,6 @@ pub fn get_c_repr_kind(kind: String) -> Option<String> {
 /* for a given ladder type `t`, get the corresponding C type
  */
 pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointer: bool) -> Option<String> {
-    eprintln!("get c repr of {}", t.pretty(dict,0));
-
     match t.get_floor_type().1.strip() {
         SugaredTypeTerm::TypeID(tyid) => {
             if tyid == dict.get_typeid_creat("native.UInt8") {
@@ -136,7 +134,7 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
                 let field_c_type = get_c_repr_type(dict, ty, false).expect("");
                 c_type.push_str(&format!("    {} {};\n",
                     field_c_type,
-                    symbol
+                    symbol.replace("-", "_").replace(".","_dot_")
                 ));
             }
 
@@ -152,7 +150,7 @@ struct {{
 
             for (i, SugaredEnumVariant{ symbol, ty }) in variants.iter().enumerate() {
                 c_type.push_str(&format!(
-                    "       {} = {}", symbol.to_uppercase(), i
+                    "       {} = {}", symbol.replace("-", "_").replace(".","_dot_").to_uppercase(), i
                 ));
 
                 if i+1 < variants.len() {
@@ -169,7 +167,7 @@ struct {{
             for SugaredEnumVariant{ symbol, ty } in variants {
                 let variant_c_type = get_c_repr_type(dict, ty, false).expect("cant get C-Repr type for variant");
                 c_type.push_str(&format!(
-                    "       {} {};\n", variant_c_type, symbol
+                    "       {} {};\n", variant_c_type, symbol.replace("-", "_").replace(".","_dot_")
                 ));
             }
 
@@ -198,6 +196,7 @@ pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredT
         laddertypes::TypeTerm::Char(c) => {
             match c {
                 '.' => format!("_dot_"),
+                '-' => format!("_minus_"),
                 _ =>
                 format!("{}", (c as u64))
             }
@@ -207,7 +206,9 @@ pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredT
         }
         laddertypes::TypeTerm::TypeID(ty_id) => {
             if let Some(name) = dict.get_typename(&ty_id) {
-                format!("{}", name.replace(".", "_dot_"))
+                name
+                    .replace("-", "_")
+                    .replace(".", "_dot_")
             } else {
                 format!("")
             }

From 35b747ea15a67d2005a55d8a00c286c0b2b0ae4a Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 2 Apr 2025 14:31:47 +0200
Subject: [PATCH 06/31] fix local src/dst types in complex morphisms

---
 src/c_gen.rs | 150 +++------------------------------------------------
 1 file changed, 6 insertions(+), 144 deletions(-)

diff --git a/src/c_gen.rs b/src/c_gen.rs
index 5677c73..49c69b5 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -2,12 +2,6 @@ use {
     crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
 };
 
-
-
-
-
-
-
 impl LdmcPrimMorph {
     pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> String {
         let mut s = self.symbol.clone();
@@ -40,9 +34,6 @@ impl LdmcPrimMorph {
 
     pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> Option<String> {
         let mut s = String::new();
-        let src_type = self.ty.src_type.clone().apply_subst(σ).clone();
-        let dst_type = self.ty.dst_type.clone().apply_subst(σ).clone();
-
         let symbol = self.instantiated_symbol_name(dict, σ);
         let src_c_symbol = encode_type_to_symbol(dict, &self.ty.strip_halo().src_type);
         let dst_c_symbol = encode_type_to_symbol(dict, &self.ty.strip_halo().dst_type);
@@ -174,8 +165,8 @@ impl LdmcCTargetMorph {
                     if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
                         let morph_symbol = inst.instantiated_symbol_name(dict, &morph.get_subst());
 
-                        let src_c_type = get_c_repr_type(dict, inst.get_type().strip_halo().src_type, true).expect("cant get c-repr type for src type");
-                        let dst_c_type = get_c_repr_type(dict, inst.get_type().strip_halo().dst_type, true).expect("cant get c-repr type for dst type");
+                        let src_c_type = encode_type_to_symbol(dict, &inst.get_type().strip_halo().src_type);
+                        let dst_c_type = encode_type_to_symbol(dict, &inst.get_type().strip_halo().dst_type);
 
                         let src_buf = if i == 0 { "src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
                         let dst_buf = if i+1 == path.len() { "dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
@@ -218,8 +209,10 @@ impl LdmcCTargetMorph {
                         let length_c_type = get_c_repr_type(dict, length_type.clone(), true).expect("cant c-repr type for array length");
                         let src_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().src_type, true).expect("cant c-repr type for src item");
                         let dst_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().dst_type, true).expect("cant c-repr type for dst item");
-                        let src_c_type = encode_type_to_symbol(dict, &ty.strip_halo().src_type);
-                        let dst_c_type = encode_type_to_symbol(dict, &ty.strip_halo().dst_type);
+                        let src_c_type = encode_type_to_symbol(dict, &ty.src_type);
+                        let dst_c_type = encode_type_to_symbol(dict, &ty.dst_type);
+
+                        // todo: self.add_active_length_prefix_map()
 
                         let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
                             length_c_type, src_item_c_type, dst_item_c_type
@@ -285,134 +278,3 @@ impl LdmcCTargetMorph {
         }
     }
 }
-
-
-/*
-pub fn generate_main(
-    type_dict: &mut impl TypeDict,
-    morph: MorphismInstance2<LdmcPrimMorph>,
-    src_type: TypeTerm, dst_type: TypeTerm
-) {
-    let mut i = 0;
-
-
-
-    /* todo: collect include files from morphism base */
-    println!(r#"
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdbool.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(type_dict, &morph_inst.σ);
-                if ! existing_instantiations.contains(&name) {
-                    if let Some(s) = item_morph.generate_instantiation(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(type_dict, &morph_inst.σ);
-                if ! existing_instantiations.contains(&name) {
-                    if let Some(s) = item_morph.generate_instantiation(type_dict, &morph_inst.σ) {
-                        println!("{}", s);
-                    } else {
-                        eprintln!("couldnt generate instance {}", name);
-                    }
-
-                    existing_instantiations.push( name );
-                }
-            }
-            _ => {}
-        }
-    }
-
-    println!(r#"
-int main() {{
-uint8_t bufA[128];
-uint8_t bufB[128];
-
-memset(bufA, 0, sizeof(bufA));
-memset(bufB, 0, sizeof(bufB));
-
-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, sizeof(bufA));
-//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 {}
-
-...with
-morph {}
----> {},
-subst σ = {:?},
-halo  Ψ = {}
-*/
-{}
-"#,
-            type_dict.unparse(&morph_inst.get_type().dst_type.param_normalize().decurry()),
-            type_dict.unparse(&morph_inst.m.get_type().src_type),
-            type_dict.unparse(&morph_inst.m.get_type().dst_type),
-            morph_inst.σ,
-            type_dict.unparse(&morph_inst.halo),
-            morph_inst.m.generate_call(type_dict, &morph_inst.σ, i)
-        );
-
-        i += 1;
-    }
-
-    let out_buf = if i%2==0 { "bufA" } else { "bufB" };
-
-    let is_string = false;
-    if let Ok((halo, σ)) = laddertypes::subtype_unify(
-        &dst_type,
-        &type_dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").unwrap()
-    ) {
-        println!(r#"
-printf("%s\n", {});"#, out_buf);
-    } else if let Ok((halo, σ)) = laddertypes::subtype_unify(
-        &dst_type,
-        &type_dict.parse("<Seq~<LengthPrefix native.UInt64> native.UInt8>").unwrap()
-    ) {
-        println!(r#"
-        /* write output
-         */
-        {{
-            LengthPrefix_uint64_t_Array_uint8_t * buf = (void*){};
-            write(1, {}, sizeof(uint64_t) + buf->len);
-        }}"#, out_buf, out_buf);
-    } else {
-        println!(r#"
-write(1, {}, sizeof({}));"#,
-            out_buf,
-            out_buf
-        );
-    }
-
-
-    println!(r#"
-return 0;
-}}
-    "#);
-
-    eprintln!("Success: generated C code");
-}
-*/

From 98592aa596b27ae23d0c2930637d6810fa638227 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 2 Apr 2025 14:37:31 +0200
Subject: [PATCH 07/31] fuse results of sub- morphisms in complex morphisms

---
 src/c_gen.rs | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/c_gen.rs b/src/c_gen.rs
index 49c69b5..829b526 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -67,6 +67,7 @@ impl LdmcCTargetMorph {
         LdmcCTargetMorph {
             includes: vec![
                 "#include <stdint.h>".into(),
+                "#define FUSE(x) { int result = x; if(result) return result; }".into()
             ],
             active_instantiations: Vec::new(),
             active_types: Vec::new(),
@@ -98,6 +99,7 @@ impl LdmcCTargetMorph {
         let mut source = String::new();
         for inc in self.includes {
             source.push_str(&inc);
+            source.push('\n');
         }
 
         for ty in self.active_types {
@@ -175,7 +177,7 @@ impl LdmcCTargetMorph {
             {{
                     {} const * restrict src = {};
                     {} * restrict dst = {};
-                    {} ( src, dst );
+                    FUSE( {} ( src, dst ) );
             }}"#,
                             src_c_type, src_buf,
                             dst_c_type, dst_buf,
@@ -224,7 +226,7 @@ impl LdmcCTargetMorph {
             {{
                     {} const * restrict src = (void*) {};
                     {} * restrict dst = (void*) {};
-                    {} ( {}, src, dst );
+                    FUSE( {} ( {}, src, dst );
             }}"#,
                             src_c_type, src_buf,
                             dst_c_type, dst_buf,
@@ -256,7 +258,7 @@ impl LdmcCTargetMorph {
                         let name = name.replace("-", "_").replace(".","_dot_");
                         c_source.push_str(
                             &format!("
-                                {} ( &src->{}, &dst->{} );
+                                FUSE( {} ( &src->{}, &dst->{} ) );
                             ",
                             inst.symbol,
                             name, name

From 67cec64dfc8e142d1694bb75b050ac60f694c113 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 2 Apr 2025 15:01:45 +0200
Subject: [PATCH 08/31] fix codegen for seq-map

---
 src/c_gen.rs | 75 +++++++++++++++++++++++-----------------------------
 1 file changed, 33 insertions(+), 42 deletions(-)

diff --git a/src/c_gen.rs b/src/c_gen.rs
index 829b526..32b3ef4 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -194,56 +194,47 @@ impl LdmcCTargetMorph {
                 })
             }
             MorphismInstance2::MapSeq { ψ, seq_repr, item_morph } => {
-                let i = 0; // <--todo
-                self.add_instantiation(dict, item_morph.as_ref().clone()).expect("add instantiation");
-                if let Some(seq_repr) = seq_repr {
+                if let Ok(item_morph_inst) = self.add_instantiation(dict, item_morph.as_ref().clone()) {
+                    if let Some(seq_repr) = seq_repr {
+                        dict.add_varname("LengthType".into());
+                        if let Ok(γ) = laddertypes::unification_sugared::unify(
+                            &dict.parse("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
+                            seq_repr.as_ref()
+                        ) {
+                            let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
+                            let ty = morph_inst.get_type().strip_halo();
+                            let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
+                            let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
 
-                    dict.add_varname("LengthType".into());
-                    if let Ok(γ) = laddertypes::unification_sugared::unify(
-                        &dict.parse("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
-                        seq_repr.as_ref()
-                    ) {
-                        let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
-                        let ty = morph_inst.get_type().strip_halo();
-                        let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
-                        let item_morph_symbol = encode_morph_type_to_symbol(dict, &item_morph.get_haloless_type());
+                            let length_c_type = get_c_repr_type(dict, length_type.clone(), true).expect("cant c-repr type for array length");
+                            let src_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().src_type, true).expect("cant c-repr type for src item");
+                            let dst_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().dst_type, true).expect("cant c-repr type for dst item");
 
-                        let length_c_type = get_c_repr_type(dict, length_type.clone(), true).expect("cant c-repr type for array length");
-                        let src_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().src_type, true).expect("cant c-repr type for src item");
-                        let dst_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().dst_type, true).expect("cant c-repr type for dst item");
-                        let src_c_type = encode_type_to_symbol(dict, &ty.src_type);
-                        let dst_c_type = encode_type_to_symbol(dict, &ty.dst_type);
+                            // todo: self.add_active_length_prefix_map()
 
-                        // todo: self.add_active_length_prefix_map()
+                            let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
+                                length_c_type, src_item_c_type, dst_item_c_type
+                            );
+                            let c_source = format!(r#"
+                        return {} ( {}, src, dst );"#,
+                                map_fn,
+                                item_morph_symbol,
+                            );
 
-                        let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
-                            length_c_type, src_item_c_type, dst_item_c_type
-                        );
-
-                        let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
-                        let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
-                        let c_source = format!(r#"
-            {{
-                    {} const * restrict src = (void*) {};
-                    {} * restrict dst = (void*) {};
-                    FUSE( {} ( {}, src, dst );
-            }}"#,
-                            src_c_type, src_buf,
-                            dst_c_type, dst_buf,
-                            map_fn,
-                            item_morph_symbol,
-                        );
-
-                        Ok(LdmcPrimMorph{
-                            symbol, type_args: Vec::new(), ty,
-                            c_source
-                        })
+                            Ok(LdmcPrimMorph{
+                                symbol, type_args: Vec::new(), ty,
+                                c_source
+                            })
+                        } else {
+                            eprintln!("Error: Unknown Seq- Representation!!");
+                            Err(())
+                        }
                     } else {
-                        eprintln!("Error: Unknown Seq- Representation!!");
+                        eprintln!("Error: missing Seq- Representation!!");
                         Err(())
                     }
                 } else {
-                    eprintln!("Error: missing Seq- Representation!!");
+                    eprintln!("failed to add item-morph instantiation");
                     Err(())
                 }
             },

From 3f1397735c507b2eb3aa9c6aeb0deb9e9b0866cc Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 2 Apr 2025 23:32:06 +0200
Subject: [PATCH 09/31] improve code generation

- improve usage of FUSE
- implement seq-map for different representations
- fix C-types in morph-function arguments
- collect active types and put typedef into header
- add generate_main() to create stdio-morphism
---
 src/c_gen.rs       | 253 ++++++++++++++++++++++++++++++++++-----------
 src/c_gen_types.rs |  16 +++
 src/main.rs        |  86 +--------------
 3 files changed, 210 insertions(+), 145 deletions(-)

diff --git a/src/c_gen.rs b/src/c_gen.rs
index 32b3ef4..41d1c99 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -1,24 +1,31 @@
 use {
-    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
+    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_arg_ty, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
 };
 
 impl LdmcPrimMorph {
     pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> String {
         let mut s = self.symbol.clone();
         for (k_id,v) in self.type_args.iter() {
-            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 = encode_type_to_symbol(dict, &val_trm);
-                    s.push_str(&format!("_{}_{}", name, val_str));
+
+                if let Some(val_trm) = σ.get(k_id) {
+                    if let laddertypes::TypeID::Var(var_id) = k_id {
+
+                        //if self.get_type().strip_halo().src_type.contains_var(*var_id) ||
+                        //self.get_type().strip_halo().dst_type.contains_var(*var_id) {
+
+                            let name = dict.get_varname(*var_id).unwrap();
+                            let val_str = encode_type_to_symbol(dict, &val_trm);
+                            s.push_str(&format!("_{}_{}", name, val_str));
+
+                            //}
+                    }
+                } else {
+                    if let laddertypes::TypeID::Var(var_id) = k_id {
+                        let k = dict.get_varname(*var_id).unwrap();
+                        s.push_str(&format!("_{:?}_MISSING", k));
+                        eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing type parameter {} ({})", k, var_id);
+                    }
                 }
-            } else {
-                if let laddertypes::TypeID::Var(var_id) = k_id {
-                    let k = dict.get_varname(*var_id).unwrap();
-                    s.push_str(&format!("_{:?}_MISSING", k));
-                    eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing type parameter {} ({})", k, var_id);
-                }
-            }
         }
         s
     }
@@ -35,8 +42,9 @@ impl LdmcPrimMorph {
     pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> Option<String> {
         let mut s = String::new();
         let symbol = self.instantiated_symbol_name(dict, σ);
-        let src_c_symbol = encode_type_to_symbol(dict, &self.ty.strip_halo().src_type);
-        let dst_c_symbol = encode_type_to_symbol(dict, &self.ty.strip_halo().dst_type);
+
+        let src_c_symbol = encode_type_to_arg_ty(dict, &self.ty.strip_halo().src_type.clone().apply_subst(σ).get_floor_type().1);
+        let dst_c_symbol = encode_type_to_arg_ty(dict, &self.ty.strip_halo().dst_type.clone().apply_subst(σ).get_floor_type().1);
 
         s.push_str(&format!(r#"
 int {} ( {} const * restrict src, {} * restrict dst ) {{
@@ -67,13 +75,25 @@ impl LdmcCTargetMorph {
         LdmcCTargetMorph {
             includes: vec![
                 "#include <stdint.h>".into(),
-                "#define FUSE(x) { int result = x; if(result) return result; }".into()
+                "#define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; }".into(),
             ],
             active_instantiations: Vec::new(),
             active_types: Vec::new(),
         }
     }
 
+    pub fn add_type(&mut self, ty: SugaredTypeTerm) {
+        if ! self.active_types.contains(&ty) {
+            match &ty {
+                SugaredTypeTerm::Seq { seq_repr, items } =>{
+                    self.add_type(items.first().unwrap().clone());
+                }
+                _=>{}
+            }
+            self.active_types.push(ty.clone());
+        }
+    }
+
     pub fn add_instantiation(
         &mut self,
         dict: &mut impl TypeDict,
@@ -85,12 +105,8 @@ impl LdmcCTargetMorph {
         }
 
         let ty = new_inst.get_type().strip_halo();
-        if ! self.active_types.contains(&ty.src_type) {
-            self.active_types.push(ty.src_type);
-        }
-        if ! self.active_types.contains(&ty.dst_type) {
-            self.active_types.push(ty.dst_type);
-        }
+        self.add_type(ty.src_type.get_floor_type().1);
+        self.add_type(ty.dst_type.get_floor_type().1);
 
         Ok(new_inst)
     }
@@ -106,7 +122,7 @@ impl LdmcCTargetMorph {
             source.push_str(&format!("
     typedef {} {};
 ",
-                get_c_repr_type(dict, ty.clone(), false).expect("cant get c-repr type"),
+                get_c_repr_type(dict, ty.clone(), false).expect(&format!("cant get c-repr type for type '{}'", ty.pretty(dict,0))),
                 encode_type_to_symbol(dict, &ty)));
         }
 
@@ -122,68 +138,72 @@ impl LdmcCTargetMorph {
         dict: &mut impl laddertypes::TypeDict,
         morph_inst: MorphismInstance2<LdmcPrimMorph>,
     ) -> Result<LdmcPrimMorph, ()> {
+        eprintln!("bake morphism:  {}
+  ------> {}", morph_inst.get_haloless_type().src_type.pretty(dict,0), morph_inst.get_haloless_type().dst_type.pretty(dict, 0));
 
         match &morph_inst {
             MorphismInstance2::Primitive { ψ, σ, morph } => {
                 let mut c_source = String::new();
                 for (ty_id, kind) in morph.type_args.iter() {
-                    if let Some(val) = σ.get(ty_id) {
-                        let type_var_value =
-                            if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
-                                c_repr_type
-                            } else {
-                                encode_type_to_value(dict, &val)
-                            };
+                    if let laddertypes::TypeID::Var(var_id) = ty_id {
+                        //if morph_inst.get_type().strip_halo().src_type.contains_var(*var_id) ||
+                        //morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
+                            if let Some(val) = σ.get(ty_id) {
+                                let type_var_value =
+                                    if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
+                                        c_repr_type
+                                    } else {
+                                        encode_type_to_value(dict, &val)
+                                    };
 
-                        c_source.push_str(&format!("    #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
+                                c_source.push_str(&format!("    #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
+                            }
+                            //}
                     }
                 }
                 c_source.push_str(&morph.c_source);
                 for (ty_id, kind) in morph.type_args.iter() {
-                    c_source.push_str(&format!("\n    #undef {}", dict.get_typename(&ty_id).unwrap()));
+                    if let laddertypes::TypeID::Var(var_id) = ty_id {
+                        //if morph_inst.get_type().strip_halo().src_type.contains_var(*var_id) ||
+                        //morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
+
+                            c_source.push_str(&format!("\n    #undef {}", dict.get_typename(&ty_id).unwrap()));
+                            //}
+                    }
                 }
 
                 Ok(LdmcPrimMorph{
                     symbol: morph.instantiated_symbol_name(dict, σ),
                     type_args: Vec::new(),
-                    ty: morph_inst.get_haloless_type(),
+                    ty: morph_inst.get_type().apply_subst(σ).strip_halo(),
                     c_source
                 })
             },
             MorphismInstance2::Chain { path } => {
                 let ty = morph_inst.get_type().strip_halo();
-                let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
+                let symbol = encode_morph_type_to_symbol(dict, &ty);
 
                 let mut c_source = String::new();
 
                 if path.len() > 1 {
                     c_source.push_str(r#"
-            uint8_t bufA[128];
-            uint8_t bufB[128];
+            uint8_t bufA[4096];
+            uint8_t bufB[4096];
     "#);
                 }
 
                 for (i,morph) in path.iter().enumerate() {
                     if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
                         let morph_symbol = inst.instantiated_symbol_name(dict, &morph.get_subst());
-
-                        let src_c_type = encode_type_to_symbol(dict, &inst.get_type().strip_halo().src_type);
-                        let dst_c_type = encode_type_to_symbol(dict, &inst.get_type().strip_halo().dst_type);
-
                         let src_buf = if i == 0 { "src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
                         let dst_buf = if i+1 == path.len() { "dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
 
                         c_source.push_str(&format!(r#"
-            {{
-                    {} const * restrict src = {};
-                    {} * restrict dst = {};
-                    FUSE( {} ( src, dst ) );
-            }}"#,
-                            src_c_type, src_buf,
-                            dst_c_type, dst_buf,
-                            morph_symbol
+        FUSE( {}, {}, {} );"#,
+                            morph_symbol, src_buf, dst_buf,
                         ));
                     } else {
+                        c_source.push_str(&format!("/* ERROR: missing morphism */"));
                         eprintln!("failed to add instantiation of item morphism");
                     }
                 }
@@ -196,28 +216,65 @@ impl LdmcCTargetMorph {
             MorphismInstance2::MapSeq { ψ, seq_repr, item_morph } => {
                 if let Ok(item_morph_inst) = self.add_instantiation(dict, item_morph.as_ref().clone()) {
                     if let Some(seq_repr) = seq_repr {
+                        dict.add_varname("Length".into());
                         dict.add_varname("LengthType".into());
+                        dict.add_varname("TerminatorValue".into());
+
                         if let Ok(γ) = laddertypes::unification_sugared::unify(
+                            &dict.parse("<StaticLength Length>").expect("parse type template").sugar(dict),
+                            seq_repr.as_ref()
+                        ) {
+                            let length = γ.get(&dict.get_typeid(&"Length".into()).expect("")).expect("cant get Length");
+                            match length {
+                                SugaredTypeTerm::Num(l) => {
+                                    let ty = morph_inst.get_type().strip_halo();
+                                    let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_type());
+                                    let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
+
+                                    self.add_type( morph_inst.get_type().strip_halo().src_type );
+                                    self.add_type( morph_inst.get_type().strip_halo().dst_type );
+
+                                    let c_source = format!(r#"
+                                        for( size_t i = 0; i < {}; ++i ) {{
+                                            FUSE( {}, &src[i], &dst[i] );
+                                        }}
+                                        "#,
+                                        l,
+                                        item_morph_symbol,
+                                    );
+
+                                    Ok(LdmcPrimMorph{
+                                        symbol, type_args: Vec::new(), ty,
+                                        c_source
+                                    })
+                                }
+                                _ => {
+                                    eprintln!("invalid length '{}'", length.pretty(dict, 0));
+                                    Err(())
+                                }
+                            }
+                        }
+
+                        else if let Ok(γ) = laddertypes::unification_sugared::unify(
                             &dict.parse("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
                             seq_repr.as_ref()
                         ) {
-                            let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
+                            // todo: assert that length type is native.UIntX
+                            //let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
+
                             let ty = morph_inst.get_type().strip_halo();
-                            let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
+                            let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_type());
                             let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
 
-                            let length_c_type = get_c_repr_type(dict, length_type.clone(), true).expect("cant c-repr type for array length");
-                            let src_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().src_type, true).expect("cant c-repr type for src item");
-                            let dst_item_c_type = get_c_repr_type(dict, item_morph.get_haloless_type().dst_type, true).expect("cant c-repr type for dst item");
+                            self.add_type( morph_inst.get_type().strip_halo().src_type );
+                            self.add_type( morph_inst.get_type().strip_halo().dst_type );
 
-                            // todo: self.add_active_length_prefix_map()
-
-                            let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
-                                length_c_type, src_item_c_type, dst_item_c_type
-                            );
                             let c_source = format!(r#"
-                        return {} ( {}, src, dst );"#,
-                                map_fn,
+                                for( size_t i = 0; i < src->len; ++i ) {{
+                                    FUSE( {}, &src->items[i], &dst->items[i] );
+                                }}
+                                dst->len = src->len;
+                                "#,
                                 item_morph_symbol,
                             );
 
@@ -225,7 +282,38 @@ impl LdmcCTargetMorph {
                                 symbol, type_args: Vec::new(), ty,
                                 c_source
                             })
-                        } else {
+                        }
+
+                        else if let Ok(γ) = laddertypes::unification_sugared::unify(
+                            &dict.parse("<ValueTerminated TerminatorValue>").expect("parse type template").sugar(dict),
+                            seq_repr.as_ref()
+                        ) {
+                            let terminator_value = γ.get(&dict.get_typeid(&"TerminatorValue".into()).expect("")).expect("cant get TerminatorValue");
+                            let ty = morph_inst.get_type().strip_halo();
+                            let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
+                            let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
+                            let terminator = encode_type_to_value(dict, terminator_value);
+
+                            let c_source = format!(r#"
+                                while( *src != {} ) {{
+                                    FUSE( {}, src, dst );
+                                    ++src;
+                                    ++dst;
+                                }}
+                                *dst = {};"#,
+                                terminator,
+                                item_morph_symbol,
+                                terminator
+                            );
+
+                            Ok(LdmcPrimMorph{
+                                symbol, type_args: Vec::new(), ty,
+                                c_source
+                            })
+                        }
+
+
+                        else {
                             eprintln!("Error: Unknown Seq- Representation!!");
                             Err(())
                         }
@@ -249,12 +337,13 @@ impl LdmcCTargetMorph {
                         let name = name.replace("-", "_").replace(".","_dot_");
                         c_source.push_str(
                             &format!("
-                                FUSE( {} ( &src->{}, &dst->{} ) );
+                                FUSE( {}, &src->{}, &dst->{} );
                             ",
                             inst.symbol,
                             name, name
                         ));
                     } else {
+                        c_source.push_str(&format!("/* ERROR: missing morphism for struct member '{}' */", name));
                         eprintln!("failed to create morphism instantiation for struct member");
                         return Err(());
                     }
@@ -271,3 +360,43 @@ impl LdmcCTargetMorph {
         }
     }
 }
+
+pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance2<LdmcPrimMorph>) -> Result<String, ()> {
+    let mut target = LdmcCTargetMorph::new();
+    let ty = morph.get_type();
+    if let Ok(inst) = target.add_instantiation(dict, morph) {
+        let mut c_source = target.into_c_source(dict);
+
+        c_source.push_str(&format!(r#"
+    #include <unistd.h>
+
+    int main() {{
+        uint8_t bufIn[4096];
+        uint8_t bufOut[4096];"#));
+
+        let (src_top, src_floor) = ty.src_type.get_floor_type();
+        if src_floor == dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
+            c_source.push_str("scanf(\"%s\", bufIn);");
+        } else {
+            c_source.push_str("read(0, bufIn, sizeof(bufIn));");
+        }
+
+        c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
+
+        if let Ok(ψ) = laddertypes::unification_sugared::subtype_unify(
+            &ty.src_type,
+            &dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
+        ) {
+            c_source.push_str("printf(\"%s\\n\", bufOut);");
+        } else {
+            c_source.push_str("write(1, bufOut, sizeof(bufOut));");
+        }
+        c_source.push_str("
+        return 0;
+    }");
+
+        Ok(c_source)
+    } else {
+        Err(())
+    }
+}
diff --git a/src/c_gen_types.rs b/src/c_gen_types.rs
index 8490ba7..0fb3b0d 100644
--- a/src/c_gen_types.rs
+++ b/src/c_gen_types.rs
@@ -227,6 +227,22 @@ pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredT
     }
 }
 
+pub fn encode_type_to_arg_ty(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm) -> String {
+    match t.get_floor_type().1 {
+        SugaredTypeTerm::Seq { seq_repr, items } => {
+
+            if let Some(seq_repr) = seq_repr {
+                if seq_repr.as_ref() == &dict.parse("<ValueTerminated 0>").expect("").sugar(dict) {
+                    return encode_type_to_symbol(dict, items.first().unwrap());
+                }
+            }
+        }
+        _=>{}
+    }
+
+    encode_type_to_symbol(dict, t)
+}
+
 pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &SugaredMorphismType) -> String {
     format!(
         "morph_{}__to_{}",
diff --git a/src/main.rs b/src/main.rs
index 7ee2bad..df68e51 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -29,8 +29,8 @@ fn main() {
         let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
         match result {
             Ok((includes, morphisms)) => {
+                println!("{}",includes);
                 eprintln!("[{}] parse ok.", mb_path.bright_yellow());
-                println!("{}", includes);
                 for m in morphisms {
                     morphism_base.add_morphism(m);
                 }
@@ -95,87 +95,7 @@ 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 struct_type1 = type_dict.parse("
-        <Struct ~ Aligned
-            <online-since          TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
-            <capacity              Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
-            <battery-charge        Energy ~ Wh ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt64 >
-            <min-sampling-period   Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
-            <cur-sampling-period   Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1000> ~ ℕ ~ native.UInt32 >
-            <max-chunk-size        ℕ ~ native.UInt32 >
-            <cur-chunk-size        ℕ ~ native.UInt32 >
-            <n-chunks-capacity     ℕ ~ native.UInt32 >
-            <n-full-data-chunks    ℕ ~ native.UInt32 >
-            <n-empty-data-chunks   ℕ ~ native.UInt32 >
-        >
-    ").expect("parse struct type");
-
-    let struct_type2 = type_dict.parse("
-        <Struct ~ Packed
-            <battery-charge        Energy ~ Wh ~ ℝ ~ native.Double >
-            <battery-capacity      Energy ~ Wh ~ ℝ ~ native.Double >
-            <min-sampling-period   Duration ~ Seconds ~ ℝ ~ native.Double >
-            <cur-sampling-period   Duration ~ Seconds ~ ℝ ~ native.Double >
-            <max-chunk-size        ℕ ~ native.UInt32 >
-            <cur-chunk-size        ℕ ~ native.UInt32 >
-            <n-chunks-capacity     ℕ ~ native.UInt32 >
-            <n-full-data-chunks    ℕ ~ native.UInt32 >
-            <n-empty-data-chunks   ℕ ~ native.UInt32 >
-            <online-since          TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ native.Double >
-        >
-    ").expect("parse struct type");
-*/
-
-/*
-    let struct_type1 = type_dict.parse("
-        RGB~<Struct
-            <red ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
-            <green ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
-            <blue ℝ ~ <QuantizedLinear 0 1 255> ~ ℕ ~ native.UInt8>
-        >
-        ").expect("parse");
-
-    let struct_type2 = type_dict.parse("
-        RGB~<Struct
-            <red ℝ ~ native.Float64>
-            <green ℝ ~ native.Float64>
-            <blue ℝ ~ native.Float64>
-        >
-    ").expect("parse");
-*/
-
     let ty = SugaredMorphismType{ src_type: src_type.sugar(&mut type_dict), dst_type: dst_type.sugar(&mut type_dict) };
-    let mut target = LdmcCTargetMorph::new();
-    target.add_instantiation(&mut type_dict, morphism_base.get_morphism_instance( &ty ).expect("cant get instance"));
-    println!("{}", target.into_c_source(&mut type_dict));
-/*
-    return;
-
-    let m = LdmcMorphism::new_struct_map(&mut type_dict, &morphism_base, struct_type1, struct_type2);
-
-    println!("{}",
-        m.into_prim_c_morphism(&mut type_dict, "morph_my_struct".into(), &HashMap::new())
-            .c_source
-    );
-
-
-return;
-    let path = laddertypes::morphism_path::ShortestPathProblem::new(
-        &morphism_base,
-        MorphismType {
-            src_type: src_type.clone(),
-            dst_type: dst_type.clone(),
-        }).solve();
-
-    match path {
-        Some(path) => {
-            c_gen::generate_main(&mut type_dict, path, src_type, dst_type);
-        }
-        None => {
-            eprintln!("Error: could not find morphism path");
-            std::process::exit(-1);
-        }
-    }
-    */
+    let m = morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism");
+    println!("{}", crate::c_gen::generate_main(&mut type_dict, m).expect("failed to generate main function"));
 }

From ef819b4711771aa1894ffee257be04f3b0e43fdf Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Thu, 3 Apr 2025 16:37:46 +0200
Subject: [PATCH 10/31] morphisms: remove 'return 0;' at end since it is now
 added by default

---
 morphisms/angle.morphism-base         | 42 +++++----------------------
 morphisms/digit.morphism-base         |  4 ---
 morphisms/length_prefix.morphism-base |  6 ----
 morphisms/posint.morphism-base        |  6 ----
 morphisms/real.morphism-base          | 41 +++++++++-----------------
 morphisms/temperature.morphism-base   | 20 +++----------
 morphisms/timepoint.morphism-base     |  1 -
 morphisms/uint.morphism-base          | 17 +++++++++++
 morphisms/unicode.morphism-base       |  4 ---
 morphisms/value_delim.morphism-base   |  6 ----
 morphisms/zigzag.morphism-base        |  2 --
 11 files changed, 42 insertions(+), 107 deletions(-)
 create mode 100644 morphisms/uint.morphism-base

diff --git a/morphisms/angle.morphism-base b/morphisms/angle.morphism-base
index 5fa3baf..e678dde 100644
--- a/morphisms/angle.morphism-base
+++ b/morphisms/angle.morphism-base
@@ -5,68 +5,42 @@
 morph_angle_as_degrees_to_turns_float ()
     Angle ~ Degrees ~ ℝ ~ native.Float32
 --> Angle ~ Turns ~ ℝ ~ native.Float32
-```
-    *dst = *src / 360.0;
-    return 0;
-```
+```*dst = *src / 360.0;```
 
 morph_angle_as_degrees_to_turns_double ()
     Angle ~ Degrees ~ ℝ ~ native.Float64
 --> Angle ~ Turns ~ ℝ ~ native.Float64
-```
-    *dst = *src / 360.0;
-    return 0;
-```
+```*dst = *src / 360.0;```
 
 
 morph_angle_as_turns_to_degrees_float ()
     Angle ~ Turns ~ ℝ ~ native.Float32
 --> Angle ~ Degrees ~ ℝ ~ native.Float32
-```
-    *dst = *src * 360.0;
-    return 0;
-```
+```*dst = *src * 360.0;```
 
 morph_angle_as_turns_to_degrees_double ()
     Angle ~ Turns ~ ℝ ~ native.Float64
 --> Angle ~ Degrees ~ ℝ ~ native.Float64
-```
-    *dst = *src * 360.0;
-    return 0;
-```
-
-
+```*dst = *src * 360.0;```
 
 
 morph_angle_as_radians_to_turns_float ()
     Angle ~ Radians ~ ℝ ~ native.Float32
 --> Angle ~ Turns ~ ℝ ~ native.Float32
-```
-    *dst = *src / PHI;
-    return 0;
-```
+```*dst = *src / PHI;```
 
 morph_angle_as_radians_to_turns_double ()
     Angle ~ Radians ~ ℝ ~ native.Float64
 --> Angle ~ Turns ~ ℝ ~ native.Float64
-```
-    *dst = *src / PHI;
-    return 0;
-```
+```*dst = *src / PHI;```
 
 
 morph_angle_as_turns_to_radians_float ()
     Angle ~ Turns ~ ℝ ~ native.Float32
 --> Angle ~ Radians ~ ℝ ~ native.Float32
-```
-    *dst = *src * PHI;
-    return 0;
-```
+```*dst = *src * PHI;```
 
 morph_angle_as_degrees_to_radians_double ()
     Angle ~ Turns ~ ℝ ~ native.Float64
 --> Angle ~ Radians ~ ℝ ~ native.Float64
-```
-    *dst = *src * PHI;
-    return 0;
-```
+```*dst = *src * PHI;```
diff --git a/morphisms/digit.morphism-base b/morphisms/digit.morphism-base
index a92fe61..f037823 100644
--- a/morphisms/digit.morphism-base
+++ b/morphisms/digit.morphism-base
@@ -60,8 +60,6 @@ morph_digit_as_uint8_to_char (Radix:ℤ_16)
         fprintf(stderr, "digit %u is out of rage for char\n", *dst);
         return -1;
     }
-
-    return 0;
 ```
 
 morph_digit_as_uint64_to_char (Radix:ℤ_16)
@@ -76,6 +74,4 @@ morph_digit_as_uint64_to_char (Radix:ℤ_16)
         fprintf(stderr, "digit %u is out of rage for char\n", *dst);
         return -1;
     }
-
-    return 0;
 ```
diff --git a/morphisms/length_prefix.morphism-base b/morphisms/length_prefix.morphism-base
index 6718c16..1a1b7f5 100644
--- a/morphisms/length_prefix.morphism-base
+++ b/morphisms/length_prefix.morphism-base
@@ -10,8 +10,6 @@ morph_array_as_valterm_to_lenpfx (Terminator:native.UInt8)
     length_prefix_uint64_t_array_uint8_t_clear(dst);
     while( *src != Terminator )
         length_prefix_uint64_t_array_uint8_t_push(dst, *src++);
-
-    return 0;
 ```
 
 
@@ -23,8 +21,6 @@ morph_array_as_lenpfx_to_valterm (Terminator:native.UInt8)
         *dst++ = src->items[i];
 
     *dst = Terminator;
-
-    return 0;
 ```
 
 morph_array_as_lenpfx_to_continuation_bit (T:Type)
@@ -42,6 +38,4 @@ morph_array_as_lenpfx_to_continuation_bit (T:Type)
         if( i+1 < src->len )
             dst[i] |= (1<<(n_bits-1));
     }
-
-    return 0;
 ```
diff --git a/morphisms/posint.morphism-base b/morphisms/posint.morphism-base
index 194399b..01248eb 100644
--- a/morphisms/posint.morphism-base
+++ b/morphisms/posint.morphism-base
@@ -11,7 +11,6 @@ morph_nat_as_u64_to_pos ()
 ```
     dst->len = 1;
     dst->items[0] = *src;
-    return 0;
 ```
 
 morph_nat_as_pos_to_u64 (Endianness:Type)
@@ -22,7 +21,6 @@ morph_nat_as_pos_to_u64 (Endianness:Type)
     ~ native.UInt64
 ```
     *dst = src->items[0];
-    return 0;
 ```
 
 morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
@@ -52,8 +50,6 @@ morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
             value /= DstRadix;
         }
     #endif
-
-    return 0;
 ```
 
 morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
@@ -91,8 +87,6 @@ morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
             value /= DstRadix;
         }
     #endif
-
-    return 0;
 ```
 
 morph_posint_endianness (Radix:ℤ)
diff --git a/morphisms/real.morphism-base b/morphisms/real.morphism-base
index 4add278..5b5b2f7 100644
--- a/morphisms/real.morphism-base
+++ b/morphisms/real.morphism-base
@@ -5,43 +5,27 @@
 morph_real_as_decimalstr_to_float ()
     ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
 --> ℝ ~ native.Float32
-```
-    sscanf(src, "%f", dst);
-    return 0;
-```
+```sscanf(src, "%f", dst);```
 
 morph_real_as_decimalstr_to_double ()
     ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
 --> ℝ ~ native.Float64
-```
-    sscanf(src, "%lf", dst);
-    return 0;
-```
+```sscanf(src, "%lf", dst);```
 
 morph_real_as_float_to_decimalstr ()
     ℝ ~ native.Float32
 --> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
-```
-    sprintf(dst, "%f", *src);
-    return 0;
-```
+```sprintf(dst, "%f", *src);```
 
 morph_real_as_double_to_decimalstr ()
     ℝ ~ native.Float64
 --> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
-```
-    sprintf(dst, "%f", *src);
-    return 0;
-```
-
+```sprintf(dst, "%f", *src);```
 
 morph_real_as_float_to_double ()
     ℝ ~ native.Float32
 --> ℝ ~ native.Float64
-```
-    *dst = *src;
-    return 0;
-```
+```*dst = *src;```
 
 morph_real_as_double_to_float ()
     ℝ ~ native.Float64
@@ -49,7 +33,6 @@ morph_real_as_double_to_float ()
 ```
     fprintf(stderr, "Warning: morphin Double -> Float. Precision loss!");
     *dst = *src;
-    return 0;
 ```
 
 morph_real_as_u64_to_float ()
@@ -58,7 +41,6 @@ morph_real_as_u64_to_float ()
 ```
     fprintf(stderr, "Warning: morphin UInt64 -> Float. Precision loss!");
     *dst = *src;
-    return 0;
 ```
 
 morph_real_as_u64_to_double ()
@@ -67,7 +49,14 @@ morph_real_as_u64_to_double ()
 ```
     fprintf(stderr, "Warning: morphin UInt64 -> Double. Precision loss!");
     *dst = *src;
-    return 0;
+```
+
+
+morph_real_as_nat_to_quantized_linear ()
+     ℝ ~ ℕ ~ native.UInt64
+-->  ℝ ~ <QuantizedLinear 0 1 1> ~ ℕ ~ native.UInt64
+```
+    *dst = *src;
 ```
 
 morph_real_as_quantized_linear_to_float (Begin: ℝ, End: ℝ, Steps: ℤ)
@@ -75,7 +64,6 @@ morph_real_as_quantized_linear_to_float (Begin: ℝ, End: ℝ, Steps: ℤ)
 --> ℝ ~ native.Float32
 ```
     *dst = (float)Begin  +  ( *src * ((float)End - (float)Begin) ) / (float)Steps;
-    return 0;
 ```
 
 morph_real_as_float_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
@@ -83,7 +71,6 @@ morph_real_as_float_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
 --> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
 ```
     *dst = ((*src - (float)Begin) * (float)Steps) / ((float)End - (float)Begin);
-    return 0;
 ```
 
 
@@ -93,7 +80,6 @@ morph_real_as_quantized_linear_to_double (Begin: ℝ, End: ℝ, Steps: ℤ)
 --> ℝ ~ native.Float64
 ```
     *dst = (double)Begin  +  ( *src * ((double)End - (double)Begin) ) / (double)Steps;
-    return 0;
 ```
 
 morph_real_as_double_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
@@ -101,5 +87,4 @@ morph_real_as_double_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
 --> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
 ```
     *dst = ((*src - (double)Begin) * (double)Steps) / ((double)End - (double)Begin);
-    return 0;
 ```
diff --git a/morphisms/temperature.morphism-base b/morphisms/temperature.morphism-base
index 6c682bc..329a6b0 100644
--- a/morphisms/temperature.morphism-base
+++ b/morphisms/temperature.morphism-base
@@ -4,31 +4,19 @@
 morph_celsius_to_kelvin ()
       Temperature ~ Celsius ~ ℝ ~ native.Float32
 -->   Temperature ~ Kelvin ~ ℝ ~ native.Float32
-```
-    *dst = *src + 273.15;
-    return 0;
-```
+```*dst = *src + 273.15;```
 
 morph_kelvin_to_celsius ()
       Temperature ~ Kelvin ~ ℝ ~ native.Float32
 -->   Temperature ~ Celsius ~ ℝ ~ native.Float32
-```
-    *dst = *src - 273.15;
-    return 0;
-```
+```*dst = *src - 273.15;```
 
 morph_celsius_to_fahrenheit ()
       Temperature ~ Celsius ~ ℝ ~ native.Float32
 -->   Temperature ~ Fahrenheit ~ ℝ ~ native.Float32
-```
-    *dst = (*src * 9.0 / 5.0) + 32.0;
-    return 0;
-```
+```*dst = (*src * 9.0 / 5.0) + 32.0;```
 
 morph_fahrenheit_to_celsius ()
       Temperature ~ Fahrenheit ~ ℝ ~ native.Float32
 -->   Temperature ~ Celsius ~ ℝ ~ native.Float32
-```
-    *dst = (*src - 32.0) * 5.0 / 9.0;
-    return 0;
-```
+```*dst = (*src - 32.0) * 5.0 / 9.0;```
diff --git a/morphisms/timepoint.morphism-base b/morphisms/timepoint.morphism-base
index bb66aec..505ed37 100644
--- a/morphisms/timepoint.morphism-base
+++ b/morphisms/timepoint.morphism-base
@@ -11,5 +11,4 @@ morph_unixtime_to_iso ()
     if (!timeinfo) return -1;
 
     strftime((char*)dst, 20, "%Y-%m-%dT%H:%M:%SZ", timeinfo);
-    return 0;
 ```
diff --git a/morphisms/uint.morphism-base b/morphisms/uint.morphism-base
new file mode 100644
index 0000000..89f8f79
--- /dev/null
+++ b/morphisms/uint.morphism-base
@@ -0,0 +1,17 @@
+```
+```
+
+morph_nat_as_u8_to_u16 ()
+      ℕ ~ native.UInt8
+-->   ℕ ~ native.UInt16
+```*dst = *src;```
+
+morph_nat_as_u16_to_u32 ()
+      ℕ ~ native.UInt16
+-->   ℕ ~ native.UInt32
+```*dst = *src;```
+
+morph_nat_as_u32_to_u64 ()
+      ℕ ~ native.UInt32
+-->   ℕ ~ native.UInt64
+```*dst = *src;```
diff --git a/morphisms/unicode.morphism-base b/morphisms/unicode.morphism-base
index c2854e5..659357b 100644
--- a/morphisms/unicode.morphism-base
+++ b/morphisms/unicode.morphism-base
@@ -28,7 +28,6 @@ morph_string_as_utf8_to_ascii ()
         }
     }
     *dst = 0;
-    return 0;
 ```
 
 morph_string_as_ascii_to_utf32 ()
@@ -39,7 +38,6 @@ morph_string_as_ascii_to_utf32 ()
 ```
     while( *src ) { *dst++ = *src++; }
     *dst = 0;
-    return 0;
 ```
 
 morph_string_as_utf8_to_utf32 ()
@@ -89,6 +87,4 @@ morph_string_as_utf8_to_utf32 ()
         *dst++ = val;
 
     *dst++ = 0;
-
-    return 0;
 ```
diff --git a/morphisms/value_delim.morphism-base b/morphisms/value_delim.morphism-base
index a370682..ab66310 100644
--- a/morphisms/value_delim.morphism-base
+++ b/morphisms/value_delim.morphism-base
@@ -27,8 +27,6 @@ morph_seqseq_valsep_uint8 (T: Type, SrcDelim: T, DstDelim: T)
             length_prefix_uint64_t_array_uint8_t_push( dst, src->items[i] );
         }
     }
-
-    return 0;
 ```
 
 
@@ -66,8 +64,6 @@ morph_seqseq_as_valsep_to_lenpfx (T: Type, Delim: T, EscKey: T)
             cur++;
         }
     }
-
-    return 0;
 ```
 
 morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
@@ -94,6 +90,4 @@ morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
             length_prefix_uint64_t_array_uint8_t_push( Delim );
         }
     }
-
-    return 0;
 ```
diff --git a/morphisms/zigzag.morphism-base b/morphisms/zigzag.morphism-base
index 5a293e2..4196e72 100644
--- a/morphisms/zigzag.morphism-base
+++ b/morphisms/zigzag.morphism-base
@@ -10,8 +10,6 @@ morph_i64_as_twos_complement_to_zigzag ()
     } else {
         *dst = (2 * (uint64_t)(- *src)) - 1;
     }
-
-    return 0;
 ```
 
 morph_i64_as_zigzag_to_twos_complement ()

From 6787e607a67dd30482b963660a9a15a34e2d5d96 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Thu, 1 May 2025 06:38:17 +0200
Subject: [PATCH 11/31] wip

---
 .../runtime/include/array/length-prefix.h     |  61 +----
 src/c_gen.rs                                  | 223 +++++++++++-------
 src/c_gen_types.rs                            | 148 ++++++------
 src/main.rs                                   |   7 +-
 src/morphism.rs                               | 170 +------------
 src/parser.rs                                 |   8 +-
 src/struct_layout.rs                          |  44 ++--
 7 files changed, 240 insertions(+), 421 deletions(-)

diff --git a/morphisms/runtime/include/array/length-prefix.h b/morphisms/runtime/include/array/length-prefix.h
index 35a4aec..3f039f2 100644
--- a/morphisms/runtime/include/array/length-prefix.h
+++ b/morphisms/runtime/include/array/length-prefix.h
@@ -7,22 +7,22 @@
     typedef struct {                                                           \
         LEN_TYPE len;                                                          \
         ITEM_TYPE items[];                                                     \
-    } LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE;                             \
+    } __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_;                             \
                                                                                \
     static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_clear(   \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data) {                   \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data) {                   \
         data->len = 0;                                                         \
     }                                                                          \
                                                                                \
     static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_push(    \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data,                     \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data,                     \
         ITEM_TYPE value) {                                                     \
         data->items[data->len++] = value;                                      \
     }                                                                          \
                                                                                \
     static inline int length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_reverse(  \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE const * restrict src,      \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *restrict dst) {           \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * restrict src,      \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *restrict dst) {           \
         for (LEN_TYPE i = 0; i < src->len; i++) {                              \
             dst->items[i] = src->items[src->len - 1 - i];                      \
         }                                                                      \
@@ -31,59 +31,10 @@
     }                                                                          \
                                                                                \
     static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_dump(    \
-        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE const * data) {            \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * data) {            \
         printf("Length: %llu\n", (unsigned long long) data->len);              \
         for (LEN_TYPE i = 0; i < data->len; i++) {                             \
             printf("%llu ", (unsigned long long) data->items[i]);              \
         }                                                                      \
         printf("\n");                                                          \
     }
-
-#define DEFINE_ALL_LENGTH_PREFIX_ARRAYS(LEN_TYPE)  \
-    DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint8_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint16_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint32_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint64_t)
-
-DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint8_t)
-DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint16_t)
-DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint32_t)
-DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint64_t)
-
-
-#define DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, SRC_ITEM_TYPE, DST_ITEM_TYPE) \
-    static inline int length_prefix_##LEN_TYPE##_array_map_##SRC_ITEM_TYPE##_to_##DST_ITEM_TYPE( \
-        int (*f)(SRC_ITEM_TYPE const * restrict, DST_ITEM_TYPE * restrict),    \
-        LengthPrefix_##LEN_TYPE##_Array_##SRC_ITEM_TYPE const * restrict src,  \
-        LengthPrefix_##LEN_TYPE##_Array_##DST_ITEM_TYPE * restrict dst)        \
-    {                                                                          \
-        if (dst->len < src->len) return -1; /* Ensure enough space */          \
-        for (LEN_TYPE i = 0; i < src->len; i++) {                              \
-            if (f(&src->items[i], &dst->items[i]) != 0) return -1;             \
-        }                                                                      \
-        dst->len = src->len;                                                   \
-        return 0;                                                              \
-    }
-
-#define DEFINE_ALL_MAPS(LEN_TYPE)                        \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint8_t)   \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint16_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint32_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint64_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint8_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint16_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint32_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint64_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint8_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint16_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint32_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint64_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint8_t)  \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint16_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint32_t) \
-    DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint64_t)
-
-DEFINE_ALL_MAPS(uint8_t)
-DEFINE_ALL_MAPS(uint16_t)
-DEFINE_ALL_MAPS(uint32_t)
-DEFINE_ALL_MAPS(uint64_t)
diff --git a/src/c_gen.rs b/src/c_gen.rs
index 41d1c99..0f21ef8 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -1,9 +1,16 @@
 use {
-    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_arg_ty, encode_type_to_symbol, encode_type_to_value, get_c_repr_type}, morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::{chain::Chain, primitive::Container}, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}, std::collections::HashMap
+    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_value, get_c_repr_arg_type,
+        get_c_repr_definition, get_c_repr_type}, morphism::LdmcPrimMorph,
+    struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}},
+    chumsky::{chain::Chain, primitive::Container},
+    laddertypes::{morphism::{MorphismInstance, Morphism, MorphismType},
+        parser::*, substitution::Substitution, unparser::*,
+        EnumVariant, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm},
+    std::collections::HashMap
 };
 
 impl LdmcPrimMorph {
-    pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> String {
+    pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> String {
         let mut s = self.symbol.clone();
         for (k_id,v) in self.type_args.iter() {
 
@@ -14,7 +21,7 @@ impl LdmcPrimMorph {
                         //self.get_type().strip_halo().dst_type.contains_var(*var_id) {
 
                             let name = dict.get_varname(*var_id).unwrap();
-                            let val_str = encode_type_to_symbol(dict, &val_trm);
+                            let val_str = get_c_repr_type(dict, &val_trm);
                             s.push_str(&format!("_{}_{}", name, val_str));
 
                             //}
@@ -31,20 +38,26 @@ impl LdmcPrimMorph {
     }
 
     pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
-        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::SugaredTypeTerm>
+        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>
     ) -> String {
         format!("int {} ({} const * restrict src, {} * restrict dst);",
             self.instantiated_symbol_name(dict, σ),
-            get_c_repr_type(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
-            get_c_repr_type(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
+            get_c_repr_definition(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
+            get_c_repr_definition(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
     }
 
-    pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl SugaredSubstitution) -> Option<String> {
+    pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> Option<String> {
         let mut s = String::new();
         let symbol = self.instantiated_symbol_name(dict, σ);
 
-        let src_c_symbol = encode_type_to_arg_ty(dict, &self.ty.strip_halo().src_type.clone().apply_subst(σ).get_floor_type().1);
-        let dst_c_symbol = encode_type_to_arg_ty(dict, &self.ty.strip_halo().dst_type.clone().apply_subst(σ).get_floor_type().1);
+        eprintln!("generate instantiation:");
+        let ty = self.ty.clone();
+        eprintln!("full type: {}   ---->    {}", ty.src_type.pretty(dict, 0),  ty.dst_type.pretty(dict,0));
+        let ty = ty.strip_halo().apply_subst(σ);
+        eprintln!("stripped type:  {}   ---->    {}", ty.src_type.pretty(dict, 0),  ty.dst_type.pretty(dict,0));
+
+        let src_c_symbol = get_c_repr_arg_type(dict, &ty.src_type);
+        let dst_c_symbol = get_c_repr_arg_type(dict, &ty.dst_type);
 
         s.push_str(&format!(r#"
 int {} ( {} const * restrict src, {} * restrict dst ) {{
@@ -66,8 +79,9 @@ int {} ( {} const * restrict src, {} * restrict dst ) {{
 
 pub struct LdmcCTargetMorph {
     includes: Vec< String >,
-    active_types: Vec< SugaredTypeTerm >,
+    active_types: Vec< TypeTerm >,
     active_instantiations: Vec< LdmcPrimMorph >,
+    macro_calls: Vec< String >
 }
 
 impl LdmcCTargetMorph {
@@ -75,18 +89,42 @@ impl LdmcCTargetMorph {
         LdmcCTargetMorph {
             includes: vec![
                 "#include <stdint.h>".into(),
+                "#include <array/length-prefix.h>".into(),
                 "#define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; }".into(),
             ],
             active_instantiations: Vec::new(),
             active_types: Vec::new(),
+            macro_calls: Vec::new()
         }
     }
 
-    pub fn add_type(&mut self, ty: SugaredTypeTerm) {
+    pub fn add_type(&mut self, dict: &mut impl TypeDict, ty: TypeTerm) {
+        let ty = ty.strip();
         if ! self.active_types.contains(&ty) {
+            eprintln!("add type {:?}", ty);
             match &ty {
-                SugaredTypeTerm::Seq { seq_repr, items } =>{
-                    self.add_type(items.first().unwrap().clone());
+                TypeTerm::Seq { seq_repr, items } =>{
+                    let item_type = items.first().unwrap().clone();
+                    self.add_type(dict, item_type.clone());
+
+                    if let Some(seq_repr) = seq_repr {
+                        dict.add_varname("LengthType".into());
+                        if let Ok(σ) =
+                            laddertypes::constraint_system::unify(
+                                seq_repr.as_ref(),
+                                &dict.parse_desugared("<LengthPrefix LengthType>").expect("").sugar(dict)
+                            )
+                        {
+                            let length_type = σ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get Length type");
+                            self.add_type(dict, length_type.clone());
+                            self.macro_calls.push(
+                                format!("DEFINE_LENGTH_PREFIX_ARRAY({}, {})\n",
+                                    get_c_repr_type(dict, &length_type),
+                                    get_c_repr_type(dict, &item_type)
+                                )
+                            );
+                        }
+                    }
                 }
                 _=>{}
             }
@@ -97,7 +135,7 @@ impl LdmcCTargetMorph {
     pub fn add_instantiation(
         &mut self,
         dict: &mut impl TypeDict,
-        morph: MorphismInstance2<LdmcPrimMorph>,
+        morph: MorphismInstance<LdmcPrimMorph>,
     ) -> Result<LdmcPrimMorph, ()> {
         let new_inst = self.bake_morphism(dict, morph)?;
         if ! self.active_instantiations.contains(&new_inst) {
@@ -105,44 +143,58 @@ impl LdmcCTargetMorph {
         }
 
         let ty = new_inst.get_type().strip_halo();
-        self.add_type(ty.src_type.get_floor_type().1);
-        self.add_type(ty.dst_type.get_floor_type().1);
+        self.add_type(dict, ty.src_type);
+        self.add_type(dict, ty.dst_type);
 
         Ok(new_inst)
     }
 
-    pub fn into_c_source(self, dict: &mut impl TypeDict) -> String {
+    pub fn into_c_source(mut self, dict: &mut impl TypeDict) -> String {
         let mut source = String::new();
+        self.includes.dedup();
+        self.macro_calls.dedup();
+        self.active_types.dedup();
+
         for inc in self.includes {
             source.push_str(&inc);
             source.push('\n');
         }
 
+        source.push('\n');
+
         for ty in self.active_types {
-            source.push_str(&format!("
-    typedef {} {};
-",
-                get_c_repr_type(dict, ty.clone(), false).expect(&format!("cant get c-repr type for type '{}'", ty.pretty(dict,0))),
-                encode_type_to_symbol(dict, &ty)));
+            if let Some(type_def) = get_c_repr_definition(dict, ty.clone(), false) {
+                let type_name = get_c_repr_type(dict, &ty);
+                source.push_str(&format!("typedef {} {};\n", type_def, type_name));
+            } else {
+                eprintln!("cant get c-repr type for type '{}'", ty.pretty(dict,0));
+            }
         }
+        source.push('\n');
+
+
+        for m in self.macro_calls {
+            source.push_str(&m);
+            source.push('\n');
+        }
+        source.push('\n');
 
         for m in self.active_instantiations {
             source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
         }
-
         source
     }
 
     pub fn bake_morphism(
         &mut self,
         dict: &mut impl laddertypes::TypeDict,
-        morph_inst: MorphismInstance2<LdmcPrimMorph>,
+        morph_inst: MorphismInstance<LdmcPrimMorph>,
     ) -> Result<LdmcPrimMorph, ()> {
-        eprintln!("bake morphism:  {}
-  ------> {}", morph_inst.get_haloless_type().src_type.pretty(dict,0), morph_inst.get_haloless_type().dst_type.pretty(dict, 0));
+        let ty = morph_inst.get_type();
+        let symbol = encode_morph_type_to_symbol(dict, &ty);
 
         match &morph_inst {
-            MorphismInstance2::Primitive { ψ, σ, morph } => {
+            MorphismInstance::Primitive { ψ, σ, morph } => {
                 let mut c_source = String::new();
                 for (ty_id, kind) in morph.type_args.iter() {
                     if let laddertypes::TypeID::Var(var_id) = ty_id {
@@ -150,7 +202,7 @@ impl LdmcCTargetMorph {
                         //morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
                             if let Some(val) = σ.get(ty_id) {
                                 let type_var_value =
-                                    if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
+                                    if let Some(c_repr_type) = get_c_repr_definition(dict, val.clone(), true) {
                                         c_repr_type
                                     } else {
                                         encode_type_to_value(dict, &val)
@@ -179,10 +231,7 @@ impl LdmcCTargetMorph {
                     c_source
                 })
             },
-            MorphismInstance2::Chain { path } => {
-                let ty = morph_inst.get_type().strip_halo();
-                let symbol = encode_morph_type_to_symbol(dict, &ty);
-
+            MorphismInstance::Chain { path } => {
                 let mut c_source = String::new();
 
                 if path.len() > 1 {
@@ -195,8 +244,8 @@ impl LdmcCTargetMorph {
                 for (i,morph) in path.iter().enumerate() {
                     if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
                         let morph_symbol = inst.instantiated_symbol_name(dict, &morph.get_subst());
-                        let src_buf = if i == 0 { "src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
-                        let dst_buf = if i+1 == path.len() { "dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
+                        let src_buf = if i == 0 { "(void*)src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
+                        let dst_buf = if i+1 == path.len() { "(void*)dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
 
                         c_source.push_str(&format!(r#"
         FUSE( {}, {}, {} );"#,
@@ -213,30 +262,28 @@ impl LdmcCTargetMorph {
                     c_source
                 })
             }
-            MorphismInstance2::MapSeq { ψ, seq_repr, item_morph } => {
+            MorphismInstance::MapSeq { ψ, seq_repr, item_morph } => {
                 if let Ok(item_morph_inst) = self.add_instantiation(dict, item_morph.as_ref().clone()) {
                     if let Some(seq_repr) = seq_repr {
                         dict.add_varname("Length".into());
                         dict.add_varname("LengthType".into());
                         dict.add_varname("TerminatorValue".into());
 
-                        if let Ok(γ) = laddertypes::unification_sugared::unify(
-                            &dict.parse("<StaticLength Length>").expect("parse type template").sugar(dict),
+                        if let Ok(γ) = laddertypes::constraint_system::unify(
+                            &dict.parse_desugared("<StaticLength Length>").expect("parse type template").sugar(dict),
                             seq_repr.as_ref()
                         ) {
                             let length = γ.get(&dict.get_typeid(&"Length".into()).expect("")).expect("cant get Length");
                             match length {
-                                SugaredTypeTerm::Num(l) => {
-                                    let ty = morph_inst.get_type().strip_halo();
-                                    let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_type());
+                                TypeTerm::Num(l) => {
                                     let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
 
-                                    self.add_type( morph_inst.get_type().strip_halo().src_type );
-                                    self.add_type( morph_inst.get_type().strip_halo().dst_type );
+                                    self.add_type( dict, morph_inst.get_type().strip_halo().src_type );
+                                    self.add_type( dict, morph_inst.get_type().strip_halo().dst_type );
 
                                     let c_source = format!(r#"
                                         for( size_t i = 0; i < {}; ++i ) {{
-                                            FUSE( {}, &src[i], &dst[i] );
+                                            FUSE( {}, &src->items[i], &dst->items[i] );
                                         }}
                                         "#,
                                         l,
@@ -255,19 +302,16 @@ impl LdmcCTargetMorph {
                             }
                         }
 
-                        else if let Ok(γ) = laddertypes::unification_sugared::unify(
-                            &dict.parse("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
+                        else if let Ok(γ) = laddertypes::constraint_system::unify(
+                            &dict.parse_desugared("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
                             seq_repr.as_ref()
                         ) {
                             // todo: assert that length type is native.UIntX
                             //let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
-
-                            let ty = morph_inst.get_type().strip_halo();
-                            let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_type());
                             let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
 
-                            self.add_type( morph_inst.get_type().strip_halo().src_type );
-                            self.add_type( morph_inst.get_type().strip_halo().dst_type );
+                            self.add_type( dict, morph_inst.get_type().strip_halo().src_type );
+                            self.add_type( dict, morph_inst.get_type().strip_halo().dst_type );
 
                             let c_source = format!(r#"
                                 for( size_t i = 0; i < src->len; ++i ) {{
@@ -284,13 +328,11 @@ impl LdmcCTargetMorph {
                             })
                         }
 
-                        else if let Ok(γ) = laddertypes::unification_sugared::unify(
-                            &dict.parse("<ValueTerminated TerminatorValue>").expect("parse type template").sugar(dict),
+                        else if let Ok(γ) = laddertypes::constraint_system::unify(
+                            &dict.parse_desugared("<ValueTerminated TerminatorValue>").expect("parse type template").sugar(dict),
                             seq_repr.as_ref()
                         ) {
                             let terminator_value = γ.get(&dict.get_typeid(&"TerminatorValue".into()).expect("")).expect("cant get TerminatorValue");
-                            let ty = morph_inst.get_type().strip_halo();
-                            let symbol = encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
                             let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
                             let terminator = encode_type_to_value(dict, terminator_value);
 
@@ -326,9 +368,7 @@ impl LdmcCTargetMorph {
                     Err(())
                 }
             },
-            MorphismInstance2::MapStruct { ψ, struct_repr, member_morph } => {
-                let ty = morph_inst.get_type().strip_halo();
-                let symbol =encode_morph_type_to_symbol(dict, &morph_inst.get_haloless_type());
+            MorphismInstance::MapStruct { ψ, src_struct_repr, dst_struct_repr, member_morph } => {
 
                 let mut c_source = String::new();
 
@@ -337,8 +377,7 @@ impl LdmcCTargetMorph {
                         let name = name.replace("-", "_").replace(".","_dot_");
                         c_source.push_str(
                             &format!("
-                                FUSE( {}, &src->{}, &dst->{} );
-                            ",
+        FUSE( {}, &src->{}, &dst->{} );",
                             inst.symbol,
                             name, name
                         ));
@@ -354,49 +393,53 @@ impl LdmcCTargetMorph {
                     c_source
                 })
             }
-            MorphismInstance2::MapEnum { ψ, enum_repr, variant_morph } => {
+            MorphismInstance::MapEnum { ψ, enum_repr, variant_morph } => {
                 todo!();
             }
         }
     }
 }
 
-pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance2<LdmcPrimMorph>) -> Result<String, ()> {
+pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance<LdmcPrimMorph>) -> Result<String, ()> {
     let mut target = LdmcCTargetMorph::new();
     let ty = morph.get_type();
-    if let Ok(inst) = target.add_instantiation(dict, morph) {
-        let mut c_source = target.into_c_source(dict);
+    match target.add_instantiation(dict, morph) {
+        Ok(inst) => {
+            let mut c_source = target.into_c_source(dict);
 
-        c_source.push_str(&format!(r#"
-    #include <unistd.h>
+            c_source.push_str(&format!(r#"
+        #include <unistd.h>
 
-    int main() {{
-        uint8_t bufIn[4096];
-        uint8_t bufOut[4096];"#));
+        int main() {{
+            uint8_t bufIn[4096];
+            uint8_t bufOut[4096];"#));
 
-        let (src_top, src_floor) = ty.src_type.get_floor_type();
-        if src_floor == dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
-            c_source.push_str("scanf(\"%s\", bufIn);");
-        } else {
-            c_source.push_str("read(0, bufIn, sizeof(bufIn));");
+            let (src_top, src_floor) = ty.src_type.get_floor_type();
+            if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
+                c_source.push_str("scanf(\"%s\", bufIn);");
+            } else {
+                c_source.push_str("read(0, bufIn, sizeof(bufIn));");
+            }
+
+            c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
+
+            if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
+                &ty.src_type,
+                &dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
+            ) {
+                c_source.push_str("printf(\"%s\\n\", bufOut);");
+            } else {
+                c_source.push_str("write(1, bufOut, sizeof(bufOut));");
+            }
+            c_source.push_str("
+            return 0;
+        }");
+
+            Ok(c_source)
         }
-
-        c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
-
-        if let Ok(ψ) = laddertypes::unification_sugared::subtype_unify(
-            &ty.src_type,
-            &dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
-        ) {
-            c_source.push_str("printf(\"%s\\n\", bufOut);");
-        } else {
-            c_source.push_str("write(1, bufOut, sizeof(bufOut));");
+        Err(err) => {
+            eprintln!("failed to create morphism instatiation");
+            Err(())
         }
-        c_source.push_str("
-        return 0;
-    }");
-
-        Ok(c_source)
-    } else {
-        Err(())
     }
 }
diff --git a/src/c_gen_types.rs b/src/c_gen_types.rs
index 0fb3b0d..8c366bb 100644
--- a/src/c_gen_types.rs
+++ b/src/c_gen_types.rs
@@ -1,5 +1,9 @@
 use {
-    crate::{morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}}, chumsky::chain::Chain, laddertypes::{morphism::{Morphism, MorphismInstance}, morphism_sugared::{MorphismInstance2, SugaredMorphismType}, parser::*, substitution_sugared::SugaredSubstitution, unparser::*, Substitution, SugaredEnumVariant, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm}
+    crate::{morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}},
+    chumsky::chain::Chain, laddertypes::{morphism::{MorphismInstance, MorphismType},
+        parser::*,
+        substitution::Substitution,
+        unparser::*, EnumVariant, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm}, std::thread::yield_now
 };
 
 /*
@@ -13,9 +17,9 @@ pub fn get_c_repr_kind(kind: String) -> Option<String> {
 
 /* for a given ladder type `t`, get the corresponding C type
  */
-pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointer: bool) -> Option<String> {
-    match t.get_floor_type().1.strip() {
-        SugaredTypeTerm::TypeID(tyid) => {
+pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer: bool) -> Option<String> {
+    match t {
+        TypeTerm::TypeID(tyid) => {
             if tyid == dict.get_typeid_creat("native.UInt8") {
                 Some("uint8_t".into())
             } else if tyid == dict.get_typeid_creat("native.UInt16") {
@@ -35,20 +39,18 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
             }
         }
 
-        SugaredTypeTerm::Seq{ seq_repr, items } => {
-            if let Some(sr_sugar) = seq_repr {
-                let sr = sr_sugar.desugar(dict);
-
+        TypeTerm::Seq{ seq_repr, items } => {
+            if let Some(seq_repr) = seq_repr {
                 let item_type = items.first().expect("no item type specified!").clone();
-                let item_c_type : String = get_c_repr_type(dict, item_type, false).expect("cant get item type representation");
+                let item_c_type : String = get_c_repr_type(dict, &item_type);
 
                 dict.add_varname("Length".into()); // Kind: Num
                 dict.add_varname("LengthType".into()); // Kind: Type
                 dict.add_varname("TermValue".into()); // Kind: Value of Type ItemType
 
-                if let Ok(σ) = laddertypes::unify(
-                    &sr,
-                    &dict.parse("<StaticLength Length>").expect("parse")
+                if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr.as_ref(),
+                    &dict.parse_desugared("<StaticLength Length>").expect("parse template type").sugar(dict)
                 ) {
                     let length = match
                         σ.get(
@@ -61,46 +63,23 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
                             return None;
                         }
                     };
-                    Some(format!("{}[{}]", item_c_type, length))
+                    Some(format!("struct {{ {} items[{}]; }} ", item_c_type, length))
                 }
-                else if let Ok(σ) = laddertypes::unify(
-                    &sr,
-                    &dict.parse("<LengthPrefix LengthType>").expect("parse")
+                else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr.as_ref(),
+                    &dict.parse_desugared("<LengthPrefix LengthType>").expect("parse template type").sugar(dict)
                 ) {
                     let length_type = σ.get(
                             &dict.get_typeid(&"LengthType".into()).expect("no LengthType ID")
-                        ).expect("no length type specified")
-                        .clone()
-                        .sugar(dict);
-                    let length_c_type : String = get_c_repr_type(dict, length_type, false).expect("cant get length type representation");
+                        ).expect("no length type specified");
 
-                    match length_c_type.as_str() {
-                        "uint8_t" |
-                        "uint16_t" |
-                        "uint32_t" |
-                        "uint64_t" => {}
-                        s => {
-                                eprintln!("invalid length type '{}' !", s);
-                                return None;
-                            }
-                        }
-                        match item_c_type.as_str() {
-                            "uint8_t" |
-                            "uint16_t" |
-                            "uint32_t" |
-                            "uint64_t" |
-                            "void*" => {}
-                            s => {
-                                eprintln!("invalid item type '{}'!", s);
-                                return None;
-                        }
-                    }
+                    let length_c_type = get_c_repr_type(dict, &length_type);
 
-                    Some(format!("LengthPrefix_{}_Array_{}", length_c_type, item_c_type))
+                    Some(format!("struct {{ {} len; {} items[]; }} ", length_c_type, item_c_type))
                 }
-                else if let Ok(σ) = laddertypes::unify(
-                    &sr,
-                    &dict.parse("<ValueTerminated TermValue>").expect("")
+                else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr.as_ref(),
+                    &dict.parse_desugared("<ValueTerminated TermValue>").expect("parse template type").sugar(dict)
                 ) {
                     if skip_pointer {
                         Some(item_c_type)
@@ -109,7 +88,7 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
                     }
                 }
                 else {
-                    eprintln!("can't get C-repr for sequence type `{}`!", dict.unparse(&sr));
+                    eprintln!("can't get C-repr for sequence type `{}`!", seq_repr.pretty(dict, 0));
                     None
                 }
             } else {
@@ -118,7 +97,7 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
             }
         }
 
-        SugaredTypeTerm::Struct{ struct_repr, members } => {
+        TypeTerm::Struct{ struct_repr, members } => {
             let c_struct_attribute =
                 if let Some(sr) = struct_repr {
                     let sr = sr.desugar(dict);
@@ -130,8 +109,8 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
 
             let mut c_type = format!("struct {} {{\n", c_struct_attribute);
 
-            for SugaredStructMember{ symbol, ty } in members {
-                let field_c_type = get_c_repr_type(dict, ty, false).expect("");
+            for StructMember{ symbol, ty } in members {
+                let field_c_type = get_c_repr_definition(dict, ty, false).expect("");
                 c_type.push_str(&format!("    {} {};\n",
                     field_c_type,
                     symbol.replace("-", "_").replace(".","_dot_")
@@ -142,13 +121,13 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: SugaredTypeTerm, skip_pointe
             Some(c_type)
         }
 
-        SugaredTypeTerm::Enum { enum_repr, variants } => {
+        TypeTerm::Enum { enum_repr, variants } => {
             let mut c_type = format!("
 struct {{
     enum {{
 ");
 
-            for (i, SugaredEnumVariant{ symbol, ty }) in variants.iter().enumerate() {
+            for (i, EnumVariant{ symbol, ty }) in variants.iter().enumerate() {
                 c_type.push_str(&format!(
                     "       {} = {}", symbol.replace("-", "_").replace(".","_dot_").to_uppercase(), i
                 ));
@@ -164,8 +143,8 @@ struct {{
     union {
 ");
 
-            for SugaredEnumVariant{ symbol, ty } in variants {
-                let variant_c_type = get_c_repr_type(dict, ty, false).expect("cant get C-Repr type for variant");
+            for EnumVariant{ symbol, ty } in variants {
+                let variant_c_type = get_c_repr_definition(dict, ty, false).expect("cant get C-Repr type for variant");
                 c_type.push_str(&format!(
                     "       {} {};\n", variant_c_type, symbol.replace("-", "_").replace(".","_dot_")
                 ));
@@ -178,9 +157,9 @@ struct {{
             Some(c_type)
         }
 
-        SugaredTypeTerm::Ladder(rungs) => {
+        TypeTerm::Ladder(rungs) => {
             if let Some(t) = rungs.last() {
-                get_c_repr_type(dict, t.clone(), false)
+                get_c_repr_definition(dict, t.clone(), false)
             } else {
                 None
             }
@@ -190,10 +169,11 @@ struct {{
     }
 }
 
-pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm)-> String {
-    let t = t.clone().desugar(dict);
-    match t {
-        laddertypes::TypeTerm::Char(c) => {
+pub fn get_c_repr_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
+    let t = t.clone().strip();
+
+    match t.desugar(dict) {
+        laddertypes::DesugaredTypeTerm::Char(c) => {
             match c {
                 '.' => format!("_dot_"),
                 '-' => format!("_minus_"),
@@ -201,57 +181,61 @@ pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::SugaredT
                 format!("{}", (c as u64))
             }
         },
-        laddertypes::TypeTerm::Num(n) => {
+        laddertypes::DesugaredTypeTerm::Num(n) => {
             format!("{}", n)
         }
-        laddertypes::TypeTerm::TypeID(ty_id) => {
+        laddertypes::DesugaredTypeTerm::TypeID(ty_id) => {
             if let Some(name) = dict.get_typename(&ty_id) {
                 name
                     .replace("-", "_")
-                    .replace(".", "_dot_")
+                    .replace(".", "")
             } else {
                 format!("")
             }
         }
-        laddertypes::TypeTerm::Ladder(rs) |
-        laddertypes::TypeTerm::App(rs) => {
+        laddertypes::DesugaredTypeTerm::Ladder(rs) |
+        laddertypes::DesugaredTypeTerm::App(rs) => {
             let mut s = String::new();
+            s.push('_');
             for r in rs {
-                s.push('_');
-
                 let r = r.sugar(dict);
-                s.push_str(&encode_type_to_symbol(dict, &r));
+                s.push_str(&get_c_repr_type(dict, &r));
+                s.push('_');
             }
             s
         }
     }
 }
 
-pub fn encode_type_to_arg_ty(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm) -> String {
-    match t.get_floor_type().1 {
-        SugaredTypeTerm::Seq { seq_repr, items } => {
-
-            if let Some(seq_repr) = seq_repr {
-                if seq_repr.as_ref() == &dict.parse("<ValueTerminated 0>").expect("").sugar(dict) {
-                    return encode_type_to_symbol(dict, items.first().unwrap());
+pub fn get_c_repr_arg_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
+    let t = t.clone().strip().get_floor_type().1;
+    dict.add_varname("TerminatorValue".into());
+    match &t {
+        TypeTerm::Seq { seq_repr, items } => {
+            if let Some(seq_repr) = seq_repr.as_ref() {
+                if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr,
+                    &dict.parse_desugared("<ValueTerminated TerminatorValue>").expect("").sugar(dict)
+                ) {
+                    return get_c_repr_type(dict, &items[0].clone().strip().get_floor_type().1);
                 }
             }
         }
-        _=>{}
-    }
 
-    encode_type_to_symbol(dict, t)
+        _ => {}
+    }
+    get_c_repr_type(dict, &t)
 }
 
-pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &SugaredMorphismType) -> String {
+pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &MorphismType) -> String {
     format!(
-        "morph_{}__to_{}",
-        encode_type_to_symbol(dict, &t.src_type),
-        encode_type_to_symbol(dict, &t.dst_type)
+        "morph__{}___TO__{}",
+        get_c_repr_type(dict, &t.strip_halo().src_type),
+        get_c_repr_type(dict, &t.strip_halo().dst_type)
     )
 }
 
-pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::SugaredTypeTerm) -> String {
+pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm) -> String {
     let t = t.clone().desugar(dict);
     dict.unparse(&t)
 }
diff --git a/src/main.rs b/src/main.rs
index df68e51..1e418d4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,14 +11,15 @@ use {
         morphism::LdmcPrimMorph,
         parser::morphism_base_parser,
     }, ariadne::{Color, Label, Report, ReportKind, Source}, c_gen::LdmcCTargetMorph, chumsky::prelude::*, laddertypes::{
-        morphism_path_sugared::SugaredShortestPathProblem, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::ParseLadderType, unparser::*, BimapTypeDict, MorphismType, SugaredTypeTerm, TypeDict
+        morphism_path::ShortestPathProblem, morphism::{MorphismInstance, Morphism, MorphismType},
+        parser::ParseLadderType, unparser::*, BimapTypeDict, TypeTerm, TypeDict
     }, std::{collections::HashMap, sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi
 };
 
 fn main() {
     let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
 
-    let mut morphism_base = laddertypes::morphism_base_sugared::SugaredMorphismBase::<LdmcPrimMorph>::new();
+    let mut morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcPrimMorph>::new();
 
     let mut args = std::env::args().skip(1);
     let src_type_arg = args.next().expect("src type expected");
@@ -95,7 +96,7 @@ 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 ty = SugaredMorphismType{ src_type: src_type.sugar(&mut type_dict), dst_type: dst_type.sugar(&mut type_dict) };
+    let ty = MorphismType{ src_type: src_type, dst_type };
     let m = morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism");
     println!("{}", crate::c_gen::generate_main(&mut type_dict, m).expect("failed to generate main function"));
 }
diff --git a/src/morphism.rs b/src/morphism.rs
index 1fb4199..6e94477 100644
--- a/src/morphism.rs
+++ b/src/morphism.rs
@@ -1,177 +1,17 @@
 
-use laddertypes::{morphism::Morphism, morphism_base::MorphismBase, morphism_path::ShortestPathProblem, morphism_sugared::{SugaredMorphism, SugaredMorphismType}, SugaredStructMember};
-use crate::{c_gen_types::encode_type_to_symbol, struct_layout::StructLayout};
+use laddertypes::{morphism_path::ShortestPathProblem, morphism::{Morphism, MorphismType}, StructMember};
+use crate::{c_gen_types::get_c_repr_type, struct_layout::StructLayout};
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct LdmcPrimMorph {
     pub symbol: String,
     pub type_args: Vec<(laddertypes::TypeID, String)>,
-    pub ty: SugaredMorphismType,
+    pub ty: MorphismType,
     pub c_source: String
 }
 
-impl LdmcPrimMorph {
-    /*
-    pub fn into_prim_c_morphism(self, dict: &mut impl laddertypes::TypeDict, symbol: String) -> LdmcPrimCMorphism {
-
-        let src_c_type = ;
-        let dst_c_type = ;
-
-        let c_source =
-            format!("
-                int {} ( {} const * restrict src, {} * restrict dst ) {{
-                    {}
-                    return 0;
-                }}
-                ",
-                symbol, src_c_type, dst_c_type,
-                self.generate_call(dict, &std::collections::HashMap::new(), 0)
-            );
-
-        LdmcPrimCMorphism {
-            symbol,
-            type_args: Vec::new(),
-            src_type,
-            dst_type,
-            c_source
-        }
-    }
-*/
-/*
-
-    pub fn new_struct_map(
-        dict: &mut impl laddertypes::TypeDict,
-        morph_base: &MorphismBase<LdmcPrimMorph>,
-        src: laddertypes::TypeTerm,
-        dst: laddertypes::TypeTerm,
-    ) -> Self {
-        let src_struct = StructLayout::parse(dict, &src).expect("cant parse src struct layout");
-        let dst_struct = StructLayout::parse(dict, &dst).expect("cant parse dst struct layout");
-
-        let mut member_morphisms = Vec::new();
-
-        for SugaredStructMember{ symbol: field_name, ty: dst_type } in dst_struct.members.iter() {
-            let mut src_type = None;
-            for SugaredStructMember{ symbol: src_name, ty: st } in src_struct.members.iter() {
-                if src_name == field_name {
-                    src_type = Some(st.clone());
-                }
-            }
-            let src_type = src_type.expect(&format!("cant find member {} in src struct", field_name));
-
-            if src_type == *dst_type {
-                member_morphisms.push(
-                    StructFieldMorphism {
-                        field_name: field_name.to_string(),
-                        item_morph: None,
-                        src_offset: src_struct.get_offset( field_name ),
-                        dst_offset: dst_struct.get_offset( field_name ),
-                    }
-                );
-            } else {
-                match ShortestPathProblem::new(
-                    &morph_base,
-                    laddertypes::MorphismType {
-                        src_type: src_type.clone().desugar(dict),
-                        dst_type: dst_type.clone().desugar(dict)
-                    }
-                ).solve()
-                {
-                    Some(path) => {
-
-                        let src_type = src_type.clone().desugar(dict);
-                        let dst_type = dst_type.clone().desugar(dict);
-
-                        let morph_symb = format!("morph_{}_to_{}",
-                            encode_type_to_symbol(dict, &src_type),
-                            encode_type_to_symbol(dict, &dst_type)
-                        );
-                        member_morphisms.push(
-                            StructFieldMorphism {
-                                field_name: field_name.to_string(),
-                                item_morph: None,//Some(Box::new(item_morph.m.into_prim_c_morphism(dict, morph_symb, &item_morph.σ))),
-                                src_offset: src_struct.get_offset( field_name ),
-                                dst_offset: dst_struct.get_offset( field_name ),
-                            }
-                        );
-                    },
-
-                    None => {
-                        eprintln!("cant map field {}", field_name);
-                    }
-                }
-            }
-        }
-
-        LdmcPrimMorph::StructMap {
-            src_struct, dst_struct,
-            member_morphisms
-        }
-    }
-    */
-}
-
-impl SugaredMorphism for LdmcPrimMorph {
-    fn get_type(&self) -> SugaredMorphismType {
+impl Morphism for LdmcPrimMorph {
+    fn get_type(&self) -> MorphismType {
         self.ty.clone()
     }
 }
-/*
-impl Morphism for LdmcMorphism {
-    fn weight(&self) -> u64 {
-        1
-    }
-
-    fn get_type(&self) -> laddertypes::MorphismType {
-        match self {
-            LdmcMorphism::Primitive(prim_morph) =>
-                laddertypes::MorphismType {
-                    src_type: prim_morph.src_type.clone().normalize(),
-                    dst_type: prim_morph.dst_type.clone().normalize()
-                },
-            LdmcMorphism::LengthPrefixMap{ length_prefix_type, item_morph } => {
-                laddertypes::MorphismType {
-                    src_type: laddertypes::TypeTerm::App(vec![ length_prefix_type.clone(), item_morph.src_type.clone() ]),
-                    dst_type: laddertypes::TypeTerm::App(vec![ length_prefix_type.clone(), item_morph.dst_type.clone() ]),
-                }
-            },
-            LdmcMorphism::ValueDelimMap{ delim, item_morph } => {
-                let value_delim_type = laddertypes::TypeTerm::App(vec![]);
-                laddertypes::MorphismType {
-                    src_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.src_type.clone() ]),
-                    dst_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.dst_type.clone() ]),
-                }
-            },
-            LdmcMorphism::StructMap { src_struct, dst_struct, member_morphisms } => {
-                laddertypes::MorphismType {
-                    src_type: src_struct.get_type(),
-                    dst_type: dst_struct.get_type()
-                }
-            }
-        }.normalize()
-    }
-
-    fn map_morphism(&self, seq_type: laddertypes::TypeTerm) -> Option< Self > {
-        match self {
-            LdmcMorphism::Primitive(prim) => {
-                let item_morph = Box::new(prim.clone());
-/*
-                if seq_type == self.length_prefix_type {
-                */
-                    Some(LdmcMorphism::LengthPrefixMap{
-                        length_prefix_type: seq_type,
-                        item_morph,
-                    })
-                    /*
-                } else if seq_type == self.value_delim_type {
-                    Some(LdmcMorphism::ValueDelimMap { delim, item_morph })
-                } else {
-                    None
-                }
-                */
-            }
-            _ => None
-        }
-    }
-}
-*/
diff --git a/src/parser.rs b/src/parser.rs
index 49320df..9590519 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,7 +1,7 @@
 use {
     crate::morphism::LdmcPrimMorph, chumsky::{
         prelude::*, text::*
-    }, laddertypes::{morphism_sugared::SugaredMorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
+    }, laddertypes::{morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
 };
 
 /* morphism-base text format:
@@ -59,13 +59,13 @@ pub fn morphism_base_parser(
                 ty_args.push((var_id, kind));
             }
 
-            let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
-            let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
+            let src_type = type_dict.parse_desugared(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
+            let dst_type = type_dict.parse_desugared(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
 
             LdmcPrimMorph {
                 symbol,
                 type_args: ty_args,
-                ty: SugaredMorphismType{
+                ty: MorphismType{
                     src_type,
                     dst_type
                 },
diff --git a/src/struct_layout.rs b/src/struct_layout.rs
index 40be995..3847814 100644
--- a/src/struct_layout.rs
+++ b/src/struct_layout.rs
@@ -1,7 +1,7 @@
 
 use std::ops::Deref;
 
-use laddertypes::{parser::*, unparser::*, SugaredStructMember, SugaredTypeTerm, TypeDict, TypeTerm};
+use laddertypes::{parser::*, unparser::*, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm};
 
 #[derive(Clone, Copy, Debug)]
 pub enum ObjectSize {
@@ -46,9 +46,9 @@ impl std::ops::Mul for ObjectSize {
     }
 }
 
-pub fn get_type_size( dict: &mut impl TypeDict, ty: SugaredTypeTerm ) -> ObjectSize {
+pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
     match &ty {
-        SugaredTypeTerm::TypeID(tyid) => {
+        TypeTerm::TypeID(tyid) => {
                  if tyid == &dict.get_typeid_creat("native.UInt8") { ObjectSize::Static(1) }
             else if tyid == &dict.get_typeid_creat("native.UInt16") { ObjectSize::Static(2) }
             else if tyid == &dict.get_typeid_creat("native.UInt32") { ObjectSize::Static(4) }
@@ -61,23 +61,23 @@ pub fn get_type_size( dict: &mut impl TypeDict, ty: SugaredTypeTerm ) -> ObjectS
             }
         },
 
-        SugaredTypeTerm::Ladder(rungs) => {
+        TypeTerm::Ladder(rungs) => {
             get_type_size(dict, rungs.last().unwrap().clone() )
         }
 
-        SugaredTypeTerm::Struct { struct_repr, members } => {
+        TypeTerm::Struct { struct_repr, members } => {
             let layout = StructLayout::parse_sugared(dict, ty).expect("invalid struct");
             layout.get_size()
         }
 
-        SugaredTypeTerm::Seq { seq_repr, items } => {
+        TypeTerm::Seq { seq_repr, items } => {
             if let Some(seq_repr) = seq_repr {
                 dict.add_typename("Length".into());
                 dict.add_typename("LengthType".into());
                 dict.add_typename("TerminatorValue".into());
 
                 if let Ok(σ) = laddertypes::unify(
-                    &seq_repr.clone().desugar(dict),
+                    &seq_repr.clone(),
                     &dict.parse("<StaticLength Length>").expect("")
                 ) {
                     if let Some(TypeTerm::Num(len)) = σ.get(&dict.get_typeid(&"Length".into()).expect("")) {
@@ -87,13 +87,13 @@ pub fn get_type_size( dict: &mut impl TypeDict, ty: SugaredTypeTerm ) -> ObjectS
                     }
                 }
                 else if let Ok(σ) = laddertypes::unify(
-                    &seq_repr.clone().desugar(dict),
+                    &seq_repr.clone(),
                     &dict.parse("<LengthPrefix LengthType>").expect("")
                 ) {
                     ObjectSize::Dynamic()
                 }
                 else if let Ok(σ) = laddertypes::unify(
-                    &seq_repr.clone().desugar(dict),
+                    &seq_repr.clone(),
                     &dict.parse("<ValueTerminated TerminatorValue>").expect("")
                 ) {
                     ObjectSize::Dynamic()
@@ -118,35 +118,35 @@ pub enum LayoutType {
 }
 
 impl LayoutType {
-    pub fn parse( dict: &mut impl TypeDict, ty: &TypeTerm ) -> Option< LayoutType > {
-        if ty == &dict.parse("Aligned").expect("parse") {
+    pub fn parse( dict: &mut impl TypeDict, ty: &DesugaredTypeTerm ) -> Option< LayoutType > {
+        if ty == &dict.parse_desugared("Aligned").expect("parse") {
             Some(LayoutType::Aligned)
-        } else if ty == &dict.parse("Packed").expect("parse") {
+        } else if ty == &dict.parse_desugared("Packed").expect("parse") {
             Some(LayoutType::Packed)
         } else {
             None
         }
     }
 
-    pub fn unparse(&self, dict: &mut impl TypeDict) -> TypeTerm {
+    pub fn unparse(&self, dict: &mut impl TypeDict) -> DesugaredTypeTerm {
         match self {
-            LayoutType::Aligned => dict.parse("Aligned").unwrap(),
-            LayoutType::Packed => dict.parse("Packed").unwrap()
+            LayoutType::Aligned => dict.parse_desugared("Aligned").unwrap(),
+            LayoutType::Packed => dict.parse_desugared("Packed").unwrap()
         }
     }
 }
 
 #[derive(Clone)]
 pub struct StructLayout {
-    pub ty: laddertypes::TypeTerm,
+    pub ty: laddertypes::DesugaredTypeTerm,
     pub layout: LayoutType,
-    pub members: Vec< SugaredStructMember >,
+    pub members: Vec< StructMember >,
     offsets: std::collections::HashMap< String, u64 >,
     size: ObjectSize
 }
 
 impl StructLayout {
-    pub fn get_type(&self) -> TypeTerm {
+    pub fn get_type(&self) -> DesugaredTypeTerm {
         self.ty.clone()
     }
 
@@ -161,7 +161,7 @@ impl StructLayout {
     pub fn init_offsets(&mut self, dict: &mut impl TypeDict) {
         let mut offset = 0;
 
-        for SugaredStructMember{symbol: field_name, ty: field_type} in self.members.iter() {
+        for StructMember{symbol: field_name, ty: field_type} in self.members.iter() {
             //let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
             match get_type_size( dict, field_type.clone() ) {
                 ObjectSize::Static(field_size) => {
@@ -208,15 +208,15 @@ impl StructLayout {
         }
     }
 
-    pub fn parse(dict: &mut impl TypeDict, struct_type: &TypeTerm) -> Option <Self> {
+    pub fn parse(dict: &mut impl TypeDict, struct_type: &DesugaredTypeTerm) -> Option <Self> {
         let st = struct_type.clone().strip().param_normalize().sugar(dict);
         Self::parse_sugared(dict, st)
     }
 
-    pub fn parse_sugared(dict: &mut impl TypeDict, st: SugaredTypeTerm) -> Option <Self> {
+    pub fn parse_sugared(dict: &mut impl TypeDict, st: TypeTerm) -> Option <Self> {
         eprintln!("{}", st.pretty(dict, 0));
         match st.clone() {
-            SugaredTypeTerm::Struct{ struct_repr, members } => {
+            TypeTerm::Struct{ struct_repr, members } => {
                 let mut sl = StructLayout {
                     ty: st.desugar(dict),
                     layout: if let Some(sr) = struct_repr {

From 3ed7a1927042c083c39221781fb5b67eb9dd0dba Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 6 May 2025 00:39:32 +0200
Subject: [PATCH 12/31] adapt changes in lib-laddertypes

---
 src/struct_layout.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/struct_layout.rs b/src/struct_layout.rs
index 3847814..d07b129 100644
--- a/src/struct_layout.rs
+++ b/src/struct_layout.rs
@@ -209,7 +209,7 @@ impl StructLayout {
     }
 
     pub fn parse(dict: &mut impl TypeDict, struct_type: &DesugaredTypeTerm) -> Option <Self> {
-        let st = struct_type.clone().strip().param_normalize().sugar(dict);
+        let st = struct_type.clone().strip().sugar(dict).normalize();
         Self::parse_sugared(dict, st)
     }
 

From 923fe987dc3df62d368a8a30fb03f0b60cb8eb60 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 7 May 2025 16:29:45 +0200
Subject: [PATCH 13/31] fix typedefs

---
 morphisms/length_prefix.morphism-base         |   4 +-
 morphisms/posint.morphism-base                |  12 +-
 .../runtime/include/array/length-prefix.h     |  38 ++--
 morphisms/value_delim.morphism-base           |  24 +-
 src/c_gen/gen_main.rs                         |  49 ++++
 src/c_gen/mod.rs                              |   7 +
 src/c_gen/morph/mod.rs                        |  76 +++++++
 src/{c_gen.rs => c_gen/morph/target_morph.rs} | 211 +++++-------------
 src/{c_gen_types.rs => c_gen/types/mod.rs}    |  22 +-
 src/main.rs                                   |  60 +----
 src/morphism.rs                               |   3 +-
 src/parser.rs                                 |   2 +-
 src/platform/x86.rs                           |  43 ++++
 src/struct_layout.rs                          |   3 +-
 14 files changed, 309 insertions(+), 245 deletions(-)
 create mode 100644 src/c_gen/gen_main.rs
 create mode 100644 src/c_gen/mod.rs
 create mode 100644 src/c_gen/morph/mod.rs
 rename src/{c_gen.rs => c_gen/morph/target_morph.rs} (64%)
 rename src/{c_gen_types.rs => c_gen/types/mod.rs} (90%)
 create mode 100644 src/platform/x86.rs

diff --git a/morphisms/length_prefix.morphism-base b/morphisms/length_prefix.morphism-base
index 1a1b7f5..a694931 100644
--- a/morphisms/length_prefix.morphism-base
+++ b/morphisms/length_prefix.morphism-base
@@ -7,9 +7,9 @@ morph_array_as_valterm_to_lenpfx (Terminator:native.UInt8)
     <Seq~<ValueTerminated Terminator> native.UInt8>
 --> <Seq~<LengthPrefix native.UInt64> native.UInt8>
 ```
-    length_prefix_uint64_t_array_uint8_t_clear(dst);
+    length_prefix_nativeUInt64_array_nativeUInt8_clear(dst);
     while( *src != Terminator )
-        length_prefix_uint64_t_array_uint8_t_push(dst, *src++);
+        length_prefix_nativeUInt64_array_nativeUInt8_push(dst, *src++);
 ```
 
 
diff --git a/morphisms/posint.morphism-base b/morphisms/posint.morphism-base
index 01248eb..9036520 100644
--- a/morphisms/posint.morphism-base
+++ b/morphisms/posint.morphism-base
@@ -38,15 +38,15 @@ morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
         value += src->items[src->len - i - 1];
     }
 
-    length_prefix_uint64_t_array_uint64_t_clear( dst );
+    length_prefix_nativeUInt64_array_nativeUInt64_clear( dst );
 
     #if DstRadix==0
-        length_prefix_uint64_t_array_uint64_t_push( dst, value );
+        length_prefix_nativeUInt64_array_nativeUInt64_push( dst, value );
     #else
         if( value == 0 ) {
-            length_prefix_uint64_t_array_uint64_t_push( dst, 0 );
+            length_prefix_nativeUInt64_array_nativeUInt64_push( dst, 0 );
         } else while( value > 0 ) {
-            length_prefix_uint64_t_array_uint64_t_push( dst, value % DstRadix );
+            length_prefix_nativeUInt64_array_nativeUInt64_push( dst, value % DstRadix );
             value /= DstRadix;
         }
     #endif
@@ -97,7 +97,7 @@ morph_posint_endianness (Radix:ℤ)
     ~ <PosInt Radix BigEndian>
     ~ <Seq~<LengthPrefix native.UInt64> <Digit Radix> ~ native.UInt64>
 ```
-    return length_prefix_uint64_t_array_uint64_t_reverse( src, dst );
+    return length_prefix_nativeUInt64_array_nativeUInt64_reverse( src, dst );
 ```
 
 morph_posint_endianness (Radix:ℤ)
@@ -108,5 +108,5 @@ morph_posint_endianness (Radix:ℤ)
     ~ <PosInt Radix LittleEndian>
     ~ <Seq~<LengthPrefix native.UInt64> <Digit Radix> ~ native.UInt64>
 ```
-    return length_prefix_uint64_t_array_uint64_t_reverse( src, dst );
+    return length_prefix_nativeUInt64_array_nativeUInt64_reverse( src, dst );
 ```
diff --git a/morphisms/runtime/include/array/length-prefix.h b/morphisms/runtime/include/array/length-prefix.h
index 3f039f2..e61f8ac 100644
--- a/morphisms/runtime/include/array/length-prefix.h
+++ b/morphisms/runtime/include/array/length-prefix.h
@@ -2,27 +2,37 @@
 
 #include <stdio.h>
 #include <stdint.h>
+/*
+typedef struct {                                                           \
+    LEN_TYPE len;                                                          \
+    ITEM_TYPE items[];                                                     \
+} __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_;                       \
+  */                                                                       \
+
+#define LENGTH_PREFIX_ARRAY_TYPE(LEN_TYPE, ITEM_TYPE)                           \
+    __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_
+
+#define LENGTH_PREFIX_ARRAY_CALL(LEN_TYPE, ITEM_TYPE, METHOD)              \
+    length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_ ## METHOD
+
+#define PRESCAN_LENGTH_PREFIX_CALL(LEN, ITEM, METHOD) \
+    LENGTH_PREFIX_ARRAY_CALL(LEN, ITEM, METHOD)
 
 #define DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, ITEM_TYPE)                        \
-    typedef struct {                                                           \
-        LEN_TYPE len;                                                          \
-        ITEM_TYPE items[];                                                     \
-    } __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_;                             \
-                                                                               \
-    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_clear(   \
-        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data) {                   \
+    static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, clear)    \
+       (__Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data) {                      \
         data->len = 0;                                                         \
     }                                                                          \
                                                                                \
-    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_push(    \
-        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data,                     \
+    static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, push)     \
+       (__Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data,                        \
         ITEM_TYPE value) {                                                     \
         data->items[data->len++] = value;                                      \
     }                                                                          \
                                                                                \
-    static inline int length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_reverse(  \
-        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * restrict src,      \
-        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *restrict dst) {           \
+    static inline int PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, reverse)   \
+      ( __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * restrict src,         \
+        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *restrict dst) {              \
         for (LEN_TYPE i = 0; i < src->len; i++) {                              \
             dst->items[i] = src->items[src->len - 1 - i];                      \
         }                                                                      \
@@ -30,8 +40,8 @@
         return 0;                                                              \
     }                                                                          \
                                                                                \
-    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_dump(    \
-        __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * data) {            \
+    static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, dump)     \
+      ( __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * data) {               \
         printf("Length: %llu\n", (unsigned long long) data->len);              \
         for (LEN_TYPE i = 0; i < data->len; i++) {                             \
             printf("%llu ", (unsigned long long) data->items[i]);              \
diff --git a/morphisms/value_delim.morphism-base b/morphisms/value_delim.morphism-base
index ab66310..6e94459 100644
--- a/morphisms/value_delim.morphism-base
+++ b/morphisms/value_delim.morphism-base
@@ -12,19 +12,19 @@ morph_seqseq_valsep_uint8 (T: Type, SrcDelim: T, DstDelim: T)
     ~ < ValueSep DstDelim T >
     ~ < Seq~<LengthPrefix native.UInt64> T >
 ```
-    length_prefix_uint64_t_array_uint8_t_clear( dst );
+    PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, clear)( dst );
 
     uint8_t * dst_items = dst->items;
     for( uint64_t i = 0; i < src->len; ++i ) {
         if( src->items[i] == SrcDelim ) {
-            length_prefix_uint64_t_array_uint8_t_push( dst, DstDelim );
+            PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, DstDelim );
         } else if( src->items[i] == DstDelim ) {
             if( DstDelim == '\n' ) {
-                length_prefix_uint64_t_array_uint8_t_push( dst, '\\' );
-                length_prefix_uint64_t_array_uint8_t_push( dst, 'n' );
+                PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, '\\' );
+                PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, 'n' );
             }
         } else {
-            length_prefix_uint64_t_array_uint8_t_push( dst, src->items[i] );
+            PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, src->items[i] );
         }
     }
 ```
@@ -42,9 +42,9 @@ morph_seqseq_as_valsep_to_lenpfx (T: Type, Delim: T, EscKey: T)
         ~ native.UInt64
     >
 ```
-    length_prefix_uint64_t_array_uint64_t_clear( dst );
+    length_prefix_nativeUInt64_array_nativeUInt64_clear( dst );
 
-    struct LengthPrefix_uint64_t_Array_uint8_t * cur_item = NULL;
+    struct LengthPrefix_nativeUInt64_Array_nativeUInt8 * cur_item = NULL;
 
     uint8_t const * start = &src->items[0];
     uint8_t const * cur = start;
@@ -58,7 +58,7 @@ morph_seqseq_as_valsep_to_lenpfx (T: Type, Delim: T, EscKey: T)
             cur_item->len = len;
             memcpy( cur_item->items, start, len );
 
-            length_prefix_uint64_t_array_uint64_t_push( dst, (uint64_t)cur_item );
+            length_prefix_nativeUInt64_array_nativeUInt64_push( dst, (uint64_t)cur_item );
             start = ++cur;
         } else {
             cur++;
@@ -77,17 +77,17 @@ morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
     ~ < ValueSep T Delim >
     ~ < Seq~<LengthPrefix native.UInt64> T >
 ```
-    length_prefix_uint64_t_array_uint8_t_clear( dst );
+    length_prefix_nativeUInt64_array_nativeUInt8_clear( dst );
 
     for( uint64_t i = 0; i < src->len; ++i ) {
-        LengthPrefix_uint64_t_Array_uint8_t * item = src->items[i];
+        LengthPrefix_nativeUInt64_Array_nativeUInt8_t * item = src->items[i];
 
         for( uint64_t j = 0; j < item->len; ++j ) {
-            length_prefix_uint64_t_array_uint8_t_push( items->items[j] );
+            length_prefix_nativeUInt64_array_nativeUInt8_push( items->items[j] );
         }
 
         if( i+1 < src->len ) {
-            length_prefix_uint64_t_array_uint8_t_push( Delim );
+            length_prefix_nativeUInt64_array_nativeUInt8_push( Delim );
         }
     }
 ```
diff --git a/src/c_gen/gen_main.rs b/src/c_gen/gen_main.rs
new file mode 100644
index 0000000..70847ea
--- /dev/null
+++ b/src/c_gen/gen_main.rs
@@ -0,0 +1,49 @@
+use {
+    laddertypes::{TypeDict, morphism::MorphismInstance, parser::*},
+    crate::LdmcPrimMorph,
+    crate::c_gen::LdmcCTargetMorph,
+    std::collections::HashMap,
+};
+
+pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance<LdmcPrimMorph>) -> Result<String, ()> {
+    let mut target = LdmcCTargetMorph::new();
+    let ty = morph.get_type();
+    match target.add_instantiation(dict, morph) {
+        Ok(inst) => {
+            let mut c_source = target.into_c_source(dict);
+
+            c_source.push_str(&format!(r#"
+        #include <unistd.h>
+
+        int main() {{
+            uint8_t bufIn[4096];
+            uint8_t bufOut[4096];"#));
+
+            let (src_top, src_floor) = ty.src_type.get_floor_type();
+            if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
+                c_source.push_str("scanf(\"%s\", bufIn);");
+            } else {
+                c_source.push_str("read(0, bufIn, sizeof(bufIn));");
+            }
+
+            c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
+
+            if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
+                &ty.src_type,
+                &dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
+            ) {
+                c_source.push_str("printf(\"%s\\n\", bufOut);");
+            } else {
+                c_source.push_str("write(1, bufOut, sizeof(bufOut));");
+            }
+            c_source.push_str("
+            return 0;
+        }");
+            Ok(c_source)
+        }
+        Err(err) => {
+            eprintln!("failed to create morphism instatiation");
+            Err(())
+        }
+    }
+}
diff --git a/src/c_gen/mod.rs b/src/c_gen/mod.rs
new file mode 100644
index 0000000..f8c11f9
--- /dev/null
+++ b/src/c_gen/mod.rs
@@ -0,0 +1,7 @@
+pub mod types;
+pub mod morph;
+pub mod gen_main;
+
+pub use {
+    morph::target_morph::LdmcCTargetMorph
+};
diff --git a/src/c_gen/morph/mod.rs b/src/c_gen/morph/mod.rs
new file mode 100644
index 0000000..49510e5
--- /dev/null
+++ b/src/c_gen/morph/mod.rs
@@ -0,0 +1,76 @@
+pub mod target_morph;
+
+use {
+    crate::{
+        c_gen::types::{
+            get_c_repr_arg_type,
+            get_c_repr_definition,
+            get_c_repr_type
+        },
+        morphism::LdmcPrimMorph
+    },
+    laddertypes::{TypeDict, Substitution},
+};
+
+impl LdmcPrimMorph {
+    pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> String {
+        let mut s = self.symbol.clone();
+        for (k_id,v) in self.type_args.iter() {
+            if let Some(val_trm) = σ.get(k_id) {
+                if let laddertypes::TypeID::Var(var_id) = k_id {
+
+                    //if self.get_type().strip_halo().src_type.contains_var(*var_id) ||
+                    //self.get_type().strip_halo().dst_type.contains_var(*var_id) {
+
+                        let name = dict.get_varname(*var_id).unwrap();
+                        let val_str = get_c_repr_type(dict, &val_trm);
+                        s.push_str(&format!("_{}_{}", name, val_str));
+
+                    //}
+                }
+            } else {
+                if let laddertypes::TypeID::Var(var_id) = k_id {
+                    let k = dict.get_varname(*var_id).unwrap();
+                    s.push_str(&format!("_{:?}_MISSING", k));
+                    eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing type parameter {} ({})", k, var_id);
+                }
+            }
+        }
+        s
+    }
+
+    pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
+        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>
+    ) -> String {
+        format!("int {} ({} const * restrict src, {} * restrict dst);",
+            self.instantiated_symbol_name(dict, σ),
+            get_c_repr_definition(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
+            get_c_repr_definition(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
+    }
+
+    pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> Option<String> {
+        let mut s = String::new();
+        let symbol = self.instantiated_symbol_name(dict, σ);
+
+        eprintln!("generate instantiation:");
+        let ty = self.ty.clone();
+        eprintln!("full type: {}   ---->    {}", ty.src_type.pretty(dict, 0),  ty.dst_type.pretty(dict,0));
+        let ty = ty.strip_halo().apply_subst(σ);
+        eprintln!("stripped type:  {}   ---->    {}", ty.src_type.pretty(dict, 0),  ty.dst_type.pretty(dict,0));
+
+        let src_c_symbol = get_c_repr_arg_type(dict, &ty.src_type);
+        let dst_c_symbol = get_c_repr_arg_type(dict, &ty.dst_type);
+
+        s.push_str(&format!(r#"
+int {} ( {} const * restrict src, {} * restrict dst ) {{
+"#,
+            symbol, src_c_symbol, dst_c_symbol,
+        ));
+        s.push_str(&self.c_source);
+        s.push_str(&format!(r#"
+    return 0;
+}}
+"#));
+        Some(s)
+    }
+}
diff --git a/src/c_gen.rs b/src/c_gen/morph/target_morph.rs
similarity index 64%
rename from src/c_gen.rs
rename to src/c_gen/morph/target_morph.rs
index 0f21ef8..fcb90fb 100644
--- a/src/c_gen.rs
+++ b/src/c_gen/morph/target_morph.rs
@@ -1,86 +1,22 @@
 use {
-    crate::{c_gen_types::{encode_morph_type_to_symbol, encode_type_to_value, get_c_repr_arg_type,
-        get_c_repr_definition, get_c_repr_type}, morphism::LdmcPrimMorph,
-    struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}},
-    chumsky::{chain::Chain, primitive::Container},
-    laddertypes::{morphism::{MorphismInstance, Morphism, MorphismType},
-        parser::*, substitution::Substitution, unparser::*,
-        EnumVariant, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm},
+    crate::{
+        c_gen::types::{
+            encode_morph_type_to_symbol, get_c_repr_definition, get_c_repr_type, encode_type_to_value
+        },
+        morphism::LdmcPrimMorph
+    },
+    laddertypes::{
+        parser::*, MorphismInstance, TypeDict, TypeTerm, Morphism
+    },
     std::collections::HashMap
 };
 
-impl LdmcPrimMorph {
-    pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> String {
-        let mut s = self.symbol.clone();
-        for (k_id,v) in self.type_args.iter() {
-
-                if let Some(val_trm) = σ.get(k_id) {
-                    if let laddertypes::TypeID::Var(var_id) = k_id {
-
-                        //if self.get_type().strip_halo().src_type.contains_var(*var_id) ||
-                        //self.get_type().strip_halo().dst_type.contains_var(*var_id) {
-
-                            let name = dict.get_varname(*var_id).unwrap();
-                            let val_str = get_c_repr_type(dict, &val_trm);
-                            s.push_str(&format!("_{}_{}", name, val_str));
-
-                            //}
-                    }
-                } else {
-                    if let laddertypes::TypeID::Var(var_id) = k_id {
-                        let k = dict.get_varname(*var_id).unwrap();
-                        s.push_str(&format!("_{:?}_MISSING", k));
-                        eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing type parameter {} ({})", k, var_id);
-                    }
-                }
-        }
-        s
-    }
-
-    pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
-        σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>
-    ) -> String {
-        format!("int {} ({} const * restrict src, {} * restrict dst);",
-            self.instantiated_symbol_name(dict, σ),
-            get_c_repr_definition(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
-            get_c_repr_definition(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
-    }
-
-    pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> Option<String> {
-        let mut s = String::new();
-        let symbol = self.instantiated_symbol_name(dict, σ);
-
-        eprintln!("generate instantiation:");
-        let ty = self.ty.clone();
-        eprintln!("full type: {}   ---->    {}", ty.src_type.pretty(dict, 0),  ty.dst_type.pretty(dict,0));
-        let ty = ty.strip_halo().apply_subst(σ);
-        eprintln!("stripped type:  {}   ---->    {}", ty.src_type.pretty(dict, 0),  ty.dst_type.pretty(dict,0));
-
-        let src_c_symbol = get_c_repr_arg_type(dict, &ty.src_type);
-        let dst_c_symbol = get_c_repr_arg_type(dict, &ty.dst_type);
-
-        s.push_str(&format!(r#"
-int {} ( {} const * restrict src, {} * restrict dst ) {{
-"#,
-            symbol, src_c_symbol, dst_c_symbol,
-        ));
-        s.push_str(&self.c_source);
-        s.push_str(&format!(r#"
-    return 0;
-}}
-"#));
-        Some(s)
-    }
-}
-
-
-
-
-
 pub struct LdmcCTargetMorph {
     includes: Vec< String >,
     active_types: Vec< TypeTerm >,
     active_instantiations: Vec< LdmcPrimMorph >,
+    active_lenpfx_types: Vec< (TypeTerm, TypeTerm) >,
+    typedefs: Vec< String >,
     macro_calls: Vec< String >
 }
 
@@ -94,6 +30,8 @@ impl LdmcCTargetMorph {
             ],
             active_instantiations: Vec::new(),
             active_types: Vec::new(),
+            active_lenpfx_types: Vec::new(),
+            typedefs: Vec::new(),
             macro_calls: Vec::new()
         }
     }
@@ -101,34 +39,51 @@ impl LdmcCTargetMorph {
     pub fn add_type(&mut self, dict: &mut impl TypeDict, ty: TypeTerm) {
         let ty = ty.strip();
         if ! self.active_types.contains(&ty) {
-            eprintln!("add type {:?}", ty);
-            match &ty {
-                TypeTerm::Seq { seq_repr, items } =>{
-                    let item_type = items.first().unwrap().clone();
-                    self.add_type(dict, item_type.clone());
+            eprintln!("add type {}", ty.pretty(dict,0));
 
-                    if let Some(seq_repr) = seq_repr {
-                        dict.add_varname("LengthType".into());
-                        if let Ok(σ) =
-                            laddertypes::constraint_system::unify(
-                                seq_repr.as_ref(),
-                                &dict.parse_desugared("<LengthPrefix LengthType>").expect("").sugar(dict)
-                            )
-                        {
-                            let length_type = σ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get Length type");
-                            self.add_type(dict, length_type.clone());
-                            self.macro_calls.push(
-                                format!("DEFINE_LENGTH_PREFIX_ARRAY({}, {})\n",
-                                    get_c_repr_type(dict, &length_type),
-                                    get_c_repr_type(dict, &item_type)
+            let (ht,ft) = ty.get_floor_type();
+            if ht.is_empty() {
+
+                match &ft {
+                    TypeTerm::Seq { seq_repr, items } => {
+                        let item_type = items.first().unwrap().clone();
+                        self.add_type(dict, item_type.clone());
+
+                        if let Some(seq_repr) = seq_repr {
+                            dict.add_varname("LengthType".into());
+                            if let Ok(σ) =
+                                laddertypes::constraint_system::unify(
+                                    seq_repr.as_ref(),
+                                    &dict.parse_desugared("<LengthPrefix LengthType>").expect("").sugar(dict)
                                 )
-                            );
+                            {
+                                let length_type = σ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get Length type");
+                                self.add_type(dict, length_type.clone());
+                                self.macro_calls.push(
+                                    format!("DEFINE_LENGTH_PREFIX_ARRAY({}, {})\n",
+                                        get_c_repr_type(dict, &length_type),
+                                        get_c_repr_type(dict, &item_type)
+                                    )
+                                );
+                            }
                         }
                     }
+                    _ => {}
                 }
-                _=>{}
+
+                self.active_types.push(ty.clone());
+                if let Some(type_def) = get_c_repr_definition(dict, ft, false) {
+                    let type_name = get_c_repr_type(dict, &ty);
+                    self.typedefs.push(format!("typedef {} {};\n", type_def, type_name));
+                } else {
+                    eprintln!("cant get c-repr type for type '{}'", ty.pretty(dict,0));
+                }
+            } else {
+                let type_name = get_c_repr_type(dict, &ty);
+                let type_def = get_c_repr_type(dict, &ft);
+                self.add_type(dict, ft);
+                self.typedefs.push(format!("typedef {} {};\n", type_def, type_name));
             }
-            self.active_types.push(ty.clone());
         }
     }
 
@@ -162,14 +117,10 @@ impl LdmcCTargetMorph {
 
         source.push('\n');
 
-        for ty in self.active_types {
-            if let Some(type_def) = get_c_repr_definition(dict, ty.clone(), false) {
-                let type_name = get_c_repr_type(dict, &ty);
-                source.push_str(&format!("typedef {} {};\n", type_def, type_name));
-            } else {
-                eprintln!("cant get c-repr type for type '{}'", ty.pretty(dict,0));
-            }
+        for typedef in self.typedefs {
+            source.push_str(&typedef);
         }
+
         source.push('\n');
 
 
@@ -201,13 +152,7 @@ impl LdmcCTargetMorph {
                         //if morph_inst.get_type().strip_halo().src_type.contains_var(*var_id) ||
                         //morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
                             if let Some(val) = σ.get(ty_id) {
-                                let type_var_value =
-                                    if let Some(c_repr_type) = get_c_repr_definition(dict, val.clone(), true) {
-                                        c_repr_type
-                                    } else {
-                                        encode_type_to_value(dict, &val)
-                                    };
-
+                                let type_var_value = get_c_repr_type(dict, val);
                                 c_source.push_str(&format!("    #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
                             }
                             //}
@@ -399,47 +344,3 @@ impl LdmcCTargetMorph {
         }
     }
 }
-
-pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance<LdmcPrimMorph>) -> Result<String, ()> {
-    let mut target = LdmcCTargetMorph::new();
-    let ty = morph.get_type();
-    match target.add_instantiation(dict, morph) {
-        Ok(inst) => {
-            let mut c_source = target.into_c_source(dict);
-
-            c_source.push_str(&format!(r#"
-        #include <unistd.h>
-
-        int main() {{
-            uint8_t bufIn[4096];
-            uint8_t bufOut[4096];"#));
-
-            let (src_top, src_floor) = ty.src_type.get_floor_type();
-            if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
-                c_source.push_str("scanf(\"%s\", bufIn);");
-            } else {
-                c_source.push_str("read(0, bufIn, sizeof(bufIn));");
-            }
-
-            c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
-
-            if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
-                &ty.src_type,
-                &dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
-            ) {
-                c_source.push_str("printf(\"%s\\n\", bufOut);");
-            } else {
-                c_source.push_str("write(1, bufOut, sizeof(bufOut));");
-            }
-            c_source.push_str("
-            return 0;
-        }");
-
-            Ok(c_source)
-        }
-        Err(err) => {
-            eprintln!("failed to create morphism instatiation");
-            Err(())
-        }
-    }
-}
diff --git a/src/c_gen_types.rs b/src/c_gen/types/mod.rs
similarity index 90%
rename from src/c_gen_types.rs
rename to src/c_gen/types/mod.rs
index 8c366bb..29cb4ec 100644
--- a/src/c_gen_types.rs
+++ b/src/c_gen/types/mod.rs
@@ -1,9 +1,9 @@
 use {
-    crate::{morphism::LdmcPrimMorph, struct_layout::{get_type_size, LayoutType, ObjectSize, StructLayout}},
-    chumsky::chain::Chain, laddertypes::{morphism::{MorphismInstance, MorphismType},
+    crate::struct_layout::LayoutType,
+    chumsky::chain::Chain, laddertypes::{morphism::MorphismType,
         parser::*,
         substitution::Substitution,
-        unparser::*, EnumVariant, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm}, std::thread::yield_now
+        unparser::*, EnumVariant, StructMember, TypeTerm, TypeDict}
 };
 
 /*
@@ -87,6 +87,16 @@ pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer
                         Some(format!("{} *", item_c_type))
                     }
                 }
+                else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr.as_ref(),
+                    &dict.parse_desugared("MsbCont").expect("parse template type").sugar(dict)
+                ) {
+                    if skip_pointer {
+                        Some(item_c_type)
+                    } else {
+                        Some(format!("{} *", item_c_type))
+                    }
+                }
                 else {
                     eprintln!("can't get C-repr for sequence type `{}`!", seq_repr.pretty(dict, 0));
                     None
@@ -219,6 +229,12 @@ pub fn get_c_repr_arg_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-
                 ) {
                     return get_c_repr_type(dict, &items[0].clone().strip().get_floor_type().1);
                 }
+                else if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
+                    seq_repr,
+                    &dict.parse_desugared("MsbCont").expect("").sugar(dict)
+                ) {
+                    return get_c_repr_type(dict, &items[0].clone().strip().get_floor_type().1);
+                }
             }
         }
 
diff --git a/src/main.rs b/src/main.rs
index 1e418d4..01df9a7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,17 +3,21 @@
 mod morphism;
 mod parser;
 mod c_gen;
-mod c_gen_types;
 mod struct_layout;
 
 use {
     crate::{
         morphism::LdmcPrimMorph,
         parser::morphism_base_parser,
-    }, ariadne::{Color, Label, Report, ReportKind, Source}, c_gen::LdmcCTargetMorph, chumsky::prelude::*, laddertypes::{
-        morphism_path::ShortestPathProblem, morphism::{MorphismInstance, Morphism, MorphismType},
-        parser::ParseLadderType, unparser::*, BimapTypeDict, TypeTerm, TypeDict
-    }, std::{collections::HashMap, sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi
+    },
+    ariadne::{Color, Label, Report, ReportKind, Source},
+    chumsky::prelude::*,
+    laddertypes::{
+        morphism::MorphismType,
+        parser::ParseLadderType, BimapTypeDict
+    },
+    std::{sync::{Arc, RwLock}},
+    tiny_ansi::TinyAnsi
 };
 
 fn main() {
@@ -26,7 +30,7 @@ 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.clone()).expect("read");
+        let src = std::fs::read_to_string(mb_path.clone()).expect("failed to read morphism base");
         let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
         match result {
             Ok((includes, morphisms)) => {
@@ -53,50 +57,10 @@ fn main() {
         }
     }
 
-    let mut γ = HashMap::new();
-    γ.insert(
-        type_dict.get_typeid_creat(&"Byte"),
-        type_dict.parse("<Seq~<StaticLength 8> Bit>").expect("parse")
-            .apply_subst(&γ)
-            .clone()
-    );
-    γ.insert(
-        type_dict.get_typeid_creat(&"x86.UInt8"),
-        type_dict.parse("ℤ_2^8 ~ <PosInt 2 BigEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>").expect("parse")
-            .apply_subst(&γ)
-            .clone()
-    );
-    γ.insert(
-        type_dict.get_typeid_creat(&"x86.UInt16"),
-        type_dict.parse("ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >").expect("parse")
-            .apply_subst(&γ)
-            .clone()
-    );
-    γ.insert(
-        type_dict.get_typeid_creat(&"x86.UInt32"),
-        type_dict.parse("ℤ_2^32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >").expect("parse")
-            .apply_subst(&γ).clone()
-    );
-    γ.insert(
-        type_dict.get_typeid_creat(&"x86.UInt64"),
-        type_dict.parse("ℤ_2^64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >").expect("parse")
-            .apply_subst(&γ).clone()
-    );
-    γ.insert(
-        type_dict.get_typeid_creat(&"x86.Float32"),
-        type_dict.parse("ℝ ~ IEEE-754.Float32 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
-            .apply_subst(&γ).clone()
-    );
-    γ.insert(
-        type_dict.get_typeid_creat(&"x86.Float64"),
-        type_dict.parse("ℝ ~ IEEE-754.Float64 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
-            .apply_subst(&γ).clone()
-    );
-
     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 ty = MorphismType{ src_type: src_type, dst_type };
+    let ty = MorphismType{ src_type, dst_type };
     let m = morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism");
-    println!("{}", crate::c_gen::generate_main(&mut type_dict, m).expect("failed to generate main function"));
+    println!("{}", crate::c_gen::gen_main::generate_main(&mut type_dict, m).expect("failed to generate main function"));
 }
diff --git a/src/morphism.rs b/src/morphism.rs
index 6e94477..28ea01e 100644
--- a/src/morphism.rs
+++ b/src/morphism.rs
@@ -1,6 +1,5 @@
 
-use laddertypes::{morphism_path::ShortestPathProblem, morphism::{Morphism, MorphismType}, StructMember};
-use crate::{c_gen_types::get_c_repr_type, struct_layout::StructLayout};
+use laddertypes::morphism::{Morphism, MorphismType};
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct LdmcPrimMorph {
diff --git a/src/parser.rs b/src/parser.rs
index 9590519..ef2acff 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -19,7 +19,7 @@ pub fn morphism_base_parser(
     just("```")
     .then(take_until(just("```")))
     .map(
-        move |(a, (b, c))| {
+        move |(_a, (b, _c))| {
             b.iter().collect()
         }
     )
diff --git a/src/platform/x86.rs b/src/platform/x86.rs
new file mode 100644
index 0000000..aaae9c2
--- /dev/null
+++ b/src/platform/x86.rs
@@ -0,0 +1,43 @@
+use std::collections::HashMap;
+
+pub fn example_substitution() {
+    let mut γ = HashMap::new();
+    γ.insert(
+        type_dict.get_typeid_creat(&"Byte"),
+        type_dict.parse("<Seq~<StaticLength 8> Bit>").expect("parse")
+            .apply_subst(&γ)
+            .clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.UInt8"),
+        type_dict.parse("ℤ_2^8 ~ <PosInt 2 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>").expect("parse")
+            .apply_subst(&γ)
+            .clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.UInt16"),
+        type_dict.parse("ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >").expect("parse")
+            .apply_subst(&γ)
+            .clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.UInt32"),
+        type_dict.parse("ℤ_2^32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >").expect("parse")
+            .apply_subst(&γ).clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.UInt64"),
+        type_dict.parse("ℤ_2^64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >").expect("parse")
+            .apply_subst(&γ).clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.Float32"),
+        type_dict.parse("ℝ ~ IEEE-754.Float32 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
+            .apply_subst(&γ).clone()
+    );
+    γ.insert(
+        type_dict.get_typeid_creat(&"x86.Float64"),
+        type_dict.parse("ℝ ~ IEEE-754.Float64 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
+            .apply_subst(&γ).clone()
+    );
+}
diff --git a/src/struct_layout.rs b/src/struct_layout.rs
index d07b129..b8816e9 100644
--- a/src/struct_layout.rs
+++ b/src/struct_layout.rs
@@ -1,7 +1,6 @@
 
-use std::ops::Deref;
 
-use laddertypes::{parser::*, unparser::*, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm};
+use laddertypes::{parser::*, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm};
 
 #[derive(Clone, Copy, Debug)]
 pub enum ObjectSize {

From 27ea365755ad238ae9a5f2e66d3d820b190feacb Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 9 May 2025 03:33:18 +0200
Subject: [PATCH 14/31] improve integration

* add command line parsing
* read morphism base directory from environment
* generate C library of multiple morphisms
---
 Cargo.toml            |  2 ++
 src/c_gen/gen_lib.rs  | 74 ++++++++++++++++++++++++++++++++++++++++
 src/c_gen/gen_main.rs | 49 ---------------------------
 src/c_gen/mod.rs      |  2 +-
 src/main.rs           | 78 ++++++++++++++++++++++++++++++++-----------
 src/parser.rs         | 28 ++++++++++++++--
 6 files changed, 161 insertions(+), 72 deletions(-)
 create mode 100644 src/c_gen/gen_lib.rs
 delete mode 100644 src/c_gen/gen_main.rs

diff --git a/Cargo.toml b/Cargo.toml
index 8eace12..c4ca5d9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,3 +8,5 @@ chumsky = "0.9.0"
 ariadne = "0.2"
 laddertypes = { path = "../lib-laddertypes", features = ["pretty"] }
 tiny-ansi = { version = "0.1.0" }
+clap = { version = "4.5.37", features = ["derive"] }
+walkdir = "2.5.0"
diff --git a/src/c_gen/gen_lib.rs b/src/c_gen/gen_lib.rs
new file mode 100644
index 0000000..fa2ce88
--- /dev/null
+++ b/src/c_gen/gen_lib.rs
@@ -0,0 +1,74 @@
+use {
+    super::types::get_c_repr_arg_type, crate::{c_gen::LdmcCTargetMorph, LdmcPrimMorph}, laddertypes::{morphism::MorphismInstance, parser::*, TypeDict}, std::collections::HashMap
+};
+
+pub fn generate_lib(
+    dict: &mut impl TypeDict,
+    morphisms: Vec< (String, MorphismInstance<LdmcPrimMorph>) >
+) -> Result<String, ()> {
+    let mut target = LdmcCTargetMorph::new();
+    let mut wrappers = String::new();
+
+    for (name, morph) in morphisms {
+        match target.add_instantiation(dict, morph) {
+            Ok(inst) => {
+                if name == "main" {
+                    let mut c_source = String::new();
+                    c_source.push_str(&format!(r#"
+                #include <unistd.h>
+
+                int main() {{
+                    uint8_t bufIn[4096];
+                    uint8_t bufOut[4096];"#));
+
+                    let (src_top, src_floor) = inst.ty.src_type.get_floor_type();
+                    if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
+                        c_source.push_str("scanf(\"%s\", bufIn);");
+                    } else {
+                        c_source.push_str("read(0, bufIn, sizeof(bufIn));");
+                    }
+
+                    c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
+
+                    if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
+                        &inst.ty.src_type,
+                        &dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
+                    ) {
+                        c_source.push_str("printf(\"%s\\n\", bufOut);");
+                    } else {
+                        c_source.push_str("write(1, bufOut, sizeof(bufOut));");
+                    }
+                    c_source.push_str("
+                    return 0;
+                }");
+                    wrappers.push_str(&c_source);
+                } else {
+                    target.add_type(dict, inst.ty.src_type.clone());
+                    target.add_type(dict, inst.ty.dst_type.clone());
+
+                    wrappers.push_str(&format!("
+                        int {} (
+                            {} const * restrict src,
+                            {} * restrict dst
+                        ) {{
+                            return {}( (void*)src, (void*)dst );
+                        }}
+                    ", name,
+                        get_c_repr_arg_type(dict, &inst.ty.src_type),
+                        get_c_repr_arg_type(dict, &inst.ty.dst_type),
+                        inst.instantiated_symbol_name(dict, &HashMap::new())
+                    ));
+                }
+            }
+            Err(_err) => {
+                eprintln!("failed to create morphism instatiation");
+                return Err(());
+            }
+        }
+    }
+
+    let mut c_source = target.into_c_source(dict);
+    c_source.push_str(&wrappers);
+
+    Ok(c_source)
+}
diff --git a/src/c_gen/gen_main.rs b/src/c_gen/gen_main.rs
deleted file mode 100644
index 70847ea..0000000
--- a/src/c_gen/gen_main.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-use {
-    laddertypes::{TypeDict, morphism::MorphismInstance, parser::*},
-    crate::LdmcPrimMorph,
-    crate::c_gen::LdmcCTargetMorph,
-    std::collections::HashMap,
-};
-
-pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance<LdmcPrimMorph>) -> Result<String, ()> {
-    let mut target = LdmcCTargetMorph::new();
-    let ty = morph.get_type();
-    match target.add_instantiation(dict, morph) {
-        Ok(inst) => {
-            let mut c_source = target.into_c_source(dict);
-
-            c_source.push_str(&format!(r#"
-        #include <unistd.h>
-
-        int main() {{
-            uint8_t bufIn[4096];
-            uint8_t bufOut[4096];"#));
-
-            let (src_top, src_floor) = ty.src_type.get_floor_type();
-            if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
-                c_source.push_str("scanf(\"%s\", bufIn);");
-            } else {
-                c_source.push_str("read(0, bufIn, sizeof(bufIn));");
-            }
-
-            c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
-
-            if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
-                &ty.src_type,
-                &dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
-            ) {
-                c_source.push_str("printf(\"%s\\n\", bufOut);");
-            } else {
-                c_source.push_str("write(1, bufOut, sizeof(bufOut));");
-            }
-            c_source.push_str("
-            return 0;
-        }");
-            Ok(c_source)
-        }
-        Err(err) => {
-            eprintln!("failed to create morphism instatiation");
-            Err(())
-        }
-    }
-}
diff --git a/src/c_gen/mod.rs b/src/c_gen/mod.rs
index f8c11f9..cf994c5 100644
--- a/src/c_gen/mod.rs
+++ b/src/c_gen/mod.rs
@@ -1,6 +1,6 @@
 pub mod types;
 pub mod morph;
-pub mod gen_main;
+pub mod gen_lib;
 
 pub use {
     morph::target_morph::LdmcCTargetMorph
diff --git a/src/main.rs b/src/main.rs
index 01df9a7..d1e114a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,33 +9,66 @@ use {
     crate::{
         morphism::LdmcPrimMorph,
         parser::morphism_base_parser,
-    },
-    ariadne::{Color, Label, Report, ReportKind, Source},
-    chumsky::prelude::*,
-    laddertypes::{
+    }, ariadne::{Color, Label, Report, ReportKind, Source}, chumsky::prelude::*, clap::{Parser, Subcommand}, laddertypes::{
         morphism::MorphismType,
         parser::ParseLadderType, BimapTypeDict
-    },
-    std::{sync::{Arc, RwLock}},
-    tiny_ansi::TinyAnsi
+    }, parser::morphism_type_parser, std::{path::PathBuf,
+    sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi,
+    walkdir::WalkDir
 };
 
-fn main() {
-    let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
+#[derive(Parser, Debug)]
+#[command(version, about, long_about = None)]
+struct Args {
+    #[arg(short='b', long)]
+    morphism_base: Vec<PathBuf>,
 
+    #[arg(short='m', long="morph")]
+    morphisms: Vec<String>
+}
+
+fn main() {
+    let args = Args::parse();
+    let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
     let mut morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcPrimMorph>::new();
 
-    let mut args = std::env::args().skip(1);
-    let src_type_arg = args.next().expect("src type expected");
-    let dst_type_arg = args.next().expect("dst type expected");
+    // 1. load morphism base
+    let mut mb_paths = args.morphism_base;
 
-    for mb_path in args {
+    // 1.1. pfade ermitteln
+    let env_var = "MORPHISM_BASE";
+    let suffix = ".morphism-base";
+
+    match std::env::var(env_var) {
+        Ok(path_str) => {
+            let path = std::path::Path::new(&path_str);
+            if path.is_dir() {
+                for entry in WalkDir::new(path)
+                    .into_iter()
+                    .filter_map(Result::ok)
+                    .filter(|e| e.path().is_file() && e.path().extension().map_or(false, |ext| ext == &suffix[1..]))
+                {
+                    mb_paths.push(entry.path().into());
+                }
+            } else {
+                eprintln!("morphism-base path is not a directory: {:?}", path);
+            }
+        }
+        Err(e) => {
+            eprintln!("failed to read environment variable {}: {}", env_var, e);
+        }
+    }
+
+    // 1.2. read files
+    for mb_path in mb_paths {
         let src = std::fs::read_to_string(mb_path.clone()).expect("failed to read morphism base");
+
+        use chumsky::Parser;
         let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
         match result {
             Ok((includes, morphisms)) => {
                 println!("{}",includes);
-                eprintln!("[{}] parse ok.", mb_path.bright_yellow());
+                eprintln!("[{}] parse ok.", mb_path.to_str().unwrap().bright_yellow());
                 for m in morphisms {
                     morphism_base.add_morphism(m);
                 }
@@ -57,10 +90,17 @@ 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("");
+    // 2. Generate Morphisms
+    let mut instances = Vec::new();
+    for morph_decl in args.morphisms.iter() {
+        use chumsky::Parser;
+        if let Ok((name, src_type, dst_type)) = morphism_type_parser(type_dict.clone()).parse(morph_decl.as_str()) {
+            let ty = MorphismType{ src_type, dst_type };
+            instances.push( (name, morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism")) );
+        }
+    }
 
-    let ty = MorphismType{ src_type, dst_type };
-    let m = morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism");
-    println!("{}", crate::c_gen::gen_main::generate_main(&mut type_dict, m).expect("failed to generate main function"));
+    println!("{}",
+        crate::c_gen::gen_lib::generate_lib(&mut type_dict, instances).expect("failed to generate main function")
+    );
 }
diff --git a/src/parser.rs b/src/parser.rs
index ef2acff..24ca0a9 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,7 +1,7 @@
 use {
     crate::morphism::LdmcPrimMorph, chumsky::{
         prelude::*, text::*
-    }, laddertypes::{morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
+    }, laddertypes::{TypeTerm, morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
 };
 
 /* morphism-base text format:
@@ -59,8 +59,8 @@ pub fn morphism_base_parser(
                 ty_args.push((var_id, kind));
             }
 
-            let src_type = type_dict.parse_desugared(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
-            let dst_type = type_dict.parse_desugared(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
+            let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type");
+            let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type");
 
             LdmcPrimMorph {
                 symbol,
@@ -76,3 +76,25 @@ pub fn morphism_base_parser(
 
     )
 }
+
+pub fn morphism_type_parser(
+    mut type_dict: Arc<RwLock< BimapTypeDict >>
+) -> impl Parser<char, (String, TypeTerm, TypeTerm), Error = Simple<char>> {
+    ident()
+        .padded()
+        .then(just(":").ignored())
+        .then(
+            take_until(just("-->").ignored())
+        )
+        .then(take_until(end()))
+        .map({
+            let type_dict = type_dict.clone();
+            move |((name, src_type), dst_type)| {
+                (
+                    name.0,
+                    type_dict.clone().parse(&src_type.0.iter().collect::<String>()).expect("parse type"),
+                    type_dict.clone().parse(&dst_type.0.iter().collect::<String>()).expect("parse type")
+                )
+            }
+        })
+}

From 1116457bcca4f831f525459ce6bbb9b5fe4dbcc9 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 10 May 2025 15:00:54 +0200
Subject: [PATCH 15/31] add example C program which generates (de)marshaling
 with ldmc

---
 examples/01-uint-example/.gitignore |  1 +
 examples/01-uint-example/main.c     | 14 ++++++++++++++
 examples/01-uint-example/makefile   | 23 +++++++++++++++++++++++
 3 files changed, 38 insertions(+)
 create mode 100644 examples/01-uint-example/.gitignore
 create mode 100644 examples/01-uint-example/main.c
 create mode 100644 examples/01-uint-example/makefile

diff --git a/examples/01-uint-example/.gitignore b/examples/01-uint-example/.gitignore
new file mode 100644
index 0000000..567609b
--- /dev/null
+++ b/examples/01-uint-example/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/examples/01-uint-example/main.c b/examples/01-uint-example/main.c
new file mode 100644
index 0000000..2db8422
--- /dev/null
+++ b/examples/01-uint-example/main.c
@@ -0,0 +1,14 @@
+#include "morphisms.h"
+
+int main(int argc, char* argv[]) {
+    if( argc > 1 ) {
+        uint64_t value;
+        demarshal( argv[1], &value );
+
+        uint64_t result = value * value;
+
+        char buf[256];
+        marshal( &result, buf );
+        printf("%s\n", buf);
+    }
+}
diff --git a/examples/01-uint-example/makefile b/examples/01-uint-example/makefile
new file mode 100644
index 0000000..528afbf
--- /dev/null
+++ b/examples/01-uint-example/makefile
@@ -0,0 +1,23 @@
+all: build/square
+.PHONY: build clean
+
+build:
+	mkdir -p build
+
+build/morphisms.h: build
+	ldmc \
+     -m "marshal: \
+	        ℕ ~ native.UInt64 \
+	    --> ℕ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>" \
+\
+     -m "demarshal:  \
+            ℕ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8> \
+	    --> ℕ ~ native.UInt64 " \
+\
+     >| build/morphisms.h
+
+build/square: build build/morphisms.h
+	gcc -Os -I../../morphisms/runtime/include/ -Ibuild main.c -o build/square
+
+clean:
+	rm build/ -rf

From a58ac1a69c451e1785edbe0a3b771bdbb9f9aceb Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 10 May 2025 15:16:51 +0200
Subject: [PATCH 16/31] in generation of main function, fix case that
 input/output buffer is a  nullterm string

---
 src/c_gen/gen_lib.rs | 17 +++++++++++------
 src/main.rs          | 15 +++++++++------
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/src/c_gen/gen_lib.rs b/src/c_gen/gen_lib.rs
index fa2ce88..f8858bb 100644
--- a/src/c_gen/gen_lib.rs
+++ b/src/c_gen/gen_lib.rs
@@ -21,18 +21,23 @@ pub fn generate_lib(
                     uint8_t bufIn[4096];
                     uint8_t bufOut[4096];"#));
 
-                    let (src_top, src_floor) = inst.ty.src_type.get_floor_type();
-                    if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
+                    if let Ok(_) = laddertypes::subtype_unify(
+                        &inst.ty.src_type,
+                        &dict.parse("<Seq~<ValueTerminated 0> Char~Ascii~native.UInt8>").expect("")
+                    ) {
                         c_source.push_str("scanf(\"%s\", bufIn);");
                     } else {
                         c_source.push_str("read(0, bufIn, sizeof(bufIn));");
                     }
 
-                    c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
+                    c_source.push_str(
+                        &format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#,
+                            inst.instantiated_symbol_name(dict, &HashMap::new()))
+                    );
 
-                    if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
-                        &inst.ty.src_type,
-                        &dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
+                    if let Ok(ψ) = laddertypes::subtype_unify(
+                        &inst.ty.dst_type,
+                        &dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("")
                     ) {
                         c_source.push_str("printf(\"%s\\n\", bufOut);");
                     } else {
diff --git a/src/main.rs b/src/main.rs
index d1e114a..b7111d6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,12 +9,15 @@ use {
     crate::{
         morphism::LdmcPrimMorph,
         parser::morphism_base_parser,
-    }, ariadne::{Color, Label, Report, ReportKind, Source}, chumsky::prelude::*, clap::{Parser, Subcommand}, laddertypes::{
-        morphism::MorphismType,
-        parser::ParseLadderType, BimapTypeDict
-    }, parser::morphism_type_parser, std::{path::PathBuf,
-    sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi,
-    walkdir::WalkDir
+    },
+    laddertypes::{
+        morphism::MorphismType, BimapTypeDict
+    }, parser::morphism_type_parser,
+    ariadne::{Color, Label, Report, ReportKind, Source},
+    clap::Parser,
+    walkdir::WalkDir,
+    tiny_ansi::TinyAnsi,
+    std::{path::PathBuf, sync::{Arc, RwLock}},
 };
 
 #[derive(Parser, Debug)]

From 783c70b2e26ba20e0ff6ceabd27d40904522677b Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 10 May 2025 15:40:49 +0200
Subject: [PATCH 17/31] add output option in cli arguments

---
 src/main.rs | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index b7111d6..5951618 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -17,7 +17,7 @@ use {
     clap::Parser,
     walkdir::WalkDir,
     tiny_ansi::TinyAnsi,
-    std::{path::PathBuf, sync::{Arc, RwLock}},
+    std::{path::PathBuf, sync::{Arc, RwLock}, io::Write},
 };
 
 #[derive(Parser, Debug)]
@@ -27,7 +27,10 @@ struct Args {
     morphism_base: Vec<PathBuf>,
 
     #[arg(short='m', long="morph")]
-    morphisms: Vec<String>
+    morphisms: Vec<String>,
+
+    #[arg(short='o', long)]
+    output: Option<PathBuf>
 }
 
 fn main() {
@@ -103,7 +106,11 @@ fn main() {
         }
     }
 
-    println!("{}",
-        crate::c_gen::gen_lib::generate_lib(&mut type_dict, instances).expect("failed to generate main function")
-    );
+    let c_source = crate::c_gen::gen_lib::generate_lib(&mut type_dict, instances).expect("failed to generate library");
+    if let Some(out_path) = args.output {
+        let mut file = std::fs::File::create(out_path).expect("failed to open output file");
+        file.write_all(c_source.as_bytes()).expect("failed to write output file");
+    } else {
+        println!("{}", c_source);
+    }
 }

From efa584dfb5c49ada3d97ce13d75225434f10ab36 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 10 May 2025 16:25:36 +0200
Subject: [PATCH 18/31] update test.sh to new cli features

---
 test/test.sh | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/test/test.sh b/test/test.sh
index 0e3fc9b..f33ab02 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -8,13 +8,12 @@ run_test_case() {
 -----------------------------------------------------------------------------
 Running test case ${TEST_NAME}"
 
-    ldmc "${SRC_TYPE}" "${DST_TYPE}" ../morphisms/*.morphism-base 2>|.tmp/ldmc_err 1>| target/src/${TEST_NAME}.c \
+    ldmc -m "main : ${SRC_TYPE} --> ${DST_TYPE}" -o target/src/${TEST_NAME}.c 2>|.tmp/ldmc_err  \
     || (echo "... error at generation:"; cat .tmp/ldmc_err; return -1);
 
     gcc -I../morphisms/runtime/include target/src/${TEST_NAME}.c -o target/${TEST_NAME} \
     || (echo "... error at compilation:"; return -2);
 
-
     LEN="$(echo -n "${EXPECT}" | wc -c)"
     RESULT="$(echo -n ${INPUT} | ./target/${TEST_NAME} 2>.tmp/target_err | head -c ${LEN})"
 

From 4a705241fe4139d34e2aac852aeeb500fbe6cb64 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 10 May 2025 16:27:56 +0200
Subject: [PATCH 19/31] manage include blocks & only output required blocks
 once

---
 src/c_gen/gen_lib.rs            |  6 ++--
 src/c_gen/morph/target_morph.rs | 54 +++++++++++++++++++++++----------
 src/main.rs                     | 27 ++++++++++-------
 3 files changed, 58 insertions(+), 29 deletions(-)

diff --git a/src/c_gen/gen_lib.rs b/src/c_gen/gen_lib.rs
index f8858bb..95359cc 100644
--- a/src/c_gen/gen_lib.rs
+++ b/src/c_gen/gen_lib.rs
@@ -1,12 +1,14 @@
 use {
-    super::types::get_c_repr_arg_type, crate::{c_gen::LdmcCTargetMorph, LdmcPrimMorph}, laddertypes::{morphism::MorphismInstance, parser::*, TypeDict}, std::collections::HashMap
+    super::types::get_c_repr_arg_type, crate::{c_gen::LdmcCTargetMorph, LdmcPrimMorph}, laddertypes::{morphism::MorphismInstance, parser::*, MorphismType, TypeDict}, std::collections::HashMap
 };
 
 pub fn generate_lib(
     dict: &mut impl TypeDict,
+    include_blocks: Vec< String >,
+    include_dependencies: HashMap< MorphismType, usize >,
     morphisms: Vec< (String, MorphismInstance<LdmcPrimMorph>) >
 ) -> Result<String, ()> {
-    let mut target = LdmcCTargetMorph::new();
+    let mut target = LdmcCTargetMorph::new( include_blocks, include_dependencies );
     let mut wrappers = String::new();
 
     for (name, morph) in morphisms {
diff --git a/src/c_gen/morph/target_morph.rs b/src/c_gen/morph/target_morph.rs
index fcb90fb..161d6fa 100644
--- a/src/c_gen/morph/target_morph.rs
+++ b/src/c_gen/morph/target_morph.rs
@@ -1,18 +1,20 @@
 use {
     crate::{
         c_gen::types::{
-            encode_morph_type_to_symbol, get_c_repr_definition, get_c_repr_type, encode_type_to_value
+            encode_morph_type_to_symbol, encode_type_to_value, get_c_repr_definition, get_c_repr_kind, get_c_repr_type
         },
         morphism::LdmcPrimMorph
     },
     laddertypes::{
-        parser::*, MorphismInstance, TypeDict, TypeTerm, Morphism
+        parser::*, Morphism, MorphismInstance, MorphismType, TypeDict, TypeTerm
     },
     std::collections::HashMap
 };
 
 pub struct LdmcCTargetMorph {
-    includes: Vec< String >,
+    include_blocks: Vec< String >,
+    include_dependencies: HashMap< MorphismType, usize >,
+    active_includes: Vec< usize >,
     active_types: Vec< TypeTerm >,
     active_instantiations: Vec< LdmcPrimMorph >,
     active_lenpfx_types: Vec< (TypeTerm, TypeTerm) >,
@@ -21,19 +23,35 @@ pub struct LdmcCTargetMorph {
 }
 
 impl LdmcCTargetMorph {
-    pub fn new() -> Self {
-        LdmcCTargetMorph {
-            includes: vec![
-                "#include <stdint.h>".into(),
-                "#include <array/length-prefix.h>".into(),
-                "#define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; }".into(),
-            ],
+    pub fn add_required_include_block(&mut self, block: String) {
+        let i = self.include_blocks.len();
+        self.active_includes.push(i);
+        self.include_blocks.push(block);
+    }
+
+    pub fn new(
+        include_blocks: Vec< String >,
+        include_dependencies: HashMap< MorphismType, usize >
+    ) -> Self {
+        let mut m = LdmcCTargetMorph {
+            include_blocks,
+            include_dependencies,
+            active_includes: Vec::new(),
             active_instantiations: Vec::new(),
             active_types: Vec::new(),
             active_lenpfx_types: Vec::new(),
             typedefs: Vec::new(),
             macro_calls: Vec::new()
-        }
+        };
+
+        m.add_required_include_block(
+            "/* default ldmc includes */
+#include <stdint.h>
+#define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; }
+
+".into()
+        );
+        m
     }
 
     pub fn add_type(&mut self, dict: &mut impl TypeDict, ty: TypeTerm) {
@@ -106,15 +124,14 @@ impl LdmcCTargetMorph {
 
     pub fn into_c_source(mut self, dict: &mut impl TypeDict) -> String {
         let mut source = String::new();
-        self.includes.dedup();
+        self.active_includes.dedup();
+        self.typedefs.dedup();
         self.macro_calls.dedup();
-        self.active_types.dedup();
 
-        for inc in self.includes {
-            source.push_str(&inc);
+        for i in self.active_includes {
+            source.push_str( &self.include_blocks[i] );
             source.push('\n');
         }
-
         source.push('\n');
 
         for typedef in self.typedefs {
@@ -146,6 +163,11 @@ impl LdmcCTargetMorph {
 
         match &morph_inst {
             MorphismInstance::Primitive { ψ, σ, morph } => {
+                if let Some(i) = self.include_dependencies.get(&morph.get_type()) {
+                    self.active_includes.push(*i);
+                }
+
+
                 let mut c_source = String::new();
                 for (ty_id, kind) in morph.type_args.iter() {
                     if let laddertypes::TypeID::Var(var_id) = ty_id {
diff --git a/src/main.rs b/src/main.rs
index 5951618..8e8f40b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,15 +9,9 @@ use {
     crate::{
         morphism::LdmcPrimMorph,
         parser::morphism_base_parser,
-    },
-    laddertypes::{
-        morphism::MorphismType, BimapTypeDict
-    }, parser::morphism_type_parser,
-    ariadne::{Color, Label, Report, ReportKind, Source},
-    clap::Parser,
-    walkdir::WalkDir,
-    tiny_ansi::TinyAnsi,
-    std::{path::PathBuf, sync::{Arc, RwLock}, io::Write},
+    }, ariadne::{Color, Label, Report, ReportKind, Source}, clap::Parser, laddertypes::{
+        morphism::MorphismType, BimapTypeDict, Morphism
+    }, parser::morphism_type_parser, std::{io::Write, path::PathBuf, sync::{Arc, RwLock}}, tiny_ansi::TinyAnsi, walkdir::WalkDir
 };
 
 #[derive(Parser, Debug)]
@@ -66,6 +60,10 @@ fn main() {
     }
 
     // 1.2. read files
+
+    let mut include_blocks = Vec::new();
+    let mut include_dependencies = std::collections::HashMap::new();
+
     for mb_path in mb_paths {
         let src = std::fs::read_to_string(mb_path.clone()).expect("failed to read morphism base");
 
@@ -73,9 +71,16 @@ fn main() {
         let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
         match result {
             Ok((includes, morphisms)) => {
-                println!("{}",includes);
                 eprintln!("[{}] parse ok.", mb_path.to_str().unwrap().bright_yellow());
+
+                let include_idx = include_blocks.len();
+
+                let mut includes_prefixed = format!("/* from `{}` */", mb_path.display());
+                includes_prefixed.push_str(&includes);
+                include_blocks.push(includes_prefixed);
+
                 for m in morphisms {
+                    include_dependencies.insert( m.get_type(), include_idx );
                     morphism_base.add_morphism(m);
                 }
             }
@@ -106,7 +111,7 @@ fn main() {
         }
     }
 
-    let c_source = crate::c_gen::gen_lib::generate_lib(&mut type_dict, instances).expect("failed to generate library");
+    let c_source = crate::c_gen::gen_lib::generate_lib(&mut type_dict, include_blocks, include_dependencies, instances).expect("failed to generate library");
     if let Some(out_path) = args.output {
         let mut file = std::fs::File::create(out_path).expect("failed to open output file");
         file.write_all(c_source.as_bytes()).expect("failed to write output file");

From 6f0a0f5927f748b0e80ee988a18cbc392103df0d Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 10 May 2025 16:28:58 +0200
Subject: [PATCH 20/31] when generating #defines for values of type variables,
 distinguish between variables of type 'Type' and others

---
 src/c_gen/morph/target_morph.rs | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/src/c_gen/morph/target_morph.rs b/src/c_gen/morph/target_morph.rs
index 161d6fa..2eb25b0 100644
--- a/src/c_gen/morph/target_morph.rs
+++ b/src/c_gen/morph/target_morph.rs
@@ -171,23 +171,21 @@ impl LdmcCTargetMorph {
                 let mut c_source = String::new();
                 for (ty_id, kind) in morph.type_args.iter() {
                     if let laddertypes::TypeID::Var(var_id) = ty_id {
-                        //if morph_inst.get_type().strip_halo().src_type.contains_var(*var_id) ||
-                        //morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
-                            if let Some(val) = σ.get(ty_id) {
-                                let type_var_value = get_c_repr_type(dict, val);
-                                c_source.push_str(&format!("    #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
-                            }
-                            //}
+                        if let Some(val) = σ.get(ty_id) {
+                            let type_var_value =
+                                if kind == "Type" {
+                                    get_c_repr_type(dict, val)
+                                } else {
+                                    encode_type_to_value(dict, val)
+                                };
+                            c_source.push_str(&format!("    #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
+                        }
                     }
                 }
                 c_source.push_str(&morph.c_source);
                 for (ty_id, kind) in morph.type_args.iter() {
                     if let laddertypes::TypeID::Var(var_id) = ty_id {
-                        //if morph_inst.get_type().strip_halo().src_type.contains_var(*var_id) ||
-                        //morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
-
-                            c_source.push_str(&format!("\n    #undef {}", dict.get_typename(&ty_id).unwrap()));
-                            //}
+                        c_source.push_str(&format!("\n    #undef {}", dict.get_typename(&ty_id).unwrap()));
                     }
                 }
 

From ea2504ff072458ce95e2d0f912d277707053f1b6 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 10 May 2025 17:53:31 +0200
Subject: [PATCH 21/31] morphisms: fix bitshift in lenpfx to msb-cont

---
 morphisms/length_prefix.morphism-base | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/morphisms/length_prefix.morphism-base b/morphisms/length_prefix.morphism-base
index a694931..1700361 100644
--- a/morphisms/length_prefix.morphism-base
+++ b/morphisms/length_prefix.morphism-base
@@ -29,13 +29,13 @@ morph_array_as_lenpfx_to_continuation_bit (T:Type)
 ```
     for( uint64_t i = 0; i < src->len; ++i ) {
         const size_t n_bits = 8*sizeof(T);
-        if( src->items[i] & (1<<(n_bits-1)) ) {
-            fprintf(stderr, "error: value to high for MsbContinuation\n");
+        if( src->items[i] & ((uint64_t)1<<(n_bits-1)) ) {
+            fprintf(stderr, "error: value has MSB set, while being used in MsbContinuation sequence!\n");
             return -1;
         }
 
         dst[i] = src->items[i];
         if( i+1 < src->len )
-            dst[i] |= (1<<(n_bits-1));
+            dst[i] |= ((uint64_t)1<<(n_bits-1));
     }
 ```

From 692a34c2574de8e3f559409e23284feffb4acee5 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 14 May 2025 10:19:48 +0200
Subject: [PATCH 22/31] main: when loading morphism base, remove . from path
 suffix variable

---
 src/main.rs | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 8e8f40b..675c12d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -37,7 +37,7 @@ fn main() {
 
     // 1.1. pfade ermitteln
     let env_var = "MORPHISM_BASE";
-    let suffix = ".morphism-base";
+    let suffix = "morphism-base";
 
     match std::env::var(env_var) {
         Ok(path_str) => {
@@ -46,7 +46,10 @@ fn main() {
                 for entry in WalkDir::new(path)
                     .into_iter()
                     .filter_map(Result::ok)
-                    .filter(|e| e.path().is_file() && e.path().extension().map_or(false, |ext| ext == &suffix[1..]))
+                    .filter(|e|
+                        e.path().is_file() &&
+                        e.path().extension().map_or(false, |ext| ext == suffix)
+                    )
                 {
                     mb_paths.push(entry.path().into());
                 }

From 7dd6352760b54b438424c9022aa7421b996270b1 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 14 May 2025 10:20:55 +0200
Subject: [PATCH 23/31] code generation: only use scanf/printf on newline('\n')
 terminated strings

---
 src/c_gen/gen_lib.rs | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/c_gen/gen_lib.rs b/src/c_gen/gen_lib.rs
index 95359cc..4615fab 100644
--- a/src/c_gen/gen_lib.rs
+++ b/src/c_gen/gen_lib.rs
@@ -25,15 +25,15 @@ pub fn generate_lib(
 
                     if let Ok(_) = laddertypes::subtype_unify(
                         &inst.ty.src_type,
-                        &dict.parse("<Seq~<ValueTerminated 0> Char~Ascii~native.UInt8>").expect("")
+                        &dict.parse("<Seq~<ValueTerminated '\\n'> Char~Ascii~native.UInt8>").expect("")
                     ) {
-                        c_source.push_str("scanf(\"%s\", bufIn);");
+                        c_source.push_str("scanf(\"%s\", bufIn);\n");
                     } else {
-                        c_source.push_str("read(0, bufIn, sizeof(bufIn));");
+                        c_source.push_str("read(0, bufIn, sizeof(bufIn));\n");
                     }
 
                     c_source.push_str(
-                        &format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#,
+                        &format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );\n"#,
                             inst.instantiated_symbol_name(dict, &HashMap::new()))
                     );
 
@@ -41,9 +41,9 @@ pub fn generate_lib(
                         &inst.ty.dst_type,
                         &dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").expect("")
                     ) {
-                        c_source.push_str("printf(\"%s\\n\", bufOut);");
+                        c_source.push_str("printf(\"%s\\n\", bufOut);\n");
                     } else {
-                        c_source.push_str("write(1, bufOut, sizeof(bufOut));");
+                        c_source.push_str("write(1, bufOut, sizeof(bufOut));\n");
                     }
                     c_source.push_str("
                     return 0;

From 24f9a0f5b5c71653b913eb500c08c4f4642d29a6 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 14 May 2025 10:28:31 +0200
Subject: [PATCH 24/31] C code gen: rename include block to header block

---
 src/c_gen/morph/target_morph.rs | 44 ++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/c_gen/morph/target_morph.rs b/src/c_gen/morph/target_morph.rs
index 2eb25b0..dd075bf 100644
--- a/src/c_gen/morph/target_morph.rs
+++ b/src/c_gen/morph/target_morph.rs
@@ -12,21 +12,21 @@ use {
 };
 
 pub struct LdmcCTargetMorph {
-    include_blocks: Vec< String >,
-    include_dependencies: HashMap< MorphismType, usize >,
-    active_includes: Vec< usize >,
+    header_blocks: Vec< String >,
+    header_dependencies: HashMap< MorphismType, usize >,
+    active_headers: Vec< usize >,
     active_types: Vec< TypeTerm >,
-    active_instantiations: Vec< LdmcPrimMorph >,
+    active_morphisms: Vec< LdmcPrimMorph >,
     active_lenpfx_types: Vec< (TypeTerm, TypeTerm) >,
     typedefs: Vec< String >,
     macro_calls: Vec< String >
 }
 
 impl LdmcCTargetMorph {
-    pub fn add_required_include_block(&mut self, block: String) {
-        let i = self.include_blocks.len();
-        self.active_includes.push(i);
-        self.include_blocks.push(block);
+    pub fn add_required_header_block(&mut self, block: String) {
+        let i = self.header_blocks.len();
+        self.active_headers.push(i);
+        self.header_blocks.push(block);
     }
 
     pub fn new(
@@ -34,18 +34,18 @@ impl LdmcCTargetMorph {
         include_dependencies: HashMap< MorphismType, usize >
     ) -> Self {
         let mut m = LdmcCTargetMorph {
-            include_blocks,
-            include_dependencies,
-            active_includes: Vec::new(),
-            active_instantiations: Vec::new(),
+            header_blocks: include_blocks,
+            header_dependencies: include_dependencies,
+            active_headers: Vec::new(),
+            active_morphisms: Vec::new(),
             active_types: Vec::new(),
             active_lenpfx_types: Vec::new(),
             typedefs: Vec::new(),
             macro_calls: Vec::new()
         };
 
-        m.add_required_include_block(
-            "/* default ldmc includes */
+        m.add_required_header_block(
+            "/* default ldmc header */
 #include <stdint.h>
 #define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; }
 
@@ -111,8 +111,8 @@ impl LdmcCTargetMorph {
         morph: MorphismInstance<LdmcPrimMorph>,
     ) -> Result<LdmcPrimMorph, ()> {
         let new_inst = self.bake_morphism(dict, morph)?;
-        if ! self.active_instantiations.contains(&new_inst) {
-            self.active_instantiations.push(new_inst.clone());
+        if ! self.active_morphisms.contains(&new_inst) {
+            self.active_morphisms.push(new_inst.clone());
         }
 
         let ty = new_inst.get_type().strip_halo();
@@ -124,12 +124,12 @@ impl LdmcCTargetMorph {
 
     pub fn into_c_source(mut self, dict: &mut impl TypeDict) -> String {
         let mut source = String::new();
-        self.active_includes.dedup();
+        self.active_headers.dedup();
         self.typedefs.dedup();
         self.macro_calls.dedup();
 
-        for i in self.active_includes {
-            source.push_str( &self.include_blocks[i] );
+        for i in self.active_headers {
+            source.push_str( &self.header_blocks[i] );
             source.push('\n');
         }
         source.push('\n');
@@ -147,7 +147,7 @@ impl LdmcCTargetMorph {
         }
         source.push('\n');
 
-        for m in self.active_instantiations {
+        for m in self.active_morphisms {
             source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
         }
         source
@@ -163,8 +163,8 @@ impl LdmcCTargetMorph {
 
         match &morph_inst {
             MorphismInstance::Primitive { ψ, σ, morph } => {
-                if let Some(i) = self.include_dependencies.get(&morph.get_type()) {
-                    self.active_includes.push(*i);
+                if let Some(i) = self.header_dependencies.get(&morph.get_type()) {
+                    self.active_headers.push(*i);
                 }
 
 

From 0c9a4ccc8bd8de8158c3c24cbdf4bd1a9374e6c2 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 16 May 2025 02:33:17 +0200
Subject: [PATCH 25/31] example: use -o option in makefile

---
 examples/01-uint-example/makefile | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/examples/01-uint-example/makefile b/examples/01-uint-example/makefile
index 528afbf..915101b 100644
--- a/examples/01-uint-example/makefile
+++ b/examples/01-uint-example/makefile
@@ -8,13 +8,13 @@ build/morphisms.h: build
 	ldmc \
      -m "marshal: \
 	        ℕ ~ native.UInt64 \
-	    --> ℕ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>" \
-\
+	    --> ℕ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8> \
+	" \
      -m "demarshal:  \
             ℕ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8> \
-	    --> ℕ ~ native.UInt64 " \
-\
-     >| build/morphisms.h
+	    --> ℕ ~ native.UInt64 \
+	" \
+     -o build/morphisms.h
 
 build/square: build build/morphisms.h
 	gcc -Os -I../../morphisms/runtime/include/ -Ibuild main.c -o build/square

From 0eb8074644f60eeec0c86945bdb90f658ed62693 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 16 May 2025 02:34:18 +0200
Subject: [PATCH 26/31] digit morphism: also print Radix in warning

---
 morphisms/digit.morphism-base | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/morphisms/digit.morphism-base b/morphisms/digit.morphism-base
index f037823..75ab631 100644
--- a/morphisms/digit.morphism-base
+++ b/morphisms/digit.morphism-base
@@ -36,7 +36,7 @@ morph_digit_as_char_to_uint64 (Radix:ℤ)
     else if( *src >= 'A' && *src <= 'F')
         *dst = 0xa + *src - 'A';
     else {
-        fprintf(stderr, "invalid digit 0x%x\n", *src);
+        fprintf(stderr, "invalid digit 0x%x (radix %u)\n", *src, Radix);
         return -1;
     }
 

From 76c005ac8bb743d736cfc62bfd9b6ab23c32a039 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 16 May 2025 13:51:45 +0200
Subject: [PATCH 27/31] morph lenpfx to valterm: make item type generic

---
 morphisms/length_prefix.morphism-base | 6 +++---
 morphisms/value_delim.morphism-base   | 5 ++++-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/morphisms/length_prefix.morphism-base b/morphisms/length_prefix.morphism-base
index 1700361..4a82515 100644
--- a/morphisms/length_prefix.morphism-base
+++ b/morphisms/length_prefix.morphism-base
@@ -13,9 +13,9 @@ morph_array_as_valterm_to_lenpfx (Terminator:native.UInt8)
 ```
 
 
-morph_array_as_lenpfx_to_valterm (Terminator:native.UInt8)
-    <Seq~<LengthPrefix native.UInt64> native.UInt8>
---> <Seq~<ValueTerminated Terminator> native.UInt8>
+morph_array_as_lenpfx_to_valterm (T: Type, Terminator: T)
+    <Seq~<LengthPrefix native.UInt64> T>
+--> <Seq~<ValueTerminated Terminator> T>
 ```
     for( uint64_t i = 0; i < src->len; ++i )
         *dst++ = src->items[i];
diff --git a/morphisms/value_delim.morphism-base b/morphisms/value_delim.morphism-base
index 6e94459..1823634 100644
--- a/morphisms/value_delim.morphism-base
+++ b/morphisms/value_delim.morphism-base
@@ -3,7 +3,7 @@
 #include <stdlib.h>
 ```
 
-morph_seqseq_valsep_uint8 (T: Type, SrcDelim: T, DstDelim: T)
+morph_valsep_delim (T: Type, SrcDelim: T, DstDelim: T)
       < Seq <Seq T> >
     ~ < ValueSep SrcDelim T >
     ~ < Seq~<LengthPrefix native.UInt64> T >
@@ -22,6 +22,9 @@ morph_seqseq_valsep_uint8 (T: Type, SrcDelim: T, DstDelim: T)
             if( DstDelim == '\n' ) {
                 PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, '\\' );
                 PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, 'n' );
+            } else {
+                PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, '\\' );
+                PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, DstDelim );
             }
         } else {
             PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, src->items[i] );

From 62f0ff9eac914d207eb60a42d193c906be10243f Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 16 May 2025 13:53:19 +0200
Subject: [PATCH 28/31] add array morphisms : StaticLength <--> LengthPrefix

---
 morphisms/length_prefix.morphism-base | 32 ++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/morphisms/length_prefix.morphism-base b/morphisms/length_prefix.morphism-base
index 4a82515..70cd3b7 100644
--- a/morphisms/length_prefix.morphism-base
+++ b/morphisms/length_prefix.morphism-base
@@ -3,15 +3,35 @@
 #include <array/length-prefix.h>
 ```
 
-morph_array_as_valterm_to_lenpfx (Terminator:native.UInt8)
-    <Seq~<ValueTerminated Terminator> native.UInt8>
---> <Seq~<LengthPrefix native.UInt64> native.UInt8>
+morph_array_as_static_to_lenpfx (Len: ℤ, T: Type)
+    <Seq~<StaticLength Len> T>
+--> <Seq~<LengthPrefix native.UInt64> T>
 ```
-    length_prefix_nativeUInt64_array_nativeUInt8_clear(dst);
-    while( *src != Terminator )
-        length_prefix_nativeUInt64_array_nativeUInt8_push(dst, *src++);
+    PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, clear)( dst );
+    for( nativeUInt64 i = 0; i < Len; ++i )
+        PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, src->items[i] );
 ```
 
+morph_array_as_lenpfx_to_static (Len: ℤ, T: Type)
+    <Seq~<LengthPrefix native.UInt64> T>
+--> <Seq~<StaticLength Len> T>
+```
+    nativeUInt64 i;
+    for( i = 0; i < Len && i < src->len; ++i )
+        dst->items[i] = src->items[i];
+
+    if( i < Len )
+        memset( &dst[i], 0, (Len-i) * sizeof(T) );
+```
+
+morph_array_as_valterm_to_lenpfx (T: Type, Terminator:T)
+    <Seq~<ValueTerminated Terminator> T>
+--> <Seq~<LengthPrefix native.UInt64> T>
+```
+    PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst );
+    while( *src != Terminator )
+        PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, *src++ );
+```
 
 morph_array_as_lenpfx_to_valterm (T: Type, Terminator: T)
     <Seq~<LengthPrefix native.UInt64> T>

From dfa364bc0f73ffa87134ae8fe27587021253dcbd Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 16 May 2025 13:55:36 +0200
Subject: [PATCH 29/31] length prefix morphism: generic calls to functions with
 C macro

---
 morphisms/value_delim.morphism-base | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/morphisms/value_delim.morphism-base b/morphisms/value_delim.morphism-base
index 1823634..d4ab039 100644
--- a/morphisms/value_delim.morphism-base
+++ b/morphisms/value_delim.morphism-base
@@ -47,17 +47,17 @@ morph_seqseq_as_valsep_to_lenpfx (T: Type, Delim: T, EscKey: T)
 ```
     length_prefix_nativeUInt64_array_nativeUInt64_clear( dst );
 
-    struct LengthPrefix_nativeUInt64_Array_nativeUInt8 * cur_item = NULL;
+    LENGTH_PREFIX_ARRAY_TYPE( nativeUInt64, T ) * cur_item = NULL;
 
-    uint8_t const * start = &src->items[0];
-    uint8_t const * cur = start;
-    uint8_t const * end = &src->items[src->len];
+    T const * start = &src->items[0];
+    T const * cur = start;
+    T const * end = &src->items[src->len];
 
     while( cur < end ) {
         if( *cur == Delim || cur+1 == end ) {
             uint64_t len = cur - start;
 
-            cur_item = malloc( sizeof(uint64_t) + sizeof(uint8_t) * len );
+            cur_item = malloc( sizeof(uint64_t) + sizeof(T) * len );
             cur_item->len = len;
             memcpy( cur_item->items, start, len );
 
@@ -80,17 +80,17 @@ morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
     ~ < ValueSep T Delim >
     ~ < Seq~<LengthPrefix native.UInt64> T >
 ```
-    length_prefix_nativeUInt64_array_nativeUInt8_clear( dst );
+    PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, clear)( dst );
 
     for( uint64_t i = 0; i < src->len; ++i ) {
-        LengthPrefix_nativeUInt64_Array_nativeUInt8_t * item = src->items[i];
+        LENGTH_PREFIX_ARRAY_TYPE( nativeUInt64, T ) * item = src->items[i];
 
         for( uint64_t j = 0; j < item->len; ++j ) {
-            length_prefix_nativeUInt64_array_nativeUInt8_push( items->items[j] );
+            PRESCAN_LENGTH_PREFIX_CALL( nativeUInt64, T, push )( items->items[j] );
         }
 
         if( i+1 < src->len ) {
-            length_prefix_nativeUInt64_array_nativeUInt8_push( Delim );
+            PRESCAN_LENGTH_PREFIX_CALL( nativeUInt64, T, push )( Delim );
         }
     }
 ```

From edd34415111e77e952e588a34cd6cd4bc3332c1f Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 27 May 2025 15:38:57 +0200
Subject: [PATCH 30/31] todo.md

---
 todo.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 todo.md

diff --git a/todo.md b/todo.md
new file mode 100644
index 0000000..39dd24f
--- /dev/null
+++ b/todo.md
@@ -0,0 +1,79 @@
+* BUG: cant find morphism when path is trivial, or when
+       *some* members of a struct have trivial morphism
+
+* BUG:  -O3 kills some Morphisms
+
+* BUG: erroneous code generation with Packed struct layout
+
+* type Aliases / typedefs (load from input file)
+  -- platform specializations
+  -- shortcuts
+
+* add highest-common-rung to generated morphism names
+  (to avoid potential ambiguities)
+
+* add bounds to Morphism type:
+   - subtype bounds
+   - trait bounds
+   - value bounds
+
+* data dependence:
+   - Each Struct creates a Context,
+   where a struct member becomes a type-variable,
+   available after it has been parsed from the input buffer.
+   - need some kind of partial Order over the member data fields,
+   to express parsing dependencies.
+
+* bounds:
+  -> ℕ ~ UInt64   --->  ℕ ~ UInt8
+    - know that value fits into UInt8 ?
+
+  -> <Digit 128> ~ UInt64   -->  <Digit 128> ~ UInt8
+     allows the following path:
+        <Digit 128> ~ UInt64
+     -> <Digit 128> ~ Char ~ Ascii ~ native.UInt8
+     -> <Digit 128> ~ native.UInt8
+
+     this will result in 'invalid digits' that are out of the ascii range
+     and is not wanted.
+     maybe the Morphism from digit to char should not exist for radix 128 (->value bounds on type vars)?
+    -fixed by adding explicit <Digit R>~UInt64 -morph-> <Digit R>~UInt8
+
+* type descriptions: signed posints?
+  - Include minus sign '-' into the <Digit Radix> type ?
+  - or use [<Digit Radix> | Sign] ?
+  - or rather  <SignedPosInt Radix Endianness> ~ {
+      sign: <Option Sign~Char>;
+      digits: <Seq <Digit 10>~Char>
+    };
+  - ?
+
+* size estimation & memory allocation
+  - from each type definition, we need to derive
+    a form for an "allocation schema",
+    of which a value instance of that type defines
+    concrete length values for arrays and members
+    and thus the total required buffer size.
+
+  - in parallel to each morphism we need to know
+    the output-allocation schema in accordance to
+    a given allocation schema of the input data.
+
+  - Complex morphisms allocate a double buffering
+    with maximum required size at each point in the chain
+
+  - optional: allocation free morphisms for members in struct morphism ?
+  - In-Place Morphisms
+
+
+* improve debugability of "no morphism path found"
+  - find a heuristic to guess "implementation overhead" of
+    a missing morphism by its type
+  - Step 1: Calculate Connected Components of src and dst Type ;
+  - Step 2: For each combination of a vertex-pair from src and dst Components,
+            calculate the implementation overhead heuristic ;
+  - Step 3: suggest to the developer the n smallest morphism types that would
+            bridge the two components
+
+
+* allow to define (ladder-typed) functions, not just morphisms

From cff14cf09624e2d4502e7e0f1b46e2919b24539a Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 28 May 2025 17:33:22 +0200
Subject: [PATCH 31/31] add MorphismInstance::Id

---
 src/c_gen/gen_lib.rs            | 3 ++-
 src/c_gen/morph/target_morph.rs | 9 +++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/c_gen/gen_lib.rs b/src/c_gen/gen_lib.rs
index 4615fab..13ffa3e 100644
--- a/src/c_gen/gen_lib.rs
+++ b/src/c_gen/gen_lib.rs
@@ -33,7 +33,8 @@ pub fn generate_lib(
                     }
 
                     c_source.push_str(
-                        &format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );\n"#,
+                        &format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );
+"#,
                             inst.instantiated_symbol_name(dict, &HashMap::new()))
                     );
 
diff --git a/src/c_gen/morph/target_morph.rs b/src/c_gen/morph/target_morph.rs
index dd075bf..cea7ed4 100644
--- a/src/c_gen/morph/target_morph.rs
+++ b/src/c_gen/morph/target_morph.rs
@@ -162,6 +162,15 @@ impl LdmcCTargetMorph {
         let symbol = encode_morph_type_to_symbol(dict, &ty);
 
         match &morph_inst {
+            MorphismInstance::Id { ψ } => {
+                self.add_required_header_block("#include <string.h>".into());
+                Ok(LdmcPrimMorph {
+                    symbol,
+                    type_args: Vec::new(),
+                    ty: MorphismType { src_type: ψ.clone(), dst_type: ψ.clone() },
+                    c_source: String::from("memcpy(dst, src, sizeof(*src));")
+                })
+            }
             MorphismInstance::Primitive { ψ, σ, morph } => {
                 if let Some(i) = self.header_dependencies.get(&morph.get_type()) {
                     self.active_headers.push(*i);