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