diff --git a/ikc3/ikc3.c b/ikc3/ikc3.c
index aae0ddb..7bf61da 100644
--- a/ikc3/ikc3.c
+++ b/ikc3/ikc3.c
@@ -68,16 +68,14 @@ sw ikc3_run (void)
tag_clean(&input);
tag_clean(&result);
}
- if (r < 0)
+ if (r < 0 ||
+ (r == 0 &&
+ (r = buf_ignore_character(&g_kc3_env.in)) <= 0))
return 0;
if ((r = buf_write_1(&g_kc3_env.out, "\n")) < 0)
return 0;
if ((r = buf_flush(&g_kc3_env.out)) < 0)
return 0;
- if (r < 0 ||
- (r == 0 &&
- (r = buf_ignore_character(&g_kc3_env.in)) <= 0))
- return 0;
}
return 0;
}
diff --git a/lib/kc3/0.1/kc3.facts b/lib/kc3/0.1/kc3.facts
index fe641e0..097b164 100644
--- a/lib/kc3/0.1/kc3.facts
+++ b/lib/kc3/0.1/kc3.facts
@@ -6,196 +6,196 @@ replace {KC3.operator_paren, :is_a, :operator}
replace {KC3.operator_paren, :sym, :"()"}
replace {KC3.operator_paren, :arity, 1}
replace {KC3.operator_paren, :symbol_value, cfn Tag "tag_paren" (Tag, Result)}
-replace {KC3.operator_paren, :operator_precedence, 14}
+replace {KC3.operator_paren, :operator_precedence, 16}
replace {KC3.operator_paren, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_brackets}
replace {KC3.operator_brackets, :is_a, :operator}
replace {KC3.operator_brackets, :sym, :"[]"}
replace {KC3.operator_brackets, :arity, 2}
replace {KC3.operator_brackets, :symbol_value, cfn Tag "kc3_access" (Tag, List, Result)}
-replace {KC3.operator_brackets, :operator_precedence, 14}
+replace {KC3.operator_brackets, :operator_precedence, 15}
replace {KC3.operator_brackets, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_bnot}
replace {KC3.operator_bnot, :is_a, :operator}
replace {KC3.operator_bnot, :sym, :~}
replace {KC3.operator_bnot, :arity, 1}
replace {KC3.operator_bnot, :symbol_value, cfn Tag "tag_bnot" (Tag, Result)}
-replace {KC3.operator_bnot, :operator_precedence, 13}
+replace {KC3.operator_bnot, :operator_precedence, 14}
replace {KC3.operator_bnot, :operator_associativity, :right}
add {KC3, :operator, KC3.operator_defstruct}
replace {KC3.operator_defstruct, :is_a, :operator}
replace {KC3.operator_defstruct, :sym, :defstruct}
replace {KC3.operator_defstruct, :arity, 1}
replace {KC3.operator_defstruct, :symbol_value, cfn Tag "kc3_defstruct" (List, Result)}
-replace {KC3.operator_defstruct, :operator_precedence, 13}
+replace {KC3.operator_defstruct, :operator_precedence, 14}
replace {KC3.operator_defstruct, :operator_associativity, :none}
add {KC3, :operator, KC3.operator_neg}
replace {KC3.operator_neg, :is_a, :operator}
replace {KC3.operator_neg, :sym, :-}
replace {KC3.operator_neg, :arity, 1}
replace {KC3.operator_neg, :symbol_value, cfn Tag "tag_neg" (Tag, Result)}
-replace {KC3.operator_neg, :operator_precedence, 13}
+replace {KC3.operator_neg, :operator_precedence, 14}
replace {KC3.operator_neg, :operator_associativity, :right}
add {KC3, :operator, KC3.operator_not}
replace {KC3.operator_not, :is_a, :operator}
replace {KC3.operator_not, :sym, :!}
replace {KC3.operator_not, :arity, 1}
replace {KC3.operator_not, :symbol_value, cfn Bool "tag_not" (Tag, Result)}
-replace {KC3.operator_not, :operator_precedence, 13}
+replace {KC3.operator_not, :operator_precedence, 14}
replace {KC3.operator_not, :operator_associativity, :right}
add {KC3, :operator, KC3.operator_pin}
replace {KC3.operator_pin, :is_a, :operator}
replace {KC3.operator_pin, :sym, :^}
replace {KC3.operator_pin, :arity, 1}
replace {KC3.operator_pin, :symbol_value, cfn Tag "kc3_identity" (Tag, Result)}
-replace {KC3.operator_pin, :operator_precedence, 13}
+replace {KC3.operator_pin, :operator_precedence, 14}
replace {KC3.operator_pin, :operator_associativity, :right}
add {KC3, :operator, KC3.operator_require}
replace {KC3.operator_require, :is_a, :operator}
replace {KC3.operator_require, :sym, :require}
replace {KC3.operator_require, :arity, 1}
replace {KC3.operator_require, :symbol_value, cfn Bool "kc3_require" (Sym)}
-replace {KC3.operator_require, :operator_precedence, 13}
+replace {KC3.operator_require, :operator_precedence, 14}
replace {KC3.operator_require, :operator_associativity, :none}
add {KC3, :operator, KC3.operator_div}
replace {KC3.operator_div, :is_a, :operator}
replace {KC3.operator_div, :sym, :/}
replace {KC3.operator_div, :arity, 2}
replace {KC3.operator_div, :symbol_value, cfn Tag "tag_div" (Tag, Tag, Result)}
-replace {KC3.operator_div, :operator_precedence, 12}
+replace {KC3.operator_div, :operator_precedence, 13}
replace {KC3.operator_div, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_mod}
replace {KC3.operator_mod, :is_a, :operator}
replace {KC3.operator_mod, :sym, :mod}
replace {KC3.operator_mod, :arity, 2}
replace {KC3.operator_mod, :symbol_value, cfn Tag "tag_mod" (Tag, Tag, Result)}
-replace {KC3.operator_mod, :operator_precedence, 12}
+replace {KC3.operator_mod, :operator_precedence, 13}
replace {KC3.operator_mod, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_mul}
replace {KC3.operator_mul, :is_a, :operator}
replace {KC3.operator_mul, :sym, :*}
replace {KC3.operator_mul, :arity, 2}
replace {KC3.operator_mul, :symbol_value, cfn Tag "tag_mul" (Tag, Tag, Result)}
-replace {KC3.operator_mul, :operator_precedence, 12}
+replace {KC3.operator_mul, :operator_precedence, 13}
replace {KC3.operator_mul, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_add}
replace {KC3.operator_add, :is_a, :operator}
replace {KC3.operator_add, :sym, :+}
replace {KC3.operator_add, :arity, 2}
replace {KC3.operator_add, :symbol_value, cfn Tag "tag_add" (Tag, Tag, Result)}
-replace {KC3.operator_add, :operator_precedence, 11}
+replace {KC3.operator_add, :operator_precedence, 12}
replace {KC3.operator_add, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_addi}
replace {KC3.operator_addi, :is_a, :operator}
replace {KC3.operator_addi, :sym, :+i}
replace {KC3.operator_addi, :arity, 2}
replace {KC3.operator_addi, :symbol_value, cfn Tag "tag_addi" (Tag, Tag, Result)}
-replace {KC3.operator_addi, :operator_precedence, 11}
+replace {KC3.operator_addi, :operator_precedence, 12}
replace {KC3.operator_addi, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_sub}
replace {KC3.operator_sub, :is_a, :operator}
replace {KC3.operator_sub, :sym, :-}
replace {KC3.operator_sub, :arity, 2}
replace {KC3.operator_sub, :symbol_value, cfn Tag "tag_sub" (Tag, Tag, Result)}
-replace {KC3.operator_sub, :operator_precedence, 11}
+replace {KC3.operator_sub, :operator_precedence, 12}
replace {KC3.operator_sub, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_shift_left}
replace {KC3.operator_shift_left, :is_a, :operator}
replace {KC3.operator_shift_left, :sym, :<<}
replace {KC3.operator_shift_left, :arity, 2}
replace {KC3.operator_shift_left, :symbol_value, cfn Tag "tag_shift_left" (Tag, Tag, Result)}
-replace {KC3.operator_shift_left, :operator_precedence, 10}
+replace {KC3.operator_shift_left, :operator_precedence, 11}
replace {KC3.operator_shift_left, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_shift_right}
replace {KC3.operator_shift_right, :is_a, :operator}
replace {KC3.operator_shift_right, :sym, :>>}
replace {KC3.operator_shift_right, :arity, 2}
replace {KC3.operator_shift_right, :symbol_value, cfn Tag "tag_shift_right" (Tag, Tag, Result)}
-replace {KC3.operator_shift_right, :operator_precedence, 10}
+replace {KC3.operator_shift_right, :operator_precedence, 11}
replace {KC3.operator_shift_right, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_lt}
replace {KC3.operator_lt, :is_a, :operator}
replace {KC3.operator_lt, :sym, :<}
replace {KC3.operator_lt, :arity, 2}
replace {KC3.operator_lt, :symbol_value, cfn Bool "tag_lt" (Tag, Tag, Result)}
-replace {KC3.operator_lt, :operator_precedence, 9}
+replace {KC3.operator_lt, :operator_precedence, 10}
replace {KC3.operator_lt, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_lte}
replace {KC3.operator_lte, :sym, :<=}
replace {KC3.operator_lte, :is_a, :operator}
replace {KC3.operator_lte, :arity, 2}
replace {KC3.operator_lte, :symbol_value, cfn Bool "tag_lte" (Tag, Tag, Result)}
-replace {KC3.operator_lte, :operator_precedence, 9}
+replace {KC3.operator_lte, :operator_precedence, 10}
replace {KC3.operator_lte, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_gt}
replace {KC3.operator_gt, :sym, :>}
replace {KC3.operator_gt, :is_a, :operator}
replace {KC3.operator_gt, :arity, 2}
replace {KC3.operator_gt, :symbol_value, cfn Bool "tag_gt" (Tag, Tag, Result)}
-replace {KC3.operator_gt, :operator_precedence, 9}
+replace {KC3.operator_gt, :operator_precedence, 10}
replace {KC3.operator_gt, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_gte}
replace {KC3.operator_gte, :sym, :>=}
replace {KC3.operator_gte, :is_a, :operator}
replace {KC3.operator_gte, :arity, 2}
replace {KC3.operator_gte, :symbol_value, cfn Bool "tag_gte" (Tag, Tag, Result)}
-replace {KC3.operator_gte, :operator_precedence, 9}
+replace {KC3.operator_gte, :operator_precedence, 10}
replace {KC3.operator_gte, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_eq}
replace {KC3.operator_eq, :is_a, :operator}
replace {KC3.operator_eq, :sym, :==}
replace {KC3.operator_eq, :arity, 2}
replace {KC3.operator_eq, :symbol_value, cfn Bool "tag_eq" (Tag, Tag, Result)}
-replace {KC3.operator_eq, :operator_precedence, 8}
+replace {KC3.operator_eq, :operator_precedence, 9}
replace {KC3.operator_eq, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_not_eq}
replace {KC3.operator_not_eq, :is_a, :operator}
replace {KC3.operator_not_eq, :sym, :!=}
replace {KC3.operator_not_eq, :arity, 2}
replace {KC3.operator_not_eq, :symbol_value, cfn Bool "tag_not_eq" (Tag, Tag, Result)}
-replace {KC3.operator_not_eq, :operator_precedence, 8}
+replace {KC3.operator_not_eq, :operator_precedence, 9}
replace {KC3.operator_not_eq, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_band}
replace {KC3.operator_band, :is_a, :operator}
replace {KC3.operator_band, :sym, :&}
replace {KC3.operator_band, :arity, 2}
replace {KC3.operator_band, :symbol_value, cfn Tag "tag_band" (Tag, Tag, Result)}
-replace {KC3.operator_band, :operator_precedence, 7}
+replace {KC3.operator_band, :operator_precedence, 8}
replace {KC3.operator_band, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_bxor}
replace {KC3.operator_bxor, :is_a, :operator}
replace {KC3.operator_bxor, :sym, :^}
replace {KC3.operator_bxor, :arity, 2}
replace {KC3.operator_bxor, :symbol_value, cfn Tag "tag_bxor" (Tag, Tag, Result)}
-replace {KC3.operator_bxor, :operator_precedence, 6}
+replace {KC3.operator_bxor, :operator_precedence, 7}
replace {KC3.operator_bxor, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_bor}
replace {KC3.operator_bor, :is_a, :operator}
replace {KC3.operator_bor, :sym, :bor}
replace {KC3.operator_bor, :arity, 2}
replace {KC3.operator_bor, :symbol_value, cfn Tag "tag_bor" (Tag, Tag, Result)}
-replace {KC3.operator_bor, :operator_precedence, 5}
+replace {KC3.operator_bor, :operator_precedence, 6}
replace {KC3.operator_bor, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_and}
replace {KC3.operator_and, :is_a, :operator}
replace {KC3.operator_and, :sym, :&&}
replace {KC3.operator_and, :arity, 2}
replace {KC3.operator_and, :symbol_value, cfn Bool "tag_and" (Tag, Tag, Result)}
-replace {KC3.operator_and, :operator_precedence, 4}
+replace {KC3.operator_and, :operator_precedence, 5}
replace {KC3.operator_and, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_or}
replace {KC3.operator_or, :is_a, :operator}
replace {KC3.operator_or, :sym, :||}
replace {KC3.operator_or, :arity, 2}
replace {KC3.operator_or, :symbol_value, cfn Bool "tag_or" (Tag, Tag, Result)}
-replace {KC3.operator_or, :operator_precedence, 3}
+replace {KC3.operator_or, :operator_precedence, 4}
replace {KC3.operator_or, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_assign}
replace {KC3.operator_assign, :is_a, :operator}
replace {KC3.operator_assign, :sym, :<-}
replace {KC3.operator_assign, :arity, 2}
replace {KC3.operator_assign, :symbol_value, cfn Tag "var_assign" (Var, Tag, Result)}
-replace {KC3.operator_assign, :operator_precedence, 2}
+replace {KC3.operator_assign, :operator_precedence, 3}
replace {KC3.operator_assign, :operator_associativity, :left}
add {KC3, :operator, KC3.operator_equal}
replace {KC3.operator_equal, :is_a, :operator}
@@ -203,14 +203,14 @@ replace {KC3.operator_equal, :arity, 2}
add {KC3.operator_equal, :is_a, :special_operator}
replace {KC3.operator_equal, :sym, :=}
replace {KC3.operator_equal, :symbol_value, cfn Tag "tag_equal" (Tag, Tag, Result)}
-replace {KC3.operator_equal, :operator_precedence, 1}
+replace {KC3.operator_equal, :operator_precedence, 2}
replace {KC3.operator_equal, :operator_associativity, :right}
add {KC3, :operator, KC3.operator_semicolumn}
replace {KC3.operator_semicolumn, :is_a, :operator}
replace {KC3.operator_semicolumn, :arity, 2}
replace {KC3.operator_semicolumn, :sym, :";"}
replace {KC3.operator_semicolumn, :symbol_value, cfn Tag "tag_semicolumn" (Tag, Tag, Result)}
-replace {KC3.operator_semicolumn, :operator_precedence, 0}
+replace {KC3.operator_semicolumn, :operator_precedence, 1}
replace {KC3.operator_semicolumn, :operator_associativity, :left}
replace {KC3, :symbol, KC3.license}
replace {KC3.license, :symbol_value, cfn Void "kc3_license" ()}
diff --git a/libkc3/buf_inspect.c b/libkc3/buf_inspect.c
index 97edddb..7e16383 100644
--- a/libkc3/buf_inspect.c
+++ b/libkc3/buf_inspect.c
@@ -122,8 +122,8 @@ sw buf_inspect_array_data_rec (s_buf *buf, const s_array *array,
while (1) {
if (dimension == array->dimension - 1) {
if (*data) {
- if ((r = data_buf_inspect(array->element_type,
- buf, *data)) <= 0)
+ if ((r = data_buf_inspect(buf, array->element_type,
+ *data)) <= 0)
goto clean;
result += r;
*data += array->dimensions[dimension].item_size;
@@ -207,7 +207,7 @@ sw buf_inspect_array_data_size_rec (s_pretty *pretty,
while (1) {
if (dimension == array->dimension - 1) {
if (*data) {
- if ((r = data_buf_inspect_size(array->element_type, pretty,
+ if ((r = data_buf_inspect_size(pretty, array->element_type,
*data)) <= 0)
goto clean;
result += r;
@@ -3148,12 +3148,12 @@ sw buf_inspect_struct (s_buf *buf, const s_struct *s)
goto clean;
result += r;
if (s->data) {
- if (! tag_type(s->type->map.value + i, &type))
- goto clean;
- if (type == &g_sym_Var)
+ if (s->type->map.value[i].type == TAG_VAR)
type = s->type->map.value[i].data.var.type;
+ else if (! tag_type(s->type->map.value + i, &type))
+ goto clean;
assert(s->type->offset[i] < s->type->size);
- if ((r = data_buf_inspect(type, buf, (char *) s->data +
+ if ((r = data_buf_inspect(buf, type, (char *) s->data +
s->type->offset[i])) < 0)
goto clean;
result += r;
@@ -3200,7 +3200,8 @@ sw buf_inspect_struct_size (s_pretty *pretty, const s_struct *s)
assert(! "buf_inspect_struct: sym_is_module(s->type->module)");
return -1;
}
- if ((r = buf_write_str_without_indent_size(pretty, &s->type->module->str)) < 0)
+ if ((r = buf_write_str_without_indent_size
+ (pretty, &s->type->module->str)) < 0)
return r;
result += r;
if ((r = buf_write_1_size(pretty, "{")) < 0)
@@ -3234,12 +3235,13 @@ sw buf_inspect_struct_size (s_pretty *pretty, const s_struct *s)
goto clean;
result += r;
if (s->data) {
- if (! tag_type(s->type->map.value + i, &type))
+ if (s->type->map.value[i].type == TAG_VAR)
+ type = s->type->map.value[i].data.var.type;
+ else if (! tag_type(s->type->map.value + i, &type))
goto clean;
assert(s->type->offset[i] < s->type->size);
- if ((r = data_buf_inspect_size(type, pretty,
- (char *) s->data +
- s->type->offset[i])) < 0)
+ if ((r = data_buf_inspect_size(pretty, type, (char *) s->data +
+ s->type->offset[i])) < 0)
goto clean;
result += r;
}
@@ -3477,7 +3479,7 @@ sw buf_inspect_tag (s_buf *buf, const s_tag *tag)
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, tag);
+ case TAG_VAR: return buf_inspect_var(buf, &tag->data.var);
case TAG_VOID: return buf_inspect_void(buf, NULL);
}
err_puts("buf_inspect_tag: unknown tag_type");
@@ -3569,7 +3571,7 @@ sw buf_inspect_tag_size (s_pretty *pretty, const s_tag *tag)
case TAG_UW:
return buf_inspect_uw_size(pretty, &tag->data.uw);
case TAG_VAR:
- return buf_inspect_var_size(pretty, tag);
+ return buf_inspect_var_size(pretty, &tag->data.var);
case TAG_VOID:
return buf_inspect_void_size(pretty, NULL);
}
@@ -3737,65 +3739,63 @@ sw buf_inspect_unquote_size (s_pretty *pretty, const s_unquote *unquote)
return result;
}
-sw buf_inspect_var (s_buf *buf, const s_tag *tag)
+sw buf_inspect_var (s_buf *buf, const s_var *var)
{
sw r;
sw result = 0;
assert(buf);
- assert(tag);
- assert(tag->type == TAG_VAR);
- assert(tag->data.var.type);
- if (tag->data.var.type == &g_sym_Tag) {
+ assert(var);
+ assert(var->type);
+ if (var->type == &g_sym_Tag) {
if ((r = buf_write_1(buf, "?")) < 0)
return r;
}
else {
- if ((r = buf_inspect_paren_sym(buf, tag->data.var.type)) < 0)
+ if ((r = buf_inspect_paren_sym(buf, var->type)) < 0)
return r;
result += r;
if ((r = buf_write_1(buf, " ?")) < 0)
return r;
result += r;
}
- if (tag->data.var.ptr) {
+ if (var->ptr) {
if ((r = buf_write_1(buf, "0x")) < 0)
return r;
result += r;
if ((r = buf_inspect_uw_hexadecimal
- (buf, (uw *) &tag->data.var.ptr)) < 0)
+ (buf, (uw *) &var->ptr)) < 0)
return r;
result += r;
}
return result;
}
-sw buf_inspect_var_size (s_pretty *pretty, const s_tag *tag)
+sw buf_inspect_var_size (s_pretty *pretty, const s_var *var)
{
sw r;
sw result = 0;
assert(pretty);
- assert(tag);
- assert(tag->type == TAG_VAR);
- assert(tag->data.var.type);
- if (tag->data.var.type == &g_sym_Tag) {
+ assert(var);
+ assert(var->type);
+ if (var->type == &g_sym_Tag) {
if ((r = buf_write_1_size(pretty, "?")) < 0)
return r;
}
else {
if ((r = buf_inspect_paren_sym_size(pretty,
- tag->data.var.type)) < 0)
+ var->type)) < 0)
return r;
result += r;
if ((r = buf_write_1_size(pretty, " ?")) < 0)
return r;
result += r;
}
- if (tag->data.var.ptr) {
+ if (var->ptr) {
if ((r = buf_write_1_size(pretty, "0x")) < 0)
return r;
result += r;
if ((r = buf_inspect_uw_hexadecimal_size
- (pretty, (uw *) &tag->data.var.ptr)) < 0)
+ (pretty, (uw *) &var->ptr)) < 0)
return r;
result += r;
}
diff --git a/libkc3/buf_inspect.h b/libkc3/buf_inspect.h
index 5d7a7b9..df1453c 100644
--- a/libkc3/buf_inspect.h
+++ b/libkc3/buf_inspect.h
@@ -203,8 +203,8 @@ sw buf_inspect_unquote (s_buf *buf, const s_unquote *unquote);
sw buf_inspect_unquote_size (s_pretty *pretty,
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 (s_pretty *pretty, const s_tag *var);
+sw buf_inspect_var (s_buf *buf, const s_var *var);
+sw buf_inspect_var_size (s_pretty *pretty, const s_var *var);
sw buf_inspect_void (s_buf *buf, const void *v);
sw buf_inspect_void_size (s_pretty *pretty, const void *v);
diff --git a/libkc3/buf_parse.c b/libkc3/buf_parse.c
index f99e4c6..b2c61a1 100644
--- a/libkc3/buf_parse.c
+++ b/libkc3/buf_parse.c
@@ -977,8 +977,9 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, sw min_precedence)
next_op_precedence = operator_precedence(&next_op);
while (1) {
if (r <= 0 ||
- operator_arity(&next_op) != 2)
+ operator_arity(&next_op) != 2) {
break;
+ }
if (next_op_precedence <= op_precedence) {
if (! operator_is_right_associative(&next_op, &b)) {
r = -1;
@@ -1022,10 +1023,20 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, sw min_precedence)
break;
call_init_op(&tmp3);
tmp3.ident = op;
- tmp3.arguments->tag = *left;
- list_next(tmp3.arguments)->tag = *right;
- tag_init_call(left);
- left->data.call = tmp3;
+ if (true) {
+ tmp3.arguments->tag = *left;
+ list_next(tmp3.arguments)->tag = *right;
+ tag_init_call(left);
+ left->data.call = tmp3;
+ }
+ else {
+ tag_init_call(&tmp3.arguments->tag);
+ tmp3.arguments->tag.data.call = tmp;
+ list_next(tmp3.arguments)->tag = *right;
+ tmp = tmp3;
+ left = &tmp.arguments->tag;
+ right = &list_next(tmp.arguments)->tag;
+ }
}
call_clean(dest);
*dest = tmp;
@@ -4176,6 +4187,7 @@ sw buf_parse_tag_primary_4 (s_buf *buf, s_tag *dest)
goto end;
goto restore;
case 'f':
+ case 'm':
if ((r = buf_parse_tag_fn(buf, dest)))
goto end;
// fall through
diff --git a/libkc3/data.c b/libkc3/data.c
index a21391c..1222776 100644
--- a/libkc3/data.c
+++ b/libkc3/data.c
@@ -12,7 +12,7 @@
*/
#include "kc3.h"
-sw data_buf_inspect (const s_sym *type, s_buf *buf, const void *data)
+sw data_buf_inspect (s_buf *buf, const s_sym *type, const void *data)
{
s_struct s = {0};
const s_struct_type *st;
@@ -101,7 +101,7 @@ sw data_buf_inspect (const s_sym *type, s_buf *buf, const void *data)
return -1;
}
-sw data_buf_inspect_size (const s_sym *type, s_pretty *pretty,
+sw data_buf_inspect_size (s_pretty *pretty, const s_sym *type,
const void *data)
{
s_struct s = {0};
@@ -159,6 +159,8 @@ sw data_buf_inspect_size (const s_sym *type, s_pretty *pretty,
return buf_inspect_sw_size(pretty, data);
if (type == &g_sym_Sym)
return buf_inspect_sym_size(pretty, data);
+ if (type == &g_sym_Tag)
+ return buf_inspect_tag_size(pretty, data);
if (type == &g_sym_Tuple)
return buf_inspect_tuple_size(pretty, data);
if (type == &g_sym_U8)
diff --git a/libkc3/data.h b/libkc3/data.h
index b121a0a..46b8db1 100644
--- a/libkc3/data.h
+++ b/libkc3/data.h
@@ -21,8 +21,8 @@
#include "types.h"
-sw data_buf_inspect (const s_sym *type, s_buf *buf, const void *v);
-sw data_buf_inspect_size (const s_sym *type, s_pretty *pretty,
+sw data_buf_inspect (s_buf *buf, const s_sym *type, const void *v);
+sw data_buf_inspect_size (s_pretty *pretty, const s_sym *type,
const void *v);
bool data_clean (const s_sym *type, void *v);
bool data_compare (const s_sym *type, const void *a, const void *b);
diff --git a/libkc3/env.c b/libkc3/env.c
index a5fdc81..28a1e84 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -1784,18 +1784,17 @@ bool env_eval_struct (s_env *env, const s_struct *s, s_struct *dest)
return false;
i = 0;
while (i < tmp.type->map.count) {
+ if (tmp.type->map.value[i].type == TAG_VAR)
+ type = tmp.type->map.value[i].data.var.type;
+ else if (! tag_type(tmp.type->map.value + i, &type))
+ goto ko;
if (s->tag) {
- if (tmp.type->map.value[i].type == TAG_VAR)
- type = tmp.type->map.value[i].data.var.type;
- else {
- if (! tag_type(tmp.type->map.value + i, &type))
- goto ko;
- }
if (! env_eval_tag(env, s->tag + i, &tag))
goto ko;
- if (tmp.type->map.value[i].type == TAG_VAR) {
- if (! data_init_cast((s8 *) tmp.data + tmp.type->offset[i],
- &type, &tag))
+ if (type == &g_sym_Tag) {
+ if (! tag_init_copy((s_tag *) ((s8 *) tmp.data +
+ tmp.type->offset[i]),
+ &tag))
goto ko_init;
}
else {
@@ -1810,13 +1809,19 @@ bool env_eval_struct (s_env *env, const s_struct *s, s_struct *dest)
tag_clean(&tag);
}
else {
- if (! tag_type(tmp.type->map.value + i, &type))
- goto ko;
- if (! tag_to_const_pointer(tmp.type->map.value + i, type, &value))
- goto ko;
- if (! data_init_copy(type, (s8 *) tmp.data + tmp.type->offset[i],
- value))
- goto ko;
+ if (type == &g_sym_Tag) {
+ if (! tag_init_copy((s_tag *) ((s8 *) tmp.data +
+ tmp.type->offset[i]),
+ tmp.type->map.value + i))
+ goto ko_init;
+ }
+ else {
+ if (! tag_to_const_pointer(tmp.type->map.value + i, type, &value))
+ goto ko;
+ if (! data_init_copy(type, (s8 *) tmp.data + tmp.type->offset[i],
+ value))
+ goto ko;
+ }
}
i++;
}
@@ -1982,8 +1987,7 @@ bool env_eval_var (s_env *env, const s_var *var, s_tag *dest)
if (var->ptr && var->ptr->type != TAG_VAR)
return tag_init_copy(dest, var->ptr) ? true : false;
tmp.type = TAG_VAR;
- tmp.data.var.ptr = var->ptr ? var->ptr : dest;
- tmp.data.var.type = var->type;
+ tmp.data.var = *var;
*dest = tmp;
return true;
}
diff --git a/libkc3/str.c b/libkc3/str.c
index 0b02a46..366d05b 100644
--- a/libkc3/str.c
+++ b/libkc3/str.c
@@ -385,7 +385,7 @@ s_str * str_init_cast (s_str *str, const s_sym * const *type,
case TAG_UW:
return str_init_uw(str, tag->data.uw);
case TAG_VAR:
- return str_init_var(str, tag);
+ return str_init_var(str, &tag->data.var);
default:
break;
}
@@ -611,41 +611,7 @@ DEF_STR_INIT_INT(u16)
DEF_STR_INIT_INT(u32)
DEF_STR_INIT_INT(u64)
DEF_STR_INIT_INT(uw)
-
-s_str * str_init_var (s_str *str, const s_tag *x)
-{
- s_buf buf;
- s_pretty pretty = {0};
- sw r;
- sw size;
- size = buf_inspect_var_size(&pretty, x);
- if (! size)
- return str_init_empty(str);
- if (size < 0) {
- err_puts("str_init_var: buf_inspect_var_size < 0");
- return NULL;
- }
- if (! buf_init_alloc(&buf, size)) {
- err_puts("str_init_var: buf_init_alloc");
- return NULL;
- }
- if ((r = buf_inspect_var(&buf, x)) < 0) {
- err_puts("str_init_var: buf_inspect_var < 0");
- buf_clean(&buf);
- return NULL;
- }
- if (r != size) {
- err_write_1("str_init_var: buf_inspect_var: ");
- err_inspect_sw_decimal(&r);
- err_write_1(" != ");
- err_inspect_sw_decimal(&size);
- err_write_1("\n");
- buf_clean(&buf);
- return NULL;
- }
- assert(buf.wpos == (uw) size);
- return buf_to_str(&buf, str);
-}
+DEF_STR_INIT_STRUCT(var)
s_str * str_init_vf (s_str *str, const char *fmt, va_list ap)
{
diff --git a/libkc3/str.h b/libkc3/str.h
index 027c6c0..304a4b5 100644
--- a/libkc3/str.h
+++ b/libkc3/str.h
@@ -76,7 +76,7 @@ PROTOTYPE_STR_INIT_INT(u16);
PROTOTYPE_STR_INIT_INT(u32);
PROTOTYPE_STR_INIT_INT(u64);
PROTOTYPE_STR_INIT_INT(uw);
-PROTOTYPE_STR_INIT(var, const s_tag *);
+PROTOTYPE_STR_INIT_STRUCT(var);
s_str * str_init_vf (s_str *str, const char *fmt, va_list ap);
/* Constructors, call str_delete after use */
diff --git a/libkc3/struct.c b/libkc3/struct.c
index d9c6ce5..b637d19 100644
--- a/libkc3/struct.c
+++ b/libkc3/struct.c
@@ -277,8 +277,8 @@ s_struct * struct_init_cast (s_struct *s, const s_sym * const *type,
s_struct * struct_init_copy (s_struct *s, const s_struct *src)
{
uw i;
- const s_sym *sym;
s_struct tmp = {0};
+ const s_sym *type;
assert(s);
assert(src);
assert(src->type);
@@ -291,10 +291,11 @@ s_struct * struct_init_copy (s_struct *s, const s_struct *src)
i = 0;
while (i < tmp.type->map.count) {
if (tmp.type->map.value[i].type == TAG_VAR)
- sym = tmp.type->map.value[i].data.var.type;
- else if (! tag_type(tmp.type->map.value + i, &sym))
+ type = tmp.type->map.value[i].data.var.type;
+ else if (! tag_type(tmp.type->map.value + i, &type))
goto ko;
- if (! data_init_copy(sym, (s8 *) tmp.data + tmp.type->offset[i],
+ if (! data_init_copy(type, (s8 *) tmp.data +
+ tmp.type->offset[i],
(s8 *) src->data + tmp.type->offset[i]))
goto ko;
i++;
diff --git a/test/buf_parse_test.c b/test/buf_parse_test.c
index 5feabfc..b642301 100644
--- a/test/buf_parse_test.c
+++ b/test/buf_parse_test.c
@@ -544,6 +544,13 @@
test_context(NULL); \
} while (0)
+#define BUF_PARSE_TEST_STRUCT(test) \
+ do { \
+ test_context("buf_parse_struct(" # test ")"); \
+ buf_init_1(&buf, false, (test)); \
+ TEST_EQ(buf_parse_struct(&buf, &s), strlen(test)); \
+ } while (0)
+
#define BUF_PARSE_TEST_SYM(test, expected) \
do { \
s_buf buf; \
@@ -1278,6 +1285,25 @@ TEST_CASE(buf_parse_str_u8)
}
TEST_CASE_END(buf_parse_str_u8)
+TEST_CASE(buf_parse_struct)
+{
+ s_buf buf;
+ s_struct s = {0};
+ const s_tag *symbol_value;
+ BUF_PARSE_TEST_STRUCT("%KC3.Operator{symbol_value: 1}");
+ TEST_ASSERT((symbol_value =
+ struct_get_tag(&s, sym_1("symbol_value"))));
+ TEST_EQ(symbol_value->type, TAG_U8);
+ struct_clean(&s);
+ BUF_PARSE_TEST_STRUCT("%KC3.Operator{symbol_value: void}");
+ TEST_ASSERT((symbol_value =
+ struct_get_tag(&s, sym_1("symbol_value"))));
+ TEST_EQ(symbol_value->type, TAG_VOID);
+ struct_clean(&s);
+ test_context(NULL);
+}
+TEST_CASE_END(buf_parse_struct)
+
TEST_CASE(buf_parse_sym)
{
BUF_PARSE_TEST_NOT_SYM("0");
diff --git a/test/ikc3/access.out.expected b/test/ikc3/access.out.expected
index 4359092..252f93d 100644
--- a/test/ikc3/access.out.expected
+++ b/test/ikc3/access.out.expected
@@ -44,9 +44,9 @@ map["a"]["b"]
%{"c" => 3}
map["a"]["b"]["c"]
3
-op = %KC3.Operator{}
+op = %KC3.Operator{symbol_value: void}
%KC3.Operator{sym: :+,
- symbol_value: ?,
+ symbol_value: void,
operator_precedence: 0,
operator_associativity: :left}
op.sym
diff --git a/test/ikc3/block.kc3 b/test/ikc3/block.kc3
index f0c90ce..ddd2d89 100644
--- a/test/ikc3/block.kc3
+++ b/test/ikc3/block.kc3
@@ -22,12 +22,12 @@ do
2
3
end
-quote do 1; end
-do 1; end
-quote do 1; 2; end
-do 1; 2; end
-quote do 1; 2; 3; end
-do 1; 2; 3; end
+quote do 1 end
+do 1 end
+quote do 1; 2 end
+do 1; 2 end
+quote do 1; 2; 3 end
+do 1; 2; 3 end
quote do
1 + 1
2 + 2
diff --git a/test/ikc3/to_lisp.kc3 b/test/ikc3/to_lisp.kc3
index cb26aa9..aae2ea6 100644
--- a/test/ikc3/to_lisp.kc3
+++ b/test/ikc3/to_lisp.kc3
@@ -1,2 +1,5 @@
+quote (a = ? <- 1 ; 2)
+quote to_lisp(quote (a = ? <- 1 ; 2))
+to_lisp(quote (a = ? <- 1 ; 2))
quote to_lisp(quote a = ? <- 1 ; 2)
to_lisp(quote a = ? <- 1 ; 2)
diff --git a/test/ikc3/to_lisp.out.expected b/test/ikc3/to_lisp.out.expected
index da1747e..50cc532 100644
--- a/test/ikc3/to_lisp.out.expected
+++ b/test/ikc3/to_lisp.out.expected
@@ -1,2 +1,5 @@
-quote to_lisp(quote a = ? <- 1 ; 2)
-[operator_semicolumn, [operator_equal, a, [operator_assign ?, 1], 2]
+quote (a = ? <- 1 ; 2)
+quote to_lisp(quote (a = ? <- 1 ; 2))
+[operator_paren [operator_semicolumn, [operator_equal, a, [operator_assign ?, 1]], 2]]
+to_lisp(quote a = ? <- 1 ; 2)
+[operator_semicolumn, [operator_equal, a, [operator_assign ?, 1]], 2]
diff --git a/test/inspect_test.c b/test/inspect_test.c
index a05dc9c..fb292e4 100644
--- a/test/inspect_test.c
+++ b/test/inspect_test.c
@@ -148,10 +148,10 @@
assert(test); \
test_context("inspect_struct(" # test ") -> " # expected); \
struct_init_1(&struct_test, (test)); \
- TEST_EQ(buf_inspect_struct_size(&pretty, &struct_test), \
- strlen(expected)); \
TEST_EQ(inspect_struct(&struct_test, &result), &result); \
TEST_STRNCMP(result.ptr.p, (expected), result.size); \
+ TEST_EQ(buf_inspect_struct_size(&pretty, &struct_test), \
+ strlen(expected)); \
str_clean(&result); \
struct_clean(&struct_test); \
test_context(NULL); \
@@ -427,15 +427,20 @@ TEST_CASE_END(inspect_str)
TEST_CASE(inspect_struct)
{
+ INSPECT_TEST_STRUCT("%KC3.Operator{symbol_value: 1}",
+ "%KC3.Operator{sym: :+,\n"
+ " symbol_value: 1,\n"
+ " operator_precedence: (Sw) 0,\n"
+ " operator_associativity: :left}");
INSPECT_TEST_STRUCT("%KC3.Operator{symbol_value: void}",
"%KC3.Operator{sym: :+,\n"
" symbol_value: void,\n"
- " operator_precedence: 0,\n"
+ " operator_precedence: (Sw) 0,\n"
" operator_associativity: :left}");
INSPECT_TEST_STRUCT("%KC3.Operator{sym: :-, symbol_value: void}",
"%KC3.Operator{sym: :-,\n"
" symbol_value: void,\n"
- " operator_precedence: 0,\n"
+ " operator_precedence: (Sw) 0,\n"
" operator_associativity: :left}");
}
TEST_CASE_END(inspect_struct)