Skip to content

Commit

Permalink
Merge pull request #79 from adam-mcdaniel/const-generics
Browse files Browse the repository at this point in the history
Const generics🧮
  • Loading branch information
adam-mcdaniel authored Sep 8, 2024
2 parents f183292 + 0fdcd0d commit a4a2e85
Show file tree
Hide file tree
Showing 124 changed files with 4,133 additions and 2,141 deletions.
65 changes: 64 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,67 @@ println(main());
The compiler is significantly faster -- about 20 times faster at compiling the AES example.
This is mainly due to the much faster parser implemented with Nom instead of Pest.
There are also several optimizations with constant evaluation I added, along with optimizations
for how declarations are typechecked.
for how declarations are typechecked.


## [0.1.1-alpha] - 2024-9-8

### Added

Added `const` generics, so constant parameters can be passed along with types through templates. This allows the typechecker to be applied to many more aspects of code, including examples like typechecking dimensions of matrix multiplications at compile time.

```rs
struct Matrix<T, const Rows: Int, const 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<const 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
}
}

let mut x = Matrix.new<Int, 4, 4>(10);
let mut y = Matrix.new<Int, 4, 4>(5);

println(x);
println(y);

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);
println(z);
```

### Changed

Changed type system to accommodate const generics. This was done by adding a `ConstParam` variant to types.

### Fixed

Improved parser speed by a significant amount during the process.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ rayon = "1.10"
## ERROR REPORTING
#######################################
codespan-reporting = "0.11"
log = {version = "0.4", features = ["release_max_level_error"] }
log = {version = "0.4", features = ["release_max_level_info"] }
env_logger = "0.11"

#######################################
Expand Down Expand Up @@ -87,5 +87,5 @@ harness = false
[dev-dependencies]
criterion = "0.5"

[profile.release]
debug = true
# [profile.release]
# debug = true
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ Go to the [web-demo](https://adam-mcdaniel.net/sage) or the [examples/frontend](
- [ ] VSCode extension (syntax highlighting, code completion, etc.)
- [ ] Typeclasses
- [ ] `no-std` implementation of compiler
- [x] `const` generics
- [x] Modules
- [x] A standard library
- [ ] Type Reflection Module
Expand Down
4 changes: 2 additions & 2 deletions docs/sage/asm/core/struct.CoreProgram.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/sage/asm/enum.Error.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/sage/asm/std/enum.StandardOp.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/sage/asm/std/struct.StandardProgram.html

Large diffs are not rendered by default.

33 changes: 17 additions & 16 deletions docs/sage/lir/enum.Arithmetic.html

Large diffs are not rendered by default.

58 changes: 30 additions & 28 deletions docs/sage/lir/enum.ConstExpr.html

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions docs/sage/lir/enum.Declaration.html

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions docs/sage/lir/enum.Error.html

Large diffs are not rendered by default.

116 changes: 58 additions & 58 deletions docs/sage/lir/enum.Expr.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/sage/lir/enum.Mutability.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/sage/lir/enum.Pattern.html

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions docs/sage/lir/enum.Put.html

Large diffs are not rendered by default.

130 changes: 91 additions & 39 deletions docs/sage/lir/enum.Type.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.And.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.Assign.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.BitwiseAnd.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.BitwiseNor.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.BitwiseNot.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/sage/lir/struct.CoreBuiltin.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.Data.html

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions docs/sage/lir/struct.Env.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/sage/lir/struct.FFIProcedure.html

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions docs/sage/lir/struct.Get.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.New.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.Not.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/sage/lir/struct.Or.html

Large diffs are not rendered by default.

27 changes: 15 additions & 12 deletions docs/sage/lir/struct.PolyProcedure.html

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/sage/lir/struct.Procedure.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/sage/lir/struct.StandardBuiltin.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.76.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/any.rs.html#141">source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.76.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&amp;self) -&gt; <a class="struct" href="https://doc.rust-lang.org/1.76.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.76.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/borrow.rs.html#208">source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="https://doc.rust-lang.org/1.76.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a>&lt;T&gt; for T<div class="where">where
T: ?<a class="trait" href="https://doc.rust-lang.org/1.76.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/borrow.rs.html#210">source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.76.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&amp;self) -&gt; <a class="primitive" href="https://doc.rust-lang.org/1.76.0/std/primitive.reference.html">&amp;T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.76.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/borrow.rs.html#216">source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="https://doc.rust-lang.org/1.76.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a>&lt;T&gt; for T<div class="where">where
T: ?<a class="trait" href="https://doc.rust-lang.org/1.76.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/borrow.rs.html#217">source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.76.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&amp;mut self) -&gt; <a class="primitive" href="https://doc.rust-lang.org/1.76.0/std/primitive.reference.html">&amp;mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.76.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/convert/mod.rs.html#763">source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="https://doc.rust-lang.org/1.76.0/core/convert/trait.From.html" title="trait core::convert::From">From</a>&lt;T&gt; for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/convert/mod.rs.html#766">source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.76.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -&gt; T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-GetSize-for-T" class="impl"><a class="src rightside" href="../../src/sage/lir/types/size.rs.html#188-195">source</a><a href="#impl-GetSize-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="trait.GetSize.html" title="trait sage::lir::GetSize">GetSize</a> for T<div class="where">where
T: <a class="trait" href="trait.GetType.html" title="trait sage::lir::GetType">GetType</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.get_size_checked" class="method trait-impl"><a class="src rightside" href="../../src/sage/lir/types/size.rs.html#192-194">source</a><a href="#method.get_size_checked" class="anchor">§</a><h4 class="code-header">fn <a href="trait.GetSize.html#tymethod.get_size_checked" class="fn">get_size_checked</a>(&amp;self, env: &amp;<a class="struct" href="struct.Env.html" title="struct sage::lir::Env">Env</a>, i: <a class="primitive" href="https://doc.rust-lang.org/1.76.0/std/primitive.usize.html">usize</a>) -&gt; <a class="enum" href="https://doc.rust-lang.org/1.76.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="https://doc.rust-lang.org/1.76.0/std/primitive.usize.html">usize</a>, <a class="enum" href="enum.Error.html" title="enum sage::lir::Error">Error</a>&gt;</h4></section></summary><div class='docblock'>Get the size of something in memory, but limit the number of recursive
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-GetSize-for-T" class="impl"><a class="src rightside" href="../../src/sage/lir/types/size.rs.html#195-202">source</a><a href="#impl-GetSize-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T&gt; <a class="trait" href="trait.GetSize.html" title="trait sage::lir::GetSize">GetSize</a> for T<div class="where">where
T: <a class="trait" href="trait.GetType.html" title="trait sage::lir::GetType">GetType</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.get_size_checked" class="method trait-impl"><a class="src rightside" href="../../src/sage/lir/types/size.rs.html#199-201">source</a><a href="#method.get_size_checked" class="anchor">§</a><h4 class="code-header">fn <a href="trait.GetSize.html#tymethod.get_size_checked" class="fn">get_size_checked</a>(&amp;self, env: &amp;<a class="struct" href="struct.Env.html" title="struct sage::lir::Env">Env</a>, i: <a class="primitive" href="https://doc.rust-lang.org/1.76.0/std/primitive.usize.html">usize</a>) -&gt; <a class="enum" href="https://doc.rust-lang.org/1.76.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="https://doc.rust-lang.org/1.76.0/std/primitive.usize.html">usize</a>, <a class="enum" href="enum.Error.html" title="enum sage::lir::Error">Error</a>&gt;</h4></section></summary><div class='docblock'>Get the size of something in memory, but limit the number of recursive
calls to prevent stack overflow. <code>i</code> is a counter to prevent infinite
recursion.</div></details><details class="toggle method-toggle" open><summary><section id="method.get_size" class="method trait-impl"><a class="src rightside" href="../../src/sage/lir/types/size.rs.html#33-35">source</a><a href="#method.get_size" class="anchor">§</a><h4 class="code-header">fn <a href="trait.GetSize.html#method.get_size" class="fn">get_size</a>(&amp;self, env: &amp;<a class="struct" href="struct.Env.html" title="struct sage::lir::Env">Env</a>) -&gt; <a class="enum" href="https://doc.rust-lang.org/1.76.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="https://doc.rust-lang.org/1.76.0/std/primitive.usize.html">usize</a>, <a class="enum" href="enum.Error.html" title="enum sage::lir::Error">Error</a>&gt;</h4></section></summary><div class='docblock'>Get the size of something in memory (number of cells).</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/convert/mod.rs.html#747-749">source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl&lt;T, U&gt; <a class="trait" href="https://doc.rust-lang.org/1.76.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a>&lt;U&gt; for T<div class="where">where
U: <a class="trait" href="https://doc.rust-lang.org/1.76.0/core/convert/trait.From.html" title="trait core::convert::From">From</a>&lt;T&gt;,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.76.0/src/core/convert/mod.rs.html#756">source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.76.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -&gt; U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
Expand Down
Loading

0 comments on commit a4a2e85

Please sign in to comment.