From d6107601a6561b926727a3f016cfe0466f85834b Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Thu, 20 Feb 2025 02:23:58 +0100
Subject: [PATCH] morphisms: add posint to u64 and vice-versa

---
 morphisms/posint.morphism-base | 59 ++++++++++++++++++++++++++--------
 1 file changed, 46 insertions(+), 13 deletions(-)

diff --git a/morphisms/posint.morphism-base b/morphisms/posint.morphism-base
index 81ea945..8300e64 100644
--- a/morphisms/posint.morphism-base
+++ b/morphisms/posint.morphism-base
@@ -1,3 +1,27 @@
+
+morph_nat_as_u64_to_pos ()
+      ℕ
+    ~ x86.UInt64
+-->   ℕ
+    ~ <PosInt 0 LittleEndian>
+    ~ <Seq~<LengthPrefix x86.UInt64> <Digit 0>~x86.UInt64>
+```
+    dst->len = 1;
+    dst->items[0] = *src;
+    return 0;
+```
+
+morph_nat_as_u64_to_pos ()
+      ℕ
+    ~ <PosInt 0 LittleEndian>
+    ~ <Seq~<LengthPrefix x86.UInt64> <Digit 0>~x86.UInt64>
+-->   ℕ
+    ~ x86.UInt64
+```
+    *dst = src->items[0];
+    return 0;
+```
+
 morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
       ℕ
     ~ <PosInt SrcRadix LittleEndian>
@@ -15,9 +39,13 @@ morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
 
     length_prefix_uint64_array_clear( dst );
 
-    while( value > 0 ) {
-        length_prefix_uint64_array_push( dst, value % DstRadix );
-        value /= DstRadix;
+    if( DstRadix == 0 ) {
+        length_prefix_uint64_array_push( dst, value );
+    } else if( DstRadix > 0 ) {
+        while( value > 0 ) {
+            length_prefix_uint64_array_push( dst, value % DstRadix );
+            value /= DstRadix;
+        }
     }
 
     return 0;
@@ -38,17 +66,22 @@ morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
         value += src->items[i];
     }
 
-    uint64_t v = value;
-    dst->len = 0;
-    while( v ) {
-        dst->len++;
-        v /= DstRadix;
-    }
+    if( DstRadix == 0 ) {
+        dst->len = 1;
+        dst->items[0] = value;
+    } else {
+        uint64_t v = value;
+        dst->len = 0;
+        while( v ) {
+            dst->len++;
+            v /= DstRadix;
+        }
 
-    uint64_t i = dst->len;
-    while( value > 0 ) {
-        dst->items[--i] = ( dst, value % DstRadix );
-        value /= DstRadix;
+        uint64_t i = dst->len;
+        while( value > 0 ) {
+            dst->items[--i] = value % DstRadix;
+            value /= DstRadix;
+        }
     }
 
     return 0;