Commit 6bd430d30c9105160039f1c0722a3e4c87943eec

Thomas de Grivel 2023-11-10T19:48:18

wip floats, use printf for ic3_test

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