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