KAYLukas / FoxyC

Adds class-oriented syntaxis to C, by using macro's only.
0 stars 0 forks source link

Implement interface calls #4

Open KAYLukas opened 10 years ago

KAYLukas commented 10 years ago

As we cannot achieve multiple inheritance (atleast not both as function and as properties) we want to implement interfaces: a set of predefined functions which are assumed to be located in the class.

We want to do something alike:

INode* n = ...
n = foxy(n $ getRootNode());

As each class can implement multiple interfaces, we have no way of addressing the right function pointer in n->class. Also as we cannot retrieve the typename of n, we cannot do something like n->class->INode->getRootNode().

The proposed workaround is rather ugly (even for our current hacking code), but should work:

Each interface struct will never be instantiated, object will only be casted towards them (which is actually a mismatching cast), and as interface do not have any properties (except for the class property), this is not really problematic.

As each interface struct is never instantiated, we can do everything with the body.

The sizeof operator is evaluated at compiletime and is always the same for the same type

A solution would be to give each interface a unique size and use this size to associate a interface with the vtable in the class of the object. Unique sizes could be defined by using COUNTER, but a problem with this approach is, that this size is only object wide (.o) and not link wide unique, i.e. different objects will assume the struct will have different sizes. This would somehow require a object local mapping from struct to class, which is unknown if this is possible. A fallback would be to interpret the call string, but this is terrible slow, and not a real solution.

KAYLukas commented 10 years ago

Does not seem possible:

We need to introduce a new syntaxis: foxy((n via INode) $ getRootNode()); We don't use the 'as' keyword as it does not prevent method hiding, which we want to make explicit. we could also allow binding instance methods to different interface methods, making an interface something more than just an 'abstract' class with multiple inheritance.

KAYLukas commented 10 years ago

We can ensure that the object n has an interface INode by defining a union in the structdef as follows: union{ Class* class; Class* __IMPLEMENTS_INTERFACE_INode; } This ensures in compile time that via can only be used on objects which implements the interface. Otherwise you should cast this.