Skip to content

Polymorphism #7

@phase

Description

@phase

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions