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