Commit b4cc5bb4b8ddc71dc3ac2942a960021ccc5a6000

Thomas de Grivel 2024-03-07T16:17:06

pcomplex

diff --git a/lib/c3/0.1/complex.facts b/lib/c3/0.1/complex.facts
index 613354c..386ac1c 100644
--- a/lib/c3/0.1/complex.facts
+++ b/lib/c3/0.1/complex.facts
@@ -2,4 +2,4 @@
   version: 1}
 replace {Complex, :is_a, :module}
 replace {Complex, :symbol, Complex.cast}
-replace {Complex.cast, :cfn, cfn Complex "complex_new_cast" (Tag)}
+replace {Complex.cast, :cfn, cfn Complex "pcomplex_init_cast" (Result, Tag)}
diff --git a/libc3/complex.h b/libc3/complex.h
index 4d2aeff..425a8a4 100644
--- a/libc3/complex.h
+++ b/libc3/complex.h
@@ -13,8 +13,6 @@
 #ifndef LIBC3_COMPLEX_H
 #define LIBC3_COMPLEX_H
 
-#include <stdarg.h>
-#include <stdio.h>
 #include "types.h"
 
 /* Stack-allocation compatible functions, call complex_clean
@@ -53,10 +51,11 @@ s_complex * complex_mul (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. */
+/* Heap-allocation functions, 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_cast (const s_tag *src);
 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);
diff --git a/libc3/pcomplex.c b/libc3/pcomplex.c
new file mode 100644
index 0000000..f677199
--- /dev/null
+++ b/libc3/pcomplex.c
@@ -0,0 +1,57 @@
+/* c3
+ * Copyright 2022-2024 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include "assert.h"
+#include "complex.h"
+#include "pcomplex.h"
+
+void pcomplex_clean (s_complex **p)
+{
+  assert(p);
+  complex_delete(*p);
+}
+
+s_complex ** pcomplex_init (s_complex **p)
+{
+  s_complex *tmp = NULL;
+  assert(p);
+  tmp = complex_new();
+  if (! tmp)
+    return NULL;
+  *p = tmp;
+  return p;
+}
+
+s_complex ** pcomplex_init_cast (s_complex **p, const s_tag *src)
+{
+  s_complex *tmp = NULL;
+  assert(p);
+  assert(src);
+  tmp = complex_new_cast(src);
+  if (! tmp)
+    return NULL;
+  *p = tmp;
+  return p;
+}
+
+s_complex ** pcomplex_init_copy (s_complex **p,
+				 const s_complex * const *src)
+{
+  s_complex *tmp = NULL;
+  assert(p);
+  assert(src);
+  tmp = complex_new_copy(*src);
+  if (! tmp)
+    return NULL;
+  *p = tmp;
+  return p;
+}
diff --git a/libc3/pcomplex.h b/libc3/pcomplex.h
new file mode 100644
index 0000000..9797078
--- /dev/null
+++ b/libc3/pcomplex.h
@@ -0,0 +1,26 @@
+/* c3
+ * Copyright 2022-2024 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef LIBC3_PCOMPLEX_H
+#define LIBC3_PCOMPLEX_H
+
+#include "types.h"
+
+/* Stack-allocation compatible functions, call pcomplex_clean
+   after use. */
+void         pcomplex_clean (s_complex **p);
+s_complex ** pcomplex_init (s_complex **p);
+s_complex ** pcomplex_init_cast (s_complex **p, const s_tag *src);
+s_complex ** pcomplex_init_copy (s_complex **p,
+				 const s_complex * const *src);
+
+#endif /* LIBC3_COMPLEX_H */
diff --git a/libc3/tag.c b/libc3/tag.c
index 2dbd76c..35aa5d5 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -21,7 +21,6 @@
 #include "call.h"
 #include "cfn.h"
 #include "compare.h"
-#include "complex.h"
 #include "env.h"
 #include "fn.h"
 #include "frame.h"
@@ -30,6 +29,7 @@
 #include "integer.h"
 #include "list.h"
 #include "map.h"
+#include "pcomplex.h"
 #include "ptr.h"
 #include "ptr_free.h"
 #include "quote.h"
@@ -140,24 +140,24 @@ void tag_clean (s_tag *tag)
 {
   assert(tag);
   switch (tag->type) {
-  case TAG_ARRAY:       array_clean(&tag->data.array);     break;
-  case TAG_BLOCK:       block_clean(&tag->data.block);     break;
-  case TAG_CALL:        call_clean(&tag->data.call);       break;
-  case TAG_CFN:         cfn_clean(&tag->data.cfn);         break;
-  case TAG_COMPLEX:     complex_delete(tag->data.complex); break;
-  case TAG_FN:          fn_clean(&tag->data.fn);           break;
-  case TAG_INTEGER:     integer_clean(&tag->data.integer); break;
-  case TAG_LIST:        list_delete_all(tag->data.list);   break;
-  case TAG_MAP:         map_clean(&tag->data.map);         break;
-  case TAG_PTR_FREE:    ptr_free_clean(&tag->data.ptr);    break;
-  case TAG_QUOTE:       quote_clean(&tag->data.quote);     break;
-  case TAG_RATIO:       ratio_clean(&tag->data.ratio);     break;
-  case TAG_STR:         str_clean(&tag->data.str);         break;
-  case TAG_STRUCT:      struct_clean(&tag->data.struct_);  break;
+  case TAG_ARRAY:       array_clean(&tag->data.array);      break;
+  case TAG_BLOCK:       block_clean(&tag->data.block);      break;
+  case TAG_CALL:        call_clean(&tag->data.call);        break;
+  case TAG_CFN:         cfn_clean(&tag->data.cfn);          break;
+  case TAG_COMPLEX:     pcomplex_clean(&tag->data.complex); break;
+  case TAG_FN:          fn_clean(&tag->data.fn);            break;
+  case TAG_INTEGER:     integer_clean(&tag->data.integer);  break;
+  case TAG_LIST:        list_delete_all(tag->data.list);    break;
+  case TAG_MAP:         map_clean(&tag->data.map);          break;
+  case TAG_PTR_FREE:    ptr_free_clean(&tag->data.ptr);     break;
+  case TAG_QUOTE:       quote_clean(&tag->data.quote);      break;
+  case TAG_RATIO:       ratio_clean(&tag->data.ratio);      break;
+  case TAG_STR:         str_clean(&tag->data.str);          break;
+  case TAG_STRUCT:      struct_clean(&tag->data.struct_);   break;
   case TAG_STRUCT_TYPE: struct_type_clean(&tag->data.struct_type);
-                                                           break;
-  case TAG_TUPLE:       tuple_clean(&tag->data.tuple);     break;
-  case TAG_UNQUOTE:     unquote_clean(&tag->data.unquote); break;
+                                                            break;
+  case TAG_TUPLE:       tuple_clean(&tag->data.tuple);      break;
+  case TAG_UNQUOTE:     unquote_clean(&tag->data.unquote);  break;
   case TAG_BOOL:
   case TAG_CHARACTER:
   case TAG_F32:
@@ -339,7 +339,8 @@ s_tag * tag_init_copy (s_tag *tag, const s_tag *src)
     cfn_init_copy(&tag->data.cfn, &src->data.cfn);
     break;
   case TAG_COMPLEX:
-    tag->data.complex = complex_new_copy(src->data.complex);
+    pcomplex_init_copy(&tag->data.complex,
+		       (const s_complex * const *) &src->data.complex);
     break;
   case TAG_FN:
     fn_init_copy(&tag->data.fn, &src->data.fn);
@@ -348,7 +349,8 @@ s_tag * tag_init_copy (s_tag *tag, const s_tag *src)
     integer_init_copy(&tag->data.integer, &src->data.integer);
     break;
   case TAG_LIST:
-    list_init_copy(&tag->data.list, (const s_list **) &src->data.list);
+    list_init_copy(&tag->data.list,
+		   (const s_list * const *) &src->data.list);
     break;
   case TAG_MAP:
     map_init_copy(&tag->data.map, &src->data.map);
@@ -700,7 +702,7 @@ bool tag_to_const_pointer (const s_tag *tag, const s_sym *type,
   case TAG_CALL:        *dest = &tag->data.call;        return true;
   case TAG_CFN:         *dest = &tag->data.cfn;         return true;
   case TAG_CHARACTER:   *dest = &tag->data.character;   return true;
-  case TAG_COMPLEX:     *dest = tag->data.complex;      return true;
+  case TAG_COMPLEX:     *dest = &tag->data.complex;     return true;
   case TAG_F32:         *dest = &tag->data.f32;         return true;
   case TAG_F64:         *dest = &tag->data.f64;         return true;
   case TAG_F128:        *dest = &tag->data.f128;        return true;
@@ -791,7 +793,7 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
     goto invalid_cast;
   case TAG_COMPLEX:
     if (type == &g_sym_Complex) {
-      *dest = tag->data.complex;
+      *dest = &tag->data.complex;
       return true;
     }
     goto invalid_cast;
@@ -838,9 +840,10 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
     }
     goto invalid_cast;
   case TAG_RATIO:
-    if (type == sym_1("Ratio") ||
-        type == sym_1("ratio"))
+    if (type == &g_sym_Ratio) {
+      *dest = &tag->data.ratio;
       return true;
+    }
     goto invalid_cast;
   case TAG_SW:
     if (type == &g_sym_Sw) {
@@ -1031,7 +1034,7 @@ bool tag_to_pointer (s_tag *tag, const s_sym *type, void **dest)
   case TAG_CALL:        *dest = &tag->data.call;        return true;
   case TAG_CFN:         *dest = &tag->data.cfn;         return true;
   case TAG_CHARACTER:   *dest = &tag->data.character;   return true;
-  case TAG_COMPLEX:     *dest =  tag->data.complex;     return true;
+  case TAG_COMPLEX:     *dest = &tag->data.complex;     return true;
   case TAG_F32:         *dest = &tag->data.f32;         return true;
   case TAG_F64:         *dest = &tag->data.f64;         return true;
   case TAG_F128:        *dest = &tag->data.f128;        return true;