From 89db7cca24cf998447d3995368c47ed0340e6884 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Fri, 11 May 2018 15:40:20 -0400 Subject: [PATCH] Issue #55 - More arithmetic op support for complex --- include/cyclone/types.h | 7 +++ runtime.c | 100 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 22696589..8a36c383 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -695,6 +695,13 @@ typedef struct { n.tag = complex_num_tag; \ n.value = (r + (i * I)); +/** Assign given complex value to the given complex number object pointer */ +#define assign_complex_num(pobj,v) \ + ((complex_num_type *)pobj)->hdr.mark = gc_color_red; \ + ((complex_num_type *)pobj)->hdr.grayed = 0; \ + ((complex_num_type *)pobj)->tag = complex_num_tag; \ + complex_num_value(pobj) = v; + /** * @brief Double-precision floating point type, also known as a flonum. */ diff --git a/runtime.c b/runtime.c index ebe42b64..63d422bc 100644 --- a/runtime.c +++ b/runtime.c @@ -3168,6 +3168,9 @@ object Cyc_fast_sum(void *data, object ptr, object x, object y) { mp_add(&bnx, &bignum_value(y), &bignum_value(bn)); mp_clear(&bnx); return bn; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, ((obj_obj2int(x)) + complex_num_value(y))); + return ptr; } } // x is double @@ -3181,6 +3184,9 @@ object Cyc_fast_sum(void *data, object ptr, object x, object y) { } else if (is_object_type(y) && type_of(y) == bignum_tag) { assign_double(ptr, double_value(x) + mp_get_double(&bignum_value(y))); return ptr; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, double_value(x) + complex_num_value(y)); + return ptr; } } // x is bignum @@ -3200,6 +3206,25 @@ object Cyc_fast_sum(void *data, object ptr, object x, object y) { alloc_bignum(data, bn); mp_add(&bignum_value(x), &bignum_value(y), &bignum_value(bn)); return bn; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, mp_get_double(&bignum_value(x)) + complex_num_value(y)); + return ptr; + } + } + // x is complex + if (is_object_type(x) && type_of(x) == complex_num_tag) { + if (obj_is_int(y)){ + assign_complex_num(ptr, complex_num_value(x) + (double)(obj_obj2int(y))); + return ptr; + } else if (is_object_type(y) && type_of(y) == double_tag) { + assign_complex_num(ptr, complex_num_value(x) + double_value(y)); + return ptr; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, complex_num_value(x) + complex_num_value(y)); + return ptr; + } else if (is_object_type(y) && type_of(y) == bignum_tag) { + assign_complex_num(ptr, complex_num_value(x) + mp_get_double(&bignum_value(y))); + return ptr; } } // still here, raise an error @@ -3243,6 +3268,9 @@ object Cyc_fast_sub(void *data, object ptr, object x, object y) { mp_sub(&bnx, &bignum_value(y), &bignum_value(bn)); mp_clear(&bnx); return bn; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, ((obj_obj2int(x)) - complex_num_value(y))); + return ptr; } } // x is double @@ -3256,6 +3284,9 @@ object Cyc_fast_sub(void *data, object ptr, object x, object y) { } else if (is_object_type(y) && type_of(y) == bignum_tag) { assign_double(ptr, double_value(x) - mp_get_double(&bignum_value(y))); return ptr; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, double_value(x) - complex_num_value(y)); + return ptr; } } // x is bignum @@ -3275,6 +3306,25 @@ object Cyc_fast_sub(void *data, object ptr, object x, object y) { alloc_bignum(data, bn); mp_sub(&bignum_value(x), &bignum_value(y), &bignum_value(bn)); return bn; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, mp_get_double(&bignum_value(x)) - complex_num_value(y)); + return ptr; + } + } + // x is complex + if (is_object_type(x) && type_of(x) == complex_num_tag) { + if (obj_is_int(y)){ + assign_complex_num(ptr, complex_num_value(x) - (double)(obj_obj2int(y))); + return ptr; + } else if (is_object_type(y) && type_of(y) == double_tag) { + assign_complex_num(ptr, complex_num_value(x) - double_value(y)); + return ptr; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, complex_num_value(x) - complex_num_value(y)); + return ptr; + } else if (is_object_type(y) && type_of(y) == bignum_tag) { + assign_complex_num(ptr, complex_num_value(x) - mp_get_double(&bignum_value(y))); + return ptr; } } // still here, raise an error @@ -3318,6 +3368,9 @@ object Cyc_fast_mul(void *data, object ptr, object x, object y) { mp_mul(&bnx, &bignum_value(y), &bignum_value(bn)); mp_clear(&bnx); return bn; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, ((obj_obj2int(x)) * complex_num_value(y))); + return ptr; } } // x is double @@ -3331,6 +3384,9 @@ object Cyc_fast_mul(void *data, object ptr, object x, object y) { } else if (is_object_type(y) && type_of(y) == bignum_tag) { assign_double(ptr, double_value(x) * mp_get_double(&bignum_value(y))); return ptr; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, double_value(x) * complex_num_value(y)); + return ptr; } } // x is bignum @@ -3350,6 +3406,25 @@ object Cyc_fast_mul(void *data, object ptr, object x, object y) { alloc_bignum(data, bn); mp_mul(&bignum_value(x), &bignum_value(y), &bignum_value(bn)); return bn; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, mp_get_double(&bignum_value(x)) * complex_num_value(y)); + return ptr; + } + } + // x is complex + if (is_object_type(x) && type_of(x) == complex_num_tag) { + if (obj_is_int(y)){ + assign_complex_num(ptr, complex_num_value(x) * (double)(obj_obj2int(y))); + return ptr; + } else if (is_object_type(y) && type_of(y) == double_tag) { + assign_complex_num(ptr, complex_num_value(x) * double_value(y)); + return ptr; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, complex_num_value(x) * complex_num_value(y)); + return ptr; + } else if (is_object_type(y) && type_of(y) == bignum_tag) { + assign_complex_num(ptr, complex_num_value(x) * mp_get_double(&bignum_value(y))); + return ptr; } } // still here, raise an error @@ -3383,6 +3458,9 @@ object Cyc_fast_div(void *data, object ptr, object x, object y) { mp_div(&bnx, &bignum_value(y), &bignum_value(bn), NULL); mp_clear(&bnx); return bn; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, ((obj_obj2int(x)) / complex_num_value(y))); + return ptr; } } // x is double @@ -3396,6 +3474,9 @@ object Cyc_fast_div(void *data, object ptr, object x, object y) { } else if (is_object_type(y) && type_of(y) == bignum_tag) { assign_double(ptr, double_value(x) / mp_get_double(&bignum_value(y))); return ptr; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, double_value(x) / complex_num_value(y)); + return ptr; } } // x is bignum @@ -3415,6 +3496,25 @@ object Cyc_fast_div(void *data, object ptr, object x, object y) { alloc_bignum(data, bn); mp_div(&bignum_value(x), &bignum_value(y), &bignum_value(bn), NULL); return bn; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, mp_get_double(&bignum_value(x)) / complex_num_value(y)); + return ptr; + } + } + // x is complex + if (is_object_type(x) && type_of(x) == complex_num_tag) { + if (obj_is_int(y)){ + assign_complex_num(ptr, complex_num_value(x) / (double)(obj_obj2int(y))); + return ptr; + } else if (is_object_type(y) && type_of(y) == double_tag) { + assign_complex_num(ptr, complex_num_value(x) / double_value(y)); + return ptr; + } else if (is_object_type(y) && type_of(y) == complex_num_tag) { + assign_complex_num(ptr, complex_num_value(x) / complex_num_value(y)); + return ptr; + } else if (is_object_type(y) && type_of(y) == bignum_tag) { + assign_complex_num(ptr, complex_num_value(x) / mp_get_double(&bignum_value(y))); + return ptr; } } // still here, raise an error