diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index 33e8ff4..2226004 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -643,12 +643,12 @@ sw buf_inspect_character_size (const character *c)
sw buf_inspect_f32 (s_buf *buf, const f32 *f)
{
- s64 exp;
+ s32 exp;
u8 i;
u8 j;
sw r;
sw result = 0;
- f64 x;
+ f32 x;
assert(buf);
assert(f);
exp = 0;
@@ -680,7 +680,7 @@ sw buf_inspect_f32 (s_buf *buf, const f32 *f)
if ((r = buf_write_1(buf, ".")) <= 0)
return r;
result += r;
- j = 0;
+ j = 7;
do {
x *= 10;
i = (u8) x;
@@ -689,8 +689,8 @@ sw buf_inspect_f32 (s_buf *buf, const f32 *f)
if ((r = buf_write_u8(buf, i)) <= 0)
return r;
result += r;
- j++;
- } while (x >= 0.000001 && j < 6);
+ j--;
+ } while (x >= pow(0.1, j) && j);
if (exp) {
if ((r = buf_write_1(buf, "e")) <= 0)
return r;
@@ -700,7 +700,7 @@ sw buf_inspect_f32 (s_buf *buf, const f32 *f)
return r;
result += r;
}
- if ((r = buf_inspect_s64(buf, &exp)) <= 0)
+ if ((r = buf_inspect_s32(buf, &exp)) <= 0)
return r;
result += r;
}
@@ -714,6 +714,7 @@ sw buf_inspect_f32_size (const f32 *f)
{
s8 b[32];
s_buf buf;
+ assert(f);
buf_init(&buf, false, sizeof(b), b);
return buf_inspect_f32(&buf, f);
}
@@ -757,7 +758,7 @@ sw buf_inspect_f64 (s_buf *buf, const f64 *f)
if ((r = buf_write_1(buf, ".")) <= 0)
return r;
result += r;
- j = 0;
+ j = 15;
do {
x *= 10;
i = (u8) x;
@@ -766,8 +767,8 @@ sw buf_inspect_f64 (s_buf *buf, const f64 *f)
if ((r = buf_write_u8(buf, i)) <= 0)
return r;
result += r;
- j++;
- } while (x > 0.0000000000001 && j < 14);
+ j--;
+ } while (x > pow(0.1, j) && j);
if (exp) {
if ((r = buf_write_1(buf, "e")) <= 0)
return r;
@@ -788,6 +789,7 @@ sw buf_inspect_f64_size (const f64 *f)
{
s8 b[64];
s_buf buf;
+ assert(f);
buf_init(&buf, false, sizeof(b), b);
return buf_inspect_f64(&buf, f);
}
@@ -1890,6 +1892,89 @@ sw buf_inspect_struct_size (const s_struct *s)
return -1;
}
+sw buf_inspect_struct_type (s_buf *buf, const s_struct_type *st)
+{
+ s_array offset_array;
+ uw offset_array_dimension;
+ sw r;
+ sw result = 0;
+ assert(buf);
+ assert(st);
+ assert(sym_is_module(st->module));
+ assert(st->offset);
+ assert(st->size);
+ if ((r = buf_write_1(buf, "%StructType{module: ")) < 0)
+ return r;
+ result += r;
+ if ((r = buf_inspect_sym(buf, &st->module)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1(buf, ", map: ")) < 0)
+ return r;
+ result += r;
+ if ((r = buf_inspect_map(buf, &st->map)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1(buf, ", offset: ")) < 0)
+ return r;
+ result += r;
+ offset_array_dimension = st->map.count;
+ array_init(&offset_array, sym_1("Uw"), 1, &offset_array_dimension);
+ offset_array.data = st->offset;
+ if ((r = buf_inspect_array(buf, &offset_array)) < 0) {
+ array_clean(&offset_array);
+ return r;
+ }
+ result += r;
+ array_clean(&offset_array);
+ if ((r = buf_write_1(buf, ", size: ")) < 0)
+ return r;
+ result += r;
+ if ((r = buf_inspect_uw(buf, &st->size)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1(buf, "}")) < 0)
+ return r;
+ result += r;
+ return result;
+}
+
+sw buf_inspect_struct_type_size (const s_struct_type *st)
+{
+ s_array offset_array;
+ uw offset_array_dimension;
+ sw r;
+ sw result;
+ assert(st);
+ assert(sym_is_module(st->module));
+ assert(st->offset);
+ assert(st->size);
+ result = strlen("%StructType{module: ");
+ if ((r = buf_inspect_sym_size(&st->module)) < 0)
+ return r;
+ result += r;
+ result += strlen(", map: ");
+ if ((r = buf_inspect_map_size(&st->map)) < 0)
+ return r;
+ result += r;
+ result += strlen(", offset: ");
+ offset_array_dimension = st->map.count;
+ array_init(&offset_array, sym_1("Uw"), 1, &offset_array_dimension);
+ offset_array.data = st->offset;
+ if ((r = buf_inspect_array_size(&offset_array)) < 0) {
+ array_clean(&offset_array);
+ return r;
+ }
+ result += r;
+ array_clean(&offset_array);
+ result += strlen(", size: ");
+ if ((r = buf_inspect_uw_size(&st->size)) < 0)
+ return r;
+ result += r;
+ result += strlen("}");
+ return result;
+}
+
sw buf_inspect_sym (s_buf *buf, const s_sym * const *sym)
{
sw r;
diff --git a/libc3/data.c b/libc3/data.c
index ac8494d..136cb47 100644
--- a/libc3/data.c
+++ b/libc3/data.c
@@ -14,7 +14,7 @@
sw data_buf_inspect (const s_sym *type, s_buf *buf, const void *data)
{
- s_struct_type *st;
+ const s_struct_type *st;
if (type == sym_1("Array"))
return buf_inspect_array(buf, data);
if (type == sym_1("Bool"))
@@ -98,7 +98,7 @@ sw data_buf_inspect (const s_sym *type, s_buf *buf, const void *data)
sw data_buf_inspect_size (const s_sym *type, const void *data)
{
- s_struct_type *st;
+ const s_struct_type *st;
if (type == sym_1("Array"))
return buf_inspect_array_size(data);
if (type == sym_1("Bool"))
@@ -182,7 +182,7 @@ sw data_buf_inspect_size (const s_sym *type, const void *data)
bool data_clean (const s_sym *type, void *data)
{
- s_struct_type *st;
+ const s_struct_type *st;
assert(type);
if (type == sym_1("Array")) {
array_clean(data);
@@ -315,7 +315,7 @@ bool data_clean (const s_sym *type, void *data)
bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
{
- s_struct_type *st;
+ const s_struct_type *st;
if (type == sym_1("Array"))
return hash_update_array(hash, data);
if (type == sym_1("Bool"))
@@ -399,7 +399,7 @@ bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
void * data_init_cast (const s_sym *type, void *data, const s_tag *tag)
{
- s_struct_type *st;
+ const s_struct_type *st;
if (type == sym_1("Array"))
return array_init_cast(data, tag);
if (type == sym_1("Bool"))
@@ -483,7 +483,7 @@ void * data_init_cast (const s_sym *type, void *data, const s_tag *tag)
void * data_init_copy (const s_sym *type, void *data, const void *src)
{
- s_struct_type *st;
+ const s_struct_type *st;
if (type == sym_1("Array"))
return array_init_copy(data, src);
if (type == sym_1("Bool"))
diff --git a/libc3/env.c b/libc3/env.c
index eb802c7..ff2f617 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -1187,10 +1187,12 @@ bool env_struct_type_exists (s_env *env, const s_sym *module)
return result;
}
-s_struct_type * env_struct_type_find (s_env *env, const s_sym *module)
+const s_struct_type * env_struct_type_find (s_env *env,
+ const s_sym *module)
{
- s_facts_cursor cursor;
- s_struct_type *result;
+ s_facts_with_cursor cursor;
+ s_fact *found;
+ const s_struct_type *result;
s_tag tag_struct_type;
s_tag tag_module;
s_tag tag_var;
@@ -1201,24 +1203,25 @@ s_struct_type * env_struct_type_find (s_env *env, const s_sym *module)
tag_init_sym_1(&tag_struct_type, "struct_type");
tag_init_var(&tag_var);
env_module_maybe_reload(env, module, &env->facts);
- facts_with_tags(&env->facts, &cursor, &tag_module,
- &tag_struct_type, &tag_var);
- if (! facts_cursor_next(&cursor)) {
- facts_cursor_clean(&cursor);
+ facts_with(&env->facts, &cursor, (t_facts_spec) {
+ &tag_module, &tag_struct_type, &tag_var, NULL, NULL });
+ found = facts_with_cursor_next(&cursor);
+ if (! found) {
+ facts_with_cursor_clean(&cursor);
return NULL;
}
- if (tag_var.type != TAG_STRUCT_TYPE) {
- tag_type(&tag_var, &type);
+ if (found->object->type != TAG_STRUCT_TYPE) {
+ tag_type(found->object, &type);
err_write_1("env_struct_type_find: module ");
err_inspect_sym(&module);
- err_write_1(": :struct_type is actually a ");
+ err_write_1(" :struct_type is actually a ");
err_inspect_sym(&type);
err_write_1("\n");
assert(! "env_struct_type_find: invalid struct_type");
return NULL;
}
- result = &tag_var.data.struct_type;
- facts_cursor_clean(&cursor);
+ result = &found->object->data.struct_type;
+ facts_with_cursor_clean(&cursor);
return result;
}
diff --git a/libc3/env.h b/libc3/env.h
index 627212f..da6e8f9 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -22,72 +22,73 @@ void env_clean (s_env *env);
s_env * env_init (s_env *env, int argc, s8 **argv);
/* Operators. */
-bool env_eval_array (s_env *env, const s_array *array,
- s_array *dest);
-bool env_eval_array_tag (s_env *env, const s_array *array,
- s_tag *dest);
-bool env_eval_call (s_env *env, const s_call *call,
- s_tag *dest);
-bool env_eval_call_arguments (s_env *env, const s_list *args,
- s_list **dest);
-bool env_eval_call_cfn (s_env *env, const s_call *call,
- s_tag *dest);
-bool env_eval_call_fn (s_env *env, const s_call *call,
+bool env_eval_array (s_env *env, const s_array *array,
+ s_array *dest);
+bool env_eval_array_tag (s_env *env, const s_array *array,
s_tag *dest);
-bool env_eval_call_resolve (s_env *env, s_call *call);
-bool env_eval_equal_list (s_env *env, const s_list *a,
- const s_list *b, s_list **dest);
-bool env_eval_equal_struct (s_env *env, const s_struct *a,
- const s_struct *b,
- s_struct *dest);
-bool env_eval_equal_tag (s_env *env, const s_tag *a,
- const s_tag *b, s_tag *dest);
-bool env_eval_equal_tuple (s_env *env, const s_tuple *a,
- const s_tuple *b, s_tuple *dest);
-bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest);
-bool env_eval_fn_call (s_env *env, const s_fn *fn,
- const s_list *arguments, s_tag *dest);
-bool env_eval_ident (s_env *env, const s_ident *ident,
+bool env_eval_call (s_env *env, const s_call *call,
+ s_tag *dest);
+bool env_eval_call_arguments (s_env *env, const s_list *args,
+ s_list **dest);
+bool env_eval_call_cfn (s_env *env, const s_call *call,
+ s_tag *dest);
+bool env_eval_call_fn (s_env *env, const s_call *call,
s_tag *dest);
-bool env_eval_list (s_env *env, const s_list *list,
- s_tag *dest);
-bool env_eval_map (s_env *env, const s_map *map,
+bool env_eval_call_resolve (s_env *env, s_call *call);
+bool env_eval_equal_list (s_env *env, const s_list *a,
+ const s_list *b, s_list **dest);
+bool env_eval_equal_struct (s_env *env, const s_struct *a,
+ const s_struct *b,
+ s_struct *dest);
+bool env_eval_equal_tag (s_env *env, const s_tag *a,
+ const s_tag *b, s_tag *dest);
+bool env_eval_equal_tuple (s_env *env, const s_tuple *a,
+ const s_tuple *b, s_tuple *dest);
+bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest);
+bool env_eval_fn_call (s_env *env, const s_fn *fn,
+ const s_list *arguments, s_tag *dest);
+bool env_eval_ident (s_env *env, const s_ident *ident,
s_tag *dest);
-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_struct (s_env *env, const s_struct *s,
- s_tag *dest);
-bool env_eval_tag (s_env *env, const s_tag *tag,
+bool env_eval_list (s_env *env, const s_list *list,
+ s_tag *dest);
+bool env_eval_map (s_env *env, const s_map *map,
+ s_tag *dest);
+bool env_eval_progn (s_env *env, const s_list *program,
s_tag *dest);
-bool env_eval_tuple (s_env *env, const s_tuple *tuple,
- s_tag *dest);
-bool env_eval_void (s_env *env, const void *_, s_tag *dest);
-s_list ** env_get_struct_type_spec (s_env *env,
- const s_sym *module,
- s_list **dest);
-bool env_module_load (s_env *env, const s_sym *module,
- s_facts *facts);
-bool env_module_maybe_reload (s_env *env,
- const s_sym *module,
- s_facts *facts);
-s8 env_operator_arity (s_env *env, const s_ident *op);
-bool env_operator_find (s_env *env, const s_ident *op);
-s_ident * env_operator_ident (s_env *env, const s_ident *op,
- s_ident *dest);
-bool env_operator_is_right_associative (s_env *env,
- const s_ident *op);
-s8 env_operator_precedence (s_env *env, const s_ident *op);
-s_ident * env_operator_resolve (s_env *env, const s_ident *op,
- u8 arity, s_ident *dest);
-const s_sym * env_operator_symbol (s_env *env, const s_ident *op);
-bool env_struct_type_exists (s_env *env,
+bool env_eval_quote (s_env *env, const s_quote *quote,
+ s_tag *dest);
+bool env_eval_struct (s_env *env, const s_struct *s,
+ s_tag *dest);
+bool env_eval_tag (s_env *env, const s_tag *tag,
+ s_tag *dest);
+bool env_eval_tuple (s_env *env, const s_tuple *tuple,
+ s_tag *dest);
+bool env_eval_void (s_env *env, const void *_, s_tag *dest);
+s_list ** env_get_struct_type_spec (s_env *env,
+ const s_sym *module,
+ s_list **dest);
+bool env_module_load (s_env *env, const s_sym *module,
+ s_facts *facts);
+bool env_module_maybe_reload (s_env *env,
+ const s_sym *module,
+ s_facts *facts);
+s8 env_operator_arity (s_env *env, const s_ident *op);
+bool env_operator_find (s_env *env, const s_ident *op);
+s_ident * env_operator_ident (s_env *env, const s_ident *op,
+ s_ident *dest);
+bool env_operator_is_right_associative (s_env *env,
+ const s_ident *op);
+s8 env_operator_precedence (s_env *env, const s_ident *op);
+s_ident * env_operator_resolve (s_env *env, const s_ident *op,
+ u8 arity, s_ident *dest);
+const s_sym * env_operator_symbol (s_env *env, const s_ident *op);
+bool env_struct_type_exists (s_env *env,
const s_sym *module);
-s_struct_type * env_struct_type_find (s_env *env, const s_sym *module);
-bool env_tag_ident_is_bound (const s_env *env,
- const s_tag *tag,
- s_facts *facts);
+const s_struct_type *
+ env_struct_type_find (s_env *env, const s_sym *module);
+bool env_tag_ident_is_bound (const s_env *env,
+ const s_tag *tag,
+ s_facts *facts);
/* Control structures. */
void env_error_f (s_env *env, const char *fmt, ...);
diff --git a/libc3/struct_type.c b/libc3/struct_type.c
index 6a907c5..bc315a4 100644
--- a/libc3/struct_type.c
+++ b/libc3/struct_type.c
@@ -43,12 +43,13 @@ bool struct_type_exists (const s_sym *module)
return env_struct_type_exists(&g_c3_env, module);
}
-s_struct_type * struct_type_find (const s_sym *module)
+const s_struct_type * struct_type_find (const s_sym *module)
{
return env_struct_type_find(&g_c3_env, module);
}
-s_struct_type * struct_type_init (s_struct_type *st, const s_sym *module,
+s_struct_type * struct_type_init (s_struct_type *st,
+ const s_sym *module,
const s_list *spec)
{
uw count;
diff --git a/libc3/struct_type.h b/libc3/struct_type.h
index 2510aad..91a566e 100644
--- a/libc3/struct_type.h
+++ b/libc3/struct_type.h
@@ -41,9 +41,9 @@ s_struct_type * struct_type_new (const s_sym *module,
const s_list *spec);
/* Utility functions. */
-bool struct_type_exists (const s_sym *module);
-s_struct_type * struct_type_find (const s_sym *module);
-uw struct_type_padding (uw offset, uw size);
+bool struct_type_exists (const s_sym *module);
+const s_struct_type * struct_type_find (const s_sym *module);
+uw struct_type_padding (uw offset, uw size);
#endif /* LIBC3_STRUCT_TYPE_H */
diff --git a/libc3/types.h b/libc3/types.h
index 659d875..3bbd936 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -320,7 +320,7 @@ struct struct_ {
void *data;
s_tag *tag;
bool free_data;
- s_struct_type *type;
+ const s_struct_type *type;
};
/* 3 */
diff --git a/test/buf_inspect_test.c b/test/buf_inspect_test.c
index ed151d0..59332f8 100644
--- a/test/buf_inspect_test.c
+++ b/test/buf_inspect_test.c
@@ -66,10 +66,11 @@
s_buf buf; \
f32 tmp; \
test_context("buf_inspect_f32(" # test ") -> " # expected); \
- buf_init(&buf, false, sizeof(b), b); \
tmp = (test); \
+ buf_init(&buf, false, sizeof(b), b); \
buf_inspect_f32(&buf, &tmp); \
TEST_STRNCMP(buf.ptr.ps8, (expected), buf.wpos); \
+ TEST_EQ(buf.wpos, strlen(expected)); \
TEST_EQ(buf_inspect_f32_size(&tmp), strlen(expected)); \
buf_init(&buf, false, sizeof(b), b); \
TEST_EQ(buf_inspect_f32(&buf, &tmp), strlen(expected)); \
@@ -82,10 +83,11 @@
s_buf buf; \
f64 tmp; \
test_context("buf_inspect_f64(" # test ") -> " # expected); \
- buf_init(&buf, false, sizeof(b), b); \
tmp = (test); \
+ buf_init(&buf, false, sizeof(b), b); \
buf_inspect_f64(&buf, &tmp); \
TEST_STRNCMP(buf.ptr.ps8, (expected), buf.wpos); \
+ TEST_EQ(buf.wpos, strlen(expected)); \
TEST_EQ(buf_inspect_f64_size(&tmp), strlen(expected)); \
buf_init(&buf, false, sizeof(b), b); \
TEST_EQ(buf_inspect_f64(&buf, &tmp), strlen(expected)); \
@@ -242,7 +244,7 @@ TEST_CASE(buf_inspect_f32)
BUF_INSPECT_TEST_F32(0.1f, "1.0e-1f");
BUF_INSPECT_TEST_F32(0.1234567f, "1.234567e-1f");
BUF_INSPECT_TEST_F32(1.234567f, "1.234567f");
- BUF_INSPECT_TEST_F32(1234567.0f, "1.234566e+6f");
+ BUF_INSPECT_TEST_F32(1234567.0f, "1.234567e+6f");
BUF_INSPECT_TEST_F32(-0.1f, "-0.1f");
BUF_INSPECT_TEST_F32(-0.1234567f, "-1.234567e-1f");
BUF_INSPECT_TEST_F32(-1.234567f, "-1.234567f");