From 6f85e004b9caed2cb06eb8467247df57dca6c3a8 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 18 Mar 2025 14:05:42 +0100
Subject: [PATCH 1/4] improve posint morphisms

---
 morphisms/posint.morphism-base | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/morphisms/posint.morphism-base b/morphisms/posint.morphism-base
index d8838e0..64dea71 100644
--- a/morphisms/posint.morphism-base
+++ b/morphisms/posint.morphism-base
@@ -14,9 +14,9 @@ morph_nat_as_u64_to_pos ()
     return 0;
 ```
 
-morph_nat_as_u64_to_pos ()
+morph_nat_as_pos_to_u64 (Endianness:Type)
       ℕ
-    ~ <PosInt 0 LittleEndian>
+    ~ <PosInt 0 Endianness>
     ~ <Seq~<LengthPrefix x86.UInt64> <Digit 0>~x86.UInt64>
 -->   ℕ
     ~ x86.UInt64
@@ -42,14 +42,16 @@ morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
 
     length_prefix_uint64_array_clear( dst );
 
-    if( DstRadix == 0 ) {
+    #if DstRadix==0
         length_prefix_uint64_array_push( dst, value );
-    } else if( DstRadix > 0 ) {
-        while( value > 0 ) {
+    #else
+        if( value == 0 ) {
+            length_prefix_uint64_array_push( dst, 0 );
+        } else while( value > 0 ) {
             length_prefix_uint64_array_push( dst, value % DstRadix );
             value /= DstRadix;
         }
-    }
+    #endif
 
     return 0;
 ```
@@ -69,13 +71,16 @@ morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
         value += src->items[i];
     }
 
-    if( DstRadix == 0 ) {
+    #if DstRadix==0
         dst->len = 1;
         dst->items[0] = value;
-    } else {
+    #else
         uint64_t v = value;
         dst->len = 0;
-        while( v ) {
+
+        if( v == 0 ) {
+            dst->len = 1;
+        } else while( v ) {
             dst->len++;
             v /= DstRadix;
         }
@@ -85,7 +90,7 @@ morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
             dst->items[--i] = value % DstRadix;
             value /= DstRadix;
         }
-    }
+    #endif
 
     return 0;
 ```

From 65cd0b6853ab92805e549e2a5da1f9f2ea45d3c3 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 18 Mar 2025 14:06:05 +0100
Subject: [PATCH 2/4] add morphisms for angle, temperature & real numbers

---
 morphisms/angle.morphism-base       |  72 +++++++++++++++++++
 morphisms/real.morphism-base        | 105 ++++++++++++++++++++++++++++
 morphisms/temperature.morphism-base |  34 +++++++++
 3 files changed, 211 insertions(+)
 create mode 100644 morphisms/angle.morphism-base
 create mode 100644 morphisms/real.morphism-base
 create mode 100644 morphisms/temperature.morphism-base

diff --git a/morphisms/angle.morphism-base b/morphisms/angle.morphism-base
new file mode 100644
index 0000000..71aba96
--- /dev/null
+++ b/morphisms/angle.morphism-base
@@ -0,0 +1,72 @@
+```
+#define PHI 6.28318530718
+```
+
+morph_angle_as_degrees_to_turns_float ()
+    Angle ~ Degrees ~ ℝ ~ native.Float
+--> Angle ~ Turns ~ ℝ ~ native.Float
+```
+    *dst = *src / 360.0;
+    return 0;
+```
+
+morph_angle_as_degrees_to_turns_double ()
+    Angle ~ Degrees ~ ℝ ~ native.Double
+--> Angle ~ Turns ~ ℝ ~ native.Double
+```
+    *dst = *src / 360.0;
+    return 0;
+```
+
+
+morph_angle_as_turns_to_degrees_float ()
+    Angle ~ Turns ~ ℝ ~ native.Float
+--> Angle ~ Degrees ~ ℝ ~ native.Float
+```
+    *dst = *src * 360.0;
+    return 0;
+```
+
+morph_angle_as_turns_to_degrees_double ()
+    Angle ~ Turns ~ ℝ ~ native.Double
+--> Angle ~ Degrees ~ ℝ ~ native.Double
+```
+    *dst = *src * 360.0;
+    return 0;
+```
+
+
+
+
+morph_angle_as_radians_to_turns_float ()
+    Angle ~ Radians ~ ℝ ~ native.Float
+--> Angle ~ Turns ~ ℝ ~ native.Float
+```
+    *dst = *src / PHI;
+    return 0;
+```
+
+morph_angle_as_radians_to_turns_double ()
+    Angle ~ Radians ~ ℝ ~ native.Double
+--> Angle ~ Turns ~ ℝ ~ native.Double
+```
+    *dst = *src / PHI;
+    return 0;
+```
+
+
+morph_angle_as_turns_to_radians_float ()
+    Angle ~ Turns ~ ℝ ~ native.Float
+--> Angle ~ Radians ~ ℝ ~ native.Float
+```
+    *dst = *src * PHI;
+    return 0;
+```
+
+morph_angle_as_degrees_to_radians_double ()
+    Angle ~ Turns ~ ℝ ~ native.Double
+--> Angle ~ Radians ~ ℝ ~ native.Double
+```
+    *dst = *src * PHI;
+    return 0;
+```
diff --git a/morphisms/real.morphism-base b/morphisms/real.morphism-base
new file mode 100644
index 0000000..204bfbd
--- /dev/null
+++ b/morphisms/real.morphism-base
@@ -0,0 +1,105 @@
+```
+#include <stdio.h>
+```
+
+morph_real_as_decimalstr_to_float ()
+    ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~x86.UInt8>
+--> ℝ ~ native.Float
+```
+    sscanf(src, "%f", dst);
+    return 0;
+```
+
+morph_real_as_decimalstr_to_double ()
+    ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~x86.UInt8>
+--> ℝ ~ native.Double
+```
+    sscanf(src, "%lf", dst);
+    return 0;
+```
+
+morph_real_as_float_to_decimalstr ()
+    ℝ ~ native.Float
+--> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~x86.UInt8>
+```
+    sprintf(dst, "%f", *src);
+    return 0;
+```
+
+morph_real_as_double_to_decimalstr ()
+    ℝ ~ native.Double
+--> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~x86.UInt8>
+```
+    sprintf(dst, "%f", *src);
+    return 0;
+```
+
+
+morph_real_as_float_to_double ()
+    ℝ ~ native.Float
+--> ℝ ~ native.Double
+```
+    *dst = *src;
+    return 0;
+```
+
+morph_real_as_double_to_float ()
+    ℝ ~ native.Double
+--> ℝ ~ native.Float
+```
+    fprintf(stderr, "Warning: morphin Double -> Float. Precision loss!");
+    *dst = *src;
+    return 0;
+```
+
+morph_real_as_u64_to_float ()
+    ℝ ~ ℕ ~ x86.UInt64
+--> ℝ ~ native.Float
+```
+    fprintf(stderr, "Warning: morphin UInt64 -> Float. Precision loss!");
+    *dst = *src;
+    return 0;
+```
+
+morph_real_as_u64_to_double ()
+    ℝ ~ ℕ ~ x86.UInt64
+--> ℝ ~ native.Double
+```
+    fprintf(stderr, "Warning: morphin UInt64 -> Double. Precision loss!");
+    *dst = *src;
+    return 0;
+```
+
+morph_real_as_quantized_linear_to_float (Begin: ℝ, End: ℝ, Steps: ℤ)
+    ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ x86.UInt64
+--> ℝ ~ 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.Float
+--> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ x86.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> ~ ℕ ~ x86.UInt64
+--> ℝ ~ 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.Double
+--> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ x86.UInt64
+```
+    *dst = ((*src - (double)Begin) * (double)Steps) / ((double)End - (double)Begin);
+    return 0;
+```
diff --git a/morphisms/temperature.morphism-base b/morphisms/temperature.morphism-base
new file mode 100644
index 0000000..7831292
--- /dev/null
+++ b/morphisms/temperature.morphism-base
@@ -0,0 +1,34 @@
+```
+```
+
+morph_celsius_to_kelvin ()
+      Temperature ~ Celsius ~ ℝ ~ native.Float
+-->   Temperature ~ Kelvin ~ ℝ ~ native.Float
+```
+    *dst = *src + 273.15;
+    return 0;
+```
+
+morph_kelvin_to_celsius ()
+      Temperature ~ Kelvin ~ ℝ ~ native.Float
+-->   Temperature ~ Celsius ~ ℝ ~ native.Float
+```
+    *dst = *src - 273.15;
+    return 0;
+```
+
+morph_celsius_to_fahrenheit ()
+      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.Float
+-->   Temperature ~ Celsius ~ ℝ ~ native.Float
+```
+    *dst = (*src - 32.0) * 5.0 / 9.0;
+    return 0;
+```

From 5d1ea93e20a3d275f38e19f6545330046a5230a4 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 18 Mar 2025 14:07:14 +0100
Subject: [PATCH 3/4] add float & double representations to C-generator

---
 src/c_gen.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/c_gen.rs b/src/c_gen.rs
index 8b7f938..3ee1259 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -30,6 +30,10 @@ pub fn get_c_repr_type(dict: &mut impl TypeDict, t: laddertypes::TypeTerm, skip_
                 Some("uint32_t".into())
             } else if t == &dict.parse("x86.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) => {

From 8b8acb81a69b7e5e200271b339dec6a554592774 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 18 Mar 2025 14:09:01 +0100
Subject: [PATCH 4/4] generated main(): use sizeof for buffer sizes

---
 src/c_gen.rs | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/c_gen.rs b/src/c_gen.rs
index 3ee1259..e13a4d3 100644
--- a/src/c_gen.rs
+++ b/src/c_gen.rs
@@ -162,15 +162,18 @@ pub fn generate_main(type_dict: &mut impl TypeDict, path: Vec<MorphismInstance<L
 
     println!(r#"
 int main() {{
-uint8_t bufA[1024];
-uint8_t bufB[1024];
+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, 1024);
+int l = read(0, bufA, sizeof(bufA));
 fprintf(stderr, "read  %d bytes\n", l);
 
         "#,
@@ -221,7 +224,7 @@ printf("%s\n", {});"#, out_buf);
         println!(r#"
 write(1, {}, {});"#,
             out_buf,
-            1024
+            "sizeof(bufA)"
         );
     }