Berry improve inheritance #107

This commit is contained in:
Stephan Hadinger 2021-06-17 08:28:55 +02:00
parent 009ea7156c
commit cd99034f79
3 changed files with 10 additions and 0 deletions

View File

@ -165,6 +165,7 @@ static binstance* newobjself(bvm *vm, bclass *c)
while (v < end) { var_setnil(v); ++v; } while (v < end) { var_setnil(v); ++v; }
obj->_class = c; obj->_class = c;
obj->super = NULL; obj->super = NULL;
obj->sub = NULL;
} }
return obj; return obj;
} }
@ -178,6 +179,7 @@ static binstance* newobject(bvm *vm, bclass *c)
be_incrtop(vm); /* protect new objects from GC */ be_incrtop(vm); /* protect new objects from GC */
for (c = c->super; c; c = c->super) { for (c = c->super; c; c = c->super) {
prev->super = newobjself(vm, c); prev->super = newobjself(vm, c);
prev->super->sub = prev;
prev = prev->super; prev = prev->super;
} }
be_stackpop(vm, 1); be_stackpop(vm, 1);

View File

@ -18,11 +18,13 @@
#define be_class_members(cl) ((cl)->members) #define be_class_members(cl) ((cl)->members)
#define be_class_super(cl) ((cl)->super) #define be_class_super(cl) ((cl)->super)
#define be_class_setsuper(self, sup) ((self)->super = (sup)) #define be_class_setsuper(self, sup) ((self)->super = (sup))
#define be_class_setsub(self, sub) ((self)->sub = (sub))
#define be_instance_name(obj) ((obj)->_class->name) #define be_instance_name(obj) ((obj)->_class->name)
#define be_instance_class(obj) ((obj)->_class) #define be_instance_class(obj) ((obj)->_class)
#define be_instance_members(obj) ((obj)->members) #define be_instance_members(obj) ((obj)->members)
#define be_instance_member_count(obj) ((obj)->_class->nvar) #define be_instance_member_count(obj) ((obj)->_class->nvar)
#define be_instance_super(obj) ((obj)->super) #define be_instance_super(obj) ((obj)->super)
#define be_instance_sub(obj) ((obj)->sub)
struct bclass { struct bclass {
bcommon_header; bcommon_header;
@ -41,6 +43,7 @@ struct bclass {
struct binstance { struct binstance {
bcommon_header; bcommon_header;
struct binstance *super; struct binstance *super;
struct binstance *sub;
bclass *_class; bclass *_class;
bgcobject *gray; /* for gc gray list */ bgcobject *gray; /* for gc gray list */
bvalue members[1]; /* members variable data field */ bvalue members[1]; /* members variable data field */

View File

@ -779,6 +779,11 @@ newframe: /* a new call frame */
int type = obj_attribute(vm, b, c, a); int type = obj_attribute(vm, b, c, a);
reg = vm->reg; reg = vm->reg;
if (basetype(type) == BE_FUNCTION) { if (basetype(type) == BE_FUNCTION) {
/* check if the object is a superinstance, if so get the lowest possible subclass */
while (obj->sub) {
obj = obj->sub;
}
var_setobj(&self, var_type(&self), obj); /* replace superinstance by lowest subinstance */
a[1] = self; a[1] = self;
} else { } else {
vm_error(vm, "attribute_error", vm_error(vm, "attribute_error",