maybe support __eq__?
This commit is contained in:
parent
181e378628
commit
2f78ae8770
1
object.h
1
object.h
@ -96,6 +96,7 @@ typedef struct KrkClass {
|
||||
KrkObj * _tostr;
|
||||
KrkObj * _call;
|
||||
KrkObj * _init;
|
||||
KrkObj * _eq;
|
||||
} KrkClass;
|
||||
|
||||
typedef struct {
|
||||
|
76
value.c
76
value.c
@ -96,32 +96,56 @@ void krk_printValueSafe(FILE * f, KrkValue printable) {
|
||||
}
|
||||
|
||||
int krk_valuesEqual(KrkValue a, KrkValue b) {
|
||||
if (a.type != b.type) return 0; /* uh, maybe not, this is complicated */
|
||||
|
||||
switch (a.type) {
|
||||
case VAL_BOOLEAN: return AS_BOOLEAN(a) == AS_BOOLEAN(b);
|
||||
case VAL_NONE: return 1; /* None always equals None */
|
||||
case VAL_KWARGS: /* Equal if same number of args; may be useful for comparing sentinels (0) to arg lists. */
|
||||
case VAL_INTEGER: return AS_INTEGER(a) == AS_INTEGER(b);
|
||||
case VAL_FLOATING: return AS_FLOATING(a) == AS_FLOATING(b);
|
||||
case VAL_HANDLER: {
|
||||
fprintf(stderr, "Attempted to compare a value to an exception handler. VM leaked a stack value.\n");
|
||||
exit(1);
|
||||
if (a.type == b.type) {
|
||||
switch (a.type) {
|
||||
case VAL_BOOLEAN: return AS_BOOLEAN(a) == AS_BOOLEAN(b);
|
||||
case VAL_NONE: return 1; /* None always equals None */
|
||||
case VAL_KWARGS: /* Equal if same number of args; may be useful for comparing sentinels (0) to arg lists. */
|
||||
case VAL_INTEGER: return AS_INTEGER(a) == AS_INTEGER(b);
|
||||
case VAL_FLOATING: return AS_FLOATING(a) == AS_FLOATING(b);
|
||||
case VAL_HANDLER: krk_runtimeError(vm.exceptions.valueError,"Invalid value"); return 0;
|
||||
case VAL_OBJECT: {
|
||||
if (AS_OBJECT(a) == AS_OBJECT(b)) return 1;
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
case VAL_OBJECT: {
|
||||
if (IS_STRING(a) && IS_STRING(b)) return AS_OBJECT(a) == AS_OBJECT(b);
|
||||
/* If their pointers are equal, assume they are always equivalent */
|
||||
if (IS_TUPLE(a) && IS_TUPLE(b)) {
|
||||
if (AS_TUPLE(a)->values.count != AS_TUPLE(b)->values.count) return 0;
|
||||
for (size_t i = 0; i < AS_TUPLE(a)->values.count; ++i) {
|
||||
if (!krk_valuesEqual(AS_TUPLE(a)->values.values[i], AS_TUPLE(b)->values.values[i])) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (AS_OBJECT(a) == AS_OBJECT(b)) return 1;
|
||||
/* TODO: __eq__ */
|
||||
return 0;
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
if (!IS_OBJECT(a) && !IS_OBJECT(b)) {
|
||||
switch (a.type) {
|
||||
case VAL_INTEGER: {
|
||||
switch (b.type) {
|
||||
case VAL_BOOLEAN: return AS_INTEGER(a) == AS_BOOLEAN(b);
|
||||
case VAL_FLOATING: return (double)AS_INTEGER(a) == AS_FLOATING(b);
|
||||
default: return 0;
|
||||
}
|
||||
} break;
|
||||
case VAL_FLOATING: {
|
||||
switch (b.type) {
|
||||
case VAL_BOOLEAN: return AS_FLOATING(a) == (double)AS_BOOLEAN(b);
|
||||
case VAL_INTEGER: return AS_FLOATING(a) == (double)AS_INTEGER(b);
|
||||
default: return 0;
|
||||
}
|
||||
} break;
|
||||
case VAL_BOOLEAN: {
|
||||
switch (b.type) {
|
||||
case VAL_INTEGER: return AS_BOOLEAN(a) == AS_INTEGER(b);
|
||||
case VAL_FLOATING: return (double)AS_BOOLEAN(a) == AS_FLOATING(b);
|
||||
default: return 0;
|
||||
}
|
||||
} break;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
KrkClass * type = AS_CLASS(krk_typeOf(1,(KrkValue[]){a}));
|
||||
if (type && type->_eq) {
|
||||
krk_push(a);
|
||||
krk_push(b);
|
||||
KrkValue result = krk_callSimple(OBJECT_VAL(type->_eq),2,0);
|
||||
if (IS_BOOLEAN(result)) return AS_BOOLEAN(result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
2
vm.c
2
vm.c
@ -225,6 +225,7 @@ void krk_finalizeClass(KrkClass * _class) {
|
||||
{&_class->_tostr, METHOD_STR},
|
||||
{&_class->_call, METHOD_CALL},
|
||||
{&_class->_init, METHOD_INIT},
|
||||
{&_class->_eq, METHOD_EQ},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
@ -2385,6 +2386,7 @@ void krk_initVM(int flags) {
|
||||
vm.specialMethodNames[METHOD_LIST_INT] = OBJECT_VAL(S("__list"));
|
||||
vm.specialMethodNames[METHOD_DICT_INT] = OBJECT_VAL(S("__dict"));
|
||||
vm.specialMethodNames[METHOD_INREPR] = OBJECT_VAL(S("__inrepr"));
|
||||
vm.specialMethodNames[METHOD_EQ] = OBJECT_VAL(S("__eq__"));
|
||||
|
||||
/* Create built-in class `object` */
|
||||
vm.objectClass = krk_newClass(S("object"));
|
||||
|
2
vm.h
2
vm.h
@ -37,6 +37,7 @@ typedef enum {
|
||||
METHOD_INREPR,
|
||||
METHOD_ORD,
|
||||
METHOD_CALL,
|
||||
METHOD_EQ,
|
||||
|
||||
METHOD__MAX,
|
||||
} KrkSpecialMethods;
|
||||
@ -133,3 +134,4 @@ extern int krk_bindMethod(KrkClass * _class, KrkString * name);
|
||||
extern int krk_callValue(KrkValue callee, int argCount, int extra);
|
||||
|
||||
extern KrkValue krk_dict_of(int argc, KrkValue argv[]);
|
||||
extern KrkValue krk_callSimple(KrkValue value, int argCount, int isMethod);
|
||||
|
Loading…
Reference in New Issue
Block a user