1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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;
}
|