mirror of
https://github.com/sigmasternchen/crap-libs
synced 2025-03-15 07:38:56 +00:00
We now have interfaces.
This commit is contained in:
parent
f3a2da064c
commit
fb73a9f720
5 changed files with 67 additions and 14 deletions
|
@ -5,8 +5,9 @@
|
|||
|
||||
#define Test construct(Test)
|
||||
|
||||
class(Test, Object_class, true) {
|
||||
extends(Object_t);
|
||||
class(Test, Object_class, (interfaces){1 namely {Cloneable_class}}, true) {
|
||||
extends(Object_t);
|
||||
implements(Cloneable);
|
||||
|
||||
const char* string;
|
||||
|
||||
|
@ -14,6 +15,13 @@ class(Test, Object_class, true) {
|
|||
void (*destruct)(defclass Test*);
|
||||
} Test_t;
|
||||
|
||||
void method(Test, print)(Test_t*);
|
||||
void method(Test, destruct)(Test_t*);
|
||||
void* method(Test, clone)(void*);
|
||||
void method(Test, populate)(Test_t*, class_t);
|
||||
Test_t* method(Test, construct)(const char*);
|
||||
|
||||
|
||||
void method(Test, print)(Test_t* this) {
|
||||
printf("%s\n", this->string);
|
||||
}
|
||||
|
@ -21,11 +29,18 @@ void method(Test, destruct)(Test_t* this) {
|
|||
this->super.destruct((Object_t*) this);
|
||||
}
|
||||
|
||||
void* method(Test, clone)(void* obj) { // parameter void* because of interface
|
||||
Test_t* test = new Test("");
|
||||
test->string = ((Test_t*) obj)->string;
|
||||
return (void*) test;
|
||||
}
|
||||
|
||||
void method(Test, populate)(Test_t* obj, class_t c) {
|
||||
populate(Object)((Object_t*) obj, c);
|
||||
|
||||
add_method(obj, Test, destruct);
|
||||
add_method(obj, Test, print);
|
||||
add_method(obj, Test, clone);
|
||||
}
|
||||
|
||||
Test_t* method(Test, construct)(const char* string) {
|
||||
|
@ -43,8 +58,9 @@ int main(void) {
|
|||
class_t c = oop_get_class_from_obj((Object_t*) obj);
|
||||
printf("class: %s\n", oop_get_class_name(c));
|
||||
printf("superclass: %s\n", oop_get_class_name(oop_get_super_class(c)));
|
||||
printf("instanceof test: %i\n", instanceof(obj, Test_class));
|
||||
printf("instanceof object: %i\n", instanceof(obj, Object_class));
|
||||
printf("instanceof Test: %i\n", instanceof(obj, Test_class));
|
||||
printf("instanceof Object: %i\n", instanceof(obj, Object_class));
|
||||
printf("instanceof Cloneable: %i\n", instanceof(obj, Cloneable_class));
|
||||
|
||||
obj->print(obj);
|
||||
obj->destruct(obj);
|
||||
|
|
26
oop/oop.c
26
oop/oop.c
|
@ -8,27 +8,45 @@ class_id_t class_ids = 0;
|
|||
|
||||
meta_class_t classes[MAX_CLASSES];
|
||||
|
||||
class_id_t oop_add_class(const char* name, class_t super, bool instanceable) {
|
||||
class_id_t oop_add_class(const char* name, bool interface, class_t super, iflist_t iflist, bool instanceable) {
|
||||
if (oop_class_exists(name))
|
||||
return oop_id_from_name(name);
|
||||
|
||||
classes[class_ids] = (meta_class_t) {
|
||||
.name = name,
|
||||
.interface = interface,
|
||||
.super = super.id,
|
||||
.nrinterfaces = iflist.nr,
|
||||
.instanceable = instanceable
|
||||
};
|
||||
|
||||
for(int i = 0; i < iflist.nr; i++) {
|
||||
classes[class_ids].interfaces[i] = iflist.interfaces[i].id;
|
||||
}
|
||||
|
||||
return class_ids++;
|
||||
}
|
||||
|
||||
bool oop_instance_of_id(void* object, class_id_t id) {
|
||||
class_id_t cid = ((Object_t*) object)->meta_obj.type.id;
|
||||
meta_class_t c = classes[cid];
|
||||
|
||||
if (cid == id)
|
||||
return true;
|
||||
for (int i = 0; i < c.nrinterfaces; i++) {
|
||||
if (c.interfaces[i] == id)
|
||||
return true;
|
||||
}
|
||||
|
||||
// iterate through superclasses of object
|
||||
for (; c.super != NO_CLASS_ID; c = classes[c.super]) {
|
||||
while (c.super != NO_CLASS_ID) {
|
||||
if (c.super == id)
|
||||
return true;
|
||||
c = classes[c.super];
|
||||
for (int i = 0; i < c.nrinterfaces; i++) {
|
||||
if (c.interfaces[i] == id)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -73,6 +91,10 @@ class_t oop_get_class_from_obj(Object_t* obj) {
|
|||
// defined by class macro in h-file
|
||||
class_t Object_class;
|
||||
|
||||
// defined by interface macro in h-file
|
||||
class_t Cloneable_class;
|
||||
|
||||
|
||||
void method(Object, destruct)(Object_t* obj) {
|
||||
free(obj);
|
||||
}
|
||||
|
|
27
oop/oop.h
27
oop/oop.h
|
@ -5,12 +5,12 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#define class(name, superclass, instanceable) class_t name##_class; __attribute__ ((constructor)) static void add_##name##_class(void) { name##_class.id = oop_add_class(#name, superclass, instanceable);} typedef struct name
|
||||
#define interface(name) class_t name##_class; __attribute__ ((constructor)) static void add_##name##_interface(void) { name##_class.id = oop_add_class(#name, true, NO_SUPER_CLASS, NO_INTERFACES, false);}
|
||||
#define class(name, superclass, interfaces, instanceable) class_t name##_class; __attribute__ ((constructor)) static void add_##name##_class(void) { name##_class.id = oop_add_class(#name, false, superclass, interfaces, instanceable);} typedef struct name
|
||||
#define method(class, method) class ##_method_## method
|
||||
#define add_method(object, class, method) object->method = class ##_method_## method
|
||||
#define implements(i) i##_interface
|
||||
|
||||
#define implements(i) i##_interface
|
||||
#define extends(type) type super
|
||||
|
||||
#define construct(name) name ##_method_construct
|
||||
|
@ -23,14 +23,22 @@
|
|||
#define defclass struct
|
||||
|
||||
#define MAX_CLASSES 1024
|
||||
#define MAX_INTERFACES 20 // per class
|
||||
#define NO_CLASS_ID -1
|
||||
#define NO_SUPER_CLASS (class_t){.id = NO_CLASS_ID}
|
||||
#define NO_INTERFACES (interfaces){.nr = 0}
|
||||
|
||||
#define namely ,
|
||||
#define and ,
|
||||
|
||||
typedef int class_id_t;
|
||||
|
||||
typedef struct meta_class {
|
||||
const char* name;
|
||||
bool interface;
|
||||
class_id_t super;
|
||||
class_id_t interfaces[MAX_INTERFACES];
|
||||
int nrinterfaces;
|
||||
bool instanceable;
|
||||
} meta_class_t;
|
||||
|
||||
|
@ -38,19 +46,26 @@ typedef struct class {
|
|||
class_id_t id;
|
||||
} class_t;
|
||||
|
||||
typedef struct iflist {
|
||||
int nr;
|
||||
class_t interfaces[MAX_INTERFACES];
|
||||
} iflist_t;
|
||||
typedef iflist_t interfaces;
|
||||
|
||||
typedef struct meta_object {
|
||||
class_t type;
|
||||
} meta_object_t;
|
||||
|
||||
class_id_t oop_add_class(const char*, class_t, bool);
|
||||
class_id_t oop_add_class(const char*, bool, class_t, iflist_t, bool);
|
||||
|
||||
#define Object construct(Object)
|
||||
|
||||
extern class(Object, NO_SUPER_CLASS, true) {
|
||||
extern class(Object, NO_SUPER_CLASS, NO_INTERFACES, true) {
|
||||
meta_object_t meta_obj;
|
||||
void (*destruct)(defclass Object*);
|
||||
} Object_t;
|
||||
|
||||
extern interface(Cloneable)
|
||||
#define Cloneable_interface void*(*clone)(void*)
|
||||
|
||||
bool oop_instance_of_id(void*, class_id_t);
|
||||
bool oop_instance_of(void*, class_t);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "../oop/oop.h"
|
||||
|
||||
#define Strbuilder construct(Strbuilder)
|
||||
extern class(Strbuilder, Object_class, true) {
|
||||
extern class(Strbuilder, Object_class, NO_INTERFACES, true) {
|
||||
extends(Object_t);
|
||||
|
||||
char* string;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "../../oop/oop.h"
|
||||
|
||||
#define Exception construct(Exception)
|
||||
class(Exception, Object_class, true) {
|
||||
class(Exception, Object_class, NO_INTERFACES, true) {
|
||||
extends(Object_t);
|
||||
|
||||
const char* msg;
|
||||
|
|
Loading…
Reference in a new issue