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 {