summaryrefslogtreecommitdiff
path: root/src/runtime/value.c
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2026-06-30 14:30:19 -0400
committerLLLL Colonq <llll@colonq>2026-06-30 14:30:19 -0400
commit1c028e3a2250a56eface56ebbb1835d77e4e2579 (patch)
tree98ea5da9d75e87f44bb3eb2e153810a6a820f9b6 /src/runtime/value.c
parent1d4447bcd888dd0bd20cf4b6dd7f9192145debf0 (diff)
Big refactorHEADmaster
Diffstat (limited to 'src/runtime/value.c')
-rw-r--r--src/runtime/value.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/runtime/value.c b/src/runtime/value.c
new file mode 100644
index 0000000..1e9d543
--- /dev/null
+++ b/src/runtime/value.c
@@ -0,0 +1,76 @@
+#include <lcq/pit/runtime/value.h>
+
+pit_value pit_value_new(pit_runtime *rt, enum pit_value_sort s, u64 data) {
+ if (s == PIT_VALUE_SORT_DOUBLE) {
+ /* if (((data >> 52) & 0b011111111111) == 0b011111111111 && ((data >> 51) & 0b1) == 0) { */
+ if (((data >> 52) & 0x7ff) == 0x7ff && ((data >> 51) & 1) == 0) {
+ pit_error(rt, "attempted to create a signalling NaN double");
+ return PIT_NIL;
+ }
+ return data;
+ }
+ return
+ /* 0b1111111111110000000000000000000000000000000000000000000000000000 */
+ 0xfff0000000000000
+ /* | (((u64) (s & 0b11)) << 49) */
+ | (((u64) (s & 3)) << 49)
+ /* | (data & 0b1111111111111111111111111111111111111111111111111); */
+ | (data & 0x1ffffffffffff);
+}
+
+bool pit_value_eq(pit_value a, pit_value b) {
+ return a == b;
+}
+
+bool pit_value_equal(pit_runtime *rt, pit_value a, pit_value b) {
+ if (pit_value_sort(a) != pit_value_sort(b)) return false;
+ switch (pit_value_sort(a)) {
+ case PIT_VALUE_SORT_DOUBLE:
+ case PIT_VALUE_SORT_INTEGER:
+ case PIT_VALUE_SORT_SYMBOL:
+ return pit_value_data(a) == pit_value_data(b);
+ case PIT_VALUE_SORT_REF: {
+ pit_value_heavy *ha = pit_value_ref_deref(rt, pit_value_as_ref(rt, a));
+ if (!ha) { pit_error(rt, "bad ref"); return false; }
+ pit_value_heavy *hb = pit_value_ref_deref(rt, pit_value_as_ref(rt, b));
+ if (!hb) { pit_error(rt, "bad ref"); return false; }
+ if (ha->hsort != hb->hsort) return false;
+ switch (ha->hsort) {
+ case PIT_VALUE_HEAVY_SORT_CELL:
+ return pit_value_equal(rt, ha->in.cell, hb->in.cell);
+ case PIT_VALUE_HEAVY_SORT_CONS:
+ return pit_value_equal(rt, ha->in.cons.car, hb->in.cons.car)
+ && pit_value_equal(rt, ha->in.cons.cdr, hb->in.cons.cdr);
+ case PIT_VALUE_HEAVY_SORT_ARRAY: {
+ if (ha->in.array.len != hb->in.array.len) return false;
+ for (i64 i = 0; i < ha->in.array.len; ++i) {
+ if (!pit_value_equal(rt, ha->in.array.data[i], hb->in.array.data[i])) return false;
+ }
+ return true;
+ }
+ case PIT_VALUE_HEAVY_SORT_BYTES: {
+ if (ha->in.bytes.len != hb->in.bytes.len) return false;
+ for (i64 i = 0; i < ha->in.bytes.len; ++i) {
+ if (ha->in.bytes.data[i] != hb->in.bytes.data[i]) return false;
+ }
+ return true;
+ }
+ case PIT_VALUE_HEAVY_SORT_FUNC:
+ return
+ pit_value_equal(rt, ha->in.func.env, hb->in.func.env)
+ && pit_value_equal(rt, ha->in.func.args, hb->in.func.args)
+ && pit_value_equal(rt, ha->in.func.body, hb->in.func.body);
+ case PIT_VALUE_HEAVY_SORT_NATIVEFUNC:
+ return ha->in.nativefunc.f == hb->in.nativefunc.f
+ && ha->in.nativefunc.data == hb->in.nativefunc.data;
+ case PIT_VALUE_HEAVY_SORT_NATIVEDATA:
+ return
+ pit_value_eq(ha->in.nativedata.tag, hb->in.nativedata.tag)
+ && ha->in.nativedata.data == hb->in.nativedata.data;
+ case PIT_VALUE_HEAVY_SORT_FORWARDING_POINTER:
+ return ha->in.forwarding_pointer == hb->in.forwarding_pointer;
+ }
+ }
+ }
+ return false;
+}