Commit 40acb9cded2f7f546779358349455a1c24b8b3cc

Thomas de Grivel 2025-01-06T18:13:38

wip smtp

diff --git a/lib/kc3/0.1/smtp.kc3 b/lib/kc3/0.1/smtp.kc3
index 75e975c..713ed32 100644
--- a/lib/kc3/0.1/smtp.kc3
+++ b/lib/kc3/0.1/smtp.kc3
@@ -2,8 +2,14 @@ defmodule SMTP do
 
   dlopen(__DIR__ + "smtp.so")
 
+  # address_add(smtp, address_type, address, name)
+  def address_add = cfn Bool "kc3_smtp_address_add" (Ptr, Sym, Str, Str)
+
   def close = cfn Bool "kc3_smtp_close" (Ptr)
 
+  # header_add(smtp, header_name, value)
+  def header_add = cfn Bool "kc3_smtp_header_add" (Ptr, Str, Str)
+
   # open(server, port, security, flags, cafile, dest)
   def open = cfn Ptr "kc3_smtp_open" (Str, Str, Sym, Sym, Str, Result)
 
diff --git a/libkc3/env.c b/libkc3/env.c
index d5ae54e..0b2935d 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -82,31 +82,33 @@ static s_env * env_init_args (s_env *env, int *argc, char ***argv);
 static s_env * env_init_globals (s_env *env);
 static s_env * env_init_toplevel (s_env *env);
 
-bool * env_and (s_env *env, s_tag *a, s_tag *b, bool *dest)
+s_tag * env_and (s_env *env, s_tag *a, s_tag *b, s_tag *dest)
 {
   s_tag eval;
-  bool tmp;
-  const s_sym *type;
+  bool p;
+  s_tag tmp;
+  const s_sym *sym_Bool = &g_sym_Bool;
   assert(env);
   assert(a);
   assert(b);
   assert(dest);
-  type = &g_sym_Bool;
   if (! env_eval_tag(env, a, &eval))
     return NULL;
-  if (! bool_init_cast(&tmp, &type, &eval)) {
+  if (! bool_init_cast(&p, &type, &eval)) {
     tag_clean(&eval);
     return NULL;
   }
   tag_clean(&eval);
-  if (tmp) {
+  tag_init_bool(&tmp, false);
+  if (p) {
     if (! env_eval_tag(env, b, &eval))
       return NULL;
-    if (! bool_init_cast(&tmp, &type, &eval)) {
+    if (! bool_init_cast(&p, &type, &eval)) {
       tag_clean(&eval);
       return NULL;
     }
-    tag_clean(&eval);
+    if (p)
+      tmp = eval;
   }
   *dest = tmp;
   return dest;
diff --git a/libkc3/env.h b/libkc3/env.h
index d69807e..97ec659 100644
--- a/libkc3/env.h
+++ b/libkc3/env.h
@@ -49,8 +49,7 @@ bool            env_sym_search_modules (s_env *env,
                                         const s_sym **dest);
 
 /* Operators. */
-bool *         env_and (s_env *env, s_tag *a, s_tag *b,
-                        bool *dest);
+s_tag *        env_and (s_env *env, s_tag *a, s_tag *b, s_tag *dest);
 bool           env_def (s_env *env, const s_ident *ident, s_tag *value);
 const s_sym *  env_def_clean (s_env *env, const s_sym *module,
                               const s_tag *tag_clean);
@@ -131,8 +130,7 @@ s_ident *      env_operator_resolve (s_env *env, const s_ident *op,
                                      u8 arity, s_ident *dest);
 const s_sym ** env_operator_symbol (s_env *env, const s_ident *op,
                                     const s_sym **dest);
-bool *         env_or (s_env *env, s_tag *a, s_tag *b,
-                       bool *dest);
+s_tag *        env_or (s_env *env, s_tag *a, s_tag *b, s_tag *dest);
 u8             env_special_operator_arity (s_env *env,
                                            const s_ident *ident);
 bool *         env_struct_type_exists (s_env *env, const s_sym *module,
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index 1648076..698343a 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -123,7 +123,7 @@ s_tag * kc3_access (s_tag *tag, s_list **key,
   return NULL;
 }
 
-bool * kc3_and (s_tag *a, s_tag *b, bool *dest)
+s_tag * kc3_and (s_tag *a, s_tag *b, s_tag *dest)
 {
   return env_and(g_kc3_env, a, b, dest);
 }
@@ -638,7 +638,7 @@ s_tag * kc3_operator_find_by_sym (const s_sym * const *sym, s_tag *dest)
   return env_operator_find_by_sym(g_kc3_env, *sym, dest);
 }
 
-bool * kc3_or (s_tag *a, s_tag *b, bool *dest)
+s_tag * kc3_or (s_tag *a, s_tag *b, s_tag *dest)
 {
   return env_or(g_kc3_env, a, b, dest);
 }
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index 06a6d09..65ccc3a 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -58,7 +58,7 @@ s_str *        kc3_str (const s_tag *tag, s_str *dest);
 /* Operators. */
 s_tag *      kc3_access (s_tag *tag, s_list **addr,
                          s_tag *dest);
-bool *       kc3_and (s_tag *a, s_tag *b, bool *dest);
+s_tag *      kc3_and (s_tag *a, s_tag *b, s_tag *dest);
 s_tag *      kc3_buf_parse_tag (s_buf *buf, s_tag *dest);
 s_tag *      kc3_def (const s_call *call, s_tag *dest);
 s_tag *      kc3_defmodule (const s_sym **name, const s_block *block,
@@ -119,7 +119,7 @@ bool         kc3_load (const s_str *path);
 bool         kc3_maybe_reload (const s_str *path);
 s_tag *      kc3_operator_find_by_sym (const s_sym * const *sym,
                                        s_tag *dest);
-bool *       kc3_or (s_tag *a, s_tag *b, bool *dest);
+s_tag *      kc3_or (s_tag *a, s_tag *b, s_tag *dest);
 s_tag *      kc3_parse_tag (s_tag *tag, const s_str *src);
 bool         kc3_require (const s_sym * const *module);
 s_str *      kc3_strerror (sw err_no, s_str *dest);
diff --git a/libkc3/tag.c b/libkc3/tag.c
index fc79f1b..3ef7f09 100644
--- a/libkc3/tag.c
+++ b/libkc3/tag.c
@@ -60,15 +60,32 @@ s_tag * tag_1 (s_tag *tag, const char *p)
   return tag_init_1(tag, p);
 }
 
-bool * tag_and (s_tag *a, s_tag *b, bool *dest)
+s_tag * tag_and (s_tag *a, s_tag *b, s_tag *dest)
 {
-  s_tag f;
+  bool p;
+  const s_sym *sym_Bool = &g_sym_Bool;
   assert(a);
   assert(b);
   assert(dest);
-  tag_init_bool(&f, false);
-  *dest = compare_tag(a, &f) != 0 && compare_tag(b, &f) != 0 ? 1 : 0;
-  return dest;
+  if (! bool_init_cast(&p, &sym_Bool, a)) {
+    err_write_1("tag_and: cannot cast to Bool: ");
+    err_inspect_tag(a);
+    err_write_1("\n");
+    assert(! "tag_and: cannot cast to Bool");
+    return NULL;
+  }
+  if (! p)
+    return tag_init_bool(dest, false);
+  if (! bool_init_cast(&p, &sym_Bool, b)) {
+    err_write_1("tag_and: cannot cast to Bool: ");
+    err_inspect_tag(b);
+    err_write_1("\n");
+    assert(! "tag_and: cannot cast to Bool");
+    return NULL;
+  }
+  if (! p)
+    return tag_init_bool(dest, false);
+  return tag_init_copy(dest, b);
 }
 
 s8 tag_arity (const s_tag *tag)
@@ -1094,16 +1111,32 @@ bool * tag_not_eq (s_tag *a, s_tag *b, bool *dest)
   return dest;
 }
 
-bool * tag_or (s_tag *a, s_tag *b, bool *dest)
+s_tag * tag_or (s_tag *a, s_tag *b, s_tag *dest)
 {
-  s_tag f;
+  bool p;
+  const s_sym *sym_Bool = &g_sym_Bool;
   assert(a);
   assert(b);
   assert(dest);
-  tag_init_bool(&f, false);
-  *dest = compare_tag(a, &f) != 0 ||
-          compare_tag(b, &f) != 0 ? 1 : 0;
-  return dest;
+  if (! bool_init_cast(&p, &sym_Bool, a)) {
+    err_write_1("tag_or: cannot cast to Bool: ");
+    err_inspect_tag(a);
+    err_write_1("\n");
+    assert(! "tag_or: cannot cast to Bool");
+    return NULL;
+  }
+  if (p)
+    return tag_init_copy(dest, a);
+  if (! bool_init_cast(&p, &sym_Bool, b)) {
+    err_write_1("tag_or: cannot cast to Bool: ");
+    err_inspect_tag(b);
+    err_write_1("\n");
+    assert(! "tag_or: cannot cast to Bool");
+    return NULL;
+  }
+  if (p)
+    return tag_init_copy(dest, b);
+  return tag_init_bool(dest, false);
 }
 
 s_tag * tag_paren (s_tag *tag, s_tag *dest)
diff --git a/libkc3/tag.h b/libkc3/tag.h
index dc4c3bc..96363c0 100644
--- a/libkc3/tag.h
+++ b/libkc3/tag.h
@@ -81,7 +81,7 @@ bool    tag_to_pointer (s_tag *tag, const s_sym *type, void **dest);
 
 /* KC3 operators. */
 s_tag * tag_add (s_tag *a, s_tag *b, s_tag *dest);
-bool *  tag_and (s_tag *a, s_tag *b, bool *dest);
+s_tag * tag_and (s_tag *a, s_tag *b, s_tag *dest);
 s_tag * tag_assign (s_tag *tag, s_tag *value, s_tag *dest);
 s_tag * tag_band (s_tag *a, s_tag *b, s_tag *dest);
 s_tag * tag_bnot (s_tag *tag, s_tag *dest);
@@ -102,7 +102,7 @@ s_tag * tag_mul (s_tag *a, s_tag *b, s_tag *dest);
 s_tag * tag_neg (s_tag *tag, s_tag *dest);
 bool *  tag_not (s_tag *tag, bool *dest);
 bool *  tag_not_eq (s_tag *a, s_tag *b, bool *dest);
-bool *  tag_or (s_tag *a, s_tag *b, bool *dest);
+s_tag * tag_or (s_tag *a, s_tag *b, s_tag *dest);
 s_tag * tag_paren (s_tag *tag, s_tag *dest);
 s_tag * tag_shift_left (s_tag *a, s_tag *b, s_tag *dest);
 s_tag * tag_shift_right (s_tag *a, s_tag *b, s_tag *dest);