Skip to content

Instantly share code, notes, and snippets.

@milesrout
Last active August 22, 2020 05:34
Show Gist options
  • Save milesrout/073dc1c298afed8f83074809bbeb4ac4 to your computer and use it in GitHub Desktop.
Save milesrout/073dc1c298afed8f83074809bbeb4ac4 to your computer and use it in GitHub Desktop.
Object system A or B?
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]));
}
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