adam-mcdaniel / sage

A programming language that's wise beyond its bytes!🌱🌿🪴
https://adam-mcdaniel.net/sage-website
MIT License
467 stars 16 forks source link

Parameterized Types in Lower Intermediate Representation #24

Closed adam-mcdaniel closed 1 year ago

adam-mcdaniel commented 1 year ago

I want to add parameterized types to the lower intermediate representation. I expect the architecture to look something like this.

// src/lir/types.rs

enum Param {
    Type(Type),
    Const(ConstExpr),
}

// ...

enum Type {
    // ...

    LetParam(Vec<(String, Vec<(String, Option<Type>)>, Box<Type>>)>, Box<Self>),
    Param(Box<Type>, Vec<Param>)
}

This way, the LetParam will be simplified in terms of the Let variant of the Type type.

let StackVec<T, N: Int> = unit StackVec = [T; N],
    List<T> = struct {
        data: T,
        next: &List<T>
    } in ...

Parameterized types can be substituted directly to an equivalent Let expression of types by converting them like so:

let List<T> = struct {
        data: T,
        next: &List<T>
    } in
        let x: List<Int> = ...

// becomes

let x: (let T = Int, MANGLED_LIST_T_NAME = struct { data: T, next: &MANGLED_LIST_T_NAME } in MANGLED_LIST_T_NAME) in ...

Whenever a parameterized type is instantiated, it checks if that specific instance of the type has already been instantiated. This prevents creating several copies of the type and possibly recursing infinitely.

If not, we drop in the type definition. This will create an in-line type definition with a mangled, unique name for that specific combination of type / const arguments.

adam-mcdaniel commented 1 year ago

This was resolved with #36