better abstraction

This commit is contained in:
overflowerror 2017-03-09 16:24:02 +01:00
parent 274d85b973
commit c3547c47f5
3 changed files with 79 additions and 37 deletions

View file

@ -7,30 +7,34 @@
class_t test_class;
__attribute__ ((constructor))
static void add_test_class(void) {
test_class.id = new_class("test", NO_SUPER_CLASS, true);
}
class(test, test_class, object_class, true) {
extends(object_t);
typedef struct test {
meta_object_t meta;
void (*destruct)(struct test*);
const char* string;
void (*print)(struct test*);
void (*destruct)(struct test*);
} test_t;
void test_method_print(test_t* this) {
void method(test, print)(test_t* this) {
printf("%s\n", this->string);
}
void test_method_destruct(test_t* this) {
free(this);
void method(test, destruct)(test_t* this) {
this->super.destruct((object_t*) this);
}
test_t* test_method_construct(const char* string) {
test_t* obj = malloc(sizeof(test_t));
void method(test, populate)(test_t* obj, const char* string) {
populate(object)((object_t*) obj, test_class);
obj->string = string;
obj->destruct = test_method_destruct;
obj->print = test_method_print;
add_method(obj, test, destruct);
add_method(obj, test, print);
}
test_t* method(test, construct)(const char* string) {
test_t* obj = malloc(sizeof(test_t));
populate(test)(obj, string);
return obj;
}

View file

@ -1,47 +1,66 @@
#include "oop.h"
#include <string.h>
#include <stdlib.h>
class_id_t class_ids = 0;
meta_class_t classes[MAX_CLASSES];
class_id_t new_class(const char* name, class_id_t super, bool instanceable) {
class_id_t oop_add_class(const char* name, class_t super, bool instanceable) {
classes[class_ids] = (meta_class_t) {
.name = name,
.super = super,
.super = super.id,
.instanceable = instanceable
};
return class_ids++;
}
bool instance_of_id(void* object, class_id_t id) {
bool oop_instance_of_id(void* object, class_id_t id) {
if (sizeof (object) < sizeof (object_t))
return false; // not an object
object_t* obj = (object_t*) object;
return obj->meta_obj.class.id == id;
return obj->meta_obj.type.id == id;
}
bool instance_of(void* object, class_t class) {
return instance_of_id(object, class.id);
bool oop_instance_of(void* object, class_t type) {
return oop_instance_of_id(object, type.id);
}
const char* get_class_name_by_id(class_id_t id) {
const char* oop_get_class_name_by_id(class_id_t id) {
return classes[id].name;
}
const char* get_class_name(class_t class) {
return get_class_name_by_id(class.id);
const char* oop_get_class_name(class_t type) {
return oop_get_class_name_by_id(type.id);
}
class_id_t id_from_name(const char* class_name) {
class_id_t oop_id_from_name(const char* class_name) {
for (int i = 0; i < class_ids; i++) {
if (strcmp(class_name, classes[i].name) == 0)
return i;
}
return NO_CLASS;
return NO_CLASS_ID;
}
bool class_exists(const char* class_name) {
return id_from_name(class_name) != NO_CLASS;
bool oop_class_exists(const char* class_name) {
return oop_id_from_name(class_name) != NO_CLASS_ID;
}
class_t object_class;
void method(object, destruct)(object_t* obj) {
free(obj);
}
object_t* method(object, construct)() {
object_t* obj = malloc(sizeof(object_t));
populate(object)(obj, object_class);
return obj;
}
void method(object, populate)(object_t* obj, class_t type) {
obj->meta_obj.type = type;
add_method(obj, object, destruct);
}

View file

@ -4,14 +4,25 @@
#include <stdbool.h>
#include <stdarg.h>
#define class(name, type, superclass, instanceable) __attribute__ ((constructor)) static void add_##name##_class(void) { type.id = oop_add_class(#name, superclass, instanceable); } typedef struct name
#define method(class, method) class ##_method_## method
#define add_method(object, class, method) object->method = class ##_method_## method
#define extends(type) type super
#define construct(name) name ##_method_construct
#define populate(name) name ##_method_populate
#define call(obj, method) (obj)->method((obj))
#define new
#define MAX_CLASSES 1024
#define NO_SUPER_CLASS -1
#define NO_CLASS -1
#define NO_CLASS_ID -1
#define NO_SUPER_CLASS (class_t){.id = NO_CLASS_ID}
typedef int class_id_t;
@ -26,19 +37,27 @@ typedef struct class {
} class_t;
typedef struct meta_object {
class_t class;
class_t type;
} meta_object_t;
typedef struct object {
class_id_t oop_add_class(const char*, class_t, bool);
#define object construct(object)
extern class_t object_class;
class(object, object_class, NO_SUPER_CLASS, true) {
meta_object_t meta_obj;
void (*destruct)(struct object*);
} object_t;
class_id_t new_class(const char*, class_id_t, bool);
bool instance_of_id(void*, class_id_t);
bool instance_of(void*, class_t);
const char* get_class_name(class_t);
class_id_t id_from_name(const char*);
bool class_exists(const char*);
bool oop_instance_of_id(void*, class_id_t);
bool oop_instance_of(void*, class_t);
const char* oop_get_class_name(class_t);
class_id_t oop_id_from_name(const char*);
bool oop_class_exists(const char*);
object_t* method(object, construct)(void);
void method(object, populate)(object_t* obj, class_t);
#endif