Skip to content

Commit

Permalink
Added an example typechecking against const generics
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-mcdaniel committed Sep 7, 2024
1 parent adf76c1 commit 63309c9
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
113 changes: 113 additions & 0 deletions examples/frontend/typecheck-const-generics.sg
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
struct Matrix<T, Rows: Int, Cols: Int> {
arr: [[T * Cols] * Rows]
}

impl Matrix<T, Rows, Cols> {
fun new(x: T): Matrix<T, Rows, Cols> {
return {arr=[[x] * Cols] * Rows};
}

fun get(&self, row: Int, col: Int): &T {
return &self.arr[row][col];
}

fun mul<NewCols: Int>(
&self,
other: &Matrix<T, Cols, NewCols>,
zero: T,
add: fun(T, T) -> T,
mul: fun(T, T) -> T
): Matrix<T, Rows, NewCols> {
let mut result = Matrix.new<T, Rows, NewCols>(zero);
for let mut j=0; j<NewCols; j+=1; {
for let mut i=0; i<Rows; i+=1; {
let mut sum = zero;
for let mut k=0; k<Cols; k+=1; {
sum = add(sum, mul(self.arr[i][k], other.arr[k][j]));
}
result.arr[i][j] = sum;
}
}
result
}

fun set<X: T>(&mut self, row: Int, col: Int) {
self.arr[row][col] = X;
}

fun set_range<N: Int, X: [T * N]>(&mut self, row: Int) {
for let mut i=0; i<Cols && i<N; i+=1; {
self.arr[row][i] = X[i];
}
}

fun set_row<X: [T * Cols]>(&mut self, row: Int) {
for let mut i=0; i<Cols; i+=1; {
self.arr[row][i] = X[i];
}
}

fun set_col<X: [T * Rows]>(&mut self, col: Int) {
for let mut i=0; i<Rows; i+=1; {
self.arr[i][col] = X[i];
}
}

fun print(&self) {
for let mut row=0; row<Rows; row+=1; {
for let mut col=0; col<Cols; col+=1; {
print(*self.get(row, col), " ");
}
println();
}
}
}

#![(defun echo(x) {
(println x)
x
})]

let mut x = Matrix.new<Int, 4, 4>(10);
let mut y = Matrix.new<Int, 4, 4>(5);
for let mut row=0; row < 4; row += 1; {
y.set_row<[1, 2, 3, 4]>(row);
}
y.set_range<4, [4, 3, 2, 1]>(0);

x.set_col<[1, 2, 3, 4, 5]>(0);
x.set<5>(1, 1);

x.print();
println();
y.print();
println();

fun add_ints(a: Int, b: Int): Int = a + b;
fun mul_ints(a: Int, b: Int): Int = a * b;

let z = y.mul<4>(&x, 0, add_ints, mul_ints);
z.print();

struct Test {
a: Matrix<Int, 10, 1>,
b: Matrix<Int, 10, 10>,
c: Matrix<Int, 10, 1>
}

impl Test {
fun new(): Test {
{a=Matrix.new<Int, 10, 1>(10), b=Matrix.new<Int, 10, 10>(5), c=Matrix.new<Int, 10, 1>(0)}
}

fun test(&mut self) {
let b = self.b;
self.c = b.mul<1>(&self.a, 0, add_ints, mul_ints);
}
}

let mut t = Test.new();
for let mut i=0; i<1; i+=1; {
t.test();
}
t.c.print();
1 change: 1 addition & 0 deletions examples/test-output/typecheck-const-generics.error.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mismatched types: expected [Int * 4], found const param [1, 2, 3, 4, 5] in ((X: [Int * 4]) => (&mut (Matrix)<Int, const param 4, const param 4>, Int) -> None)<const param [1, 2, 3, 4, 5]>

0 comments on commit 63309c9

Please sign in to comment.