Commit 0fd81ceaa027a4e53bc3dbbac852249da93aad11

Thomas de Grivel 2024-08-06T12:39:18

fix tag_div for tag_integer_reduce

diff --git a/.ikc3_history b/.ikc3_history
index 5625af5..8766cd7 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,9 +1,3 @@
-type(-65536 * 65536 + 1)
-type(-65536 * 65536 - 1)
-type(-65536 * 65536 + 1)
--256 * 256 + 1
-type(-256 * 256 + 1)
-type(-256 * 256 / 8 + 1)
 type(-256 * 256 / 2 + 1)
 type(-256 * 128 + 1)
 type(-256 * 128 + 2)
@@ -97,3 +91,9 @@ quote "a#{a}"
 quote "a#{:a}"
 quote "a#{%KC3.Operator{}}"
 quote "a#{%KC3.Operator{sym: :-}}"
+type(18446744073709551615)
+18446744073709551615
+type(4294967296)
+type( -2147483648)
+type(4294967296)
+type(-9223372036854775808)
diff --git a/lib/kc3/0.1/httpd.kc3 b/lib/kc3/0.1/httpd.kc3
index 832c785..5e87b7b 100644
--- a/lib/kc3/0.1/httpd.kc3
+++ b/lib/kc3/0.1/httpd.kc3
@@ -1,6 +1,17 @@
 defmodule HTTPd do
 
-  def server_loop = fn (client) {
+  def server = fn (host, port) {
+    socket = Socket.listen(host, port)
+    puts("KC3 HTTPd: listening on #{host}:#{port}")
+    while true do
+      client = Socket.Buf.accept(socket)
+      server_client(client)
+      Socket.Buf.close(client)
+    end
+    Socket.close(socket)
+  }
+
+  def server_client = fn (client) {
     puts("HTTPd.server_loop: got client #{client}")
     req = HTTP.Request.buf_parse(client.buf_rw.r)
     if req do
@@ -33,16 +44,6 @@ defmodule HTTPd do
     end
   }
 
-  def server = fn (host, port) {
-    socket = Socket.listen(host, port)
-    puts("KC3 HTTPd: listening on #{host}:#{port}")
-    while true do
-      client = Socket.Buf.accept(socket)
-      server_loop(client)
-      Socket.Buf.close(client)
-    end
-  }
-
   def main = fn {
     () {
       host = getenv("KC3_HTTPD_HOST")
diff --git a/libkc3/tag_div.c b/libkc3/tag_div.c
index c29053d..7943ad8 100644
--- a/libkc3/tag_div.c
+++ b/libkc3/tag_div.c
@@ -486,10 +486,20 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
       tag_init_s8(dest, (s8) ((s64) a->data.s8 / (s64) b->data.u32));
       return tag_integer_reduce(dest);
     case TAG_U64:
-      tag_init_s8(dest, a->data.s8 / (s8) b->data.u64);
+      integer_init_s8(&tmp, a->data.s8);
+      integer_init_u64(&tmp2, b->data.u64);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     case TAG_UW:
-      tag_init_s8(dest, a->data.s8 / (s8) b->data.uw);
+      integer_init_s8(&tmp, a->data.s8);
+      integer_init_uw(&tmp2, b->data.uw);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     default:
       goto ko;
@@ -543,10 +553,20 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
       tag_init_s16(dest, (s16) ((s64) a->data.s16 / (s64) b->data.u32));
       return tag_integer_reduce(dest);
     case TAG_U64:
-      tag_init_s16(dest, (s16) a->data.s16 / (s16) b->data.u64);
+      integer_init_s16(&tmp, a->data.s16);
+      integer_init_u64(&tmp2, b->data.u64);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     case TAG_UW:
-      tag_init_s16(dest, (s16) a->data.s16 / (s16) b->data.uw);
+      integer_init_s16(&tmp, a->data.s16);
+      integer_init_uw(&tmp2, b->data.uw);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     default:
       goto ko;
@@ -600,10 +620,20 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
       tag_init_s32(dest, a->data.s32 / (s64) b->data.u32);
       return tag_integer_reduce(dest);
     case TAG_U64:
-      tag_init_s32(dest, a->data.s32 / (s32) b->data.u64);
+      integer_init_s32(&tmp, a->data.s32);
+      integer_init_u64(&tmp2, b->data.u64);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     case TAG_UW:
-      tag_init_s32(dest, a->data.s32 / (s32) b->data.uw);
+      integer_init_s32(&tmp, a->data.s32);
+      integer_init_uw(&tmp2, b->data.uw);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     default:
       goto ko;
@@ -657,10 +687,21 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
       tag_init_s64(dest, a->data.s64 / (s64) b->data.u32);
       return tag_integer_reduce(dest);
     case TAG_U64:
-      tag_init_s64(dest, a->data.s64 / (s64) b->data.u64);
+      integer_init_s64(&tmp, a->data.s64);
+      integer_init_u64(&tmp2, b->data.u64);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     case TAG_UW:
-      tag_init_s64(dest, a->data.s64 / (s64) b->data.uw);
+      integer_init_s64(&tmp, a->data.s64);
+
+      integer_init_uw (&tmp2, b->data.uw);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     default:
       goto ko;
@@ -714,10 +755,20 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
       tag_init_sw(dest, a->data.sw / (sw) b->data.u32);
       return tag_integer_reduce(dest);
     case TAG_U64:
-      tag_init_sw(dest, a->data.sw / (sw) b->data.u64);
+      integer_init_sw(&tmp, a->data.sw);
+      integer_init_u64 (&tmp2, b->data.u64);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     case TAG_UW:
-      tag_init_sw(dest, a->data.sw / (sw) b->data.uw);
+      integer_init_sw(&tmp, a->data.sw);
+      integer_init_uw (&tmp2, b->data.uw);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
       return tag_integer_reduce(dest);
     default:
       goto ko;
@@ -918,69 +969,45 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
       ratio_clean(&r);
       return dest;
     case TAG_S8:
-      if (a->data.u64 > S64_MAX) {
-        integer_init_u64(&tmp, a->data.u64);
-        integer_init_s32(&tmp2, (s32) b->data.s8);
-        dest->type = TAG_INTEGER;
-        integer_div(&tmp, &tmp2, &dest->data.integer);
-        integer_clean(&tmp);
-        integer_clean(&tmp2);
-        return tag_integer_reduce(dest);
-      }
-      else
-        return tag_init_s64(dest, (s64) a->data.u64 / (s64) b->data.s8);
+      integer_init_u64(&tmp, a->data.u64);
+      integer_init_s8(&tmp2, b->data.s8);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
+      return tag_integer_reduce(dest);
     case TAG_S16:
-      if (a->data.u64 > S64_MAX) {
-        integer_init_u64(&tmp, a->data.u64);
-        integer_init_s32(&tmp2, (s32) b->data.s16);
-        dest->type = TAG_INTEGER;
-        integer_div(&tmp, &tmp2, &dest->data.integer);
-        integer_clean(&tmp);
-        integer_clean(&tmp2);
-        return tag_integer_reduce(dest);
-      }
-      else
-        return tag_init_s64(dest, (s64) a->data.u64 /
-                            (s64) b->data.s16);
+      integer_init_u64(&tmp, a->data.u64);
+      integer_init_s16(&tmp2, b->data.s16);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
+      return tag_integer_reduce(dest);
     case TAG_S32:
-      if (a->data.u64 > S64_MAX) {
-        integer_init_u64(&tmp, a->data.u64);
-        integer_init_s32(&tmp2, b->data.s32);
-        dest->type = TAG_INTEGER;
-        integer_div(&tmp, &tmp2, &dest->data.integer);
-        integer_clean(&tmp);
-        integer_clean(&tmp2);
-        return tag_integer_reduce(dest);
-      }
-      else
-        return tag_init_s64(dest, (s64) a->data.u64 /
-                            (s64) b->data.s32);
+      integer_init_u64(&tmp, a->data.u64);
+      integer_init_s32(&tmp2, b->data.s32);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
+      return tag_integer_reduce(dest);
     case TAG_S64:
-      if (a->data.u64 > S64_MAX) {
-        integer_init_u64(&tmp, a->data.u64);
-        integer_init_s64(&tmp2, b->data.s64);
-        dest->type = TAG_INTEGER;
-        integer_div(&tmp, &tmp2, &dest->data.integer);
-        integer_clean(&tmp);
-        integer_clean(&tmp2);
-        return tag_integer_reduce(dest);
-      }
-      else
-        return tag_init_s64(dest, (s64) a->data.u64 / b->data.s64);
+      integer_init_u64(&tmp, a->data.u64);
+      integer_init_s64(&tmp2, b->data.s64);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
+      return tag_integer_reduce(dest);
     case TAG_SW:
-      if (a->data.u64 > SW_MAX) {
-        integer_init_u64(&tmp, a->data.u64);
-        integer_init_sw(&tmp2, b->data.sw);
-        dest->type = TAG_INTEGER;
-        integer_div(&tmp, &tmp2, &dest->data.integer);
-        integer_clean(&tmp);
-        integer_clean(&tmp2);
-        return tag_integer_reduce(dest);
-      }
-      else {
-        tag_init_sw(dest, (sw) a->data.u64 / b->data.sw);
-        return tag_integer_reduce(dest);
-      }
+      integer_init_u64(&tmp, a->data.u64);
+      integer_init_sw(&tmp2, b->data.sw);
+      dest->type = TAG_INTEGER;
+      integer_div(&tmp, &tmp2, &dest->data.integer);
+      integer_clean(&tmp);
+      integer_clean(&tmp2);
+      return tag_integer_reduce(dest);
     case TAG_U8:
       tag_init_u64(dest, a->data.u64 / (u64) b->data.u8);
       return tag_integer_reduce(dest);
diff --git a/test/ikc3/puts.out.expected b/test/ikc3/puts.out.expected
index bf68ef7..a9f264f 100644
--- a/test/ikc3/puts.out.expected
+++ b/test/ikc3/puts.out.expected
@@ -6,4 +6,4 @@ puts(%{hello: "World !"})
 (Sw) 20
 puts("Test #{:a}")
 Test a
-(Sw) 10
+(Sw) 7