diff --git a/.ic3_history b/.ic3_history
index 769aad0..9f82eaf 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,16 +1,3 @@
-0.5 + 1
-1/2 + 1
-1 +i 1 + 1
-1 +i 1 + 0.5
-1 +i 1 + (F32) 0.5
-1 +i 1 + 0.5f
-1.5f +i 1 + 0.5f
-1.5f +i 2 + 0.5f
-2/3 +i 2 + 0.5f
-2/3 +i 2 + 1/2
-2/3 +i 2
-2/3 +i 2/2
-2/3 +i 2/1
2/3 +i 2/3
2/3 +i 2/3 + 0.5
3 +i 2 + 0.5
@@ -97,3 +84,16 @@ sqrt(-2) * sqrt(-2)
ic3> (1 +i 2) + (2 +i 3)
(1 +i 2) / (2 +i 3)
(1/1 +i 2/1) / (2 +i 3)
+(Ratio) 0
+(Ratio) 1
+(Ratio) 1.2
+(Ratio) 42
+(Ratio) 42 / 3
+((Ratio) 42) / 3
+((Ratio) 42) / 5
+(Ratio) 42 / 5
+(Ratio) 42
+((Ratio) 42) / 5
+(Ratio) 42
+(Ratio) 42 / 5
+(Ratio) 42 / 6
diff --git a/lib/c3/0.1/ratio.facts b/lib/c3/0.1/ratio.facts
new file mode 100644
index 0000000..63ea854
--- /dev/null
+++ b/lib/c3/0.1/ratio.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {Ratio, :is_a, :module}
+replace {Ratio, :symbol, Ratio.cast}
+replace {Ratio.cast, :cfn, cfn Ratio "ratio_init_cast" (Result, Tag)}
diff --git a/libc3/ratio.c b/libc3/ratio.c
index 7da0ad5..1a0b8da 100644
--- a/libc3/ratio.c
+++ b/libc3/ratio.c
@@ -141,6 +141,49 @@ s_ratio * ratio_init_1 (s_ratio *q, const char *p)
return q;
}
+s_ratio * ratio_init_cast (s_ratio *c, const s_tag *src)
+{
+ assert(c);
+ assert(src);
+ switch (src->type) {
+ case TAG_F32:
+ return ratio_init_f32(c, src->data.f32);
+ case TAG_F64:
+ return ratio_init_f64(c, src->data.f64);
+ case TAG_F128:
+ return ratio_init_f128(c, src->data.f128);
+ case TAG_INTEGER:
+ return ratio_init_integer(c, &src->data.integer);
+ case TAG_RATIO:
+ return ratio_init_copy(c, &src->data.ratio);
+ case TAG_SW:
+ return ratio_init_sw(c, src->data.sw);
+ case TAG_S64:
+ return ratio_init_s64(c, src->data.s64);
+ case TAG_S32:
+ return ratio_init_s32(c, src->data.s32);
+ case TAG_S16:
+ return ratio_init_s16(c, src->data.s16);
+ case TAG_S8:
+ return ratio_init_s8(c, src->data.s8);
+ case TAG_U8:
+ return ratio_init_u8(c, src->data.u8);
+ case TAG_U16:
+ return ratio_init_u16(c, src->data.u16);
+ case TAG_U32:
+ return ratio_init_u32(c, src->data.u32);
+ case TAG_U64:
+ return ratio_init_u64(c, src->data.u64);
+ case TAG_UW:
+ return ratio_init_uw(c, src->data.uw);
+ default:
+ break;
+ }
+ err_puts("ratio_init_cast: invalid tag type");
+ assert(! "ratio_init_cast: invalid tag type");
+ return NULL;
+}
+
s_ratio * ratio_init_copy (s_ratio *dest, const s_ratio *src)
{
s_ratio tmp = {0};
diff --git a/libc3/sym.c b/libc3/sym.c
index 8837f9e..d24bd85 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -499,6 +499,10 @@ bool sym_must_clean (const s_sym *sym, bool *must_clean)
*must_clean = true;
return true;
}
+ if (sym == &g_sym_Ratio) {
+ *must_clean = true;
+ return true;
+ }
if (sym == &g_sym_S8) {
*must_clean = false;
return true;
@@ -665,6 +669,10 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
*dest = &ffi_type_pointer;
return true;
}
+ if (sym == &g_sym_Ratio) {
+ *dest = &ffi_type_pointer;
+ return true;
+ }
if (sym == &g_sym_S8) {
*dest = &ffi_type_sint8;
return true;
@@ -807,6 +815,10 @@ bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
*dest = TAG_QUOTE;
return true;
}
+ if (sym == &g_sym_Ratio) {
+ *dest = TAG_RATIO;
+ return true;
+ }
if (sym == &g_sym_S8) {
*dest = TAG_S8;
return true;
@@ -962,6 +974,10 @@ bool sym_type_size (const s_sym *type, uw *dest)
*dest = sizeof(s_quote);
return true;
}
+ if (type == &g_sym_Ratio) {
+ *dest = sizeof(s_ratio);
+ return true;
+ }
if (type == &g_sym_S8) {
*dest = sizeof(s8);
return true;