Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Const generics🧮 #79

Merged
merged 29 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c899528
First working example of const generics
adam-mcdaniel Sep 5, 2024
7d48232
Added const-generics
adam-mcdaniel Sep 6, 2024
34414db
Fixed bug where typechecking worked on first pass, but not second
adam-mcdaniel Sep 6, 2024
adf76c1
Added matrix const-generics to example
adam-mcdaniel Sep 7, 2024
63309c9
Added an example typechecking against const generics
adam-mcdaniel Sep 7, 2024
ad69910
Fixed warning
adam-mcdaniel Sep 7, 2024
fdffb3c
Fixed const generics for structs and tuples
adam-mcdaniel Sep 7, 2024
066a6e3
A little optimization
adam-mcdaniel Sep 7, 2024
d4f2829
Fixed warnings
adam-mcdaniel Sep 7, 2024
8faccaf
Added `const` keyword to template constants
adam-mcdaniel Sep 7, 2024
f699f27
Fixed example
adam-mcdaniel Sep 7, 2024
b8a6ac7
Added better typechecking for polymorphic code
adam-mcdaniel Sep 7, 2024
37bb819
Trying to optimize templates
adam-mcdaniel Sep 7, 2024
c088667
Changed log info to debug, added time reporting for parsing
adam-mcdaniel Sep 7, 2024
e9a20ba
Massively optimized parser
adam-mcdaniel Sep 7, 2024
09f2d8a
Added optimization to monomorphization
adam-mcdaniel Sep 7, 2024
09b4d77
Removed warnings
adam-mcdaniel Sep 7, 2024
a17ad01
Removed warnings
adam-mcdaniel Sep 7, 2024
4e98083
Fixed bug where procedure argument types needed to be sized during ty…
adam-mcdaniel Sep 7, 2024
8c5bb90
Fixed web example falling through to other example
adam-mcdaniel Sep 7, 2024
22755f3
Removed extraneous comments and some unused code
adam-mcdaniel Sep 8, 2024
9e36b7e
Removed extraneous comments and some unused code
adam-mcdaniel Sep 8, 2024
2853c59
Removed extraneous comments and some unused code
adam-mcdaniel Sep 8, 2024
ced28fc
Added comments, removed old code
adam-mcdaniel Sep 8, 2024
daaad1e
Added more const generics to examples
adam-mcdaniel Sep 8, 2024
84b5218
Added to examples, fixed bug where consts couldn't be symbols
adam-mcdaniel Sep 8, 2024
9c996c6
Improved web example
adam-mcdaniel Sep 8, 2024
1500d99
Improved web example
adam-mcdaniel Sep 8, 2024
0fdcd0d
Added const generics to readme
adam-mcdaniel Sep 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading