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);
}