Commit a736cc170aa4f13fc5e79e6d1cf1e7fc4ec978a1

Thomas de Grivel 2024-03-05T20:23:53

x +i y

diff --git a/.ic3_history b/.ic3_history
index 450cb65..1f0d452 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,26 +1,3 @@
-m("Quentin")
-if true 1 :else 2
-quote if true 1 :else 2
-if true 1
-quote if true 1
-2 3 4 5 6 7 8
-1
-if_then_else 1 2 3
-if_then_else true 2 3
-if_then_else false 2 3
-if
-1 2 3
-4
-if true 1 :else 2
-if
-true
-1 :else 2
-if 
-true 1 :else 2
-if true 1 :else 2
-if true 1 :else
-2
-if true 1
 C3.if
 1 2 3 4
 i = C3.if
@@ -97,3 +74,26 @@ sqrt(-1)
 1 +i 1 + (2 +i 2)
 1 +i 1 * (2 +i 2)
 (1 +i 1) * (2 +i 2)
+0.5
+0.5 + 1
+1/2 + 1
+1 +i 1 + 1
+1 +i 1 + 0.5
+1 +i 1 + (F32) 0.5
+1 +i 1 + 0.5f
+1.5f +i 1 + 0.5f
+1.5f +i 2 + 0.5f
+2/3 +i 2 + 0.5f
+2/3 +i 2 + 1/2
+2/3 +i 2
+2/3 +i 2/2
+2/3 +i 2/1
+2/3 +i 2/3
+2/3 +i 2/3 + 0.5
+3 +i 2 + 0.5
+3 +i 2 + 1
+3 +i 2 + 2
+3 +i 2 + 2 +i 3
+3 +i 2 + 2 +i 3 +i 1
+3 +i 2 + 2 +i 3 +i 1 + 2
+3 +i 2 + 2 +i 3 +i 1 + 1
diff --git a/libc3/complex.c b/libc3/complex.c
index fac6bdd..5ccb6aa 100644
--- a/libc3/complex.c
+++ b/libc3/complex.c
@@ -19,6 +19,29 @@
 #include "tag.h"
 #include "tag_init.h"
 
+#define DEF_COMPLEX_INIT(type)                                         \
+  s_complex * complex_init_ ## type (s_complex *c, type src)           \
+  {                                                                    \
+    assert(c);                                                         \
+    tag_init_ ## type(&c->x, src);                                     \
+    tag_init_u8(&c->y, 0);                                             \
+    return c;                                                          \
+  }
+
+DEF_COMPLEX_INIT(f32)
+DEF_COMPLEX_INIT(f64)
+DEF_COMPLEX_INIT(f128)
+DEF_COMPLEX_INIT(s8)
+DEF_COMPLEX_INIT(s16)
+DEF_COMPLEX_INIT(s32)
+DEF_COMPLEX_INIT(s64)
+DEF_COMPLEX_INIT(sw)
+DEF_COMPLEX_INIT(u8)
+DEF_COMPLEX_INIT(u16)
+DEF_COMPLEX_INIT(u32)
+DEF_COMPLEX_INIT(u64)
+DEF_COMPLEX_INIT(uw)
+
 s_complex * complex_add (const s_complex *a, const s_complex *b,
                          s_complex *dest)
 {
@@ -90,6 +113,51 @@ s_complex * complex_init (s_complex *c)
   return c;
 }
 
+s_complex * complex_init_cast (s_complex *c, const s_tag *src)
+{
+  assert(c);
+  assert(src);
+  switch (src->type) {
+  case TAG_COMPLEX:
+    return complex_init_copy(c, src->data.complex);
+  case TAG_F32:
+    return complex_init_f32(c, src->data.f32);
+  case TAG_F64:
+    return complex_init_f64(c, src->data.f64);
+  case TAG_F128:
+    return complex_init_f128(c, src->data.f128);
+  case TAG_INTEGER:
+    return complex_init_integer(c, &src->data.integer);
+  case TAG_RATIO:
+    return complex_init_ratio(c, &src->data.ratio);
+  case TAG_SW:
+    return complex_init_sw(c, src->data.sw);
+  case TAG_S64:
+    return complex_init_s64(c, src->data.s64);
+  case TAG_S32:
+    return complex_init_s32(c, src->data.s32);
+  case TAG_S16:
+    return complex_init_s16(c, src->data.s16);
+  case TAG_S8:
+    return complex_init_s8(c, src->data.s8);
+  case TAG_U8:
+    return complex_init_u8(c, src->data.u8);
+  case TAG_U16:
+    return complex_init_u16(c, src->data.u16);
+  case TAG_U32:
+    return complex_init_u32(c, src->data.u32);
+  case TAG_U64:
+    return complex_init_u64(c, src->data.u64);
+  case TAG_UW:
+    return complex_init_uw(c, src->data.uw);
+  default:
+    break;
+  }
+  err_puts("complex_init_cast: invalid tag type");
+  assert(! "complex_init_cast: invalid tag type");
+  return NULL;
+}
+
 s_complex * complex_init_copy (s_complex *c, const s_complex *src)
 {
   assert(c);
@@ -99,6 +167,22 @@ s_complex * complex_init_copy (s_complex *c, const s_complex *src)
   return c;
 }
 
+s_complex * complex_init_integer (s_complex *c, const s_integer *src)
+{
+  assert(c);
+  tag_init_integer_copy(&c->x, src);
+  tag_init_u8(&c->y, 0);
+  return c;
+}
+
+s_complex * complex_init_ratio (s_complex *c, const s_ratio *src)
+{
+  assert(c);
+  tag_init_ratio_copy(&c->x, src);
+  tag_init_u8(&c->y, 0);
+  return c;
+}
+
 s_complex * complex_mul (const s_complex *a, const s_complex *b,
                          s_complex *dest)
 {
diff --git a/libc3/complex.h b/libc3/complex.h
index 9fe4424..4d2aeff 100644
--- a/libc3/complex.h
+++ b/libc3/complex.h
@@ -17,13 +17,28 @@
 #include <stdio.h>
 #include "types.h"
 
-/* Stack allocation compatible functions */
+/* Stack-allocation compatible functions, call complex_clean
+   after use. */
+void        complex_clean (s_complex *c);
 s_complex * complex_init (s_complex *c);
 s_complex * complex_init_1 (s_complex *c, const s8 *p);
-s_complex * complex_init_copy (s_complex *a, const s_complex *x);
-s_complex * complex_init_f32 (s_complex *a, f32 x, f32 y);
-s_complex * complex_init_f64 (s_complex *a, f64 x, f64 y);
-void        complex_clean (s_complex *c);
+s_complex * complex_init_cast (s_complex *c, const s_tag *src);
+s_complex * complex_init_copy (s_complex *c, const s_complex *src);
+s_complex * complex_init_f32 (s_complex *c, f32 src);
+s_complex * complex_init_f64 (s_complex *c, f64 src);
+s_complex * complex_init_f128 (s_complex *c, f128 src);
+s_complex * complex_init_integer (s_complex *c, const s_integer *src);
+s_complex * complex_init_ratio (s_complex *c, const s_ratio *src);
+s_complex * complex_init_s8 (s_complex *c, s8 src);
+s_complex * complex_init_s16 (s_complex *c, s16 src);
+s_complex * complex_init_s32 (s_complex *c, s32 src);
+s_complex * complex_init_s64 (s_complex *c, s64 src);
+s_complex * complex_init_sw (s_complex *c, sw src);
+s_complex * complex_init_u8 (s_complex *c, u8 src);
+s_complex * complex_init_u16 (s_complex *c, u16 src);
+s_complex * complex_init_u32 (s_complex *c, u32 src);
+s_complex * complex_init_u64 (s_complex *c, u64 src);
+s_complex * complex_init_uw (s_complex *c, uw src);
 
 /* Setters */
 s_complex * complex_set_double (s_complex *a, double x, double y);
diff --git a/libc3/tag_add.c b/libc3/tag_add.c
index c2bfb9e..4fb43b1 100644
--- a/libc3/tag_add.c
+++ b/libc3/tag_add.c
@@ -18,6 +18,7 @@
 
 s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
 {
+  s_complex c;
   s_integer tmp;
   s_integer tmp2;
   assert(a);
@@ -29,12 +30,79 @@ s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
     case TAG_COMPLEX:
       return tag_init_complex(dest, complex_new_add(a->data.complex,
                                                     b->data.complex));
+    case TAG_F32:
+      complex_init_f32(&c, b->data.f32);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_F64:
+      complex_init_f64(&c, b->data.f64);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_F128:
+      complex_init_f128(&c, b->data.f128);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_INTEGER:
+      if (! complex_init_integer(&c, &b->data.integer))
+        return NULL;
+      if (! tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                   &c))) {
+                                                   
+        complex_clean(&c);
+        return NULL;
+      }
+      complex_clean(&c);
+      return dest;
+    case TAG_S8:
+      complex_init_s8(&c, b->data.s8);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_S16:
+      complex_init_s16(&c, b->data.s16);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_S32:
+      complex_init_s32(&c, b->data.s32);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_S64:
+      complex_init_s64(&c, b->data.s64);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_SW:
+      complex_init_sw(&c, b->data.sw);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_U8:
+      complex_init_u8(&c, b->data.u8);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_U16:
+      complex_init_u16(&c, b->data.u16);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_U32:
+      complex_init_u32(&c, b->data.u32);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_U64:
+      complex_init_u64(&c, b->data.u64);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
+    case TAG_UW:
+      complex_init_uw(&c, b->data.uw);
+      return tag_init_complex(dest, complex_new_add(a->data.complex,
+                                                    &c));
     default:
       break;
     }
     break;
   case TAG_F32:
     switch (b->type) {
+    case TAG_COMPLEX:
+      complex_init_f32(&c, a->data.f32);
+      return tag_init_complex(dest, complex_new_add(&c,
+                                                    b->data.complex));
     case TAG_F32:
       return tag_init_f32(dest, a->data.f32 + b->data.f32);
     case TAG_F64:
@@ -99,6 +167,16 @@ s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
   }
   case TAG_INTEGER:
     switch (b->type) {
+    case TAG_COMPLEX:
+      if (! complex_init_integer(&c, &a->data.integer))
+        return NULL;
+      if (! tag_init_complex(dest, complex_new_add(&c,
+                                                   b->data.complex))) {
+        complex_clean(&c);
+        return NULL;
+      }
+      complex_clean(&c);
+      return dest;
     case TAG_F32:
       return tag_init_f32(dest, (f32) integer_to_f64(&a->data.integer) +
                           b->data.f32);
diff --git a/libc3/tag_addi.c b/libc3/tag_addi.c
index f34f23e..14eddd8 100644
--- a/libc3/tag_addi.c
+++ b/libc3/tag_addi.c
@@ -12,27 +12,41 @@
  */
 #include "alloc.h"
 #include "assert.h"
+#include "complex.h"
 #include "tag.h"
 
 s_tag * tag_addi (const s_tag *a, const s_tag *b, s_tag *dest)
 {
   s_complex *c;
+  s_complex ca = {0};
+  s_complex cb = {0};
   assert(a);
   assert(b);
   assert(dest);
   c = alloc(sizeof(s_complex));
   if (! c)
     return NULL;
-  if (! tag_init_copy(&c->x, a)) {
+  if (! complex_init_cast(&ca, a)) {
     free(c);
     return NULL;
   }
-  if (! tag_init_copy(&c->y, b)) {
+  if (! complex_init_cast(&cb, b)) {
+    complex_clean(&ca);
+    free(c);
+    return NULL;
+  }
+  if (! tag_sub(&ca.x, &cb.y, &c->x)) {
+    complex_clean(&cb);
+    complex_clean(&ca);
+    free(c);
+    return NULL;
+  }
+  if (! tag_add(&ca.y, &cb.x, &c->y)) {
     tag_clean(&c->x);
+    complex_clean(&cb);
+    complex_clean(&ca);
     free(c);
     return NULL;
   }
-  dest->type = TAG_COMPLEX;
-  dest->data.complex = c;
-  return dest;
+  return tag_init_complex(dest, c);
 }