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))