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"));
 }