#include <stdio.h>
#include <stdlib.h>
struct class_typeinfo {
char *name;
};
typedef struct class_typeinfo class_typeinfo;
#define METHODS(methods...) methods
#define MEMBERS(members...) members
#define CLASS_VTBL(name) _##name##_vtable_
#define CLASS_MTHD(name, method) _##name##_##method##_
#define CLASS_DECL(name, methods, members) \
typedef struct name name; \
struct CLASS_VTBL(name) { \
void (*init)(name *); \
void (*destroy)(name *); \
class_typeinfo typeinfo; \
methods \
}; \
struct CLASS_VTBL(name) CLASS_VTBL(name); \
struct name { \
struct CLASS_VTBL(name) vtable; \
members \
};
#define ARGS(args...) args
#define IMPLEMENT(class, method, return_t, args, body...) \
return_t CLASS_MTHD(class, method)(args) { \
body \
}
#define CTOR(class, body...) \
void _##class##_init##_(class *self) { \
body \
}
#define DTOR(class, body...) \
void _##class##_destroy##_(class *self) { \
body \
}
#define NEW(class) \
class *tmpname = malloc(sizeof(class)); \
tmpname->vtable = CLASS_VTBL(class); \
tmpname->vtable.init(tmpname);
#define METHODCALL(object, method, args...) \
object->vtable.method(object, ## args)
CLASS_DECL(foo,
METHODS(
int (*inc)(foo *self);
int (*dec)(foo *self);
void (*set)(foo *self, int new_value);
int (*get)(foo *self);
),
MEMBERS(
int local;
)
);
CTOR(foo,
self->local = 0;
);
DTOR(foo, {});
IMPLEMENT(foo, inc, int, ARGS(foo *self),
self->local += 1;
return self->local;
);
IMPLEMENT(foo, dec, int, ARGS(foo *self),
self->local -= 1;
return self->local;
);
IMPLEMENT(foo, set, void, ARGS(foo *self, int new_value),
self->local = new_value;
);
IMPLEMENT(foo, get, int, ARGS(foo *self),
return self->local;
);
int main() {
// until I figure out how to actually put these in the struct AOT.
CLASS_VTBL(foo).init = _foo_init_;
CLASS_VTBL(foo).destroy = _foo_destroy_;
CLASS_VTBL(foo).inc = _foo_inc_;
CLASS_VTBL(foo).dec = _foo_dec_;
CLASS_VTBL(foo).set = _foo_set_;
CLASS_VTBL(foo).get = _foo_get_;
NEW(foo);
foo *obj = tmpname;
printf("obj->local starts at %i\n", obj->local);
METHODCALL(obj, inc);
METHODCALL(obj, inc);
METHODCALL(obj, dec);
printf("obj->inc() returns %i\n", METHODCALL(obj, inc));
METHODCALL(obj, set, 10);
printf("obj->get() after setting to 10 is %i\n", METHODCALL(obj, get));
}
Comments