-
Notifications
You must be signed in to change notification settings - Fork 0
Description
When designing polymorphism, we need to take the LLVM backend into account, as it is the main backend (and currently the only one that exists).
Inheritance subtype polymorphism
Here is some example syntax for how I want to do this.
class A
let a : Int32
;
class B : A
let b : Int32
;
initB () : B
let b = new B(),
b.a = 7,
b.b = 8,
b
Classes in the AST will hold one parent Class.
class Clazz(val parent : Clazz, ...)
This will create two types in IR. There are two different ways to express these types.
%A = type { i32 }
%B = type { i32, i32 }
%A = type { i32 }
%B = type { %A*, i32 }
The second way poses a problem: Is %A*
the parent class or a field? With the first way, we know every element in the type is a field, with some of them coming from the parent class.
Generics parametric polymorphism
Generics are a great for code reuse and other stuff, so here are some designs for them.
class Box<T>
let value : T
;
main ()
let boxInt32 = new Box<Int32>(),
boxInt32.value = 32,
let boxInt64 = new Box<Int64>(),
boxInt64.value = 64l,
0
Generics can be stored inside the Type class.
class Type(val generics : List<Type> = listOf(), ...)
Only the needed types will be generated.
%Box_Int32 = type { i32 }
%Box_Int64 = type { i64 }
These will be generated in the getLLVMType
function. When parsing, we need to send the generic types in the current Class to getType
. Then we can check if the fields of a Class are one of the generic types.