Commit 505fbb73914de4ccd942d09f98d11e3ebde99505

Thomas de Grivel 2023-09-03T21:52:55

eval is evil

diff --git a/README.md b/README.md
index c944001..e0c41ad 100644
--- a/README.md
+++ b/README.md
@@ -108,13 +108,13 @@ Script interpreter.
      - floating point numbers
    - variables
       - DONE = equal
-      - funcall
+      - DONE funcall
    - DONE boolean operators
    - DONE comparison operators
    - arrays
      - DONE parse
      - DONE inspect
-     - [][][] data
+     - DONE [][][] data
    - lists
    - defmodule
    - structs
@@ -135,9 +135,6 @@ Script interpreter.
    - buf_sha256
    - buf_popen
    - tests
-     - sizeof(sw) == sizeof(void *)
-     - `(-S8_MIN - S8_MAX) == 1`
-     - `UW_MAX == ((1 << 8 * sizeof(uw)) - 1)`
      - DONE group tests by test case
    - DONE ci
    - DONE c function call
diff --git a/lib/c3/0.1/list.facts b/lib/c3/0.1/list.facts
index dd5d118..1279c47 100644
--- a/lib/c3/0.1/list.facts
+++ b/lib/c3/0.1/list.facts
@@ -5,10 +5,10 @@ add {List, :name, "List"}
 add {List, :path, "list.facts"}
 add {List, :symbol, List.map}
 add {List.map, :fn, fn {
-  (_, ()) {
+  ((), _) {
     ()
   }
-  (f, (a | b)) {
-    (f(a) | List.map(b))
+  ((a | b), f) {
+    (f(a) | List.map(b, f))
   }
 }}
diff --git a/libc3/env.c b/libc3/env.c
index 02e2a54..8f5d84d 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -71,6 +71,17 @@ void env_error_tag (s_env *env, const s_tag *tag)
   }
 }
 
+bool env_eval_array (s_env *env, const s_array *array, s_tag *dest)
+{
+  assert(env);
+  assert(array);
+  assert(dest);
+  (void) env;
+  dest->type = TAG_ARRAY;
+  array_copy(array, &dest->data.array);
+  return true;
+}
+
 bool env_eval_call (s_env *env, const s_call *call, s_tag *dest)
 {
   s_call c;
@@ -179,6 +190,7 @@ bool env_eval_call_fn (s_env *env, const s_call *call, s_tag *dest)
       clause = fn->clauses;
       while (clause) {
         err_inspect_fn_pattern(clause->pattern);
+        err_puts("\n");
         clause = clause->next_clause;
       }
       err_puts("\nArguments :\n");
@@ -316,6 +328,7 @@ bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
   switch (a->type) {
   case TAG_F32:
   case TAG_F64:
+  case TAG_INTEGER:
   case TAG_S8:
   case TAG_S16:
   case TAG_S32:
@@ -329,6 +342,7 @@ bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
     switch (b->type) {
     case TAG_F32:
     case TAG_F64:
+    case TAG_INTEGER:
     case TAG_S8:
     case TAG_S16:
     case TAG_S32:
@@ -340,7 +354,7 @@ bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
     case TAG_U64:
     case TAG_UW:
       if (compare_tag(a, b)) {
-        warnx("env_eval_compare_tag: value mismatch");
+        warnx("env_eval_equal_tag: numeric value mismatch");
         return false;
       }
       tag_copy(a, dest);
@@ -437,6 +451,29 @@ bool env_eval_ident (s_env *env, const s_ident *ident, s_tag *dest)
   return true;
 }
 
+bool env_eval_list (s_env *env, const s_list *list, s_tag *dest)
+{
+  s_list *next;
+  s_list *tmp = NULL;
+  s_list **tail = &tmp;
+  assert(env);
+  assert(dest);
+  while (list) {
+    *tail = list_new(NULL, NULL);
+    if (! env_eval_tag(env, &list->tag, &(*tail)->tag))
+      return false;
+    next = list_next(list);
+    if (! next)
+      if (! env_eval_tag(env, &list->next, &(*tail)->next))
+        return false;
+    tail = &(*tail)->next.data.list;
+    list = next;
+  }
+  dest->type = TAG_LIST;
+  dest->data.list = tmp;
+  return true;
+}
+
 bool env_eval_progn (s_env *env, const s_list *program, s_tag *dest)
 {
   const s_list *next;
@@ -473,13 +510,18 @@ bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
   case TAG_VOID:
     tag_init_void(dest);
     return true;
+  case TAG_ARRAY:
+    return env_eval_array(env, &tag->data.array, dest);
   case TAG_CALL:
     return env_eval_call(env, &tag->data.call, dest);
   case TAG_IDENT:
     return env_eval_ident(env, &tag->data.ident, dest);
+  case TAG_LIST:
+    return env_eval_list(env, tag->data.list, dest);
   case TAG_QUOTE:
     return env_eval_quote(env, &tag->data.quote, dest);
-  case TAG_ARRAY:
+  case TAG_TUPLE:
+    return env_eval_tuple(env, &tag->data.tuple, dest);
   case TAG_BOOL:
   case TAG_CFN:
   case TAG_CHARACTER:
@@ -487,7 +529,6 @@ bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
   case TAG_F64:
   case TAG_FN:
   case TAG_INTEGER:
-  case TAG_LIST:
   case TAG_PTAG:
   case TAG_S8:
   case TAG_S16:
@@ -496,7 +537,6 @@ bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
   case TAG_SW:
   case TAG_STR:
   case TAG_SYM:
-  case TAG_TUPLE:
   case TAG_U8:
   case TAG_U16:
   case TAG_U32:
@@ -511,6 +551,24 @@ bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
   return false;
 }
 
+bool env_eval_tuple (s_env *env, const s_tuple *tuple, s_tag *dest)
+{
+  uw i = 0;
+  s_tuple tmp;
+  assert(env);
+  assert(tuple);
+  assert(dest);
+  tuple_init(&tmp, tuple->count);
+  while (i < tuple->count) {
+    if (! env_eval_tag(env, &tuple->tag[i], &tmp.tag[i]))
+      return false;
+    i++;
+  }
+  dest->type = TAG_TUPLE;
+  dest->data.tuple = tmp;
+  return true;
+}
+
 s_env * env_init (s_env *env)
 {
   assert(env);
diff --git a/libc3/env.h b/libc3/env.h
index 4e9ab73..bf8ad2d 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -22,6 +22,8 @@ void    env_clean (s_env *env);
 s_env * env_init (s_env *env);
 
 /* Modifiers. */
+bool       env_eval_array(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,
@@ -40,11 +42,15 @@ bool       env_eval_equal_tuple (s_env *env, const s_tuple *a,
 bool       env_eval_fn (s_env *env, const s_fn *fn, 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,
+                          s_tag *dest);
 bool       env_eval_progn (s_env *env, const s_list *program,
                            s_tag *dest);
-bool       env_eval_quote(s_env *env, const s_quote *quote,
-                          s_tag *dest);
+bool       env_eval_quote (s_env *env, const s_quote *quote,
+                           s_tag *dest);
 bool       env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest);
+bool       env_eval_tuple (s_env *env, const s_tuple *tuple,
+                           s_tag *dest);
 bool       env_module_load (s_env *env, const s_sym *name,
                             s_facts *facts);
 bool       env_operator_is_binary (s_env *env, const s_ident *op);
diff --git a/test/ic3/list.in b/test/ic3/list.in
index 9ffd0cc..d26447d 100644
--- a/test/ic3/list.in
+++ b/test/ic3/list.in
@@ -12,31 +12,33 @@
 (() | ((), (), () | ()))
 (((), ()) | ((), ()))
 ((() | ()) | (() | ()))
-(a | ())
-(a, b)
-(a, b, c)
-(a | b)
-(a, b | c)
-(a, b, c, d)
-(a, b, c | d)
+(:a | ())
+(:a, :b)
+(:a, :b, :c)
+(:a | :b)
+(:a, :b | :c)
+(:a, :b, :c, :d)
+(:a, :b, :c | :d)
 
 # comment 0
 # comment 0b
 ( # comment 1
   # comment 1b
-  a # comment 2
-    # comment 2b
-  , # comment 3
-    # comment 3b
-  b ## comment 4
-    ## comment 4b
-  , ## comment 5
-    ## comment 5b
-  c ## comment 6
-    ## comment 6b
-  | ## comment 7
-    ## comment 7b
-  d ## comment 8
-    ## comment 8b
-  ) ## comment 9
-    ## comment 9b
+  :a # comment 2
+     # comment 2b
+  ,  # comment 3
+     # comment 3b
+  :b ## comment 4
+     ## comment 4b
+  ,  ## comment 5
+     ## comment 5b
+  :c ## comment 6
+     ## comment 6b
+  |  ## comment 7
+     ## comment 7b
+  :d ## comment 8
+     ## comment 8b
+  )  ## comment 9
+     ## comment 9b
+
+List.map((1, 2, 3, 4), fn (x) { x * 2 })
diff --git a/test/ic3/list.out.expected b/test/ic3/list.out.expected
index 91ffee3..07eec58 100644
--- a/test/ic3/list.out.expected
+++ b/test/ic3/list.out.expected
@@ -12,11 +12,11 @@
 ((), (), (), ())
 (((), ()), (), ())
 ((() | ()), ())
-(a | ())
-(a, b)
-(a, b, c)
-(a | b)
-(a, b | c)
-(a, b, c, d)
-(a, b, c | d)
-(a, b, c | d)
+(:a | ())
+(:a, :b)
+(:a, :b, :c)
+(:a | :b)
+(:a, :b | :c)
+(:a, :b, :c, :d)
+(:a, :b, :c | :d)
+(:a, :b, :c | :d)
diff --git a/test/ic3/tuple.in b/test/ic3/tuple.in
index c9bdfbe..116dce1 100644
--- a/test/ic3/tuple.in
+++ b/test/ic3/tuple.in
@@ -35,9 +35,9 @@
 
 # comment 10
 { # comment 11
-  a # comment 12
+  :a # comment 12
   , # comment 13
-  b ## comment 14
+  :b ## comment 14
   , ## comment 15
-  c ## comment 16
+  :c ## comment 16
   } ## comment 17
diff --git a/test/ic3/tuple.out.expected b/test/ic3/tuple.out.expected
index f3b386b..b8de9cc 100644
--- a/test/ic3/tuple.out.expected
+++ b/test/ic3/tuple.out.expected
@@ -16,4 +16,4 @@
 {{:a, :b}, {:c, :d}, {:e, :f}, {:g, :h}}
 {{:a, :b}, {:c, :d}, {:e, :f}, {:g, :h}, {:i, :j}}
 {:a, :b, :c}
-{a, b, c}
+{:a, :b, :c}