diff --git a/.ic3_history b/.ic3_history
index 5eb1a86..70bbea2 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,7 +1,3 @@
-type(3)
-type(2)
-type(1 + 2)
-type(quote 1 + 2)
123.123
123.1230
123.123000001
@@ -97,3 +93,7 @@ hello("Thomas")
hello = fn (name) { "Hello, #{name} !" }
name("Thomas")
hello("Thomas")
+hello = fn (name) { "Hello, #{name} !" }
+hello("Paul")
+quote hello("Paul")
+hello
diff --git a/libc3/array.c b/libc3/array.c
index b10a46e..33c7a12 100644
--- a/libc3/array.c
+++ b/libc3/array.c
@@ -258,13 +258,8 @@ s_array * array_init_cast (s_array *array, const s_tag *tag)
return NULL;
}
-s_array * array_init_copy (s_array *a, const s_array *src)
+s_array * array_init_copy_shallow (s_array *array, const s_array *src)
{
- u8 *data_tmp;
- u8 *data_src;
- uw i = 0;
- uw item_size;
- bool must_clean;
s_array tmp = {0};
assert(a);
assert(src);
@@ -282,8 +277,26 @@ s_array * array_init_copy (s_array *a, const s_array *src)
}
memcpy(tmp.dimensions, src->dimensions,
src->dimension * sizeof(s_array_dimension));
+ }
+ *array = tmp;
+ return array;
+}
+
+s_array * array_init_copy (s_array *a, const s_array *src)
+{
+ u8 *data_tmp;
+ u8 *data_src;
+ uw i = 0;
+ uw item_size;
+ bool must_clean;
+ s_array tmp;
+ assert(a);
+ assert(src);
+ if (! array_init_copy_shallow(&tmp, src))
+ return NULL;
+ if (tmp.dimension) {
if (src->data) {
- tmp.data = tmp.free_data = calloc(1, src->size);
+ tmp.data = tmp.free_data = calloc(1, tmp.size);
if (! tmp.data) {
warnx("array_init_copy: failed to allocate memory");
assert(! "array_init_copy: failed to allocate memory");
diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index d982471..9ba3c1c 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -2156,6 +2156,7 @@ sw buf_inspect_tag (s_buf *buf, const s_tag *tag)
case TAG_U16: return buf_inspect_u16(buf, &tag->data.u16);
case TAG_U32: return buf_inspect_u32(buf, &tag->data.u32);
case TAG_U64: return buf_inspect_u64(buf, &tag->data.u64);
+ case TAG_UNQUOTE: return buf_inspect_unquote(buf, &tag->data.unquote);
case TAG_UW: return buf_inspect_uw(buf, &tag->data.uw);
case TAG_VAR: return buf_inspect_var(buf, NULL);
case TAG_VOID: return buf_inspect_void(buf, NULL);
@@ -2206,6 +2207,8 @@ sw buf_inspect_tag_size (const s_tag *tag)
case TAG_U16: return buf_inspect_u16_size(&tag->data.u16);
case TAG_U32: return buf_inspect_u32_size(&tag->data.u32);
case TAG_U64: return buf_inspect_u64_size(&tag->data.u64);
+ case TAG_UNQUOTE:
+ return buf_inspect_unquote_size(&tag->data.unquote);
case TAG_UW: return buf_inspect_uw_size(&tag->data.uw);
case TAG_VAR: return buf_inspect_var_size(NULL);
case TAG_VOID: return buf_inspect_void_size(NULL);
diff --git a/libc3/buf_inspect.h b/libc3/buf_inspect.h
index 2306cff..28b0672 100644
--- a/libc3/buf_inspect.h
+++ b/libc3/buf_inspect.h
@@ -147,6 +147,8 @@ BUF_INSPECT_U_PROTOTYPES(8);
BUF_INSPECT_U_PROTOTYPES(16);
BUF_INSPECT_U_PROTOTYPES(32);
BUF_INSPECT_U_PROTOTYPES(64);
+sw buf_inspect_unquote (s_buf *buf, const s_unquote *unquote);
+sw buf_inspect_unquote_size (const s_unquote *unquote);
BUF_INSPECT_U_PROTOTYPES(w);
sw buf_inspect_var (s_buf *buf, const s_tag *var);
sw buf_inspect_var_size (const s_tag *var);
diff --git a/libc3/compare.c b/libc3/compare.c
index 202a557..10cffa4 100644
--- a/libc3/compare.c
+++ b/libc3/compare.c
@@ -892,6 +892,8 @@ s8 compare_tag (const s_tag *a, const s_tag *b) {
&b->data.sym->str);
case TAG_TUPLE: return compare_tuple(&a->data.tuple,
&b->data.tuple);
+ case TAG_UNQUOTE: return compare_unquote(&a->data.unquote,
+ &b->data.unquote);
case TAG_VAR: return compare_ptr(a, b);
case TAG_F32:
case TAG_F64:
@@ -1154,11 +1156,19 @@ s8 compare_tuple (const s_tuple *a, const s_tuple *b)
}
COMPARE_DEF(u8)
-
COMPARE_DEF(u16)
-
COMPARE_DEF(u32)
-
COMPARE_DEF(u64)
+s8 compare_unquote (const s_unquote *a, const s_unquote *b)
+{
+ if (a == b)
+ return 0;
+ if (! a)
+ return -1;
+ if (! b)
+ return 1;
+ return compare_tag(a->tag, b->tag);
+}
+
COMPARE_DEF(uw)
diff --git a/libc3/compare.h b/libc3/compare.h
index 67375b7..2a778e2 100644
--- a/libc3/compare.h
+++ b/libc3/compare.h
@@ -57,6 +57,7 @@ COMPARE_PROTOTYPE(u8);
COMPARE_PROTOTYPE(u16);
COMPARE_PROTOTYPE(u32);
COMPARE_PROTOTYPE(u64);
+s8 compare_unquote (const s_unquote *a, const s_unquote *b);
COMPARE_PROTOTYPE(uw);
#endif /* LIBC3_COMPARE_H */
diff --git a/libc3/env.c b/libc3/env.c
index d08fec1..0caeb01 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -665,46 +665,27 @@ bool env_eval_quote (s_env *env, const s_quote *quote, s_tag *dest)
return env_eval_quote_tag(env, quote->tag, dest);
}
-bool env_eval_quote_array_tag (s_env *env, const s_array *array,
- s_tag *dest)
+bool env_eval_quote_array (s_env *env, const s_array *array,
+ s_tag *dest)
{
uw i;
- s_tag *tag;
- s_tag tag_eval;
+ s_tag *tag;
+ s_tag tag_eval;
s_array tmp = {0};
assert(env);
assert(array);
assert(dest);
- if ((! array->dimension || array->data || ! array->tags) &&
- ! tag_init_array_copy(dest, array))
- return false;
- if (! array->tags) {
- tmp.data = tmp.free_data = calloc(tmp.dimensions[0].count,
- tmp.dimensions[0].item_size);
- if (! tmp.data) {
- warn("env_eval_array: failed to allocate memory");
- assert(! "env_eval_array: failed to allocate memory");
- return false;
- }
- data = tmp.data;
- tag = tmp.tags;
- i = 0;
- while (i < tmp.count) {
- if (! env_eval_tag(env, tag, &tag_eval))
- goto ko;
- if (! data_init_cast(tmp.element_type, data, &tag_eval)) {
- err_write_1("env_eval_array: cannot cast ");
- err_inspect_tag(&tag_eval);
- err_write_1(" to ");
- err_inspect_sym(&tmp.element_type);
- err_puts(".");
- goto ko;
- }
- tag_clean(&tag_eval);
- data += item_size;
- tag++;
- i++;
- }
+ if (! array->dimension || array->data || ! array->tags) {
+ return tag_init_array_copy(dest, array))
+ tag = array->tags;
+ i = 0;
+ while (i < array->count) {
+ if (tag->type == TAG_UNQUOTE) {
+ if (! env_eval_tag(env, tag, &tag_eval))
+ goto ko;
+ }
+ else
+
}
}
*dest = tmp;
diff --git a/libc3/env.h b/libc3/env.h
index 39976c8..586c5ae 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -57,6 +57,8 @@ 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_array (s_env *env, const s_array *array,
+ s_tag *dest);
bool env_eval_quote_tag (s_env *env, const s_tag *tag,
s_tag *dest);
bool env_eval_struct (s_env *env, const s_struct *s,
diff --git a/libc3/list_init.c b/libc3/list_init.c
index d3b52aa..8f98f03 100644
--- a/libc3/list_init.c
+++ b/libc3/list_init.c
@@ -51,6 +51,18 @@ s_list * list_init_array (s_list *list, const s_sym *type,
return list;
}
+s_list * list_init_array_copy (s_list *list, const s_array *a,
+ s_list *next)
+{
+ s_list tmp;
+ assert(list);
+ list_init(&tmp, next);
+ if (! tag_init_array_copy(&tmp.tag, a))
+ return NULL;
+ *list = tmp;
+ return list;
+}
+
s_list * list_init_bool (s_list *list, bool b, s_list *next)
{
s_list tmp;
@@ -470,6 +482,19 @@ s_list * list_new_array (const s_sym *type, uw dimension,
return list;
}
+s_list * list_new_array_copy (const s_array *a, s_list *next)
+{
+ s_list *list;
+ list = list_new(next);
+ if (! list)
+ return NULL;
+ if (! tag_init_array_copy(&list->tag, a)) {
+ free(list);
+ return NULL;
+ }
+ return list;
+}
+
s_list * list_new_bool (bool b, s_list *next)
{
s_list *list;
diff --git a/libc3/list_init.h b/libc3/list_init.h
index 9a2b0fe..cacebe3 100644
--- a/libc3/list_init.h
+++ b/libc3/list_init.h
@@ -19,6 +19,8 @@
s_list * list_init_array (s_list *list, const s_sym *type,
uw dimension, const uw *dimensions,
s_list *next);
+s_list * list_init_array_copy (s_list *list, const s_array *a,
+ s_list *next);
s_list * list_init_bool (s_list *list, bool b, s_list *next);
s_list * list_init_call (s_list *list, s_list *next);
s_list * list_init_character (s_list *list, character c, s_list *next);
@@ -72,6 +74,7 @@ s_list * list_init_void (s_list *list, s_list *next);
/* Heap-allocation functions, call list_delete after use. */
s_list * list_new_array (const s_sym *type, uw dimension,
const uw *dimensions, s_list *next);
+s_list * list_new_array_copy (const s_array *a, s_list *next);
s_list * list_new_bool (bool b, s_list *next);
s_list * list_new_call (s_list *next);
s_list * list_new_character (character c, s_list *next);
@@ -120,6 +123,7 @@ s_list * list_new_void (s_list *next);
/* Setters. */
s_list * list_array (s_list *list, const s_sym *type, uw dimension,
const uw *dimensions);
+s_list * list_array_copy (s_list *list, const s_array *a);
s_list * list_bool (s_list *list, bool b);
s_list * list_call (s_list *list);
s_list * list_character (s_list *list, character c);
diff --git a/libc3/tag_init.c b/libc3/tag_init.c
index acba8d6..1b0afeb 100644
--- a/libc3/tag_init.c
+++ b/libc3/tag_init.c
@@ -50,6 +50,17 @@ s_tag * tag_init_array (s_tag *tag, const s_sym *type, uw dimension,
return tag;
}
+s_tag * tag_init_array_copy (s_tag *tag, const s_array *a)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_ARRAY;
+ if (! array_init_copy(&tmp.data.array, a))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_init_bool (s_tag *tag, bool b)
{
s_tag tmp = {0};
@@ -453,6 +464,21 @@ s_tag * tag_new_array (const s_sym *type, uw dimension,
return tag;
}
+s_tag * tag_new_array_copy (const s_array *a)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_array_copy: calloc");
+ return NULL;
+ }
+ tag->type = TAG_ARRAY;
+ if (! array_init_copy(&tag->data.array, a)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
s_tag * tag_new_bool (bool b)
{
s_tag *tag;
@@ -961,6 +987,18 @@ s_tag * tag_array (s_tag *tag, const s_sym *type, uw dimension,
return tag;
}
+s_tag * tag_array_copy (s_tag *tag, const s_array *a)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_ARRAY;
+ if (! array_init_copy(&tmp.data.array, a))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_bool (s_tag *tag, bool b)
{
s_tag tmp = {0};
diff --git a/libc3/tag_init.h b/libc3/tag_init.h
index 652d230..5f1547c 100644
--- a/libc3/tag_init.h
+++ b/libc3/tag_init.h
@@ -18,6 +18,7 @@
/* Stack-allocation compatible functions, call tag_clean after use. */
s_tag * tag_init_array (s_tag *tag, const s_sym *type, uw dimension,
const uw *dimensions);
+s_tag * tag_init_array_copy (s_tag *tag, const s_array *a);
s_tag * tag_init_bool (s_tag *tag, bool b);
s_tag * tag_init_call (s_tag *tag);
s_tag * tag_init_character (s_tag *tag, character c);
@@ -62,6 +63,7 @@ s_tag * tag_init_void (s_tag *tag);
/* Heap-allocation functions, call tag_delete after use. */
s_tag * tag_new_array (const s_sym *type, uw dimension,
const uw *dimensions);
+s_tag * tag_new_array_copy (const s_array *a);
s_tag * tag_new_bool (bool b);
s_tag * tag_new_call (void);
s_tag * tag_new_character (character c);
@@ -106,6 +108,7 @@ s_tag * tag_new_void (void);
/* Setters. */
s_tag * tag_array (s_tag *tag, const s_sym *type, uw dimension,
const uw *dimensions);
+s_tag * tag_array_copy (s_tag *tag, const s_array *a);
s_tag * tag_bool (s_tag *tag, bool b);
s_tag * tag_call (s_tag *tag);
s_tag * tag_character (s_tag *tag, character c);
diff --git a/libc3/tag_init.rb b/libc3/tag_init.rb
index a5372c7..2922eef 100644
--- a/libc3/tag_init.rb
+++ b/libc3/tag_init.rb
@@ -304,6 +304,8 @@ class TagInitList
[Arg.new("const s_sym *", "type"),
Arg.new("uw", "dimension"),
Arg.new("const uw *", "dimensions")]),
+ TagInit.new("array", "copy", "TAG_ARRAY", :init_mode_init,
+ [Arg.new("const s_array *", "a")]),
TagInit.new("bool", "TAG_BOOL", :init_mode_direct,
[Arg.new("bool", "b")]),
TagInit.new("call", "TAG_CALL", :init_mode_init, []),
diff --git a/libc3/types.h b/libc3/types.h
index 7384bbe..247b412 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -122,6 +122,7 @@ typedef enum {
TAG_STRUCT_TYPE,
TAG_SYM,
TAG_TUPLE,
+ TAG_UNQUOTE,
TAG_VAR,
TAG_IDENT
} e_tag_type;
@@ -168,6 +169,7 @@ typedef struct tag_type_list s_tag_type_list;
typedef struct timespec s_time;
typedef struct tuple s_tuple;
typedef struct type s_type;
+typedef struct unquote s_unquote;
typedef struct unwind_protect s_unwind_protect;
/* unions */
@@ -283,6 +285,10 @@ struct tuple {
s_tag *tag;
};
+struct unquote {
+ s_tag *tag;
+};
+
struct unwind_protect {
jmp_buf buf;
jmp_buf *jmp;
@@ -433,6 +439,7 @@ union tag_data {
u16 u16;
u32 u32;
u64 u64;
+ s_unquote unquote;
uw uw;
};