diff --git a/Cargo.toml b/Cargo.toml
index c4ca5d9..8eace12 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,5 +8,3 @@ 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/examples/01-uint-example/.gitignore b/examples/01-uint-example/.gitignore
deleted file mode 100644
index 567609b..0000000
--- a/examples/01-uint-example/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build/
diff --git a/examples/01-uint-example/main.c b/examples/01-uint-example/main.c
deleted file mode 100644
index 2db8422..0000000
--- a/examples/01-uint-example/main.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#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
deleted file mode 100644
index 915101b..0000000
--- a/examples/01-uint-example/makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-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 \
-	" \
-     -o 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
diff --git a/morphisms/angle.morphism-base b/morphisms/angle.morphism-base
index e678dde..71aba96 100644
--- a/morphisms/angle.morphism-base
+++ b/morphisms/angle.morphism-base
@@ -3,44 +3,70 @@
 ```
 
 morph_angle_as_degrees_to_turns_float ()
-    Angle ~ Degrees ~ ℝ ~ native.Float32
---> Angle ~ Turns ~ ℝ ~ native.Float32
-```*dst = *src / 360.0;```
+    Angle ~ Degrees ~ ℝ ~ native.Float
+--> Angle ~ Turns ~ ℝ ~ native.Float
+```
+    *dst = *src / 360.0;
+    return 0;
+```
 
 morph_angle_as_degrees_to_turns_double ()
-    Angle ~ Degrees ~ ℝ ~ native.Float64
---> Angle ~ Turns ~ ℝ ~ native.Float64
-```*dst = *src / 360.0;```
+    Angle ~ Degrees ~ ℝ ~ native.Double
+--> Angle ~ Turns ~ ℝ ~ native.Double
+```
+    *dst = *src / 360.0;
+    return 0;
+```
 
 
 morph_angle_as_turns_to_degrees_float ()
-    Angle ~ Turns ~ ℝ ~ native.Float32
---> Angle ~ Degrees ~ ℝ ~ native.Float32
-```*dst = *src * 360.0;```
+    Angle ~ Turns ~ ℝ ~ native.Float
+--> Angle ~ Degrees ~ ℝ ~ native.Float
+```
+    *dst = *src * 360.0;
+    return 0;
+```
 
 morph_angle_as_turns_to_degrees_double ()
-    Angle ~ Turns ~ ℝ ~ native.Float64
---> Angle ~ Degrees ~ ℝ ~ native.Float64
-```*dst = *src * 360.0;```
+    Angle ~ Turns ~ ℝ ~ native.Double
+--> Angle ~ Degrees ~ ℝ ~ native.Double
+```
+    *dst = *src * 360.0;
+    return 0;
+```
+
+
 
 
 morph_angle_as_radians_to_turns_float ()
-    Angle ~ Radians ~ ℝ ~ native.Float32
---> Angle ~ Turns ~ ℝ ~ native.Float32
-```*dst = *src / PHI;```
+    Angle ~ Radians ~ ℝ ~ native.Float
+--> Angle ~ Turns ~ ℝ ~ native.Float
+```
+    *dst = *src / PHI;
+    return 0;
+```
 
 morph_angle_as_radians_to_turns_double ()
-    Angle ~ Radians ~ ℝ ~ native.Float64
---> Angle ~ Turns ~ ℝ ~ native.Float64
-```*dst = *src / PHI;```
+    Angle ~ Radians ~ ℝ ~ native.Double
+--> Angle ~ Turns ~ ℝ ~ native.Double
+```
+    *dst = *src / PHI;
+    return 0;
+```
 
 
 morph_angle_as_turns_to_radians_float ()
-    Angle ~ Turns ~ ℝ ~ native.Float32
---> Angle ~ Radians ~ ℝ ~ native.Float32
-```*dst = *src * PHI;```
+    Angle ~ Turns ~ ℝ ~ native.Float
+--> Angle ~ Radians ~ ℝ ~ native.Float
+```
+    *dst = *src * PHI;
+    return 0;
+```
 
 morph_angle_as_degrees_to_radians_double ()
-    Angle ~ Turns ~ ℝ ~ native.Float64
---> Angle ~ Radians ~ ℝ ~ native.Float64
-```*dst = *src * PHI;```
+    Angle ~ Turns ~ ℝ ~ native.Double
+--> Angle ~ Radians ~ ℝ ~ native.Double
+```
+    *dst = *src * PHI;
+    return 0;
+```
diff --git a/morphisms/digit.morphism-base b/morphisms/digit.morphism-base
index 75ab631..a92fe61 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 (radix %u)\n", *src, Radix);
+        fprintf(stderr, "invalid digit 0x%x\n", *src);
         return -1;
     }
 
@@ -60,6 +60,8 @@ 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)
@@ -74,4 +76,6 @@ 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 70cd3b7..6718c16 100644
--- a/morphisms/length_prefix.morphism-base
+++ b/morphisms/length_prefix.morphism-base
@@ -3,44 +3,28 @@
 #include <array/length-prefix.h>
 ```
 
-morph_array_as_static_to_lenpfx (Len: ℤ, T: Type)
-    <Seq~<StaticLength Len> T>
---> <Seq~<LengthPrefix native.UInt64> T>
+morph_array_as_valterm_to_lenpfx (Terminator:native.UInt8)
+    <Seq~<ValueTerminated Terminator> native.UInt8>
+--> <Seq~<LengthPrefix native.UInt64> native.UInt8>
 ```
-    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 );
+    length_prefix_uint64_t_array_uint8_t_clear(dst);
     while( *src != Terminator )
-        PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, *src++ );
+        length_prefix_uint64_t_array_uint8_t_push(dst, *src++);
+
+    return 0;
 ```
 
-morph_array_as_lenpfx_to_valterm (T: Type, Terminator: T)
-    <Seq~<LengthPrefix native.UInt64> T>
---> <Seq~<ValueTerminated Terminator> T>
+
+morph_array_as_lenpfx_to_valterm (Terminator:native.UInt8)
+    <Seq~<LengthPrefix native.UInt64> native.UInt8>
+--> <Seq~<ValueTerminated Terminator> native.UInt8>
 ```
     for( uint64_t i = 0; i < src->len; ++i )
         *dst++ = src->items[i];
 
     *dst = Terminator;
+
+    return 0;
 ```
 
 morph_array_as_lenpfx_to_continuation_bit (T:Type)
@@ -49,13 +33,15 @@ 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] & ((uint64_t)1<<(n_bits-1)) ) {
-            fprintf(stderr, "error: value has MSB set, while being used in MsbContinuation sequence!\n");
+        if( src->items[i] & (1<<(n_bits-1)) ) {
+            fprintf(stderr, "error: value to high for MsbContinuation\n");
             return -1;
         }
 
         dst[i] = src->items[i];
         if( i+1 < src->len )
-            dst[i] |= ((uint64_t)1<<(n_bits-1));
+            dst[i] |= (1<<(n_bits-1));
     }
+
+    return 0;
 ```
diff --git a/morphisms/posint.morphism-base b/morphisms/posint.morphism-base
index 9036520..194399b 100644
--- a/morphisms/posint.morphism-base
+++ b/morphisms/posint.morphism-base
@@ -11,6 +11,7 @@ morph_nat_as_u64_to_pos ()
 ```
     dst->len = 1;
     dst->items[0] = *src;
+    return 0;
 ```
 
 morph_nat_as_pos_to_u64 (Endianness:Type)
@@ -21,6 +22,7 @@ morph_nat_as_pos_to_u64 (Endianness:Type)
     ~ native.UInt64
 ```
     *dst = src->items[0];
+    return 0;
 ```
 
 morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
@@ -38,18 +40,20 @@ morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
         value += src->items[src->len - i - 1];
     }
 
-    length_prefix_nativeUInt64_array_nativeUInt64_clear( dst );
+    length_prefix_uint64_t_array_uint64_t_clear( dst );
 
     #if DstRadix==0
-        length_prefix_nativeUInt64_array_nativeUInt64_push( dst, value );
+        length_prefix_uint64_t_array_uint64_t_push( dst, value );
     #else
         if( value == 0 ) {
-            length_prefix_nativeUInt64_array_nativeUInt64_push( dst, 0 );
+            length_prefix_uint64_t_array_uint64_t_push( dst, 0 );
         } else while( value > 0 ) {
-            length_prefix_nativeUInt64_array_nativeUInt64_push( dst, value % DstRadix );
+            length_prefix_uint64_t_array_uint64_t_push( dst, value % DstRadix );
             value /= DstRadix;
         }
     #endif
+
+    return 0;
 ```
 
 morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
@@ -87,6 +91,8 @@ morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
             value /= DstRadix;
         }
     #endif
+
+    return 0;
 ```
 
 morph_posint_endianness (Radix:ℤ)
@@ -97,7 +103,7 @@ morph_posint_endianness (Radix:ℤ)
     ~ <PosInt Radix BigEndian>
     ~ <Seq~<LengthPrefix native.UInt64> <Digit Radix> ~ native.UInt64>
 ```
-    return length_prefix_nativeUInt64_array_nativeUInt64_reverse( src, dst );
+    return length_prefix_uint64_t_array_uint64_t_reverse( src, dst );
 ```
 
 morph_posint_endianness (Radix:ℤ)
@@ -108,5 +114,5 @@ morph_posint_endianness (Radix:ℤ)
     ~ <PosInt Radix LittleEndian>
     ~ <Seq~<LengthPrefix native.UInt64> <Digit Radix> ~ native.UInt64>
 ```
-    return length_prefix_nativeUInt64_array_nativeUInt64_reverse( src, dst );
+    return length_prefix_uint64_t_array_uint64_t_reverse( src, dst );
 ```
diff --git a/morphisms/real.morphism-base b/morphisms/real.morphism-base
index 5b5b2f7..3302f80 100644
--- a/morphisms/real.morphism-base
+++ b/morphisms/real.morphism-base
@@ -4,87 +4,102 @@
 
 morph_real_as_decimalstr_to_float ()
     ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
---> ℝ ~ native.Float32
-```sscanf(src, "%f", dst);```
+--> ℝ ~ native.Float
+```
+    sscanf(src, "%f", dst);
+    return 0;
+```
 
 morph_real_as_decimalstr_to_double ()
     ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
---> ℝ ~ native.Float64
-```sscanf(src, "%lf", dst);```
+--> ℝ ~ native.Double
+```
+    sscanf(src, "%lf", dst);
+    return 0;
+```
 
 morph_real_as_float_to_decimalstr ()
-    ℝ ~ native.Float32
+    ℝ ~ native.Float
 --> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
-```sprintf(dst, "%f", *src);```
+```
+    sprintf(dst, "%f", *src);
+    return 0;
+```
 
 morph_real_as_double_to_decimalstr ()
-    ℝ ~ native.Float64
+    ℝ ~ native.Double
 --> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
-```sprintf(dst, "%f", *src);```
+```
+    sprintf(dst, "%f", *src);
+    return 0;
+```
+
 
 morph_real_as_float_to_double ()
-    ℝ ~ native.Float32
---> ℝ ~ native.Float64
-```*dst = *src;```
+    ℝ ~ native.Float
+--> ℝ ~ native.Double
+```
+    *dst = *src;
+    return 0;
+```
 
 morph_real_as_double_to_float ()
-    ℝ ~ native.Float64
---> ℝ ~ native.Float32
+    ℝ ~ native.Double
+--> ℝ ~ native.Float
 ```
     fprintf(stderr, "Warning: morphin Double -> Float. Precision loss!");
     *dst = *src;
+    return 0;
 ```
 
 morph_real_as_u64_to_float ()
     ℝ ~ ℕ ~ native.UInt64
---> ℝ ~ native.Float32
+--> ℝ ~ native.Float
 ```
     fprintf(stderr, "Warning: morphin UInt64 -> Float. Precision loss!");
     *dst = *src;
+    return 0;
 ```
 
 morph_real_as_u64_to_double ()
     ℝ ~ ℕ ~ native.UInt64
---> ℝ ~ native.Float64
+--> ℝ ~ native.Double
 ```
     fprintf(stderr, "Warning: morphin UInt64 -> Double. Precision loss!");
     *dst = *src;
-```
-
-
-morph_real_as_nat_to_quantized_linear ()
-     ℝ ~ ℕ ~ native.UInt64
--->  ℝ ~ <QuantizedLinear 0 1 1> ~ ℕ ~ native.UInt64
-```
-    *dst = *src;
+    return 0;
 ```
 
 morph_real_as_quantized_linear_to_float (Begin: ℝ, End: ℝ, Steps: ℤ)
     ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
---> ℝ ~ native.Float32
+--> ℝ ~ native.Float
 ```
     *dst = (float)Begin  +  ( *src * ((float)End - (float)Begin) ) / (float)Steps;
+    return 0;
 ```
 
 morph_real_as_float_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
-    ℝ ~ native.Float32
+    ℝ ~ native.Float
 --> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
 ```
     *dst = ((*src - (float)Begin) * (float)Steps) / ((float)End - (float)Begin);
+    return 0;
 ```
 
 
 
 morph_real_as_quantized_linear_to_double (Begin: ℝ, End: ℝ, Steps: ℤ)
     ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
---> ℝ ~ native.Float64
+--> ℝ ~ native.Double
 ```
     *dst = (double)Begin  +  ( *src * ((double)End - (double)Begin) ) / (double)Steps;
+    return 0;
 ```
 
 morph_real_as_double_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
-    ℝ ~ native.Float64
+    ℝ ~ native.Double
 --> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
 ```
     *dst = ((*src - (double)Begin) * (double)Steps) / ((double)End - (double)Begin);
+    return 0;
 ```
diff --git a/morphisms/runtime/include/array/length-prefix.h b/morphisms/runtime/include/array/length-prefix.h
index e61f8ac..35a4aec 100644
--- a/morphisms/runtime/include/array/length-prefix.h
+++ b/morphisms/runtime/include/array/length-prefix.h
@@ -2,37 +2,27 @@
 
 #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)                        \
-    static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, clear)    \
-       (__Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data) {                      \
+    typedef struct {                                                           \
+        LEN_TYPE len;                                                          \
+        ITEM_TYPE items[];                                                     \
+    } LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE;                             \
+                                                                               \
+    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_clear(   \
+        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data) {                   \
         data->len = 0;                                                         \
     }                                                                          \
                                                                                \
-    static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, push)     \
-       (__Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data,                        \
+    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_push(    \
+        LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data,                     \
         ITEM_TYPE value) {                                                     \
         data->items[data->len++] = value;                                      \
     }                                                                          \
                                                                                \
-    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) {              \
+    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) {           \
         for (LEN_TYPE i = 0; i < src->len; i++) {                              \
             dst->items[i] = src->items[src->len - 1 - i];                      \
         }                                                                      \
@@ -40,11 +30,60 @@ typedef struct {                                                           \
         return 0;                                                              \
     }                                                                          \
                                                                                \
-    static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, dump)     \
-      ( __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * data) {               \
+    static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_dump(    \
+        LengthPrefix_##LEN_TYPE##_Array_##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/morphisms/temperature.morphism-base b/morphisms/temperature.morphism-base
index 329a6b0..7831292 100644
--- a/morphisms/temperature.morphism-base
+++ b/morphisms/temperature.morphism-base
@@ -2,21 +2,33 @@
 ```
 
 morph_celsius_to_kelvin ()
-      Temperature ~ Celsius ~ ℝ ~ native.Float32
--->   Temperature ~ Kelvin ~ ℝ ~ native.Float32
-```*dst = *src + 273.15;```
+      Temperature ~ Celsius ~ ℝ ~ native.Float
+-->   Temperature ~ Kelvin ~ ℝ ~ native.Float
+```
+    *dst = *src + 273.15;
+    return 0;
+```
 
 morph_kelvin_to_celsius ()
-      Temperature ~ Kelvin ~ ℝ ~ native.Float32
--->   Temperature ~ Celsius ~ ℝ ~ native.Float32
-```*dst = *src - 273.15;```
+      Temperature ~ Kelvin ~ ℝ ~ native.Float
+-->   Temperature ~ Celsius ~ ℝ ~ native.Float
+```
+    *dst = *src - 273.15;
+    return 0;
+```
 
 morph_celsius_to_fahrenheit ()
-      Temperature ~ Celsius ~ ℝ ~ native.Float32
--->   Temperature ~ Fahrenheit ~ ℝ ~ native.Float32
-```*dst = (*src * 9.0 / 5.0) + 32.0;```
+      Temperature ~ Celsius ~ ℝ ~ native.Float
+-->   Temperature ~ Fahrenheit ~ ℝ ~ native.Float
+```
+    *dst = (*src * 9.0 / 5.0) + 32.0;
+    return 0;
+```
 
 morph_fahrenheit_to_celsius ()
-      Temperature ~ Fahrenheit ~ ℝ ~ native.Float32
--->   Temperature ~ Celsius ~ ℝ ~ native.Float32
-```*dst = (*src - 32.0) * 5.0 / 9.0;```
+      Temperature ~ Fahrenheit ~ ℝ ~ native.Float
+-->   Temperature ~ Celsius ~ ℝ ~ native.Float
+```
+    *dst = (*src - 32.0) * 5.0 / 9.0;
+    return 0;
+```
diff --git a/morphisms/timepoint.morphism-base b/morphisms/timepoint.morphism-base
index 505ed37..bb66aec 100644
--- a/morphisms/timepoint.morphism-base
+++ b/morphisms/timepoint.morphism-base
@@ -11,4 +11,5 @@ 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
deleted file mode 100644
index 89f8f79..0000000
--- a/morphisms/uint.morphism-base
+++ /dev/null
@@ -1,17 +0,0 @@
-```
-```
-
-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 659357b..c2854e5 100644
--- a/morphisms/unicode.morphism-base
+++ b/morphisms/unicode.morphism-base
@@ -28,6 +28,7 @@ morph_string_as_utf8_to_ascii ()
         }
     }
     *dst = 0;
+    return 0;
 ```
 
 morph_string_as_ascii_to_utf32 ()
@@ -38,6 +39,7 @@ morph_string_as_ascii_to_utf32 ()
 ```
     while( *src ) { *dst++ = *src++; }
     *dst = 0;
+    return 0;
 ```
 
 morph_string_as_utf8_to_utf32 ()
@@ -87,4 +89,6 @@ 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 d4ab039..a370682 100644
--- a/morphisms/value_delim.morphism-base
+++ b/morphisms/value_delim.morphism-base
@@ -3,7 +3,7 @@
 #include <stdlib.h>
 ```
 
-morph_valsep_delim (T: Type, SrcDelim: T, DstDelim: T)
+morph_seqseq_valsep_uint8 (T: Type, SrcDelim: T, DstDelim: T)
       < Seq <Seq T> >
     ~ < ValueSep SrcDelim T >
     ~ < Seq~<LengthPrefix native.UInt64> T >
@@ -12,24 +12,23 @@ morph_valsep_delim (T: Type, SrcDelim: T, DstDelim: T)
     ~ < ValueSep DstDelim T >
     ~ < Seq~<LengthPrefix native.UInt64> T >
 ```
-    PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, clear)( dst );
+    length_prefix_uint64_t_array_uint8_t_clear( dst );
 
     uint8_t * dst_items = dst->items;
     for( uint64_t i = 0; i < src->len; ++i ) {
         if( src->items[i] == SrcDelim ) {
-            PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, DstDelim );
+            length_prefix_uint64_t_array_uint8_t_push( dst, DstDelim );
         } else if( src->items[i] == DstDelim ) {
             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 );
+                length_prefix_uint64_t_array_uint8_t_push( dst, '\\' );
+                length_prefix_uint64_t_array_uint8_t_push( dst, 'n' );
             }
         } else {
-            PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, src->items[i] );
+            length_prefix_uint64_t_array_uint8_t_push( dst, src->items[i] );
         }
     }
+
+    return 0;
 ```
 
 
@@ -45,28 +44,30 @@ morph_seqseq_as_valsep_to_lenpfx (T: Type, Delim: T, EscKey: T)
         ~ native.UInt64
     >
 ```
-    length_prefix_nativeUInt64_array_nativeUInt64_clear( dst );
+    length_prefix_uint64_t_array_uint64_t_clear( dst );
 
-    LENGTH_PREFIX_ARRAY_TYPE( nativeUInt64, T ) * cur_item = NULL;
+    struct LengthPrefix_uint64_t_Array_uint8_t * cur_item = NULL;
 
-    T const * start = &src->items[0];
-    T const * cur = start;
-    T const * end = &src->items[src->len];
+    uint8_t const * start = &src->items[0];
+    uint8_t const * cur = start;
+    uint8_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(T) * len );
+            cur_item = malloc( sizeof(uint64_t) + sizeof(uint8_t) * len );
             cur_item->len = len;
             memcpy( cur_item->items, start, len );
 
-            length_prefix_nativeUInt64_array_nativeUInt64_push( dst, (uint64_t)cur_item );
+            length_prefix_uint64_t_array_uint64_t_push( dst, (uint64_t)cur_item );
             start = ++cur;
         } else {
             cur++;
         }
     }
+
+    return 0;
 ```
 
 morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
@@ -80,17 +81,19 @@ morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
     ~ < ValueSep T Delim >
     ~ < Seq~<LengthPrefix native.UInt64> T >
 ```
-    PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, clear)( dst );
+    length_prefix_uint64_t_array_uint8_t_clear( dst );
 
     for( uint64_t i = 0; i < src->len; ++i ) {
-        LENGTH_PREFIX_ARRAY_TYPE( nativeUInt64, T ) * item = src->items[i];
+        LengthPrefix_uint64_t_Array_uint8_t * item = src->items[i];
 
         for( uint64_t j = 0; j < item->len; ++j ) {
-            PRESCAN_LENGTH_PREFIX_CALL( nativeUInt64, T, push )( items->items[j] );
+            length_prefix_uint64_t_array_uint8_t_push( items->items[j] );
         }
 
         if( i+1 < src->len ) {
-            PRESCAN_LENGTH_PREFIX_CALL( nativeUInt64, T, push )( Delim );
+            length_prefix_uint64_t_array_uint8_t_push( Delim );
         }
     }
+
+    return 0;
 ```
diff --git a/morphisms/zigzag.morphism-base b/morphisms/zigzag.morphism-base
index 4196e72..5a293e2 100644
--- a/morphisms/zigzag.morphism-base
+++ b/morphisms/zigzag.morphism-base
@@ -10,6 +10,8 @@ morph_i64_as_twos_complement_to_zigzag ()
     } else {
         *dst = (2 * (uint64_t)(- *src)) - 1;
     }
+
+    return 0;
 ```
 
 morph_i64_as_zigzag_to_twos_complement ()
diff --git a/platforms/json.lt b/platforms/json.lt
deleted file mode 100644
index 8e69138..0000000
--- a/platforms/json.lt
+++ /dev/null
@@ -1,100 +0,0 @@
-
-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
deleted file mode 100644
index e69de29..0000000
diff --git a/platforms/protobuf.lt b/platforms/protobuf.lt
deleted file mode 100644
index ce273f6..0000000
--- a/platforms/protobuf.lt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-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
deleted file mode 100644
index e69de29..0000000
diff --git a/platforms/x86.lt b/platforms/x86.lt
deleted file mode 100644
index 0348efc..0000000
--- a/platforms/x86.lt
+++ /dev/null
@@ -1,5 +0,0 @@
-
-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>;
diff --git a/src/c_gen.rs b/src/c_gen.rs
new file mode 100644
index 0000000..ac68a93
--- /dev/null
+++ b/src/c_gen.rs
@@ -0,0 +1,419 @@
+use {
+    laddertypes::{TypeDict, TypeTerm, parser::*, unparser::*, morphism::{Morphism, MorphismInstance}},
+    crate::morphism::{LdmcPrimCMorphism, LdmcMorphism}
+};
+
+/*
+*/
+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())
+            } 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 {
+                            None
+                        }
+                    }
+
+                    _ => None
+                }
+            }
+        }
+        None => None
+    }
+}
+
+
+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)
+        }
+        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('_');
+                s.push_str(&encode_type_to_symbol(dict, r));
+            }
+            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) {
+    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");
+}
+
+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 generate_call(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>, i: u64) {
+        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" };
+
+                println!(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" };
+                println!(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" };
+                println!(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, σ),
+                    '}');
+            }
+        }
+    }
+}
diff --git a/src/c_gen/gen_lib.rs b/src/c_gen/gen_lib.rs
deleted file mode 100644
index 13ffa3e..0000000
--- a/src/c_gen/gen_lib.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-use {
-    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( include_blocks, include_dependencies );
-    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];"#));
-
-                    if let Ok(_) = laddertypes::subtype_unify(
-                        &inst.ty.src_type,
-                        &dict.parse("<Seq~<ValueTerminated '\\n'> Char~Ascii~native.UInt8>").expect("")
-                    ) {
-                        c_source.push_str("scanf(\"%s\", bufIn);\n");
-                    } else {
-                        c_source.push_str("read(0, bufIn, sizeof(bufIn));\n");
-                    }
-
-                    c_source.push_str(
-                        &format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );
-"#,
-                            inst.instantiated_symbol_name(dict, &HashMap::new()))
-                    );
-
-                    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);\n");
-                    } else {
-                        c_source.push_str("write(1, bufOut, sizeof(bufOut));\n");
-                    }
-                    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/mod.rs b/src/c_gen/mod.rs
deleted file mode 100644
index cf994c5..0000000
--- a/src/c_gen/mod.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-pub mod types;
-pub mod morph;
-pub mod gen_lib;
-
-pub use {
-    morph::target_morph::LdmcCTargetMorph
-};
diff --git a/src/c_gen/morph/mod.rs b/src/c_gen/morph/mod.rs
deleted file mode 100644
index 49510e5..0000000
--- a/src/c_gen/morph/mod.rs
+++ /dev/null
@@ -1,76 +0,0 @@
-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/morph/target_morph.rs b/src/c_gen/morph/target_morph.rs
deleted file mode 100644
index cea7ed4..0000000
--- a/src/c_gen/morph/target_morph.rs
+++ /dev/null
@@ -1,375 +0,0 @@
-use {
-    crate::{
-        c_gen::types::{
-            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::*, Morphism, MorphismInstance, MorphismType, TypeDict, TypeTerm
-    },
-    std::collections::HashMap
-};
-
-pub struct LdmcCTargetMorph {
-    header_blocks: Vec< String >,
-    header_dependencies: HashMap< MorphismType, usize >,
-    active_headers: Vec< usize >,
-    active_types: Vec< TypeTerm >,
-    active_morphisms: Vec< LdmcPrimMorph >,
-    active_lenpfx_types: Vec< (TypeTerm, TypeTerm) >,
-    typedefs: Vec< String >,
-    macro_calls: Vec< String >
-}
-
-impl LdmcCTargetMorph {
-    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(
-        include_blocks: Vec< String >,
-        include_dependencies: HashMap< MorphismType, usize >
-    ) -> Self {
-        let mut m = LdmcCTargetMorph {
-            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_header_block(
-            "/* default ldmc header */
-#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) {
-        let ty = ty.strip();
-        if ! self.active_types.contains(&ty) {
-            eprintln!("add type {}", ty.pretty(dict,0));
-
-            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));
-            }
-        }
-    }
-
-    pub fn add_instantiation(
-        &mut self,
-        dict: &mut impl TypeDict,
-        morph: MorphismInstance<LdmcPrimMorph>,
-    ) -> Result<LdmcPrimMorph, ()> {
-        let new_inst = self.bake_morphism(dict, morph)?;
-        if ! self.active_morphisms.contains(&new_inst) {
-            self.active_morphisms.push(new_inst.clone());
-        }
-
-        let ty = new_inst.get_type().strip_halo();
-        self.add_type(dict, ty.src_type);
-        self.add_type(dict, ty.dst_type);
-
-        Ok(new_inst)
-    }
-
-    pub fn into_c_source(mut self, dict: &mut impl TypeDict) -> String {
-        let mut source = String::new();
-        self.active_headers.dedup();
-        self.typedefs.dedup();
-        self.macro_calls.dedup();
-
-        for i in self.active_headers {
-            source.push_str( &self.header_blocks[i] );
-            source.push('\n');
-        }
-        source.push('\n');
-
-        for typedef in self.typedefs {
-            source.push_str(&typedef);
-        }
-
-        source.push('\n');
-
-
-        for m in self.macro_calls {
-            source.push_str(&m);
-            source.push('\n');
-        }
-        source.push('\n');
-
-        for m in self.active_morphisms {
-            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: MorphismInstance<LdmcPrimMorph>,
-    ) -> Result<LdmcPrimMorph, ()> {
-        let ty = morph_inst.get_type();
-        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);
-                }
-
-
-                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 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 {
-                        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().apply_subst(σ).strip_halo(),
-                    c_source
-                })
-            },
-            MorphismInstance::Chain { path } => {
-                let mut c_source = String::new();
-
-                if path.len() > 1 {
-                    c_source.push_str(r#"
-            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_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( {}, {}, {} );"#,
-                            morph_symbol, src_buf, dst_buf,
-                        ));
-                    } else {
-                        c_source.push_str(&format!("/* ERROR: missing morphism */"));
-                        eprintln!("failed to add instantiation of item morphism");
-                    }
-                }
-
-                Ok(LdmcPrimMorph {
-                    symbol, type_args: Vec::new(), ty,
-                    c_source
-                })
-            }
-            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::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 {
-                                TypeTerm::Num(l) => {
-                                    let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
-
-                                    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->items[i], &dst->items[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::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 item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
-
-                            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 ) {{
-                                    FUSE( {}, &src->items[i], &dst->items[i] );
-                                }}
-                                dst->len = src->len;
-                                "#,
-                                item_morph_symbol,
-                            );
-
-                            Ok(LdmcPrimMorph{
-                                symbol, type_args: Vec::new(), ty,
-                                c_source
-                            })
-                        }
-
-                        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 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(())
-                        }
-                    } else {
-                        eprintln!("Error: missing Seq- Representation!!");
-                        Err(())
-                    }
-                } else {
-                    eprintln!("failed to add item-morph instantiation");
-                    Err(())
-                }
-            },
-            MorphismInstance::MapStruct { ψ, src_struct_repr, dst_struct_repr, member_morph } => {
-
-                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!("
-        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(());
-                    }
-                }
-
-                Ok(LdmcPrimMorph{
-                    symbol, type_args: Vec::new(), ty,
-                    c_source
-                })
-            }
-            MorphismInstance::MapEnum { ψ, enum_repr, variant_morph } => {
-                todo!();
-            }
-        }
-    }
-}
diff --git a/src/c_gen/types/mod.rs b/src/c_gen/types/mod.rs
deleted file mode 100644
index 29cb4ec..0000000
--- a/src/c_gen/types/mod.rs
+++ /dev/null
@@ -1,257 +0,0 @@
-use {
-    crate::struct_layout::LayoutType,
-    chumsky::chain::Chain, laddertypes::{morphism::MorphismType,
-        parser::*,
-        substitution::Substitution,
-        unparser::*, EnumVariant, StructMember, TypeTerm, TypeDict}
-};
-
-/*
-*/
-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_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") {
-                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
-            }
-        }
-
-        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);
-
-                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::constraint_system::subtype_unify(
-                    seq_repr.as_ref(),
-                    &dict.parse_desugared("<StaticLength Length>").expect("parse template type").sugar(dict)
-                ) {
-                    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!("struct {{ {} items[{}]; }} ", item_c_type, length))
-                }
-                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");
-
-                    let length_c_type = get_c_repr_type(dict, &length_type);
-
-                    Some(format!("struct {{ {} len; {} items[]; }} ", length_c_type, item_c_type))
-                }
-                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)
-                    } else {
-                        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
-                }
-            } else {
-                eprintln!("no sequence-representation type specified!");
-                None
-            }
-        }
-
-        TypeTerm::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 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_")
-                ));
-            }
-
-            c_type.push_str("}");
-            Some(c_type)
-        }
-
-        TypeTerm::Enum { enum_repr, variants } => {
-            let mut c_type = format!("
-struct {{
-    enum {{
-");
-
-            for (i, EnumVariant{ symbol, ty }) in variants.iter().enumerate() {
-                c_type.push_str(&format!(
-                    "       {} = {}", symbol.replace("-", "_").replace(".","_dot_").to_uppercase(), i
-                ));
-
-                if i+1 < variants.len() {
-                    c_type.push_str(",\n");
-                }
-            }
-
-            c_type.push_str("
-    } tag;
-
-    union {
-");
-
-            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_")
-                ));
-            }
-
-            c_type.push_str("
-    };
-}");
-
-            Some(c_type)
-        }
-
-        TypeTerm::Ladder(rungs) => {
-            if let Some(t) = rungs.last() {
-                get_c_repr_definition(dict, t.clone(), false)
-            } else {
-                None
-            }
-        }
-
-        _ => { None }
-    }
-}
-
-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_"),
-                _ =>
-                format!("{}", (c as u64))
-            }
-        },
-        laddertypes::DesugaredTypeTerm::Num(n) => {
-            format!("{}", n)
-        }
-        laddertypes::DesugaredTypeTerm::TypeID(ty_id) => {
-            if let Some(name) = dict.get_typename(&ty_id) {
-                name
-                    .replace("-", "_")
-                    .replace(".", "")
-            } else {
-                format!("")
-            }
-        }
-        laddertypes::DesugaredTypeTerm::Ladder(rs) |
-        laddertypes::DesugaredTypeTerm::App(rs) => {
-            let mut s = String::new();
-            s.push('_');
-            for r in rs {
-                let r = r.sugar(dict);
-                s.push_str(&get_c_repr_type(dict, &r));
-                s.push('_');
-            }
-            s
-        }
-    }
-}
-
-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);
-                }
-                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);
-                }
-            }
-        }
-
-        _ => {}
-    }
-    get_c_repr_type(dict, &t)
-}
-
-pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &MorphismType) -> String {
-    format!(
-        "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::TypeTerm) -> String {
-    let t = t.clone().desugar(dict);
-    dict.unparse(&t)
-}
diff --git a/src/main.rs b/src/main.rs
index 675c12d..13b8629 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,88 +3,44 @@
 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::LdmcPrimMorph,
+        morphism::LdmcMorphism,
         parser::morphism_base_parser,
-    }, 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)]
-#[command(version, about, long_about = None)]
-struct Args {
-    #[arg(short='b', long)]
-    morphism_base: Vec<PathBuf>,
-
-    #[arg(short='m', long="morph")]
-    morphisms: Vec<String>,
-
-    #[arg(short='o', long)]
-    output: Option<PathBuf>
-}
-
 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 morphism_base = laddertypes::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("")
+    ]);
 
-    // 1. load morphism base
-    let mut mb_paths = args.morphism_base;
+    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.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)
-                    )
-                {
-                    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
-
-    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");
-
-        use chumsky::Parser;
+    for mb_path in args {
+        let src = std::fs::read_to_string(mb_path.clone()).expect("read");
         let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
         match result {
             Ok((includes, morphisms)) => {
-                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);
-
+                eprintln!("[{}] parse ok.", mb_path.bright_yellow());
+                println!("{}", includes);
                 for m in morphisms {
-                    include_dependencies.insert( m.get_type(), include_idx );
-                    morphism_base.add_morphism(m);
+                    morphism_base.add_morphism(LdmcMorphism::Primitive(m));
                 }
             }
             Err(errs) => {
@@ -104,21 +60,22 @@ fn main() {
         }
     }
 
-    // 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 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(),
+    });
+
+    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 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");
-    } else {
-        println!("{}", c_source);
-    }
 }
diff --git a/src/morphism.rs b/src/morphism.rs
index 28ea01e..a1f2aab 100644
--- a/src/morphism.rs
+++ b/src/morphism.rs
@@ -1,16 +1,76 @@
 
-use laddertypes::morphism::{Morphism, MorphismType};
+use laddertypes::morphism::Morphism;
 
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct LdmcPrimMorph {
+#[derive(Clone, Debug)]
+pub struct LdmcPrimCMorphism {
     pub symbol: String,
     pub type_args: Vec<(laddertypes::TypeID, String)>,
-    pub ty: MorphismType,
+    pub src_type: laddertypes::TypeTerm,
+    pub dst_type: laddertypes::TypeTerm,
     pub c_source: String
 }
 
-impl Morphism for LdmcPrimMorph {
-    fn get_type(&self) -> MorphismType {
-        self.ty.clone()
+#[derive(Clone)]
+pub enum LdmcMorphism {
+    Primitive( LdmcPrimCMorphism ),
+    LengthPrefixMap{
+        length_prefix_type: laddertypes::TypeTerm,
+        item_morph: Box<LdmcPrimCMorphism>
+    },
+    ValueDelimMap{
+        delim: u64,
+        item_morph: Box<LdmcPrimCMorphism>
+    }
+}
+
+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() ]),
+                }
+            }
+        }.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 24ca0a9..f45fddf 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,7 +1,11 @@
 use {
-    crate::morphism::LdmcPrimMorph, chumsky::{
+    chumsky::{
         prelude::*, text::*
-    }, laddertypes::{TypeTerm, morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
+    },
+    std::sync::{Arc, RwLock},
+
+    laddertypes::{TypeDict, BimapTypeDict, parser::*},
+    crate::morphism::LdmcPrimCMorphism
 };
 
 /* morphism-base text format:
@@ -14,12 +18,12 @@ use {
  */
 pub fn morphism_base_parser(
     type_dict: Arc<RwLock< BimapTypeDict >>
-) -> impl Parser<char, (String, Vec<LdmcPrimMorph>), Error = Simple<char>> {
+) -> impl Parser<char, (String, Vec<LdmcPrimCMorphism>), Error = Simple<char>> {
 
     just("```")
     .then(take_until(just("```")))
     .map(
-        move |(_a, (b, _c))| {
+        move |(a, (b, c))| {
             b.iter().collect()
         }
     )
@@ -62,13 +66,11 @@ pub fn morphism_base_parser(
             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 {
+            LdmcPrimCMorphism {
                 symbol,
                 type_args: ty_args,
-                ty: MorphismType{
-                    src_type,
-                    dst_type
-                },
+                src_type,
+                dst_type,
                 c_source
             }
         })
@@ -76,25 +78,3 @@ 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")
-                )
-            }
-        })
-}
diff --git a/src/platform/x86.rs b/src/platform/x86.rs
deleted file mode 100644
index aaae9c2..0000000
--- a/src/platform/x86.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-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
deleted file mode 100644
index b8816e9..0000000
--- a/src/struct_layout.rs
+++ /dev/null
@@ -1,244 +0,0 @@
-
-
-use laddertypes::{parser::*, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm};
-
-#[derive(Clone, Copy, Debug)]
-pub enum ObjectSize {
-    Static(u64),
-    Dynamic(/* function to get size at runtime */),
-    Unknown
-}
-
-impl std::ops::Add for ObjectSize {
-    type Output = Self;
-
-    fn add(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),
-        }
-    }
-}
-
-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),
-        }
-    }
-}
-
-pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
-    match &ty {
-        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) }
-            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
-            }
-        },
-
-        TypeTerm::Ladder(rungs) => {
-            get_type_size(dict, rungs.last().unwrap().clone() )
-        }
-
-        TypeTerm::Struct { struct_repr, members } => {
-            let layout = StructLayout::parse_sugared(dict, ty).expect("invalid struct");
-            layout.get_size()
-        }
-
-        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(),
-                    &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(),
-                    &dict.parse("<LengthPrefix LengthType>").expect("")
-                ) {
-                    ObjectSize::Dynamic()
-                }
-                else if let Ok(σ) = laddertypes::unify(
-                    &seq_repr.clone(),
-                    &dict.parse("<ValueTerminated TerminatorValue>").expect("")
-                ) {
-                    ObjectSize::Dynamic()
-                }
-                else {
-                    ObjectSize::Unknown
-                }
-            } else {
-                ObjectSize::Unknown
-            }
-        }
-
-        _ => ObjectSize::Unknown
-    }
-
-}
-
-#[derive(Clone, Copy, Debug, PartialEq)]
-pub enum LayoutType {
-    Aligned,
-    Packed
-}
-
-impl LayoutType {
-    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_desugared("Packed").expect("parse") {
-            Some(LayoutType::Packed)
-        } else {
-            None
-        }
-    }
-
-    pub fn unparse(&self, dict: &mut impl TypeDict) -> DesugaredTypeTerm {
-        match self {
-            LayoutType::Aligned => dict.parse_desugared("Aligned").unwrap(),
-            LayoutType::Packed => dict.parse_desugared("Packed").unwrap()
-        }
-    }
-}
-
-#[derive(Clone)]
-pub struct StructLayout {
-    pub ty: laddertypes::DesugaredTypeTerm,
-    pub layout: LayoutType,
-    pub members: Vec< StructMember >,
-    offsets: std::collections::HashMap< String, u64 >,
-    size: ObjectSize
-}
-
-impl StructLayout {
-    pub fn get_type(&self) -> DesugaredTypeTerm {
-        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 init_offsets(&mut self, dict: &mut impl TypeDict) {
-        let mut offset = 0;
-
-        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) => {
-                    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
-                        }
-                    }
-
-                    // 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!("Struct member `{}` has unknown size!", field_name);
-                    self.offsets.insert(field_name.clone(), offset);
-                    self.size = ObjectSize::Unknown;
-                    return;
-                }
-            }
-        }
-
-        match self.size {
-            ObjectSize::Dynamic() => {
-
-            }
-            _ => {
-                self.size = ObjectSize::Static(offset);
-            }
-        }
-    }
-
-    pub fn parse(dict: &mut impl TypeDict, struct_type: &DesugaredTypeTerm) -> Option <Self> {
-        let st = struct_type.clone().strip().sugar(dict).normalize();
-        Self::parse_sugared(dict, st)
-    }
-
-    pub fn parse_sugared(dict: &mut impl TypeDict, st: TypeTerm) -> Option <Self> {
-        eprintln!("{}", st.pretty(dict, 0));
-        match st.clone() {
-            TypeTerm::Struct{ struct_repr, members } => {
-                let mut sl = StructLayout {
-                    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.init_offsets(dict);
-
-                Some(sl)
-            }
-
-            _ => {
-                eprintln!("not a struct");
-                None
-            }
-        }
-    }
-}
diff --git a/test/test.sh b/test/test.sh
index f33ab02..0e3fc9b 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -8,12 +8,13 @@ run_test_case() {
 -----------------------------------------------------------------------------
 Running test case ${TEST_NAME}"
 
-    ldmc -m "main : ${SRC_TYPE} --> ${DST_TYPE}" -o target/src/${TEST_NAME}.c 2>|.tmp/ldmc_err  \
+    ldmc "${SRC_TYPE}" "${DST_TYPE}" ../morphisms/*.morphism-base 2>|.tmp/ldmc_err 1>| target/src/${TEST_NAME}.c \
     || (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})"
 
diff --git a/todo.md b/todo.md
deleted file mode 100644
index 39dd24f..0000000
--- a/todo.md
+++ /dev/null
@@ -1,79 +0,0 @@
-* 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