diff --git a/README.md b/README.md
index e222012..4742f3d 100644
--- a/README.md
+++ b/README.md
@@ -245,8 +245,11 @@ All these list formats are supported in pattern matching.
- negative facts : 4 + 2n = not 3 + 2n
- with ignore variables
- math
- - floating point numbers
+ - fractions
+ - floating point numbers (decimals)
- structs
+ - unions
+ - enums
- errors (setjmp, longjmp)
- stacktrace
- ffi ?
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 1c03c4e..94e33db 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -2415,6 +2415,17 @@ sw buf_parse_tag_list (s_buf *buf, s_tag *dest)
return r;
}
+
+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)
+ tag_integer_reduce(dest);
+ return r;
+}
+
sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
{
sw r;
@@ -2431,11 +2442,8 @@ sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
goto restore;
result += r;
}
- if ((r = buf_parse_tag_integer(buf, dest)) != 0) {
- tag_integer_reduce(dest);
- goto end;
- }
- if ((r = buf_parse_tag_array(buf, dest)) != 0 ||
+ if ((r = buf_parse_tag_number(buf, dest)) != 0 ||
+ (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 ||
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index 7f6a0cc..21f61d7 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -103,6 +103,7 @@ 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);
sw buf_parse_tag_list (s_buf *buf, s_tag *dest);
+sw buf_parse_tag_number (s_buf *buf, s_tag *dest);
sw buf_parse_tag_primary (s_buf *buf, s_tag *dest);
sw buf_parse_tag_quote (s_buf *buf, s_tag *dest);
sw buf_parse_tag_str (s_buf *buf, s_tag *dest);
diff --git a/libc3/float.h b/libc3/float.h
index 6200085..aec8a65 100644
--- a/libc3/float.h
+++ b/libc3/float.h
@@ -15,6 +15,12 @@
* @brief Floating point numbers operations.
*
* Structure to manipulate floating point numbers.
+ * C3 floating point numbers are two s_integer :
+ * - num The numerator.
+ * - div The divisor, which is always a positive power of 10.
+ *
+ * All operations are supported in tag_add, tag_mul, tag_neg etc.
+ *
*/
#ifndef FLOAT_H
#define FLOAT_H
@@ -24,20 +30,24 @@
/* Stack-allocation compatible functions */
s_float * float_init (s_float *f);
s_float * float_init_1 (s_float *f, const s8 *s);
-s_float * float_init_sw (s_float *f, sw integer, sw bitshift);
+s_float * float_init_integer (s_float *f, const s_integer *num,
+ const s_integer *div);
+s_float * float_init_w (s_float *f, sw num, uw div);
/* Heap-allocation compatible functions, call float_delete after use */
void float_delete (s_float *f);
-s_float * float_new (s_float *f);
-s_float * float_new_1 (s_float *f, const s8 *s);
-s_float * float_new_sw (s_float *f, sw integer, sw bitshift);
+s_float * float_new ();
+s_float * float_new_1 (const s8 *s);
+s_float * float_new_integer (const s_integer *num,
+ const s_integer *div);
+s_float * float_new_w (sw num, uw div);
-/* Modifiers */
-s_float * float_add (s_float *a, s_float *b);
-s_float * float_mul (s_float *a, s_float *b);
-s_float * float_neg (s_float *f);
-s_float * float_sq (s_float *f);
-s_float * float_sqrt (s_float *f);
-s_float * float_sub (s_float *a, s_float *b);
+/* Operators */
+s_float * float_add (const s_float *a, const s_float *b, s_float *result);
+s_float * float_mul (const s_float *a, const s_float *b, s_float *result);
+s_float * float_neg (const s_float *f, s_float *result);
+s_float * float_sq (const s_float *f, s_float *result);
+s_float * float_sqrt (const s_float *f, s_float *result);
+s_float * float_sub (const s_float *a, s_float *b, s_float *result);
#endif /* FLOAT_H */
diff --git a/libc3/types.h b/libc3/types.h
index 4c9be63..ee17922 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -131,12 +131,13 @@ typedef struct facts_cursor s_facts_cursor;
typedef struct facts_spec_cursor s_facts_spec_cursor;
typedef struct facts_with_cursor s_facts_with_cursor;
typedef struct facts_with_cursor_level s_facts_with_cursor_level;
-typedef struct float_ s_float;
+typedef struct float_s s_float;
typedef struct fn s_fn;
typedef struct fn_clause s_fn_clause;
typedef struct frame s_frame;
typedef struct ident s_ident;
typedef struct integer s_integer;
+typedef struct integer_fraction s_integer_fraction;
typedef struct list s_list;
typedef struct list s_list_map;
typedef struct log s_log;
@@ -201,11 +202,6 @@ struct fact_w {
uw id; /* serial id */
};
-struct float_ {
- sw integer;
- sw bit_shift;
-};
-
struct fn_clause {
uw arity;
s_list *pattern;
@@ -335,6 +331,11 @@ struct cfn {
bool special_operator;
};
+struct integer_fraction {
+ s_integer num;
+ s_integer div;
+};
+
struct log {
s_buf buf;
u64 count;
@@ -360,6 +361,10 @@ struct array {
const s_sym *type;
};
+struct float_s {
+ s_integer_fraction f; /* divisor is always 10^n */
+};
+
/* 5 */
union tag_data {
diff --git a/test/ic3_test b/test/ic3_test
index a1291b3..d8788dd 100755
--- a/test/ic3_test
+++ b/test/ic3_test
@@ -17,13 +17,13 @@ if [ "x$IC3" = "x" ]; then
fi
test_ko() {
- echo -n "${TEST_COLOR_KO}F${TEST_COLOR_RESET}"
+ printf "%s" "${TEST_COLOR_KO}F${TEST_COLOR_RESET}"
TEST_KO=$(($TEST_KO + 1))
TEST_COUNT=$(($TEST_COUNT + 1))
}
test_ok() {
- echo -n "${TEST_COLOR_OK}.${TEST_COLOR_RESET}"
+ printf "%s" "${TEST_COLOR_OK}.${TEST_COLOR_RESET}"
TEST_OK=$(($TEST_OK + 1))
TEST_COUNT=$(($TEST_COUNT + 1))
}
@@ -60,7 +60,7 @@ done
echo
DIFFS="$(for TARGET in $TARGETS; do
if [ -f "${TARGET}.diff" ]; then
- echo -n "${TARGET}.diff "
+ printf "%s " "${TARGET}.diff"
fi
done)"
if [ "x$DIFFS" != "x" ]; then