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);
|
krk_initTable(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t hashTupleValues(KrkTuple *tuple);
|
||||||
|
|
||||||
static uint32_t hashValue(KrkValue value) {
|
static uint32_t hashValue(KrkValue value) {
|
||||||
if (IS_STRING(value)) return (AS_STRING(value))->hash;
|
if (IS_STRING(value)) return (AS_STRING(value))->hash;
|
||||||
if (IS_INTEGER(value)) return (uint32_t)(AS_INTEGER(value));
|
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_BOOLEAN(value)) return (uint32_t)(AS_BOOLEAN(value));
|
||||||
if (IS_NONE(value)) return 0;
|
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_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);
|
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) {
|
KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue key) {
|
||||||
uint32_t index = hashValue(key) % capacity;
|
uint32_t index = hashValue(key) % capacity;
|
||||||
KrkTableEntry * tombstone = NULL;
|
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];
|
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[]) {
|
static KrkValue _tuple_repr(int argc, KrkValue argv[]) {
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
krk_runtimeError(vm.exceptions.argumentError, "tuple.__repr__ does not expect arguments");
|
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, ".__len__", _tuple_len);
|
||||||
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__contains__", _tuple_contains);
|
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__contains__", _tuple_contains);
|
||||||
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__iter__", _tuple_iter);
|
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__iter__", _tuple_iter);
|
||||||
|
krk_defineNative(&vm.baseClasses.tupleClass->methods, ".__eq__", _tuple_eq);
|
||||||
krk_finalizeClass(vm.baseClasses.tupleClass);
|
krk_finalizeClass(vm.baseClasses.tupleClass);
|
||||||
ADD_BASE_CLASS(vm.baseClasses.bytesClass, "bytes", vm.objectClass);
|
ADD_BASE_CLASS(vm.baseClasses.bytesClass, "bytes", vm.objectClass);
|
||||||
krk_defineNative(&vm.baseClasses.bytesClass->methods, ".__init__", _bytes_init);
|
krk_defineNative(&vm.baseClasses.bytesClass->methods, ".__init__", _bytes_init);
|
||||||
|
Loading…
Reference in New Issue
Block a user