-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compilation strategy for polymorphism #60
Comments
However, the question is: How to determine the correct return type? Obviously it makes no sense for each overload to return |
What would be smart is for If the signature is:
Then for each combination (ex. Thus, we can create the following: int8_t add(int8_t a, int8_t b);
int16_t add(int8_t a, int16_t b);
int32_t add(int8_t a, int32_t b);
int64_t add(int8_t a, int64_t b);
int16_t add(int16_t a, int8_t b);
int16_t add(int16_t a, int16_t b);
int32_t add(int16_t a, int32_t b);
// and so on...
int16_t add3(int8_t a, int16_t b, int8_t c);
int16_t add3(int8_t a, int16_t b, int16_t c);
int32_t add3(int8_t a, int16_t b, int32_t c);
int64_t add3(int8_t a, int16_t b, int64_t c);
// and so on... |
class Size {
final int c, llvm;
const Size({@required this.c, @required this.llvm});
}
class BonoboType {
Size get size;
} |
The strategy of determining the correct parameters works nicely for numbers, but what about non-numbers?
The generated C might look something like this: typedef struct {} Automobile;
void Automobile_run(Car* this, double fuel) {
Car_run(this, fuel);
}
void Automobile_run(Plane* this, double fuel) {
Plane_run(this, fuel);
}
typedef struct {
Automobile* super;
} Car;
Car* Car_new() {
Car* instance = (Car*) malloc(sizeof(Car));
return instance;
}
void Car_run(Car* this, double fuel) {
print("Vroom!");
}
typedef struct {
Automobile* super;
} Plane;
Plane* Plane_new() {
Plane* instance = (Plane*) malloc(sizeof(Plane));
return instance;
}
void Plane_run(Plane* this, double fuel) {
print("Whoosh!");
} |
The question is, what about a return type? Obviously, structs can't be inherited, but using What if: typedef struct {
Car *car = NULL;
Plane *plane = NULL;
} Automobile; This solution works well, IMO. |
Generates: Automobile* carFactory() {
Car *car = Car_new();
Automobile *automobile = (Automobile*) malloc(sizeof(Automobile));
automobile->car = car;
return car;
} The compiler is definitely going to have to do a lot of heavy lifting, but I feel that this is a viable way to handle classes and polymorphism in the compiler. |
In Bonobo, we have support for inheritance. Obviously, C does not. What C does have, though, are overloads for different types.
To compile methods that take parameters of types that have multiple forms, we can generate overloads.
For example, take the type
Int
. This is not 100% a perfect example, because integers are primitives, butInt
in reality can have different sizes:Int8
,Int16
,Int32
,Int64
, all of which map to specific C types.Say you have a function,
add
, in a modulefoo
, that takes twoInt
s:Creating overloads that take the different variants of
Int
, compiled to C, is not that difficult:This way, the C compiler would not compile about the types of the passed integers.
The text was updated successfully, but these errors were encountered: