Last active
August 22, 2020 05:34
-
-
Save milesrout/073dc1c298afed8f83074809bbeb4ac4 to your computer and use it in GitHub Desktop.
Object system A or B?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum object_type { INT, CSTR }; | |
struct object { | |
int type; | |
union { | |
int intvalue; | |
const char *cstrvalue; | |
}; | |
}; | |
int | |
object_equal(struct object *l, struct object *r) | |
{ | |
if (l->type == INT && r->type == INT) { | |
return l->intvalue == r->intvalue; | |
} | |
else if (l->type == CSTR && r->type == CSTR) { | |
return strcmp(l->cstrvalue, r->cstrvalue) == 0; | |
} | |
else { | |
return 0; | |
} | |
} | |
struct object | |
int_new(int z) | |
{ | |
return (struct object){ INT, z }; | |
} | |
struct object | |
cstr_new(const char *s) | |
{ | |
return (struct object){ CSTR, s }; | |
} | |
int main() | |
{ | |
struct object objs[] = {int_new(1), cstr_new("2")}; | |
printf("1 == 1: %d\n", object_equal(&objs[0], &objs[0])); | |
printf("1 == '2': %d\n", object_equal(&objs[0], &objs[1])); | |
printf("'2' == '2': %d\n", object_equal(&objs[1], &objs[1])); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct object_vtable { | |
const char *(*str)(struct object *); | |
const char *(*repr)(struct object *); | |
int (*eq)(struct object *, struct object *); | |
}; | |
struct object { | |
struct object_vtable *vtable; | |
}; | |
struct int_object { | |
struct object object; | |
int z; | |
}; | |
struct cstr_object { | |
struct object object; | |
const char *cstr; | |
}; | |
struct object_vtable cstr_vtable = { ..., &cstr_eq }; | |
struct object_vtable int_vtable = { ..., &int_eq }; | |
struct object Int = { &int_vtable }; | |
struct object CStr = { &cstr_vtable }; | |
struct int_object | |
int_new(int z) | |
{ | |
return (struct int_object){ Int, z }; | |
} | |
struct cstr_object | |
cstr_new(const char *s) | |
{ | |
return (struct cstr_object){ Cstr, s }; | |
} | |
/* def __eq__(self, other): | |
* if isinstance(other, CStr): | |
* return self.str == other.str | |
* return False | |
*/ | |
int | |
int_eq(struct object *l, struct object *r) | |
{ | |
if (r.vtable == int_vtable) { | |
return ((struct int_object *)l)->z == ((struct int_object *)r)->z; | |
} | |
return 0; | |
} | |
int | |
cstr_eq(struct object *l, struct object *r) | |
{ | |
if (r.vtable == cstr_vtable) { | |
return strcmp(((struct cstr_object *)l)->cstr, ((struct cstr_object *)r)->cstr) == 0; | |
} | |
return 0; | |
} | |
/* def equals(a, b): return type(a).__eq__(a, b) | |
* not quite how it works in Python because if issubclass(type(b), type(a)): return type(b).__eq__(b, a) | |
*/ | |
int obj_equal(struct object *l, struct object *r) | |
{ | |
return l->vtable->eq(l, r); | |
} | |
int main() | |
{ | |
struct int_object one = int_new(1); | |
struct cstr_object two = cstr_new("two"); | |
struct object *objs[] = {&one.object, &two.object}; | |
printf("1 == 1: %d\n", obj_equal(objs[0], objs[0])); | |
printf("1 == '2': %d\n", obj_equal(objs[0], objs[1])); | |
printf("'2' == '2': %d\n", obj_equal(objs[1], objs[1])); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment