Commit d4de6a3c9858ccf5f0ddb60d0140a134f2222b7c

Thomas de Grivel 2023-11-24T20:02:33

ic3> Map.map, Map.to_list

diff --git a/.ic3_history b/.ic3_history
new file mode 100644
index 0000000..d5d4136
--- /dev/null
+++ b/.ic3_history
@@ -0,0 +1,31 @@
+%{a: a} = %{a: 1, b: 2, c: 3}
+a
+1 + 10000000000000000000000000000000000
+a = 1 + 10000000000000000000000000000000000
+a / 2
+a << 3
+a << 4
+(U8) { 1, 2, 3, 256, 257, 258 }
+a = (U8) { 1, 2, 3, 256, 257, 258 }
+a[0]
+a[1]
+a[2]
+a[10]
+a[-10]
+a[0]
+Map.map
+Map.map(%{a: 1, b: 2, c: 3}, fn (k, v) { [v | k] })
+Map.map(%{a: 1, b: 2, c: 3}, fn (k, v) { {k, v} })
+to_list = fn (map = %{}) { Map.map(map, fn (k, v) { {k, v} })
+to_list(%{a: 1, b: b})
+to_list = fn (map) { Map.map(map, fn (k, v) { {k, v} })
+to_list(%{a: 1, b: b})
+to_list = fn (map) { Map.map(map, fn (k, v) { {k, v} } }
+to_list = fn (m) { Map.map(m, fn (k, v) { {k, v} } }
+to_list = fn (m) { Map.map(m, fn (k, v) { {k, v} }) }
+to_list = fn (map = %{}) { Map.map(map, fn (k, v) { {k, v} }) }
+to_list(%{a: 1, b: b})
+to_list(%{a: 1, b: 2})
+to_list = fn (map) { Map.map(map, fn (k, v) { {k, v} }) }
+to_list(%{a: 1, b: 2})
+Map.to_list(%{a: 1, b: 2})
diff --git a/libc3/env.c b/libc3/env.c
index d2c73f0..1d21136 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -194,7 +194,8 @@ bool env_eval_call (s_env *env, const s_call *call, s_tag *dest)
   return result;
 }
 
-bool env_eval_call_arguments (s_env *env, s_list *args, s_list **dest)
+bool env_eval_call_arguments (s_env *env, const s_list *args,
+                              s_list **dest)
 {
   s_list **tail;
   s_list *tmp;
@@ -246,62 +247,10 @@ bool env_eval_call_cfn (s_env *env, const s_call *call, s_tag *dest)
 
 bool env_eval_call_fn (s_env *env, const s_call *call, s_tag *dest)
 {
-  s_list *args = NULL;
-  s_list *args_final = NULL;
-  s_frame frame;
-  s_fn *fn;
-  s_fn_clause *clause;
-  s_tag tag;
-  s_list *tmp = NULL;
   assert(env);
   assert(call);
   assert(dest);
-  fn = call->fn;
-  assert(fn);
-  frame_init(&frame, env->frame);
-  env->frame = &frame;
-  clause = fn->clauses;
-  if (call->arguments) {
-    if (fn->macro || fn->special_operator)
-      args_final = call->arguments;
-    else {
-      if (! env_eval_call_arguments(env, call->arguments, &args)) {
-        env->frame = frame_clean(&frame);
-        return false;
-      }
-      args_final = args;
-    }
-    /* FIXME: bindings go through clauses */
-    while (clause && ! env_eval_equal_list(env, clause->pattern,
-                                           args_final, &tmp))
-      clause = clause->next_clause;
-    if (! clause) {
-      err_puts("env_eval_call_fn: no clause matching.\nTried clauses :\n");
-      clause = fn->clauses;
-      while (clause) {
-        err_inspect_fn_pattern(clause->pattern);
-        err_puts("\n");
-        clause = clause->next_clause;
-      }
-      err_puts("\nArguments :\n");
-      err_inspect_fn_pattern(args);
-      err_puts("\n");
-      list_delete_all(args);
-      env->frame = frame_clean(&frame);
-      return false;
-    }
-  }
-  if (! env_eval_progn(env, clause->algo, &tag)) {
-    list_delete_all(args);
-    list_delete_all(tmp);
-    env->frame = frame_clean(&frame);
-    return false;
-  }
-  *dest = tag;
-  list_delete_all(args);
-  list_delete_all(tmp);
-  env->frame = frame_clean(&frame);
-  return true;
+  return env_eval_fn_call(env, call->fn, call->arguments, dest);
 }
 
 bool env_eval_call_resolve (s_env *env, s_call *call)
@@ -557,6 +506,64 @@ bool env_eval_equal_tuple (s_env *env, const s_tuple *a,
   return true;
 }
 
+bool env_eval_fn_call (s_env *env, const s_fn *fn,
+                       const s_list *arguments, s_tag *dest)
+{
+  s_list *args = NULL;
+  const s_list *args_final = NULL;
+  s_fn_clause *clause;
+  s_frame frame;
+  s_tag tag;
+  s_list *tmp = NULL;
+  assert(env);
+  assert(fn);
+  assert(dest);
+  frame_init(&frame, env->frame);
+  env->frame = &frame;
+  clause = fn->clauses;
+  if (arguments) {
+    if (fn->macro || fn->special_operator)
+      args_final = arguments;
+    else {
+      if (! env_eval_call_arguments(env, arguments, &args)) {
+        env->frame = frame_clean(&frame);
+        return false;
+      }
+      args_final = args;
+    }
+    /* FIXME: bindings go through clauses */
+    while (clause && ! env_eval_equal_list(env, clause->pattern,
+                                           args_final, &tmp))
+      clause = clause->next_clause;
+    if (! clause) {
+      err_puts("env_eval_call_fn: no clause matching.\nTried clauses :\n");
+      clause = fn->clauses;
+      while (clause) {
+        err_inspect_fn_pattern(clause->pattern);
+        err_puts("\n");
+        clause = clause->next_clause;
+      }
+      err_puts("\nArguments :\n");
+      err_inspect_fn_pattern(args);
+      err_puts("\n");
+      list_delete_all(args);
+      env->frame = frame_clean(&frame);
+      return false;
+    }
+  }
+  if (! env_eval_progn(env, clause->algo, &tag)) {
+    list_delete_all(args);
+    list_delete_all(tmp);
+    env->frame = frame_clean(&frame);
+    return false;
+  }
+  *dest = tag;
+  list_delete_all(args);
+  list_delete_all(tmp);
+  env->frame = frame_clean(&frame);
+  return true;
+}
+
 bool env_eval_ident (s_env *env, const s_ident *ident, s_tag *dest)
 {
   const s_tag *tag;
diff --git a/libc3/env.h b/libc3/env.h
index ed4e9a5..a924941 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -28,7 +28,7 @@ bool          env_eval_array_tag (s_env *env, const s_array *array,
                                   s_tag *dest);
 bool          env_eval_call (s_env *env, const s_call *call,
                              s_tag *dest);
-bool          env_eval_call_arguments (s_env *env, s_list *args,
+bool          env_eval_call_arguments (s_env *env, const s_list *args,
                                        s_list **dest);
 bool          env_eval_call_cfn (s_env *env, const s_call *call,
                                  s_tag *dest);
@@ -42,6 +42,8 @@ bool          env_eval_equal_tag (s_env *env, const s_tag *a,
 bool          env_eval_equal_tuple (s_env *env, const s_tuple *a,
                                     const s_tuple *b, s_tuple *dest);
 bool          env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest);
+bool          env_eval_fn_call (s_env *env, const s_fn *fn,
+                                const s_list *arguments, s_tag *dest);
 bool          env_eval_ident (s_env *env, const s_ident *ident,
                               s_tag *dest);
 bool          env_eval_list (s_env *env, const s_list *list,
diff --git a/libc3/eval.c b/libc3/eval.c
index bf1b616..8903491 100644
--- a/libc3/eval.c
+++ b/libc3/eval.c
@@ -19,3 +19,8 @@ bool eval_tag (const s_tag *tag, s_tag *dest)
 {
   return env_eval_tag(&g_c3_env, tag, dest);
 }
+
+bool eval_fn_call (const s_fn *fn, const s_list *args, s_tag *dest)
+{
+  return env_eval_fn_call(&g_c3_env, fn, args, dest);
+}
diff --git a/libc3/eval.h b/libc3/eval.h
index 5029d11..0831648 100644
--- a/libc3/eval.h
+++ b/libc3/eval.h
@@ -19,6 +19,8 @@ bool eval_call_function (const s_call *call,
                          s_tag *dest);
 bool eval_call_macro (const s_call *call, s_tag *dest);
 bool eval_fn (const s_fn *fn, s_tag *dest);
+bool eval_fn_call (const s_fn *fn, const s_list *arguments,
+                   s_tag *dest);
 bool eval_ident (const s_ident *ident, s_tag *dest);
 bool eval_progn (const s_list *program, s_tag *dest);
 bool eval_tag (const s_tag *tag, s_tag *dest);
diff --git a/libc3/map.c b/libc3/map.c
index b28f7e8..7b9e384 100644
--- a/libc3/map.c
+++ b/libc3/map.c
@@ -17,6 +17,7 @@
 #include "buf.h"
 #include "buf_parse.h"
 #include "compare.h"
+#include "eval.h"
 #include "list.h"
 #include "map.h"
 #include "tag.h"
@@ -147,15 +148,30 @@ s_map * map_init_from_lists (s_map *map, const s_list *keys,
 
 s_list ** map_map (const s_map *map, const s_fn *fn, s_list **result)
 {
+  s_list *args;
+  uw i = 0;
+  s_list **t;
+  s_list *tmp;
   assert(map);
   assert(fn);
   assert(result);
-  (void) map;
-  (void) fn;
-  (void) result;
-  assert(! "not implemented");
-  errx(1, "not implemented");
-  return NULL;
+  t = &tmp;
+  *t = NULL;
+  while (i < map->count) {
+    args = list_new(map->keys + i,
+                    list_new(map->values + i, NULL));
+    *t = list_new(NULL, NULL);
+    if (! eval_fn_call(fn, args, &(*t)->tag)) {
+      list_delete_all(args);
+      list_delete_all(tmp);
+      return NULL;
+    }
+    t = &(*t)->next.data.list;
+    list_delete_all(args);
+    i++;
+  }
+  *result = tmp;
+  return result;
 }
 
 s_map * map_new (uw count)
diff --git a/libc3/sym.c b/libc3/sym.c
index 0b56acd..eca3f16 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -166,9 +166,6 @@ ffi_type * sym_to_ffi_type (const s_sym *sym, ffi_type *result_type)
   if (sym == sym_1("Integer") ||
       sym == sym_1("integer"))
     return &ffi_type_pointer;
-  if (sym == sym_1("List") ||
-      sym == sym_1("list"))
-    return &ffi_type_pointer;
   if (sym == sym_1("S8") ||
       sym == sym_1("s8"))
     return &ffi_type_sint8;
@@ -206,6 +203,18 @@ ffi_type * sym_to_ffi_type (const s_sym *sym, ffi_type *result_type)
   if (sym == sym_1("Uw") ||
       sym == sym_1("uw"))
     return &ffi_type_ulong;
+  if (sym == sym_1("Bool") ||
+      sym == sym_1("bool"))
+    return &ffi_type_uchar;
+  if (sym == sym_1("Fn") ||
+      sym == sym_1("fn"))
+    return &ffi_type_pointer;
+  if (sym == sym_1("List") ||
+      sym == sym_1("list"))
+    return &ffi_type_pointer;
+  if (sym == sym_1("Map") ||
+      sym == sym_1("map"))
+    return &ffi_type_pointer;
   if (sym == sym_1("Void") ||
       sym == sym_1("void"))
     return &ffi_type_void;
diff --git a/linenoise b/linenoise
index 86275b5..a7327ba 160000
--- a/linenoise
+++ b/linenoise
@@ -1 +1 @@
-Subproject commit 86275b5b1a58814bc7182b73e3435c6644c0a946
+Subproject commit a7327ba54af89b97ce7e5585b3bdbe39a31bbc48