Commit 188f80398a439cc7e7ce0119e356f7e135ffd9cf

Thomas de Grivel 2024-04-10T17:39:49

def x = %C3.Operator{}

diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index 74dd4c6..31bdbea 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -1,5 +1,3 @@
-def fib = fn (x) { if x < 0 then 0 else fib(x - 2) + fib(x - 1) end }
-def fib = fn { (0) { 1 } (1) { 1 } (x) { if x < 0 then 0 else fib(x - 2) + fib(x - 1) end }}
 do end
 end
 do end
@@ -97,3 +95,5 @@ List.last([1, 2, 3, 4])
 (Tag) ?
 (U8) ?
 type((U8) ?)
+def operator_muul = %C3.Operator{sym: :****, symbol_value: cfn Tag "tag_mul" (Tag, Tag, Result), operator_precedence: 11, operator_associativity: :left}
+2 **** 4
diff --git a/libc3/data.c b/libc3/data.c
index 34c6d71..c49aff5 100644
--- a/libc3/data.c
+++ b/libc3/data.c
@@ -524,6 +524,8 @@ void * data_init_cast (void *data, const s_sym *type, const s_tag *tag)
     return sw_init_cast(data, type, tag);
   if (type == &g_sym_Sym)
     return sym_init_cast(data, type, tag);
+  if (type == &g_sym_Tag)
+    return tag_init_copy(data, tag);
   if (type == &g_sym_Tuple)
     return tuple_init_cast(data, type, tag);
   if (type == &g_sym_U8)
diff --git a/libc3/env.c b/libc3/env.c
index b3d48ed..3d87197 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -1279,8 +1279,11 @@ bool env_eval_struct (s_env *env, const s_struct *s, s_tag *dest)
     return false;
   i = 0;
   while (i < t->type->map.count) {
-    if (! tag_type(t->type->map.value + i, &type))
-      goto ko;
+    if (t->type->map.value[i].type == TAG_VAR)
+      type = t->type->map.value[i].data.var.type;
+    else
+      if (! tag_type(t->type->map.value + i, &type))
+        goto ko;
     if (s->tag) {
       if (! env_eval_tag(env, s->tag + i, &tag))
         goto ko;
diff --git a/libc3/sym.c b/libc3/sym.c
index f1cf9c8..5b42938 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -1072,6 +1072,10 @@ bool sym_type_size (const s_sym *type, uw *dest)
     *dest = sizeof(s_sym *);
     return true;
   }
+  if (type == &g_sym_Tag) {
+    *dest = sizeof(s_tag);
+    return true;
+  }
   if (type == &g_sym_Tuple) {
     *dest = sizeof(s_tuple);
     return true;
diff --git a/libc3/tag.c b/libc3/tag.c
index 65a1f94..40f16af 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -686,8 +686,12 @@ uw * tag_size (const s_tag *tag, uw *dest)
   const s_sym *type;
   uw tmp = 0;
   assert(tag);
-  if (! tag_type(tag, &type) ||
-      ! sym_type_size(type, &tmp))
+  if (tag->type == TAG_VAR) {
+    if (! sym_type_size(tag->data.var.type, &tmp))
+      return NULL;
+  }
+  else if (! tag_type(tag, &type) ||
+           ! sym_type_size(type, &tmp))
     return NULL;
   *dest = tmp;
   return dest;
diff --git a/libc3/var.c b/libc3/var.c
index 0bf28b0..e294fa0 100644
--- a/libc3/var.c
+++ b/libc3/var.c
@@ -21,16 +21,12 @@ s_tag * var_init_cast (s_tag *tag, const s_sym *type, const s_tag *src)
   void *data;
   s_tag tmp;
   assert(tag);
-  assert(tag->type == TAG_VAR);
   assert(type);
+  assert(type != &g_sym_Var);
   assert(src);
-  if (type != tag->data.var.type) {
-    err_write_1("var_init_cast: invalid type, expected ");
-    err_inspect_sym(&tag->data.var.type);
-    err_write_1(" got ");
-    err_inspect_sym(&type);
-    err_write_1("\n");
-    assert(! "var_init_cast: invalid type");
+  if (type == &g_sym_Var) {
+    err_puts("var_init_cast: cannot cast to Var");
+    assert(! "var_init_cast: cannot cast to Var");
     return NULL;
   }
   if (! sym_to_tag_type(type, &tmp.type))