Implement __eq__ and hashing for tuples
This commit is contained in:
parent
f43eff0f2e
commit
975d4dcb9b
11
table.c
11
table.c
@ -20,6 +20,8 @@ void krk_freeTable(KrkTable * table) {
|
||||
krk_initTable(table);
|
||||
}
|
||||
|
||||
static uint32_t hashTupleValues(KrkTuple *tuple);
|
||||
|
||||
static uint32_t hashValue(KrkValue value) {
|
||||
if (IS_STRING(value)) return (AS_STRING(value))->hash;
|
||||
if (IS_INTEGER(value)) return (uint32_t)(AS_INTEGER(value));
|
||||
@ -27,9 +29,18 @@ static uint32_t hashValue(KrkValue value) {
|
||||
if (IS_BOOLEAN(value)) return (uint32_t)(AS_BOOLEAN(value));
|
||||
if (IS_NONE(value)) return 0;
|
||||
if (IS_BYTES(value)) return (AS_BYTES(value))->hash; /* Same as strings, but we don't have an interning table */
|
||||
if (IS_TUPLE(value)) return hashTupleValues(AS_TUPLE(value));
|
||||
return (((uint32_t)(intptr_t)AS_OBJECT(value)) >> 4)| (((uint32_t)(intptr_t)AS_OBJECT(value)) << 28);
|
||||
}
|
||||
|
||||
static uint32_t hashTupleValues(KrkTuple *tuple) {
|
||||
uint32_t hash = 0;
|
||||
for (size_t i = 0; i < tuple->values.count; ++i) {
|
||||
hash += hashValue(tuple->values.values[i]);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue key) {
|
||||
uint32_t index = hashValue(key) % capacity;
|
||||
KrkTableEntry * tombstone = NULL;
|
||||
|
12
vm.c
12
vm.c
@ -2450,6 +2450,17 @@ static KrkValue _tuple_get(int argc, KrkValue argv[]) {
|
||||
return tuple->values.values[index];
|
||||
}
|
||||
|
||||
static KrkValue _tuple_eq(int argc, KrkValue argv[]) {
|
||||
if (!IS_TUPLE(argv[1])) return BOOLEAN_VAL(0);
|
||||
KrkTuple * self = AS_TUPLE(argv[0]);
|
||||
KrkTuple * them = AS_TUPLE(argv[1]);
|
||||
if (self->values.count != them->values.count) return BOOLEAN_VAL(0);
|
||||
for (size_t i = 0; i < self->values.count; ++i) {
|
||||
if (!krk_valuesEqual(self->values.values[i], them->values.values[i])) return BOOLEAN_VAL(0);
|
||||
}
|
||||
return BOOLEAN_VAL(1);
|
||||
}
|
||||
|
||||
static KrkValue _tuple_repr(int argc, KrkValue argv[]) {
|
||||
if (argc != 1) {
|
||||
krk_runtimeError(vm.exceptions.argumentError, "tuple.__repr__ does not expect arguments");
|
||||
@ -3187,6 +3198,7 @@ void krk_initVM(int flags) {
|
||||
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__len__", _tuple_len);
|
||||
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__contains__", _tuple_contains);
|
||||
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__iter__", _tuple_iter);
|
||||
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__eq__", _tuple_eq);
|
||||
krk_finalizeClass(vm.baseClasses.tupleClass);
|
||||
ADD_BASE_CLASS(vm.baseClasses.bytesClass, "bytes", vm.objectClass);
|
||||
krk_defineNative(&vm.baseClasses.bytesClass->methods, ".__init__", _bytes_init);
|
||||
|
Loading…
Reference in New Issue
Block a user