Commit a059c8f3f4e5e354c15cbd75c632d5d8301b0524

jeremy 2024-11-14T14:53:48

wip fact_with_macro

diff --git a/lib/kc3/0.1/facts.kc3 b/lib/kc3/0.1/facts.kc3
index 838c1b4..2af460d 100644
--- a/lib/kc3/0.1/facts.kc3
+++ b/lib/kc3/0.1/facts.kc3
@@ -45,6 +45,9 @@ defmodule Facts do
   # with(facts, [[?, ?, ?]], fn (fact) {result}) -> result
   def with = cfn Tag "kc3_facts_with" (Facts, List, Fn, Result)
 
+  # with_macro(facts, [[?, ?, ?]], do result end) -> result
+  def with_macro = cfn_macro Tag "kc3_facts_with_macro" (Facts, List, Block, Result)
+
   # with_tags(facts, subject, predicate, object,
   #           fn (fact) {result}) -> result
   def with_tags = cfn Tag "kc3_facts_with_tags" (Facts, Tag, Tag, Tag,
diff --git a/libkc3/env.c b/libkc3/env.c
index ff4ef47..713c0f3 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -2312,6 +2312,41 @@ s_tag * env_facts_with (s_env *env, s_facts *facts, s_list **spec,
   return NULL;
 }
 
+s_tag * env_facts_with_macro (s_env *env, s_facts *facts, s_list **spec,
+                              s_block *block, s_tag *dest)
+{
+  s_facts_with_cursor cursor = {0};
+  const s_fact *fact = NULL;
+  s_tag spec_tag = {0};
+  s_tag tmp = {0};
+  if (! env_eval_list(env, *spec, &spec_tag))
+    return NULL;
+  if (spec_tag.type != TAG_LIST) {
+    err_puts("env_facts_with_macro: spec is not a List");
+    assert(! "env_facts_with_macro: spec is not a List");
+    return NULL;
+  }
+  if (! facts_with_list(facts, &cursor, spec_tag.data.list))
+    return NULL;
+  while (1) {
+    if (! facts_with_cursor_next(&cursor, &fact))
+      goto clean;
+    if (! fact)
+      break;
+    tag_clean(&tmp);
+    if (! env_eval_block(env, block, &tmp)) {
+      goto clean;
+    }
+  }
+  *dest = tmp;
+  return dest;
+ clean:
+  err_puts("env_facts_with: error");
+  assert(! "env_facts_with: error");
+  tag_clean(&tmp);
+  return NULL;
+}
+
 s_tag * env_facts_with_tags (s_env *env, s_facts *facts, s_tag *subject,
                              s_tag *predicate, s_tag *object,
                              s_fn *callback, s_tag *dest)
diff --git a/libkc3/env.h b/libkc3/env.h
index 1373b4b..33d6e51 100644
--- a/libkc3/env.h
+++ b/libkc3/env.h
@@ -78,6 +78,9 @@ s_tag *        env_facts_first_with_tags (s_env *env, s_facts *facts,
 s_tag *        env_facts_with (s_env *env, s_facts *facts,
                                s_list **spec, s_fn *callback,
                                s_tag *dest);
+s_tag *        env_facts_with_macro (s_env *env, s_facts *facts,
+                                     s_list **spec, s_block *block,
+                                     s_tag *dest);
 s_tag *        env_facts_with_tags (s_env *env, s_facts *facts,
                                     s_tag *subject, s_tag *predicate,
                                     s_tag *object, s_fn *callback,
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index c9e96a4..9dad5b2 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -311,6 +311,12 @@ s_tag * kc3_facts_with (s_facts *facts, s_list **spec,
   return env_facts_with(&g_kc3_env, facts, spec, callback, dest);
 }
 
+s_tag * kc3_facts_with_macro (s_facts *facts, s_list **spec,
+                              s_block *block, s_tag *dest)
+{
+  return env_facts_with_macro(&g_kc3_env, facts, spec, block, dest);
+}
+
 s_tag * kc3_facts_with_tags (s_facts *facts, s_tag *subject,
                              s_tag *predicate, s_tag *object,
                              s_fn *callback, s_tag *dest)
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index c3c2972..60647be 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -100,6 +100,8 @@ bool *       kc3_facts_replace_tags (s_facts *facts,
                                      bool *dest);
 s_tag *      kc3_facts_with (s_facts *facts, s_list **spec,
                              s_fn *callback, s_tag *dest);
+s_tag *      kc3_facts_with_macro (s_facts *facts, s_list **spec,
+                             s_block *block, s_tag *dest);
 s_tag *      kc3_facts_with_tags (s_facts *facts, s_tag *subject,
                                   s_tag *predicate, s_tag *object,
                                   s_fn *callback, s_tag *dest);