diff --git a/.ic3_history b/.ic3_history
index bb0aca1..450cb65 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,8 +1,3 @@
-quote "Hello, " + (unquote name) + " !"
-m = macro (name) { quote "Hello, " + (unquote name) + " !" }
-n = "123"
-m(n)
-m = macro (name) { quote "Hello, " + (unquote name) + " !" }
m("Quentin")
if true 1 :else 2
quote if true 1 :else 2
@@ -97,3 +92,8 @@ sqrt(9)
sqrt(16)
sqrt(-1)
1 + 2 +i 3
+1 +i 1
+1 +i 1 + 2 +i 2
+1 +i 1 + (2 +i 2)
+1 +i 1 * (2 +i 2)
+(1 +i 1) * (2 +i 2)
diff --git a/libc3/complex.c b/libc3/complex.c
index b58acb4..fac6bdd 100644
--- a/libc3/complex.c
+++ b/libc3/complex.c
@@ -13,6 +13,7 @@
#include <math.h>
#include "alloc.h"
#include "assert.h"
+#include "complex.h"
#include "f32.h"
#include "f64.h"
#include "tag.h"
@@ -43,6 +44,44 @@ void complex_delete (s_complex *c)
free(c);
}
+s_complex * complex_div (const s_complex *a, const s_complex *b,
+ s_complex *dest)
+{
+ s_tag axbx;
+ s_tag axby;
+ s_tag aybx;
+ s_tag ayby;
+ s_tag axbx_ayby;
+ s_tag aybx_axby;
+ s_tag bx2;
+ s_tag by2;
+ s_tag bx2_by2;
+ s_complex tmp = {0};
+ assert(a);
+ assert(b);
+ assert(dest);
+ assert(tag_is_number(&a->x));
+ assert(tag_is_number(&a->y));
+ assert(tag_is_number(&b->x));
+ assert(tag_is_number(&b->y));
+ // a.x * b.x + a.y * b.y a.y * b.x - a.x * b.y
+ // --------------------- +i ---------------------
+ // b.x * b.x + b.y * b.y b.x * b.x + b.y * b.y
+ tag_mul(&a->x, &b->x, &axbx);
+ tag_mul(&a->y, &b->y, &ayby);
+ tag_add(&axbx, &ayby, &axbx_ayby);
+ tag_mul(&b->x, &b->x, &bx2);
+ tag_mul(&b->y, &b->y, &by2);
+ tag_add(&bx2, &by2, &bx2_by2);
+ tag_div(&axbx_ayby, &bx2_by2, &tmp.x);
+ tag_mul(&a->y, &b->x, &aybx);
+ tag_mul(&a->x, &b->y, &axby);
+ tag_sub(&aybx, &axby, &aybx_axby);
+ tag_div(&aybx_axby, &bx2_by2, &tmp.y);
+ *dest = tmp;
+ return dest;
+}
+
s_complex * complex_init (s_complex *c)
{
assert(c);
@@ -96,6 +135,58 @@ s_complex * complex_new (void)
return c;
}
+s_complex * complex_new_add (const s_complex *a, const s_complex *b)
+{
+ s_complex *c;
+ c = alloc(sizeof(s_complex));
+ if (! c)
+ return NULL;
+ if (! complex_add(a, b, c)) {
+ free(c);
+ return NULL;
+ }
+ return c;
+}
+
+s_complex * complex_new_div (const s_complex *a, const s_complex *b)
+{
+ s_complex *c;
+ c = alloc(sizeof(s_complex));
+ if (! c)
+ return NULL;
+ if (! complex_div(a, b, c)) {
+ free(c);
+ return NULL;
+ }
+ return c;
+}
+
+s_complex * complex_new_mul (const s_complex *a, const s_complex *b)
+{
+ s_complex *c;
+ c = alloc(sizeof(s_complex));
+ if (! c)
+ return NULL;
+ if (! complex_mul(a, b, c)) {
+ free(c);
+ return NULL;
+ }
+ return c;
+}
+
+s_complex * complex_new_sub (const s_complex *a, const s_complex *b)
+{
+ s_complex *c;
+ c = alloc(sizeof(s_complex));
+ if (! c)
+ return NULL;
+ if (! complex_sub(a, b, c)) {
+ free(c);
+ return NULL;
+ }
+ return c;
+}
+
s_complex * complex_new_copy (const s_complex *src)
{
s_complex *c;
diff --git a/libc3/complex.h b/libc3/complex.h
index 2f2a22f..9fe4424 100644
--- a/libc3/complex.h
+++ b/libc3/complex.h
@@ -31,16 +31,20 @@ s_complex * complex_set_double (s_complex *a, double x, double y);
/* Modifiers */
s_complex * complex_add (const s_complex *a, const s_complex *b,
s_complex *dest);
-s_complex * complex_sub (const s_complex *a, const s_complex *b,
+s_complex * complex_div (const s_complex *a, const s_complex *b,
s_complex *dest);
s_complex * complex_mul (const s_complex *a, const s_complex *b,
s_complex *dest);
-s_complex * complex_div (const s_complex *a, const s_complex *b,
+s_complex * complex_sub (const s_complex *a, const s_complex *b,
s_complex *dest);
/* Constructors, call complex_delete after use. */
void complex_delete (s_complex *c);
s_complex * complex_new (void);
+s_complex * complex_new_add (const s_complex *a, const s_complex *b);
+s_complex * complex_new_div (const s_complex *a, const s_complex *b);
+s_complex * complex_new_mul (const s_complex *a, const s_complex *b);
+s_complex * complex_new_sub (const s_complex *a, const s_complex *b);
s_complex * complex_new_copy (const s_complex *a);
/* Observers */
diff --git a/libc3/list_init.c b/libc3/list_init.c
index 979911e..fac1925 100644
--- a/libc3/list_init.c
+++ b/libc3/list_init.c
@@ -85,6 +85,17 @@ s_list * list_init_character (s_list *list, character c, s_list *next)
return list;
}
+s_list * list_init_complex (s_list *list, s_complex *c, s_list *next)
+{
+ s_list tmp;
+ assert(list);
+ list_init(&tmp, next);
+ if (! tag_init_complex(&tmp.tag, c))
+ return NULL;
+ *list = tmp;
+ return list;
+}
+
s_list * list_init_f32 (s_list *list, f32 f, s_list *next)
{
s_list tmp;
@@ -592,6 +603,19 @@ s_list * list_new_character (character c, s_list *next)
return list;
}
+s_list * list_new_complex (s_complex *c, s_list *next)
+{
+ s_list *list;
+ list = list_new(next);
+ if (! list)
+ return NULL;
+ if (! tag_init_complex(&list->tag, c)) {
+ free(list);
+ return NULL;
+ }
+ return list;
+}
+
s_list * list_new_f32 (f32 f, s_list *next)
{
s_list *list;
diff --git a/libc3/list_init.h b/libc3/list_init.h
index 372b6ef..8bc30e1 100644
--- a/libc3/list_init.h
+++ b/libc3/list_init.h
@@ -14,6 +14,7 @@ s_list * list_init_bool (s_list *list, bool b, s_list *next);
s_list * list_init_call (s_list *list, s_list *next);
s_list * list_init_character (s_list *list, character c, s_list *next);
+s_list * list_init_complex (s_list *list, s_complex *c, s_list *next);
s_list * list_init_f32 (s_list *list, f32 f, s_list *next);
s_list * list_init_f64 (s_list *list, f64 f, s_list *next);
s_list * list_init_f128 (s_list *list, f128 f, s_list *next);
@@ -78,6 +79,7 @@ s_list * list_new_bool (bool b, s_list *next);
s_list * list_new_call (s_list *next);
s_list * list_new_character (character c, s_list *next);
+s_list * list_new_complex (s_complex *c, s_list *next);
s_list * list_new_f32 (f32 f, s_list *next);
s_list * list_new_f64 (f64 f, s_list *next);
s_list * list_new_f128 (f128 f, s_list *next);
@@ -133,6 +135,7 @@ s_list * list_bool (s_list *list, bool b);
s_list * list_call (s_list *list);
s_list * list_character (s_list *list, character c);
+s_list * list_complex (s_list *list, s_complex *c);
s_list * list_f32 (s_list *list, f32 f);
s_list * list_f64 (s_list *list, f64 f);
s_list * list_f128 (s_list *list, f128 f);
diff --git a/libc3/tag_add.c b/libc3/tag_add.c
index 8c29dfd..c2bfb9e 100644
--- a/libc3/tag_add.c
+++ b/libc3/tag_add.c
@@ -11,6 +11,7 @@
* THIS SOFTWARE.
*/
#include "assert.h"
+#include "complex.h"
#include "integer.h"
#include "ratio.h"
#include "tag.h"
@@ -23,6 +24,15 @@ s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
assert(b);
assert(dest);
switch (a->type) {
+ case TAG_COMPLEX:
+ switch (b->type) {
+ case TAG_COMPLEX:
+ return tag_init_complex(dest, complex_new_add(a->data.complex,
+ b->data.complex));
+ default:
+ break;
+ }
+ break;
case TAG_F32:
switch (b->type) {
case TAG_F32:
diff --git a/libc3/tag_init.c b/libc3/tag_init.c
index 8699cc7..042e8b2 100644
--- a/libc3/tag_init.c
+++ b/libc3/tag_init.c
@@ -82,6 +82,16 @@ s_tag * tag_init_character (s_tag *tag, character c)
return tag;
}
+s_tag * tag_init_complex (s_tag *tag, s_complex *c)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_COMPLEX;
+ tmp.data.complex = c;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_init_f32 (s_tag *tag, f32 f)
{
s_tag tmp = {0};
@@ -569,6 +579,17 @@ s_tag * tag_new_character (character c)
return tag;
}
+s_tag * tag_new_complex (s_complex *c)
+{
+ s_tag *tag;
+ tag = alloc(sizeof(s_tag));
+ if (! tag)
+ return NULL;
+ tag->type = TAG_COMPLEX;
+ tag->data.complex = c;
+ return tag;
+}
+
s_tag * tag_new_f32 (f32 f)
{
s_tag *tag;
@@ -1134,6 +1155,17 @@ s_tag * tag_character (s_tag *tag, character c)
return tag;
}
+s_tag * tag_complex (s_tag *tag, s_complex *c)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_COMPLEX;
+ tmp.data.complex = c;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_f32 (s_tag *tag, f32 f)
{
s_tag tmp = {0};
diff --git a/libc3/tag_init.h b/libc3/tag_init.h
index 91589f3..39c2c05 100644
--- a/libc3/tag_init.h
+++ b/libc3/tag_init.h
@@ -12,6 +12,7 @@ s_tag * tag_init_bool (s_tag *tag, bool b);
s_tag * tag_init_call (s_tag *tag);
s_tag * tag_init_character (s_tag *tag, character c);
s_tag * tag_init_copy (s_tag *tag, const s_tag *src);
+s_tag * tag_init_complex (s_tag *tag, s_complex *c);
s_tag * tag_init_f32 (s_tag *tag, f32 f);
s_tag * tag_init_f64 (s_tag *tag, f64 f);
s_tag * tag_init_f128 (s_tag *tag, f128 f);
@@ -63,6 +64,7 @@ s_tag * tag_new_bool (bool b);
s_tag * tag_new_call (void);
s_tag * tag_new_character (character c);
s_tag * tag_new_copy (const s_tag *src);
+s_tag * tag_new_complex (s_complex *c);
s_tag * tag_new_f32 (f32 f);
s_tag * tag_new_f64 (f64 f);
s_tag * tag_new_f128 (f128 f);
@@ -114,6 +116,7 @@ s_tag * tag_bool (s_tag *tag, bool b);
s_tag * tag_call (s_tag *tag);
s_tag * tag_character (s_tag *tag, character c);
s_tag * tag_copy (s_tag *tag, const s_tag *src);
+s_tag * tag_complex (s_tag *tag, s_complex *c);
s_tag * tag_f32 (s_tag *tag, f32 f);
s_tag * tag_f64 (s_tag *tag, f64 f);
s_tag * tag_f128 (s_tag *tag, f128 f);
diff --git a/libc3/tag_init.rb b/libc3/tag_init.rb
index c1dada4..17c398f 100644
--- a/libc3/tag_init.rb
+++ b/libc3/tag_init.rb
@@ -45,6 +45,7 @@ class TagInit
@args_list.each do |arg|
@first_arg_deref ||= arg.type != "const s_sym *" &&
+ arg.type != "s_complex *" &&
arg.type != "s_list *" &&
arg.type.match?(/\*$/) ?
"*#{arg.name}" : arg.name
@@ -312,6 +313,8 @@ class TagInitList
[Arg.new("character", "c")]),
TagInitProto.new("copy", nil, :init_mode_none,
[Arg.new("const s_tag *", "src")]),
+ TagInit.new("complex", "TAG_COMPLEX", :init_mode_direct,
+ [Arg.new("s_complex *", "c")]),
TagInit.new("f32", "TAG_F32", :init_mode_direct,
[Arg.new("f32", "f")]),
TagInit.new("f64", "TAG_F64", :init_mode_direct,
diff --git a/test/ic3/complex.in b/test/ic3/complex.in
new file mode 100644
index 0000000..ae43325
--- /dev/null
+++ b/test/ic3/complex.in
@@ -0,0 +1,34 @@
+quote 0 +i 0
+0 +i 0
+quote 0 +i 1
+0 +i 1
+quote 1 +i 256
+1 +i 256
+quote 256 +i 65536
+256 +i 65536
+quote 65536 +i 4294967296
+65536 +i 4294967296
+quote 4294967296 +i 18446744073709551616
+4294967296 +i 18446744073709551616
+quote 18446744073709551616 +i 340282366920938463463374607431768211456
+18446744073709551616 +i 340282366920938463463374607431768211456
+quote 340282366920938463463374607431768211456 +i 115792089237316195423570985008687907853269984665640564039457584007913129639936
+340282366920938463463374607431768211456 +i 115792089237316195423570985008687907853269984665640564039457584007913129639936
+quote 115792089237316195423570985008687907853269984665640564039457584007913129639936 +i 115792089237316195423570985008687907853269984665640564039457584007913129639936
+115792089237316195423570985008687907853269984665640564039457584007913129639936 +i 115792089237316195423570985008687907853269984665640564039457584007913129639936
+quote 0 +i -1
+0 +i -1
+quote -1 +i -256
+-1 +i -256
+quote -256 +i -65536
+-256 +i -65536
+quote -65536 +i -4294967296
+-65536 +i -4294967296
+quote -4294967296 +i -18446744073709551616
+-4294967296 +i -18446744073709551616
+quote -18446744073709551616 +i -340282366920938463463374607431768211456
+-18446744073709551616 +i -340282366920938463463374607431768211456
+quote -340282366920938463463374607431768211456 +i -115792089237316195423570985008687907853269984665640564039457584007913129639936
+-340282366920938463463374607431768211456 +i -115792089237316195423570985008687907853269984665640564039457584007913129639936
+quote -115792089237316195423570985008687907853269984665640564039457584007913129639936 +i -115792089237316195423570985008687907853269984665640564039457584007913129639936
+-115792089237316195423570985008687907853269984665640564039457584007913129639936 +i -115792089237316195423570985008687907853269984665640564039457584007913129639936
diff --git a/test/ic3/complex.out.expected b/test/ic3/complex.out.expected
new file mode 100644
index 0000000..577e492
--- /dev/null
+++ b/test/ic3/complex.out.expected
@@ -0,0 +1,34 @@
+0 +i 0
+0 +i 0
+0 +i 1
+0 +i 1
+1 +i 256
+1 +i 256
+256 +i 65536
+256 +i 65536
+65536 +i 4294967296
+65536 +i 4294967296
+4294967296 +i 18446744073709551616
+4294967296 +i 18446744073709551616
+18446744073709551616 +i 340282366920938463463374607431768211456
+18446744073709551616 +i 340282366920938463463374607431768211456
+340282366920938463463374607431768211456 +i 115792089237316195423570985008687907853269984665640564039457584007913129639936
+340282366920938463463374607431768211456 +i 115792089237316195423570985008687907853269984665640564039457584007913129639936
+115792089237316195423570985008687907853269984665640564039457584007913129639936 +i 115792089237316195423570985008687907853269984665640564039457584007913129639936
+115792089237316195423570985008687907853269984665640564039457584007913129639936 +i 115792089237316195423570985008687907853269984665640564039457584007913129639936
+0 +i -1
+0 +i -1
+-1 +i -256
+-1 +i -256
+-256 +i -65536
+-256 +i -65536
+-65536 +i -4294967296
+-65536 +i -4294967296
+-4294967296 +i -18446744073709551616
+-4294967296 +i -18446744073709551616
+-18446744073709551616 +i -340282366920938463463374607431768211456
+-18446744073709551616 +i -340282366920938463463374607431768211456
+-340282366920938463463374607431768211456 +i -115792089237316195423570985008687907853269984665640564039457584007913129639936
+-340282366920938463463374607431768211456 +i -115792089237316195423570985008687907853269984665640564039457584007913129639936
+-115792089237316195423570985008687907853269984665640564039457584007913129639936 +i -115792089237316195423570985008687907853269984665640564039457584007913129639936
+-115792089237316195423570985008687907853269984665640564039457584007913129639936 +i -115792089237316195423570985008687907853269984665640564039457584007913129639936
diff --git a/test/ic3/complex.ret.expected b/test/ic3/complex.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ic3/complex.ret.expected
@@ -0,0 +1 @@
+0