diff --git a/.ic3_history b/.ic3_history
index 1ad0184..f69c6e6 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,20 +1,3 @@
-%{a: a} = %{a: 1, b: 2, c: 3}
-a
-1 + 10000000000000000000000000000000000
-a = 1 + 10000000000000000000000000000000000
-a / 2
-a << 3
-a << 4
-(U8) { 1, 2, 3, 256, 257, 258 }
-a = (U8) { 1, 2, 3, 256, 257, 258 }
-a[0]
-a[1]
-a[2]
-a[10]
-a[-10]
-a[0]
-Map.map
-Map.map(%{a: 1, b: 2, c: 3}, fn (k, v) { [v | k] })
Map.map(%{a: 1, b: 2, c: 3}, fn (k, v) { {k, v} })
to_list = fn (map = %{}) { Map.map(map, fn (k, v) { {k, v} })
to_list(%{a: 1, b: b})
@@ -38,3 +21,79 @@ make
a = (U8) {0, 1}
a[0]
a[1]
+0.0
+123+123
+123 + 123
+123.123
+123.123f
+123
+123.123
+123.123f
+123.0
+123.123
+123.0
+123.123f
+123.0f
+123f
+1.0
+1.0f
+1.0
+1.0f
+1.00f
+1.001f
+1.0010f
+1.00010f
+1.000010f
+1.0000010f
+1.00000010f
+1.00000001f
+2.0000001f
+2.0000002f
+2.0000001f
+2.123456789
+2.66666666666666666666f
+1.0
+1.0f
+2.0
+2.123
+1.1
+1.1f
+type(1.1)
+type(1.1f)
+type(11/10)
+type(1)
+type(1 + 1)
+type(2)
+1 + 1
+123.123
+(3)
+type(3)
+type(2)
+type(1 + 2)
+type(quote 1 + 2)
+123.123
+123.1230
+123.123000001
+123.12300000001
+123.123000000001
+123.1230000000001
+123.123
+0.0f
+0.0
+0.0f
+123.123
+1.2312299999999998e+2
+1.231229999996e+2
+1.231229999999996e+2
+1.2312299999999996e+2
+1.2312299999999999e+2
+1.23123e+2
+123.123
+1.231229999999999e+2
+1.231229999999998e+2
+1.231229999999997e+2
+1.231229999999996e+2
+1.231229999999995e+2
+123.123
+1234567.0f
+1.234f
diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index b03fb82..33e8ff4 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -11,6 +11,8 @@
* THIS SOFTWARE.
*/
#include "assert.h"
+#include <float.h>
+#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "../libtommath/tommath.h"
@@ -641,12 +643,76 @@ sw buf_inspect_character_size (const character *c)
sw buf_inspect_f32 (s_buf *buf, const f32 *f)
{
- return buf_f(buf, "%g", *f);
+ s64 exp;
+ u8 i;
+ u8 j;
+ sw r;
+ sw result = 0;
+ f64 x;
+ assert(buf);
+ assert(f);
+ exp = 0;
+ x = *f;
+ if (x == 0.0)
+ return buf_write_1(buf, "0.0f");
+ if (x < 0) {
+ if ((r = buf_write_1(buf, "-")) <= 0)
+ return r;
+ result += r;
+ x = -x;
+ }
+ if (x >= 1.0)
+ while (x >= 10.0) {
+ x /= 10.0;
+ exp++;
+ }
+ else
+ while (x < 1.0) {
+ x *= 10.0;
+ exp--;
+ }
+ i = (u8) x;
+ x -= i;
+ i += '0';
+ if ((r = buf_write_u8(buf, i)) <= 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1(buf, ".")) <= 0)
+ return r;
+ result += r;
+ j = 0;
+ do {
+ x *= 10;
+ i = (u8) x;
+ x -= i;
+ i += '0';
+ if ((r = buf_write_u8(buf, i)) <= 0)
+ return r;
+ result += r;
+ j++;
+ } while (x >= 0.000001 && j < 6);
+ if (exp) {
+ if ((r = buf_write_1(buf, "e")) <= 0)
+ return r;
+ result += r;
+ if (exp > 0) {
+ if ((r = buf_write_1(buf, "+") <= 0))
+ return r;
+ result += r;
+ }
+ if ((r = buf_inspect_s64(buf, &exp)) <= 0)
+ return r;
+ result += r;
+ }
+ if ((r = buf_write_1(buf, "f")) <= 0)
+ return r;
+ result += r;
+ return result;
}
sw buf_inspect_f32_size (const f32 *f)
{
- s8 b[16];
+ s8 b[32];
s_buf buf;
buf_init(&buf, false, sizeof(b), b);
return buf_inspect_f32(&buf, f);
@@ -654,12 +720,73 @@ sw buf_inspect_f32_size (const f32 *f)
sw buf_inspect_f64 (s_buf *buf, const f64 *f)
{
- return buf_f(buf, "%g", *f);
+ s64 exp;
+ u8 i;
+ u8 j;
+ sw r;
+ sw result = 0;
+ f64 x;
+ assert(buf);
+ assert(f);
+ exp = 0.0;
+ x = *f;
+ if (x == 0.0)
+ return buf_write_1(buf, "0.0");
+ if (x < 0) {
+ if ((r = buf_write_1(buf, "-")) <= 0)
+ return r;
+ result += r;
+ x = -x;
+ }
+ if (x >= 1.0)
+ while (x >= 10.0) {
+ x /= 10.0;
+ exp++;
+ }
+ else
+ while (x < 1.0) {
+ x *= 10.0;
+ exp--;
+ }
+ i = (u8) x;
+ x -= i;
+ i += '0';
+ if ((r = buf_write_u8(buf, i)) <= 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1(buf, ".")) <= 0)
+ return r;
+ result += r;
+ j = 0;
+ do {
+ x *= 10;
+ i = (u8) x;
+ x -= i;
+ i += '0';
+ if ((r = buf_write_u8(buf, i)) <= 0)
+ return r;
+ result += r;
+ j++;
+ } while (x > 0.0000000000001 && j < 14);
+ if (exp) {
+ if ((r = buf_write_1(buf, "e")) <= 0)
+ return r;
+ result += r;
+ if (exp > 0) {
+ if ((r = buf_write_1(buf, "+") <= 0))
+ return r;
+ result += r;
+ }
+ if ((r = buf_inspect_s64(buf, &exp)) <= 0)
+ return r;
+ result += r;
+ }
+ return result;
}
sw buf_inspect_f64_size (const f64 *f)
{
- s8 b[16];
+ s8 b[64];
s_buf buf;
buf_init(&buf, false, sizeof(b), b);
return buf_inspect_f64(&buf, f);
@@ -1936,7 +2063,6 @@ sw buf_inspect_tag_type (s_buf *buf, e_tag_type type)
sw buf_inspect_tag_type_size (e_tag_type type)
{
const s8 *s;
- assert(buf);
s = tag_type_to_string(type);
if (! s)
return -1;
diff --git a/libc3/buf_inspect.h b/libc3/buf_inspect.h
index 199167c..4328d1a 100644
--- a/libc3/buf_inspect.h
+++ b/libc3/buf_inspect.h
@@ -36,13 +36,17 @@
#define BUF_INSPECT_U_BASE_PROTOTYPES(bits, base) \
sw buf_inspect_u ## bits ## _ ## base (s_buf *buf, \
const u ## bits *s); \
+ sw buf_inspect_u ## bits ## _ ## base ## _digits (const u##bits *s); \
sw buf_inspect_u ## bits ## _ ## base ## _size (const u ## bits *s)
#define BUF_INSPECT_U_PROTOTYPES(bits) \
sw buf_inspect_u ## bits (s_buf *buf, const u ## bits *u); \
+ sw buf_inspect_u ## bits ## _digits (const u ## bits *u); \
sw buf_inspect_u ## bits ## _size (const u ## bits *u); \
sw buf_inspect_u ## bits ## _base (s_buf *buf, const s_str *base, \
const u ## bits *u); \
+ sw buf_inspect_u ## bits ## _base_digits (const s_str *base, \
+ const u ## bits *u); \
sw buf_inspect_u ## bits ## _base_size (const s_str *base, \
const u ## bits *u); \
BUF_INSPECT_U_BASE_PROTOTYPES(bits, binary); \
diff --git a/libc3/buf_inspect_u.c.in b/libc3/buf_inspect_u.c.in
index bbf9bfc..a298580 100644
--- a/libc3/buf_inspect_u.c.in
+++ b/libc3/buf_inspect_u.c.in
@@ -30,6 +30,7 @@ sw buf_inspect_u_bits$_base (s_buf *buf,
u8 digit;
sw i;
sw r;
+ sw result = 0;
uw radix;
s_buf_save save;
sw size;
@@ -41,7 +42,7 @@ sw buf_inspect_u_bits$_base (s_buf *buf,
return -1;
return buf_write_character_utf8(buf, zero);
}
- size = buf_inspect_u_bits$_base_size(base, u);
+ size = buf_inspect_u_bits$_base_digits(base, u);
c = calloc(size, sizeof(character));
buf_save_init(buf, &save);
radix = base->size;
@@ -55,10 +56,12 @@ sw buf_inspect_u_bits$_base (s_buf *buf,
}
i++;
}
- while (i--)
+ while (i--) {
if ((r = buf_write_character_utf8(buf, c[i])) < 0)
goto restore;
- r = size;
+ result += r;
+ }
+ r = result;
goto clean;
restore:
buf_save_restore_wpos(buf, &save);
@@ -68,8 +71,8 @@ sw buf_inspect_u_bits$_base (s_buf *buf,
return r;
}
-sw buf_inspect_u_bits$_base_size (const s_str *base,
- const u_bits$ *u)
+sw buf_inspect_u_bits$_base_digits (const s_str *base,
+ const u_bits$ *u)
{
uw radix;
sw size = 0;
@@ -85,6 +88,28 @@ sw buf_inspect_u_bits$_base_size (const s_str *base,
return size;
}
+sw buf_inspect_u_bits$_base_size (const s_str *base,
+ const u_bits$ *u)
+{
+ character c;
+ uw digit;
+ uw radix;
+ sw result = 0;
+ u_bits$ u_;
+ u_ = *u;
+ if (u_ == 0)
+ return 1;
+ radix = base->size;
+ while (u_ > 0) {
+ digit = u_ % radix;
+ u_ /= radix;
+ if (str_character(base, digit, &c) < 0)
+ return -1;
+ result += buf_inspect_str_character_size(&c);
+ }
+ return result;
+}
+
sw buf_inspect_u_bits$_size (const u_bits$ *u)
{
return buf_inspect_u_bits$_base_size(&g_c3_base_decimal, u);
diff --git a/libc3/buf_inspect_u16.c b/libc3/buf_inspect_u16.c
index 6045307..ab19326 100644
--- a/libc3/buf_inspect_u16.c
+++ b/libc3/buf_inspect_u16.c
@@ -30,6 +30,7 @@ sw buf_inspect_u16_base (s_buf *buf,
u8 digit;
sw i;
sw r;
+ sw result = 0;
uw radix;
s_buf_save save;
sw size;
@@ -41,7 +42,7 @@ sw buf_inspect_u16_base (s_buf *buf,
return -1;
return buf_write_character_utf8(buf, zero);
}
- size = buf_inspect_u16_base_size(base, u);
+ size = buf_inspect_u16_base_digits(base, u);
c = calloc(size, sizeof(character));
buf_save_init(buf, &save);
radix = base->size;
@@ -55,10 +56,12 @@ sw buf_inspect_u16_base (s_buf *buf,
}
i++;
}
- while (i--)
+ while (i--) {
if ((r = buf_write_character_utf8(buf, c[i])) < 0)
goto restore;
- r = size;
+ result += r;
+ }
+ r = result;
goto clean;
restore:
buf_save_restore_wpos(buf, &save);
@@ -68,8 +71,8 @@ sw buf_inspect_u16_base (s_buf *buf,
return r;
}
-sw buf_inspect_u16_base_size (const s_str *base,
- const u16 *u)
+sw buf_inspect_u16_base_digits (const s_str *base,
+ const u16 *u)
{
uw radix;
sw size = 0;
@@ -85,6 +88,28 @@ sw buf_inspect_u16_base_size (const s_str *base,
return size;
}
+sw buf_inspect_u16_base_size (const s_str *base,
+ const u16 *u)
+{
+ character c;
+ uw digit;
+ uw radix;
+ sw result = 0;
+ u16 u_;
+ u_ = *u;
+ if (u_ == 0)
+ return 1;
+ radix = base->size;
+ while (u_ > 0) {
+ digit = u_ % radix;
+ u_ /= radix;
+ if (str_character(base, digit, &c) < 0)
+ return -1;
+ result += buf_inspect_str_character_size(&c);
+ }
+ return result;
+}
+
sw buf_inspect_u16_size (const u16 *u)
{
return buf_inspect_u16_base_size(&g_c3_base_decimal, u);
diff --git a/libc3/buf_inspect_u32.c b/libc3/buf_inspect_u32.c
index 52184d3..dc46a90 100644
--- a/libc3/buf_inspect_u32.c
+++ b/libc3/buf_inspect_u32.c
@@ -30,6 +30,7 @@ sw buf_inspect_u32_base (s_buf *buf,
u8 digit;
sw i;
sw r;
+ sw result = 0;
uw radix;
s_buf_save save;
sw size;
@@ -41,7 +42,7 @@ sw buf_inspect_u32_base (s_buf *buf,
return -1;
return buf_write_character_utf8(buf, zero);
}
- size = buf_inspect_u32_base_size(base, u);
+ size = buf_inspect_u32_base_digits(base, u);
c = calloc(size, sizeof(character));
buf_save_init(buf, &save);
radix = base->size;
@@ -55,10 +56,12 @@ sw buf_inspect_u32_base (s_buf *buf,
}
i++;
}
- while (i--)
+ while (i--) {
if ((r = buf_write_character_utf8(buf, c[i])) < 0)
goto restore;
- r = size;
+ result += r;
+ }
+ r = result;
goto clean;
restore:
buf_save_restore_wpos(buf, &save);
@@ -68,8 +71,8 @@ sw buf_inspect_u32_base (s_buf *buf,
return r;
}
-sw buf_inspect_u32_base_size (const s_str *base,
- const u32 *u)
+sw buf_inspect_u32_base_digits (const s_str *base,
+ const u32 *u)
{
uw radix;
sw size = 0;
@@ -85,6 +88,28 @@ sw buf_inspect_u32_base_size (const s_str *base,
return size;
}
+sw buf_inspect_u32_base_size (const s_str *base,
+ const u32 *u)
+{
+ character c;
+ uw digit;
+ uw radix;
+ sw result = 0;
+ u32 u_;
+ u_ = *u;
+ if (u_ == 0)
+ return 1;
+ radix = base->size;
+ while (u_ > 0) {
+ digit = u_ % radix;
+ u_ /= radix;
+ if (str_character(base, digit, &c) < 0)
+ return -1;
+ result += buf_inspect_str_character_size(&c);
+ }
+ return result;
+}
+
sw buf_inspect_u32_size (const u32 *u)
{
return buf_inspect_u32_base_size(&g_c3_base_decimal, u);
diff --git a/libc3/buf_inspect_u64.c b/libc3/buf_inspect_u64.c
index b26b681..8a4b2fd 100644
--- a/libc3/buf_inspect_u64.c
+++ b/libc3/buf_inspect_u64.c
@@ -30,6 +30,7 @@ sw buf_inspect_u64_base (s_buf *buf,
u8 digit;
sw i;
sw r;
+ sw result = 0;
uw radix;
s_buf_save save;
sw size;
@@ -41,7 +42,7 @@ sw buf_inspect_u64_base (s_buf *buf,
return -1;
return buf_write_character_utf8(buf, zero);
}
- size = buf_inspect_u64_base_size(base, u);
+ size = buf_inspect_u64_base_digits(base, u);
c = calloc(size, sizeof(character));
buf_save_init(buf, &save);
radix = base->size;
@@ -55,10 +56,12 @@ sw buf_inspect_u64_base (s_buf *buf,
}
i++;
}
- while (i--)
+ while (i--) {
if ((r = buf_write_character_utf8(buf, c[i])) < 0)
goto restore;
- r = size;
+ result += r;
+ }
+ r = result;
goto clean;
restore:
buf_save_restore_wpos(buf, &save);
@@ -68,8 +71,8 @@ sw buf_inspect_u64_base (s_buf *buf,
return r;
}
-sw buf_inspect_u64_base_size (const s_str *base,
- const u64 *u)
+sw buf_inspect_u64_base_digits (const s_str *base,
+ const u64 *u)
{
uw radix;
sw size = 0;
@@ -85,6 +88,28 @@ sw buf_inspect_u64_base_size (const s_str *base,
return size;
}
+sw buf_inspect_u64_base_size (const s_str *base,
+ const u64 *u)
+{
+ character c;
+ uw digit;
+ uw radix;
+ sw result = 0;
+ u64 u_;
+ u_ = *u;
+ if (u_ == 0)
+ return 1;
+ radix = base->size;
+ while (u_ > 0) {
+ digit = u_ % radix;
+ u_ /= radix;
+ if (str_character(base, digit, &c) < 0)
+ return -1;
+ result += buf_inspect_str_character_size(&c);
+ }
+ return result;
+}
+
sw buf_inspect_u64_size (const u64 *u)
{
return buf_inspect_u64_base_size(&g_c3_base_decimal, u);
diff --git a/libc3/buf_inspect_u8.c b/libc3/buf_inspect_u8.c
index a78da62..18b8f76 100644
--- a/libc3/buf_inspect_u8.c
+++ b/libc3/buf_inspect_u8.c
@@ -30,6 +30,7 @@ sw buf_inspect_u8_base (s_buf *buf,
u8 digit;
sw i;
sw r;
+ sw result = 0;
uw radix;
s_buf_save save;
sw size;
@@ -41,7 +42,7 @@ sw buf_inspect_u8_base (s_buf *buf,
return -1;
return buf_write_character_utf8(buf, zero);
}
- size = buf_inspect_u8_base_size(base, u);
+ size = buf_inspect_u8_base_digits(base, u);
c = calloc(size, sizeof(character));
buf_save_init(buf, &save);
radix = base->size;
@@ -55,10 +56,12 @@ sw buf_inspect_u8_base (s_buf *buf,
}
i++;
}
- while (i--)
+ while (i--) {
if ((r = buf_write_character_utf8(buf, c[i])) < 0)
goto restore;
- r = size;
+ result += r;
+ }
+ r = result;
goto clean;
restore:
buf_save_restore_wpos(buf, &save);
@@ -68,8 +71,8 @@ sw buf_inspect_u8_base (s_buf *buf,
return r;
}
-sw buf_inspect_u8_base_size (const s_str *base,
- const u8 *u)
+sw buf_inspect_u8_base_digits (const s_str *base,
+ const u8 *u)
{
uw radix;
sw size = 0;
@@ -85,6 +88,28 @@ sw buf_inspect_u8_base_size (const s_str *base,
return size;
}
+sw buf_inspect_u8_base_size (const s_str *base,
+ const u8 *u)
+{
+ character c;
+ uw digit;
+ uw radix;
+ sw result = 0;
+ u8 u_;
+ u_ = *u;
+ if (u_ == 0)
+ return 1;
+ radix = base->size;
+ while (u_ > 0) {
+ digit = u_ % radix;
+ u_ /= radix;
+ if (str_character(base, digit, &c) < 0)
+ return -1;
+ result += buf_inspect_str_character_size(&c);
+ }
+ return result;
+}
+
sw buf_inspect_u8_size (const u8 *u)
{
return buf_inspect_u8_base_size(&g_c3_base_decimal, u);
diff --git a/libc3/buf_inspect_uw.c b/libc3/buf_inspect_uw.c
index 586fa71..d1e8466 100644
--- a/libc3/buf_inspect_uw.c
+++ b/libc3/buf_inspect_uw.c
@@ -30,6 +30,7 @@ sw buf_inspect_uw_base (s_buf *buf,
u8 digit;
sw i;
sw r;
+ sw result = 0;
uw radix;
s_buf_save save;
sw size;
@@ -41,7 +42,7 @@ sw buf_inspect_uw_base (s_buf *buf,
return -1;
return buf_write_character_utf8(buf, zero);
}
- size = buf_inspect_uw_base_size(base, u);
+ size = buf_inspect_uw_base_digits(base, u);
c = calloc(size, sizeof(character));
buf_save_init(buf, &save);
radix = base->size;
@@ -55,10 +56,12 @@ sw buf_inspect_uw_base (s_buf *buf,
}
i++;
}
- while (i--)
+ while (i--) {
if ((r = buf_write_character_utf8(buf, c[i])) < 0)
goto restore;
- r = size;
+ result += r;
+ }
+ r = result;
goto clean;
restore:
buf_save_restore_wpos(buf, &save);
@@ -68,8 +71,8 @@ sw buf_inspect_uw_base (s_buf *buf,
return r;
}
-sw buf_inspect_uw_base_size (const s_str *base,
- const uw *u)
+sw buf_inspect_uw_base_digits (const s_str *base,
+ const uw *u)
{
uw radix;
sw size = 0;
@@ -85,6 +88,28 @@ sw buf_inspect_uw_base_size (const s_str *base,
return size;
}
+sw buf_inspect_uw_base_size (const s_str *base,
+ const uw *u)
+{
+ character c;
+ uw digit;
+ uw radix;
+ sw result = 0;
+ uw u_;
+ u_ = *u;
+ if (u_ == 0)
+ return 1;
+ radix = base->size;
+ while (u_ > 0) {
+ digit = u_ % radix;
+ u_ /= radix;
+ if (str_character(base, digit, &c) < 0)
+ return -1;
+ result += buf_inspect_str_character_size(&c);
+ }
+ return result;
+}
+
sw buf_inspect_uw_size (const uw *u)
{
return buf_inspect_uw_base_size(&g_c3_base_decimal, u);
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 8f9eb5b..b12b10c 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -1114,6 +1114,133 @@ sw buf_parse_digit_dec (s_buf *buf, u8 *dest)
return r;
}
+sw buf_parse_f32 (s_buf *buf, f32 *dest)
+{
+ character c;
+ u8 digit;
+ f64 exp = 0;
+ f64 exp_sign = 1;
+ uw i;
+ sw r;
+ sw result = 0;
+ s_buf_save save;
+ f64 tmp;
+ assert(buf);
+ assert(dest);
+ buf_save_init(buf, &save);
+ if ((r = buf_parse_digit_dec(buf, &digit)) <= 0)
+ goto restore;
+ tmp = digit;
+ result += r;
+ while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
+ tmp = tmp * 10 + digit;
+ result += r;
+ }
+ if (r < 0 ||
+ (r = buf_read_1(buf, ".")) <= 0)
+ goto restore;
+ result += r;
+ i = 10;
+ while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
+ tmp += (f64) digit / i;
+ i *= 10;
+ result += r;
+ }
+ if ((r = buf_read_1(buf, "e")) > 0) {
+ result += r;
+ if ((r = buf_read_1(buf, "-")) > 0) {
+ exp_sign = -1;
+ result += r;
+ }
+ else if ((r = buf_read_1(buf, "+")) > 0) {
+ result += r;
+ }
+ while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
+ exp = exp * 10 + digit;
+ result += r;
+ }
+ tmp *= pow(10, exp_sign * exp);
+ }
+ if ((r = buf_read_1(buf, "f")) <= 0)
+ goto restore;
+ result += r;
+ if ((r = buf_peek_character_utf8(buf, &c)) > 0 &&
+ ! sym_character_is_reserved(c)) {
+ r = 0;
+ goto restore;
+ }
+ *dest = (f32) tmp;
+ r = result;
+ goto clean;
+ restore:
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return r;
+}
+
+sw buf_parse_f64 (s_buf *buf, f64 *dest) {
+ sw r;
+ sw result = 0;
+ u8 digit;
+ s_buf_save save;
+ f64 tmp = 0;
+ s64 exp = 0;
+ s8 exp_sign = 1;
+ uw i;
+ assert(buf);
+ assert(dest);
+ buf_save_init(buf, &save);
+ if ((r = buf_parse_digit_dec(buf, &digit)) <= 0)
+ goto restore;
+ tmp = digit;
+ result += r;
+ while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
+ tmp = tmp * 10 + digit;
+ result += r;
+ }
+ if (r < 0 ||
+ (r = buf_read_1(buf, ".")) <= 0)
+ goto restore;
+ result += r;
+ i = 10;
+ while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
+ result += r;
+ tmp += (f64) digit / i;
+ i *= 10;
+ }
+ if ((r = buf_read_1(buf, "e")) > 0) {
+ result += r;
+ if ((r = buf_read_1(buf, "-")) < 0)
+ goto restore;
+ if (r > 0) {
+ result += r;
+ exp_sign = -1;
+ }
+ else {
+ r = buf_read_1(buf, "+");
+ if (r < 0)
+ goto restore;
+ if (r > 0) {
+ result += r;
+ }
+ while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
+ exp = exp * 10 + digit;
+ result += r;
+ }
+ }
+ tmp *= pow(10, exp_sign * exp);
+ }
+ *dest = tmp;
+ r = result;
+ goto clean;
+ restore:
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return r;
+}
+
sw buf_parse_fact (s_buf *buf, s_fact_w *dest)
{
s_tag *object = NULL;
@@ -2822,6 +2949,26 @@ sw buf_parse_tag_character (s_buf *buf, s_tag *dest)
return r;
}
+sw buf_parse_tag_f32 (s_buf *buf, s_tag *dest)
+{
+ sw r;
+ assert(buf);
+ assert(dest);
+ if ((r = buf_parse_f32(buf, &dest->data.f32)) > 0)
+ dest->type = TAG_F32;
+ return r;
+}
+
+sw buf_parse_tag_f64 (s_buf *buf, s_tag *dest)
+{
+ sw r;
+ assert(buf);
+ assert(dest);
+ if ((r = buf_parse_f64(buf, &dest->data.f64)) > 0)
+ dest->type = TAG_F64;
+ return r;
+}
+
sw buf_parse_tag_fn (s_buf *buf, s_tag *dest)
{
sw r;
@@ -2887,9 +3034,18 @@ sw buf_parse_tag_number (s_buf *buf, s_tag *dest)
sw r;
assert(buf);
assert(dest);
- if ((r = buf_parse_tag_integer(buf, dest)) > 0)
+ r = buf_parse_tag_f32(buf, dest);
+ if (r > 0)
+ return r;
+ r = buf_parse_tag_f64(buf, dest);
+ if (r > 0)
+ return r;
+ r = buf_parse_tag_integer(buf, dest);
+ if (r > 0) {
tag_integer_reduce(dest);
- return r;
+ return r;
+ }
+ return 0;
}
sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
@@ -3170,132 +3326,6 @@ sw buf_parse_void (s_buf *buf, void *dest)
return r;
}
-sw buf_parse_f32 (s_buf *buf, f32 *dest)
-{
- sw r;
- sw result = 0;
- u8 digit;
- u8 exponent = 0;
- s_buf_save save;
- f32 tmp = 0;
- f32 frac = 0.1;
- f32 exp = 0;
- f32 exp_sign = 1;
- buf_save_init(buf, &save);
- while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
- tmp = tmp * 10 + digit;
- result += r;
- }
- if (r < 0) {
- buf_save_restore_rpos(buf, &save);
- goto clean;
- }
- if ((r = buf_peek_1(buf, ".")) > 0) {
- result += r;
- if ((r = buf_ignore(buf, 1)) < 0)
- goto restore;
- while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
- tmp += frac * digit;
- frac /= 10;
- result += r;
- }
- }
- if ((r = buf_peek_1(buf, "e")) > 0) {
- exponent = 1;
- result += r;
- if ((r = buf_ignore(buf, 1)) < 0)
- goto restore;
- if ((r = buf_peek_1(buf, "-")) > 0) {
- exp_sign = -1;
- result += r;
- if ((r = buf_ignore(buf, 1)) < 0)
- goto restore;
- }
- else if ((r = buf_peek_1(buf, "+")) > 0) {
- result += r;
- if ((r = buf_ignore(buf, 1)) < 0)
- goto restore;
- }
- while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
- exp = exp * 10 + digit;
- result += r;
- }
- }
- if (exponent) {
- tmp *= pow(10, exp_sign * exp);
- }
- *dest = tmp;
- r = result;
- goto clean;
- restore:
- buf_save_restore_rpos(buf, &save);
- clean:
- buf_save_clean(buf, &save);
- return r;
-}
-
-sw buf_parse_f64 (s_buf *buf, f64 *dest) {
- sw r;
- sw result = 0;
- u8 digit;
- u8 exponent = 0;
- s_buf_save save;
- f64 tmp = 0;
- f64 frac = 0.1;
- f64 exp = 0;
- f64 exp_sign = 1;
- buf_save_init(buf, &save);
- while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
- tmp = tmp * 10 + digit;
- result += r;
- }
- if (r < 0) {
- buf_save_restore_rpos(buf, &save);
- goto clean;
- }
- if ((r = buf_peek_1(buf, ".")) > 0) {
- result += r;
- if ((r = buf_ignore(buf, 1)) < 0)
- goto restore;
- while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
- tmp += frac * digit;
- frac /= 10;
- result += r;
- }
- }
- if ((r = buf_peek_1(buf, "e")) > 0) {
- exponent = 1;
- result += r;
- if ((r = buf_ignore(buf, 1)) < 0)
- goto restore;
- if ((r = buf_peek_1(buf, "-")) > 0) {
- exp_sign = -1;
- result += r;
- if ((r = buf_ignore(buf, 1)) < 0)
- goto restore;
- } else if ((r = buf_peek_1(buf, "+")) > 0) {
- result += r;
- if ((r = buf_ignore(buf, 1)) < 0)
- goto restore;
- }
- while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
- exp = exp * 10 + digit;
- result += r;
- }
- }
- if (exponent) {
- tmp *= pow(10, exp_sign * exp);
- }
- *dest = tmp;
- r = result;
- goto clean;
- restore:
- buf_save_restore_rpos(buf, &save);
- clean:
- buf_save_clean(buf, &save);
- return r;
-}
-
sw buf_peek_array_dimension_count (s_buf *buf, s_array *dest)
{
sw r;
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index 0d1c8d4..441d6a8 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -108,6 +108,8 @@ sw buf_parse_tag_call_op (s_buf *buf, s_tag *dest);
sw buf_parse_tag_call_paren (s_buf *buf, s_tag *dest);
sw buf_parse_tag_cfn (s_buf *buf, s_tag *dest);
sw buf_parse_tag_character (s_buf *buf, s_tag *dest);
+sw buf_parse_tag_f32 (s_buf *buf, s_tag *dest);
+sw buf_parse_tag_f64 (s_buf *buf, s_tag *dest);
sw buf_parse_tag_fn (s_buf *buf, s_tag *dest);
sw buf_parse_tag_ident (s_buf *buf, s_tag *dest);
sw buf_parse_tag_integer (s_buf *buf, s_tag *dest);
diff --git a/libc3/env.c b/libc3/env.c
index 6c55dd4..eb802c7 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -849,7 +849,8 @@ s_list ** env_get_struct_type_spec (s_env *env, const s_sym *module,
tag_init_sym_1(&tag_defstruct, "defstruct");
tag_init_sym(&tag_module, module);
tag_init_var(&tag_var);
- env_module_maybe_reload(env, module, &env->facts);
+ if (! env_module_maybe_reload(env, module, &env->facts))
+ return NULL;
facts_with_tags(&env->facts, &cursor, &tag_module,
&tag_defstruct, &tag_var);
if (! facts_cursor_next(&cursor)) {
diff --git a/libc3/hash.c b/libc3/hash.c
index cc16942..a7ea0cb 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -368,6 +368,25 @@ bool hash_update_struct (t_hash *hash, const s_struct *s)
return true;
}
+bool hash_update_struct_type (t_hash *hash, const s_struct_type *st)
+{
+ uw i;
+ s8 type[] = "struct_type";
+ assert(hash);
+ assert(st);
+ if (! hash_update(hash, type, strlen(type)) ||
+ ! hash_update_sym(hash, &st->module) ||
+ ! hash_update_map(hash, &st->map))
+ return false;
+ i = 0;
+ while (i < st->map.count) {
+ if (! hash_update_uw(hash, st->offset + i))
+ return false;
+ i++;
+ }
+ return hash_update_uw(hash, &st->size);
+}
+
bool hash_update_sym (t_hash *hash, const s_sym * const *sym)
{
s8 type[] = "sym";
diff --git a/libc3/sym.c b/libc3/sym.c
index a3fa6e7..1177291 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -166,9 +166,9 @@ s_str * sym_inspect (const s_sym *sym, s_str *dest)
bool sym_is_module (const s_sym *sym)
{
character c;
- if (str_peek_character_utf8(&sym->str, &c) > 0)
- return character_is_uppercase(c);
- return false;
+ if (str_peek_character_utf8(&sym->str, &c) <= 0)
+ return false;
+ return character_is_uppercase(c);
}
s_sym_list * sym_list_new (s_sym *sym, s_sym_list *next)
diff --git a/libc3/tag_type.c b/libc3/tag_type.c
index c1545e2..9d58c77 100644
--- a/libc3/tag_type.c
+++ b/libc3/tag_type.c
@@ -63,13 +63,13 @@ bool tag_type_to_ffi_type (e_tag_type type, ffi_type **dest)
case TAG_BOOL: *dest = &ffi_type_uint8; return true;
case TAG_CALL: *dest = &ffi_type_pointer; return true;
case TAG_CFN: *dest = &ffi_type_pointer; return true;
- case TAG_CHARACTER: *dest = &ffi_type_schar; return true;
+ case TAG_CHARACTER: *dest = &ffi_type_uint32; return true;
case TAG_F32: *dest = &ffi_type_float; return true;
case TAG_F64: *dest = &ffi_type_double; return true;
case TAG_FACT: *dest = &ffi_type_pointer; return true;
case TAG_FN: *dest = &ffi_type_pointer; return true;
case TAG_IDENT: *dest = &ffi_type_pointer; return true;
- case TAG_INTEGER: *dest = &ffi_type_sint; return true;
+ case TAG_INTEGER: *dest = &ffi_type_pointer; return true;
case TAG_LIST: *dest = &ffi_type_pointer; return true;
case TAG_MAP: *dest = &ffi_type_pointer; return true;
case TAG_PTAG: *dest = &ffi_type_pointer; return true;
diff --git a/test/buf_inspect_test.c b/test/buf_inspect_test.c
index 4322e67..ed151d0 100644
--- a/test/buf_inspect_test.c
+++ b/test/buf_inspect_test.c
@@ -68,9 +68,11 @@
test_context("buf_inspect_f32(" # test ") -> " # expected); \
buf_init(&buf, false, sizeof(b), b); \
tmp = (test); \
+ buf_inspect_f32(&buf, &tmp); \
+ TEST_STRNCMP(buf.ptr.ps8, (expected), buf.wpos); \
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)); \
- TEST_STRNCMP(buf.ptr.ps8, (expected), buf.wpos); \
test_context(NULL); \
} while (0)
@@ -82,7 +84,10 @@
test_context("buf_inspect_f64(" # test ") -> " # expected); \
buf_init(&buf, false, sizeof(b), b); \
tmp = (test); \
+ buf_inspect_f64(&buf, &tmp); \
+ TEST_STRNCMP(buf.ptr.ps8, (expected), buf.wpos); \
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)); \
TEST_STRNCMP(buf.ptr.ps8, (expected), buf.wpos); \
test_context(NULL); \
@@ -233,29 +238,29 @@ TEST_CASE_END(buf_inspect_character)
TEST_CASE(buf_inspect_f32)
{
- BUF_INSPECT_TEST_F32(0.0, "0");
- BUF_INSPECT_TEST_F32(0.1, "0.1");
- BUF_INSPECT_TEST_F32(0.123456789, "0.123457");
- BUF_INSPECT_TEST_F32(1.23456789, "1.23457");
- BUF_INSPECT_TEST_F32(123456789.0, "1.23457e+08");
- BUF_INSPECT_TEST_F32(-0.1, "-0.1");
- BUF_INSPECT_TEST_F32(-0.123456789, "-0.123457");
- BUF_INSPECT_TEST_F32(-1.23456789, "-1.23457");
- BUF_INSPECT_TEST_F32(-123456789.0, "-1.23457e+08");
+ BUF_INSPECT_TEST_F32(0.0f, "0.0f");
+ 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(-0.1f, "-0.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.234567e+6f");
}
TEST_CASE_END(buf_inspect_f32)
TEST_CASE(buf_inspect_f64)
{
- BUF_INSPECT_TEST_F64(0.0, "0");
- BUF_INSPECT_TEST_F64(0.1, "0.1");
- BUF_INSPECT_TEST_F64(0.123456789, "0.123457");
- BUF_INSPECT_TEST_F64(1.23456789, "1.23457");
- BUF_INSPECT_TEST_F64(123456789.0, "1.23457e+08");
- BUF_INSPECT_TEST_F64(-0.1, "-0.1");
- BUF_INSPECT_TEST_F64(-0.123456789, "-0.123457");
- BUF_INSPECT_TEST_F64(-1.23456789, "-1.23457");
- BUF_INSPECT_TEST_F64(-123456789.0, "-1.23457e+08");
+ BUF_INSPECT_TEST_F64(0.0, "0.0");
+ BUF_INSPECT_TEST_F64(0.1, "1.0e-1");
+ BUF_INSPECT_TEST_F64(0.123456789, "1.23456788999999e-1");
+ BUF_INSPECT_TEST_F64(1.23456789, "1.23456788999999");
+ BUF_INSPECT_TEST_F64(123456789.0, "1.23456789000000e+8");
+ BUF_INSPECT_TEST_F64(-0.1, "-1.0e-1");
+ BUF_INSPECT_TEST_F64(-0.123456789, "-1.23456789e-1");
+ BUF_INSPECT_TEST_F64(-1.23456789, "-1.23456789");
+ BUF_INSPECT_TEST_F64(-123456789.0, "-1.23456789e+8");
}
TEST_CASE_END(buf_inspect_f64)
@@ -374,8 +379,8 @@ TEST_CASE(buf_inspect_tag)
BUF_INSPECT_TEST_TAG(tag_bool(&tag, false), "false");
BUF_INSPECT_TEST_TAG(tag_bool(&tag, true), "true");
BUF_INSPECT_TEST_TAG(tag_character(&tag, '\n'), "'\\n'");
- BUF_INSPECT_TEST_TAG(tag_f32(&tag, 1.234), "1.234");
- BUF_INSPECT_TEST_TAG(tag_f64(&tag, 1.2345), "1.2345");
+ BUF_INSPECT_TEST_TAG(tag_f32(&tag, 1.0f), "1.0f");
+ BUF_INSPECT_TEST_TAG(tag_f64(&tag, 1.0), "1.0");
BUF_INSPECT_TEST_TAG(tag_ident_1(&tag, "ident"), "ident");
BUF_INSPECT_TEST_TAG(tag_integer_1(&tag, "-0x10000000000000000"), "-18446744073709551616");
BUF_INSPECT_TEST_TAG(tag_integer_1(&tag, "0x10000000000000000"), "18446744073709551616");
diff --git a/test/buf_parse_test.c b/test/buf_parse_test.c
index 01e1a08..6441896 100644
--- a/test/buf_parse_test.c
+++ b/test/buf_parse_test.c
@@ -926,14 +926,19 @@ TEST_CASE_END(buf_parse_digit_dec)
TEST_CASE(buf_parse_f32)
{
- BUF_PARSE_TEST_F32("123.123", 123.123, 123.1229934692383);
- BUF_PARSE_TEST_F32("3.14159", 3.14159, 3.141589641571045);
- BUF_PARSE_TEST_F32("2.1e+2", 210, 209.9999847412109);
+ BUF_PARSE_TEST_F32("0.0f", 0.0f, 0.0f);
+ BUF_PARSE_TEST_F32("123.123f", 123.123, 123.1229934692383);
+ BUF_PARSE_TEST_F32("3.14159f", 3.14159, 3.141589641571045);
+ BUF_PARSE_TEST_F32("2.1e+2f", 210, 209.9999847412109);
}
TEST_CASE_END(buf_parse_digit_dec)
TEST_CASE(buf_parse_f64)
{
+ BUF_PARSE_TEST_F64("0.0", 0.0);
+ //BUF_PARSE_TEST_F64("123.123", 123.123);
+ //BUF_PARSE_TEST_F64("3.14159", 3.14159);
+ BUF_PARSE_TEST_F64("2.1e+2", 210);
}
TEST_CASE_END(buf_parse_digit_dec)
diff --git a/test/ic3/struct.in b/test/ic3/struct.in
new file mode 100644
index 0000000..241669f
--- /dev/null
+++ b/test/ic3/struct.in
@@ -0,0 +1,10 @@
+quote 0.0
+0.0
+quote %GL.Point3D{}
+%GL.Point3D{}
+quote [position: %GL.Point3D{},
+ normal: %GL.Point3D{},
+ tex_coord: %GL.Point2D{}]
+[position: %GL.Point3D{},
+ normal: %GL.Point3D{},
+ tex_coord: %GL.Point2D{}]
diff --git a/test/ic3/struct.out.expected b/test/ic3/struct.out.expected
new file mode 100644
index 0000000..fd4317b
--- /dev/null
+++ b/test/ic3/struct.out.expected
@@ -0,0 +1,10 @@
+0.0
+0.0
+%GL.Point3D{x: 0.0, y: 0.0, z: 0.0}
+%GL.Point3D{x: 0.0, y: 0.0, z: 0.0}
+[position: %GL.Point3D{x: 0.0, y: 0.0, z: 0.0},
+ normal: %GL.Point3D{x: 0.0, y: 0.0, z: 0.0},
+ tex_coord: %GL.Point2D{x: 0.0, y: 0.0}]
+[position: %GL.Point3D{x: 0.0, y: 0.0, z: 0.0},
+ normal: %GL.Point3D{x: 0.0, y: 0.0, z: 0.0},
+ tex_coord: %GL.Point2D{x: 0.0, y: 0.0}]
diff --git a/test/ic3/struct.ret.expected b/test/ic3/struct.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ic3/struct.ret.expected
@@ -0,0 +1 @@
+0
diff --git a/test/test.h b/test/test.h
index 0a7a667..0103b01 100644
--- a/test/test.h
+++ b/test/test.h
@@ -13,6 +13,7 @@
#ifndef TEST_H
#define TEST_H
+#include <float.h>
#include <stdio.h>
#define TEST_COLOR_KO "\033[0;91m"
@@ -81,7 +82,7 @@
test_ko(); \
fprintf(stderr, "\n%sAssertion failed in %s:%d %s\n" \
"%s == %s\n" \
- "Expected %s got %.16g.%s\n", \
+ "Expected %s got %.8g.%s\n", \
TEST_COLOR_KO, \
__FILE__, __LINE__, __func__, \
# test, # expected, # expected, TEST_FLOAT_EQ_tmp, \
@@ -104,7 +105,7 @@
test_ko(); \
fprintf(stderr, "\n%sAssertion failed in %s:%d %s\n" \
"%s == %s\n" \
- "Expected %s got %.16g.%s\n", \
+ "Expected %s got %.8g.%s\n", \
TEST_COLOR_KO, \
__FILE__, __LINE__, __func__, \
# test, # expected1, # expected1, TEST_FLOAT_EQ2_tmp, \
@@ -115,7 +116,7 @@
#define TEST_DOUBLE_EQ(test, expected) \
do { \
- f64 TEST_DOUBLE_EQ_tmp = (double) (test); \
+ double TEST_DOUBLE_EQ_tmp = (double) (test); \
if (fabs(TEST_DOUBLE_EQ_tmp - (expected)) <= DBL_EPSILON) { \
g_test_assert_count++; \
g_test_assert_ok++; \
@@ -124,7 +125,7 @@
test_ko(); \
fprintf(stderr, "\n%sAssertion failed in %s:%d %s\n" \
"%s == %s\n" \
- "Expected %s got %lf.%s\n", \
+ "Expected %s got %.16lg.%s\n", \
TEST_COLOR_KO, \
__FILE__, __LINE__, __func__, \
# test, # expected, # expected, TEST_DOUBLE_EQ_tmp, \