diff --git a/README.md b/README.md
index 4d739f6..0b2e673 100644
--- a/README.md
+++ b/README.md
@@ -175,6 +175,7 @@ Script interpreter. Works the same as ic3 but is not interactive.
- DONE funcall
- DONE boolean operators
- DONE comparison operators
+ - cast
- arrays
- parse
- DONE inspect
diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index d848c31..b75721e 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -246,6 +246,8 @@ sw buf_inspect_call (s_buf *buf, const s_call *call)
sw result = 0;
if (call->ident.sym == sym_1("[]"))
return buf_inspect_call_brackets(buf, call);
+ if (call->ident.sym == sym_1("cast"))
+ return buf_inspect_cast(buf, call);
if (operator_is_unary(&call->ident))
return buf_inspect_call_op_unary(buf, call);
if ((op_precedence = operator_precedence(&call->ident)) > 0)
@@ -461,6 +463,87 @@ sw buf_inspect_call_size (const s_call *call)
return result;
}
+sw buf_inspect_cast (s_buf *buf, const s_call *call)
+{
+ s_tag *arg;
+ const s_sym *module;
+ sw r;
+ sw result = 0;
+ assert(buf);
+ assert(call);
+ assert(call->arguments);
+ assert(! list_next(call->arguments));
+ module = call->ident.module_name;
+ if ((r = buf_inspect_paren_sym(buf, module)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1(buf, " ")) < 0)
+ return r;
+ result += r;
+ arg = &call->arguments->tag;
+ if ((r = buf_inspect_tag(buf, arg)) < 0)
+ return r;
+ result += r;
+ return result;
+}
+
+sw buf_inspect_cast_size (const s_call *call)
+{
+ s_tag *arg;
+ const s_sym *module;
+ sw r;
+ sw result = 0;
+ assert(buf);
+ assert(call);
+ assert(call->arguments);
+ assert(! list_next(call->arguments));
+ module = call->ident.module_name;
+ if ((r = buf_inspect_paren_sym_size(module)) < 0)
+ return r;
+ result += r;
+ result += strlen(" ");
+ arg = &call->arguments->tag;
+ if ((r = buf_inspect_tag_size(arg)) < 0)
+ return r;
+ result += r;
+ return result;
+}
+
+sw buf_inspect_paren_sym (s_buf *buf, const s_sym *sym)
+{
+ sw r;
+ sw result = 0;
+ assert(buf);
+ assert(sym);
+ if ((r = buf_write_1(buf, "(")) <= 0)
+ goto clean;
+ result += r;
+ if ((r = buf_inspect_sym(buf, sym)) <= 0)
+ goto clean;
+ result += r;
+ if ((r = buf_write_1(buf, ")")) <= 0)
+ goto clean;
+ result += r;
+ r = result;
+ clean:
+ return r;
+}
+
+sw buf_inspect_paren_sym_size (const s_sym *sym)
+{
+ sw r;
+ sw result = 0;
+ assert(sym);
+ result += strlen("(");
+ if ((r = buf_inspect_sym_size(sym)) <= 0)
+ goto clean;
+ result += r;
+ result += strlen(")");
+ r = result;
+ clean:
+ return r;
+}
+
sw buf_inspect_cfn (s_buf *buf, const s_cfn *cfn)
{
s_list *arg_type;
diff --git a/libc3/buf_inspect.h b/libc3/buf_inspect.h
index 935c9a1..e91faca 100644
--- a/libc3/buf_inspect.h
+++ b/libc3/buf_inspect.h
@@ -64,6 +64,8 @@ sw buf_inspect_call_op_unary_size (const s_call *call);
sw buf_inspect_call_paren (s_buf *buf, const s_call *call);
sw buf_inspect_call_paren_size (const s_call *call);
sw buf_inspect_call_size (const s_call *call);
+sw buf_inspect_cast (s_buf *buf, const s_call *call);
+sw buf_inspect_cast_size (const s_call *call);
sw buf_inspect_cfn (s_buf *buf, const s_cfn *cfn);
sw buf_inspect_cfn_size (const s_cfn *cfn);
sw buf_inspect_character (s_buf *buf, const character *c);
@@ -93,6 +95,8 @@ sw buf_inspect_integer (s_buf *buf, const s_integer *x);
sw buf_inspect_integer_size (const s_integer *x);
sw buf_inspect_list (s_buf *buf, const s_list *list);
sw buf_inspect_list_size (const s_list *list);
+sw buf_inspect_paren_sym (s_buf *buf, const s_sym *sym);
+sw buf_inspect_paren_sym_size (const s_sym *sym);
sw buf_inspect_ptag (s_buf *buf, p_tag ptag);
sw buf_inspect_ptag_size (p_tag ptag);
sw buf_inspect_quote (s_buf *buf, const s_quote *quote);
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 5964623..91be70f 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -48,26 +48,25 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
sw result = 0;
s_buf_save save;
s_array tmp;
+ const s_sym *type;
assert(buf);
assert(dest);
buf_save_init(buf, &save);
tmp = *dest;
- if ((r = buf_parse_array_type(buf, &tmp)) <= 0)
+ if ((r = buf_parse_paren_sym(buf, &type)) <= 0)
goto clean;
result += r;
+ sym_to_tag_type(type, &tmp.type);
if ((r = buf_ignore_spaces(buf)) < 0)
goto restore;
result += r;
if ((r = buf_peek_array_dimension_count(buf, &tmp)) <= 0) {
- warnx("buf_parse_array: buf_peek_array_dimension_count");
goto restore;
}
if ((r = buf_peek_array_dimensions(buf, &tmp)) <= 0) {
- warnx("buf_parse_array: buf_peek_array_dimensions");
goto restore;
}
if ((r = buf_parse_array_data(buf, &tmp)) < 0) {
- warnx("buf_parse_array: buf_peek_array_data");
goto restore;
}
result += r;
@@ -351,42 +350,6 @@ sw buf_parse_array_dimensions_rec (s_buf *buf, s_array *dest,
return r;
}
-sw buf_parse_array_type (s_buf *buf, s_array *dest)
-{
- sw r;
- sw result = 0;
- s_buf_save save;
- e_tag_type tmp;
- s_ident type_ident;
- buf_save_init(buf, &save);
- if ((r = buf_read_1(buf, "(")) <= 0)
- goto clean;
- result += r;
- if ((r = buf_ignore_spaces(buf)) < 0)
- goto restore;
- result += r;
- if ((r = buf_parse_ident(buf, &type_ident)) <= 0)
- goto restore;
- result += r;
- if (! ident_to_tag_type(&type_ident, &tmp))
- goto restore;
- if ((r = buf_ignore_spaces(buf)) < 0)
- goto restore;
- result += r;
- if ((r = buf_read_1(buf, ")")) <= 0)
- goto restore;
- result += r;
- r = result;
- dest->type = tmp;
- goto clean;
- restore:
- r = 0;
- buf_save_restore_rpos(buf, &save);
- clean:
- buf_save_clean(buf, &save);
- return r;
-}
-
sw buf_parse_bool (s_buf *buf, bool *p)
{
character c;
@@ -806,6 +769,36 @@ sw buf_parse_call_paren (s_buf *buf, s_call *dest)
return r;
}
+sw buf_parse_cast (s_buf *buf, s_call *dest)
+{
+ const s_sym *module = NULL;
+ sw r;
+ sw result = 0;
+ s_buf_save save;
+ s_call tmp;
+ buf_save_init(buf, &save);
+ if ((r = buf_parse_paren_sym(buf, &module)) <= 0)
+ goto clean;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
+ call_init_op_unary(&tmp);
+ ident_init(&tmp.ident, module, sym_1("cast"));
+ if ((r = buf_parse_tag(buf, &tmp.arguments->tag)) <= 0)
+ goto clean;
+ result += r;
+ *dest = tmp;
+ r = result;
+ goto clean;
+ restore:
+ call_clean(&tmp);
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return r;
+}
+
sw buf_parse_cfn (s_buf *buf, s_cfn *dest)
{
s_list *arg_types = NULL;
@@ -1756,6 +1749,39 @@ sw buf_parse_new_tag (s_buf *buf, s_tag **dest)
return r;
}
+sw buf_parse_paren_sym (s_buf *buf, const s_sym **dest)
+{
+ sw r;
+ sw result = 0;
+ s_buf_save save;
+ const s_sym *tmp;
+ buf_save_init(buf, &save);
+ if ((r = buf_read_1(buf, "(")) <= 0)
+ goto clean;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_parse_sym(buf, &tmp)) <= 0)
+ goto restore;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_read_1(buf, ")")) <= 0)
+ goto restore;
+ result += r;
+ r = result;
+ *dest = tmp;
+ goto clean;
+ restore:
+ r = 0;
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return r;
+}
+
sw buf_parse_ptag (s_buf *buf, p_tag *ptag)
{
(void) buf;
@@ -2164,6 +2190,16 @@ sw buf_parse_tag_call_op_unary (s_buf *buf, s_tag *dest)
return r;
}
+sw buf_parse_tag_cast (s_buf *buf, s_tag *dest)
+{
+ sw r;
+ assert(buf);
+ assert(dest);
+ if ((r = buf_parse_cast(buf, &dest->data.call)) > 0)
+ dest->type = TAG_CALL;
+ return r;
+}
+
sw buf_parse_tag_cfn (s_buf *buf, s_tag *dest)
{
sw r;
@@ -2245,6 +2281,7 @@ sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
goto end;
}
if ((r = buf_parse_tag_array(buf, dest)) != 0 ||
+ (r = buf_parse_tag_cast(buf, dest)) != 0 ||
(r = buf_parse_tag_call(buf, dest)) != 0 ||
(r = buf_parse_tag_call_paren(buf, dest)) != 0 ||
(r = buf_parse_tag_call_op_unary(buf, dest)) != 0 ||
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index 92bd99b..3f82916 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -45,7 +45,6 @@ sw buf_parse_array (s_buf *buf, s_array *dest);
sw buf_parse_array_data (s_buf *buf, s_array *dest);
sw buf_parse_array_dimension_count (s_buf *buf, s_array *dest);
sw buf_parse_array_dimensions (s_buf *buf, s_array *dest);
-sw buf_parse_array_type (s_buf *buf, s_array *dest);
sw buf_parse_bool (s_buf *buf, bool *dest);
sw buf_parse_brackets (s_buf *buf, s_call *dest);
sw buf_parse_call (s_buf *buf, s_call *dest);
@@ -54,6 +53,7 @@ sw buf_parse_call_op (s_buf *buf, s_call *dest);
sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence);
sw buf_parse_call_op_unary (s_buf *buf, s_call *dest);
sw buf_parse_call_paren (s_buf *buf, s_call *dest);
+sw buf_parse_cast (s_buf *buf, s_call *dest);
sw buf_parse_cfn (s_buf *buf, s_cfn *dest);
sw buf_parse_character (s_buf *buf, character *dest);
sw buf_parse_comments (s_buf *buf);
@@ -80,6 +80,7 @@ sw buf_parse_integer (s_buf *buf, s_integer *dest);
sw buf_parse_list (s_buf *buf, s_list **dest);
sw buf_parse_module_name (s_buf *buf, const s_sym **dest);
sw buf_parse_new_tag (s_buf *buf, s_tag **dest);
+sw buf_parse_paren_sym (s_buf *buf, const s_sym **dest);
sw buf_parse_ptag (s_buf *buf, p_tag *dest);
sw buf_parse_quote (s_buf *buf, s_quote *dest);
sw buf_parse_str (s_buf *buf, s_str *dest);
diff --git a/libc3/module.h b/libc3/module.h
index b20af17..adaeed1 100644
--- a/libc3/module.h
+++ b/libc3/module.h
@@ -23,17 +23,17 @@
#include "types.h"
/* Modifiers */
-bool module_ensure_loaded (const s_sym *name, s_facts *facts);
-bool module_load (const s_sym *name, s_facts *facts);
-bool module_maybe_reload (const s_sym *name, s_facts *facts);
+bool module_ensure_loaded (const s_sym *name, s_facts *facts);
+bool module_load (const s_sym *name, s_facts *facts);
+bool module_maybe_reload (const s_sym *name, s_facts *facts);
/* Observers */
-s_tag * module_load_time (const s_sym *name, s_facts *facts,
- s_tag *dest);
-s_str * module_name_path (const s_str *prefix, const s_sym *name,
- s_str *dest);
-sw module_name_path_size (const s_str *prefix,
- const s_sym *name);
-
+s_tag * module_load_time (const s_sym *name, s_facts *facts,
+ s_tag *dest);
+s_str * module_name_path (const s_str *prefix, const s_sym *name,
+ s_str *dest);
+sw module_name_path_size (const s_str *prefix,
+ const s_sym *name);
+const s_sym * module_to_sym (const s_sym *module);
#endif /* MODULE_H */
diff --git a/libc3/tag.c b/libc3/tag.c
index c1210b5..51f10c6 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -3948,7 +3948,7 @@ sw tag_type_size (e_tag_type type)
return sizeof(s_tag);
}
assert(! "tag_type_size: invalid tag type");
- err(1, "tag_type_size: invalid tag type");
+ errx(1, "tag_type_size: invalid tag type");
return -1;
}
@@ -4218,6 +4218,44 @@ ffi_type * tag_type_to_ffi_type (e_tag_type type)
return &ffi_type_void;
}
+const s_sym * tag_type_to_module (e_tag_type tag_type)
+{
+ switch (tag_type) {
+ case TAG_VOID: return sym_1("Void");
+ case TAG_ARRAY: return sym_1("Array");
+ case TAG_BOOL: return sym_1("Bool");
+ case TAG_CALL: return sym_1("Call");
+ case TAG_CFN: return sym_1("Cfn");
+ case TAG_CHARACTER: return sym_1("Character");
+ case TAG_F32: return sym_1("F32");
+ case TAG_F64: return sym_1("F64");
+ case TAG_FACT: return sym_1("Fact");
+ case TAG_FN: return sym_1("Fn");
+ case TAG_IDENT: return sym_1("Ident");
+ case TAG_INTEGER: return sym_1("Integer");
+ case TAG_SW: return sym_1("Sw");
+ case TAG_S64: return sym_1("S64");
+ case TAG_S32: return sym_1("S32");
+ case TAG_S16: return sym_1("S16");
+ case TAG_S8: return sym_1("S8");
+ case TAG_U8: return sym_1("U8");
+ case TAG_U16: return sym_1("U16");
+ case TAG_U32: return sym_1("U32");
+ case TAG_U64: return sym_1("U64");
+ case TAG_UW: return sym_1("Uw");
+ case TAG_LIST: return sym_1("List");
+ case TAG_PTAG: return sym_1("Ptag");
+ case TAG_QUOTE: return sym_1("Quote");
+ case TAG_STR: return sym_1("Str");
+ case TAG_SYM: return sym_1("Sym");
+ case TAG_TUPLE: return sym_1("Tuple");
+ case TAG_VAR: return sym_1("Var");
+ }
+ assert(! "tag_type_to_module: invalid tag type");
+ errx(1, "tag_type_to_module: invalid tag type: %d", tag_type);
+ return NULL;
+}
+
s8 * tag_type_to_string (e_tag_type type)
{
switch (type) {
diff --git a/libc3/tag.h b/libc3/tag.h
index 2aafb86..8e127e5 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -115,6 +115,7 @@ sw tag_type_size (e_tag_type type);
f_buf_inspect tag_type_to_buf_inspect (e_tag_type type);
f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type);
f_buf_parse tag_type_to_buf_parse (e_tag_type type);
+const s_sym * tag_type_to_module (e_tag_type type);
s8 * tag_type_to_string (e_tag_type type);
const s_sym * tag_type_to_sym (e_tag_type tag_type);
diff --git a/test/ic3/array.in b/test/ic3/array.in
index 5ffa445..83eddcb 100644
--- a/test/ic3/array.in
+++ b/test/ic3/array.in
@@ -1,12 +1,12 @@
-(u8) {0, 1}
-a = (u8) {0, 1}
+(U8) {0, 1}
+a = (U8) {0, 1}
quote a[0]
quote a[1]
a[0]
a[1]
-(u8) {{0, 1},
+(U8) {{0, 1},
{2, 3}}
-b = (u8) {{0, 1},
+b = (U8) {{0, 1},
{2, 3}}
quote b[0][0]
quote b[0][1]
@@ -16,7 +16,7 @@ b[0][0]
b[0][1]
b[1][0]
b[1][1]
-c = (u8) {{{0, 1},
+c = (U8) {{{0, 1},
{2, 3}},
{{4, 5},
{6, 7}}}
@@ -36,7 +36,7 @@ c[1][0][0]
c[1][0][1]
c[1][1][0]
c[1][1][1]
-d = (u8) {{{{0, 1},
+d = (U8) {{{{0, 1},
{2, 3}},
{{4, 5},
{6, 7}}},
diff --git a/test/ic3/cast.in b/test/ic3/cast.in
new file mode 100644
index 0000000..ad06b8e
--- /dev/null
+++ b/test/ic3/cast.in
@@ -0,0 +1,2 @@
+quote (U8) 256
+quote (U16) 65536
diff --git a/test/ic3/cast.out.expected b/test/ic3/cast.out.expected
new file mode 100644
index 0000000..6944714
--- /dev/null
+++ b/test/ic3/cast.out.expected
@@ -0,0 +1,2 @@
+(U8) 256
+(U16) 65536
diff --git a/test/ic3/cast.ret.expected b/test/ic3/cast.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ic3/cast.ret.expected
@@ -0,0 +1 @@
+0