Commit 1eec90f49150fa2db687ff010a55eaead85669b5

Thomas de Grivel 2024-11-21T22:26:39

list_access and list_at (my_list[3] => # third element)

diff --git a/.ikc3_history b/.ikc3_history
index ae9be53..4413ac4 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,34 +1,3 @@
-puts(inspect(%{a: 1, b: 2}))
-puts(inspect(quote if true do 1 else %{a: 1, b: 2} end))
-puts(quote if true do 1 else %{a: 1, b: 2} end)
-quote 1 + 1
-type(quote 1 + 1)
-type(quote plop(1 + 1))
-type(quote quote plop(1 + 1))
-def eval = macro (args) { args }
-eval(quote 1 + 1)
-eval(1 + 1)
-def eval = macro (args) { unquote(args) }
-eval(1 + 1)
-def eval = macro (args) { args }
-eval(1 + 1)
-eval(quote 1 + 1)
-a = %KC3.Operator{sym: :****, symbol_value: fn (a, b) { (a + b) * 4 }}
-def op_muul = %KC3.Operator{sym: :****, symbol_value: fn (a, b) { (a + b) * 4 }}
-3 **** 4
-3 //// 4
-def op_muul = %KC3.Operator{sym: :////, symbol_value: fn (a, b) { (a - b) * 4 }}
-3 //// 4
-{a, b, c} = {1, 2, 3}
-%{a: a, b: b, c: c} = %{a: 1, b: 2, c: 3}
-a
-b
-c
-Compare.str_case_insensitive("Range", "range")
-!Compare.str_case_insensitive("Range", "range")
-! Compare.str_case_insensitive("Range", "range")
-! 0
-quit
 q
 exit
 exit(Ã)
@@ -97,3 +66,34 @@ type(123456789012345678901234/2)
 123456789012345678901234/2 * 0.1
 (123456789012345678901234/2) * 0.1
 (F128) 123456789012345678901234/2 * 0.1
+List.to_array
+0 - 2
+Tuple[]
+type(Tuple[])
+type((Tuple[]) {{1, 2, 3}})
+type((Tuple[]) {1, 2, 3})
+[1][0]
+([1])[0]
+access([1, 2, 3], 2)
+access([1, 2, 3], [2])
+access([1, 2, 3], [0])
+access([1, 2, 3], [1])
+access([1, 2, 3], [2])
+access([1, 2, 3], [3])
+a = [1, 2, 3]
+a[0]
+a[1]
+a[2]
+a[3]
+points = [{(F128) 0, (F128) 1}, {(F128) 0.5, (F128) 0.6}]
+points[0]
+points[1]
+points[2]
+points[3]
+points
+points = [{(F128) 0, (F128) 1}, {(F128) 0.5, (F128) 0.6}]
+points
+points[3]
+points[0]
+points[1]
+points[2]
diff --git a/lib/kc3/0.1/list.kc3 b/lib/kc3/0.1/list.kc3
index 3060f05..76850a5 100644
--- a/lib/kc3/0.1/list.kc3
+++ b/lib/kc3/0.1/list.kc3
@@ -46,6 +46,8 @@ defmodule List do
 
   def sort_by = cfn List "list_sort_by" (List, Callable, Result)
 
+  def to_array = cfn Array "kc3_list_to_array" (List, Sym, Result)
+
   def unique = cfn List "list_unique" (List, Result)
 
 end
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index f27f086..2145d7f 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -73,10 +73,11 @@ s_tag * kc3_access (s_tag *tag, s_list **key,
   case TAG_LIST:
     if (list_is_alist(tag->data.list)) {
       if (! alist_access(tag->data.list, *key, dest))
-        return tag_init_void(dest);
+        return list_access(tag->data.list, *key, dest);
       return dest;
     }
-    break;
+    else
+      return list_access(tag->data.list, *key, dest);
   case TAG_MAP:
     return map_access(&tag->data.map, *key, dest);
   case TAG_STRUCT:
@@ -428,6 +429,13 @@ void kc3_license (void)
   buf_flush(&g_kc3_env.out);
 }
 
+s_array * kc3_list_to_array (s_list **list,
+                             const s_sym * const *array_type,
+                             s_array *dest)
+{
+  return list_to_array(*list, *array_type, dest);
+}
+
 bool kc3_load (const s_str *path)
 {
   return env_load(&g_kc3_env, path);
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index dd5cfe8..d7d3b68 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -109,6 +109,9 @@ s_tag *      kc3_facts_with_tags (s_facts *facts, s_tag *subject,
 s_tag *      kc3_identity (s_tag *tag, s_tag *dest);
 s_tag *      kc3_integer_reduce (s_tag *tag, s_tag *dest);
 s_tag *      kc3_let (s_tag *vars, s_tag *tag, s_tag *dest);
+s_array *    kc3_list_to_array (s_list **list,
+                                const s_sym * const *array_type,
+                                s_array *dest);
 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,
diff --git a/libkc3/list.c b/libkc3/list.c
index 3b16305..9abdd02 100644
--- a/libkc3/list.c
+++ b/libkc3/list.c
@@ -21,10 +21,59 @@
 #include "compare.h"
 #include "data.h"
 #include "eval.h"
+#include "kc3_main.h"
 #include "list.h"
 #include "sym.h"
 #include "tag.h"
 #include "tuple.h"
+#include "uw.h"
+
+s_tag * list_access (s_list *list, s_list *key, s_tag *dest)
+{
+  s_tag  *key_first;
+  s_list *key_next;
+  s_tag *r;
+  const s_sym *sym_Uw = &g_sym_Uw;
+  s_tag tag;
+  uw i;
+  assert(list);
+  assert(key);
+  assert(dest);
+  key_first = &key->tag;
+  if (! uw_init_cast(&i, &sym_Uw, key_first)) {
+    err_puts("list_access: invalid key");
+    assert(! "list_access: invalid key");
+    return NULL;
+  }
+  key_next = list_next(key);
+  if (! key_next)
+    return list_at(list, i, dest);
+  if (! list_at(list, i, &tag))
+    return NULL;
+  r = kc3_access(&tag, &key_next, dest);
+  tag_clean(&tag);
+  return r;
+}
+
+s_tag * list_at (s_list *list, uw position, s_tag *dest)
+{
+  s_list *l;
+  uw p;
+  assert(list);
+  assert(dest);
+  l = list;
+  p = position;
+  while (p) {
+    p--;
+    l = list_next(l);
+    if (! l) {
+      err_puts("list_at: position exceeds list length");
+      assert(! "list_at: position exceeds list length");
+      return NULL;
+    }
+  }
+  return tag_init_copy(dest, &l->tag);
+}
 
 void list_clean (s_list *list)
 {
diff --git a/libkc3/list.h b/libkc3/list.h
index 0f81a5a..7ad57f0 100644
--- a/libkc3/list.h
+++ b/libkc3/list.h
@@ -49,6 +49,8 @@ s_list * list_new_str_1 (char *free, const char *p, s_list *next);
 s_list * list_new_tag_copy (s_tag *tag, s_list *next);
 
 /* Observers */
+s_tag *   list_at (s_list *list, uw position, s_tag *dest);
+s_tag *   list_access (s_list *list, s_list *key, s_tag *dest);
 s_list ** list_cast (const s_tag *tag, s_list **list);
 bool *    list_has (const s_list * const *list, const s_tag *tag,
                     bool *dest);