adam-mcdaniel/sage

Parameterized Types in Lower Intermediate Representation

adam-mcdaniel opened this issue · 1 comments

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.

This was resolved with #36