Skip to content

Commit

Permalink
feat: Implement closures in the comptime interpreter (#5682)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves #4879

## Summary\*

Implements closures in the comptime interpreter.

## Additional Context

This ended up being much easier than expected. Almost makes me
suspicious.

## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
jfecher authored Aug 5, 2024
1 parent d52fc05 commit 9e2a323
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
7 changes: 5 additions & 2 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
fn call_closure(
&mut self,
closure: HirLambda,
// TODO: How to define environment here?
_environment: Vec<Value>,
environment: Vec<Value>,
arguments: Vec<(Value, Location)>,
call_location: Location,
) -> IResult<Value> {
Expand All @@ -246,6 +245,10 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
self.define_pattern(parameter, typ, argument, arg_location)?;
}

for (param, arg) in closure.captures.into_iter().zip(environment) {
self.define(param.ident.id, arg);
}

let result = self.evaluate(closure.body)?;

self.exit_function(previous_state);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "comptime_closures"
type = "bin"
authors = [""]
compiler_version = ">=0.32.0"

[dependencies]
39 changes: 39 additions & 0 deletions test_programs/compile_success_empty/comptime_closures/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
fn main() {
comptime
{
closure_test(0);
}
}

fn closure_test(mut x: Field) {
let one = 1;
let add1 = |z| {
(|| {
*z += one;
})()
};

let two = 2;
let add2 = |z| {
*z = *z + two;
};

add1(&mut x);
assert(x == 1);

add2(&mut x);
assert(x == 3);

issue_2120();
}

fn issue_2120() {
let x1 = &mut 42;
let set_x1 = |y| { *x1 = y; };

assert(*x1 == 42);
set_x1(44);
assert(*x1 == 44);
set_x1(*x1);
assert(*x1 == 44);
}

0 comments on commit 9e2a323

Please sign in to comment.