Skip to content

Commit

Permalink
fix: use an unified Function object, fix some problems, comments
Browse files Browse the repository at this point in the history
  • Loading branch information
alehander92 committed Jul 28, 2023
1 parent 0c1ed5a commit a3c9ad7
Show file tree
Hide file tree
Showing 29 changed files with 639 additions and 165 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "closures_mut_ref"
authors = [""]
compiler_version = "0.8.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use dep::std;

fn main(mut x: Field) {

let add1 = |z| {
*z = *z + 1;
};

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

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

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

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "fibonacci_by_ref"
authors = [""]
compiler_version = "0.8.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
prev = "1"
cur = "2"
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
fn fib_fn(a: Field, b: Field, res: &mut Field) {
*res = a + b;
}

fn main(mut prev: Field, mut cur: Field) {

let mut fib = prev + cur;
for i in 1..10 {
prev = cur;
cur = fib;
fib_fn(prev, cur, &mut fib);
assert(prev + cur == fib);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "higher_order_fn_selector"
authors = [""]
compiler_version = "0.8.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
fn f(x: &mut Field) -> Field {
*x = *x - 1;
1
}

fn g(x: &mut Field) -> Field {
*x *= 2;
1
}

fn h(x: &mut Field) -> Field {
*x *= 3;
1
}

use dep::std;

fn selector(flag:&mut bool) -> fn(&mut Field) -> Field { //TODO: Can we have fn(&mut Field) -> () return type?
let mut my_func = f;

if *flag {
my_func = g;
}
else {
my_func = h;
};

// Flip the flag for the next function call
*flag = !(*flag);
my_func
}

fn main() {

let mut flag: bool = true;

let mut x: Field = 100;
let returned_func = selector(&mut flag);
let status = returned_func(&mut x);

assert(x == 200);

let mut y: Field = 100;
let returned_func2 = selector(&mut flag);
let status2 = returned_func2(&mut y);

assert(y == 300);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "higher_order_functions"
authors = [""]
compiler_version = "0.1"

[dependencies]
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use dep::std;

fn main() -> pub Field {
let f = if 3 * 7 > 200 as u32 { foo } else { bar };
assert(f()[1] == 2);
// Lambdas:
assert(twice(|x| x * 2, 5) == 20);
assert((|x, y| x + y + 1)(2, 3) == 6);

// nested lambdas
assert((|a, b| {
a + (|c| c + 2)(b)
})(0, 1) == 3);


// Closures:
let a = 42;
let g = || a;
assert(g() == 42);

// TODO: enable this again after fixing #2054
// https://github.com/noir-lang/noir/issues/2054
// by @jfecher's PR https://github.com/noir-lang/noir/pull/2057

// Mutable variables cannot be captured, but you can
// copy them into immutable variables and capture those:
// let mut x = 2;
// x = x + 1;
// let z = x;

// Add extra mutations to ensure we can mutate x without the
// captured z changing.
// x = x + 1;
// TODO: this behavior changed in the new ssa backend:
// now even z is changed, and it wasn't in the previous backend
// assert(z == 2);
// fails!
// decide what to do after opening an issue about the simpler
// variable alias case
//
// assert((|y| y + z)(1) == 4);

let ret = twice(add1, 3);

test_array_functions();
ret
}

/// Test the array functions in std::array
fn test_array_functions() {
let myarray: [i32; 3] = [1, 2, 3];
assert(myarray.any(|n| n > 2));

let evens: [i32; 3] = [2, 4, 6];
assert(evens.all(|n| n > 1));

assert(evens.fold(0, |a, b| a + b) == 12);
assert(evens.reduce(|a, b| a + b) == 12);

// TODO: is this a sort_via issue with the new backend,
// or something more general?
//
// currently it fails only with `--experimental-ssa` with
// "not yet implemented: Cast into signed"
// but it worked with the original ssa backend
// (before dropping it)
//
// let descending = myarray.sort_via(|a, b| a > b);
// assert(descending == [3, 2, 1]);

assert(evens.map(|n| n / 2) == myarray);
}

fn foo() -> [u32; 2] {
[1, 3]
}

fn bar() -> [u32; 2] {
[3, 2]
}

fn add1(x: Field) -> Field {
x + 1
}

fn twice(f: fn(Field) -> Field, x: Field) -> Field {
f(f(x))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"backend":"acvm-backend-barretenberg","abi":{"parameters":[],"param_witnesses":{},"return_type":null,"return_witnesses":[]},"bytecode":[155,194,56,97,194,4,0],"proving_key":null,"verification_key":null}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":32},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":32},"visibility":"private"},{"name":"z","type":{"kind":"integer","sign":"unsigned","width":32},"visibility":"private"}],"param_witnesses":{"x":[1],"y":[2],"z":[3]},"return_type":null,"return_witnesses":[]},"bytecode":"H4sIAAAAAAAA/9WUTW6DMBSEJ/yFhoY26bYLjoAxBLPrVYpK7n+EgmoHamWXeShYQsYSvJ+Z9/kDwCf+1m58ArsXi3PgnUN7dt/u7P9fdi8fW8rlATduCW89GFe5l2iMES90YBd+EyTyjIjtGYIm+HF1eanroa0GpdV3WXW9acq66S9GGdWY5qcyWg+mNm3Xd23ZqVoP6tp0+moDJ5AxNOTUWdk6VUTsOSb6wtRPCuDYziaZAzGA92OMFCsAPCUqMAOcQg5gZwIb4BdsA+A9seeU6AtTPymAUzubZA7EAD6MMTKsAPCUqMAMcAY5gJ0JbIBfsQ2AD8SeM6IvTP2kAM7sbJI5EAP4OMbIsQLAU6ICM8A55AB2JrABfsM2AD4Se86Jvjy5freeQ2LPObGud6J+Ce5ADz6LzJqX9Z4W75HdgzszkQj0BC+Pr6PohSpl0kkg7hm84Zfq+8z36N/l9OyaLtcv2EfpKJUUAAA=","proving_key":null,"verification_key":null}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "inner_outer_cl"
authors = [""]
compiler_version = "0.7.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fn main() {
let cl_outer = |x| {
let cl_inner = |y| {
x + y
};
cl_inner(1)
};
let result = cl_outer(1);
assert(result == 2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "ret_fn_ret_cl"
authors = [""]
compiler_version = "0.7.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "10"
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use dep::std;

fn f(x: Field) -> Field {
x
}

fn ret_fn() -> fn(Field) -> Field {
let y = 1;
let inner_closure = |z| -> Field{
z + y
};
std::println(inner_closure(1));
f
}

fn ret_closure() -> fn(Field) -> Field {
let cl = |z: Field| -> Field {
z
};
cl
}

fn main(x : Field) {
let result_fn = ret_fn();
assert(result_fn(x) == x); // Works

let result_cl = ret_closure();
assert(result_cl(x) == x);
}
2 changes: 1 addition & 1 deletion crates/noirc_evaluator/src/ssa_refactor/ssa_gen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ impl<'a> FunctionContext<'a> {
ast::Type::String(len) => Type::Array(Rc::new(vec![Type::char()]), *len as usize),
ast::Type::Unit => panic!("convert_non_tuple_type called on a unit type"),
ast::Type::Tuple(_) => panic!("convert_non_tuple_type called on a tuple: {typ}"),
ast::Type::Function(_, _) => Type::Function,
ast::Type::Function(_, _, _) => Type::Function,
ast::Type::Slice(element) => {
let element_types = Self::convert_type(element).flatten();
Type::Slice(Rc::new(element_types))
Expand Down
3 changes: 2 additions & 1 deletion crates/noirc_evaluator/src/ssa_refactor/ssa_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ impl<'a> FunctionContext<'a> {
/// Codegen any non-tuple expression so that we can unwrap the Values
/// tree to return a single value for use with most SSA instructions.
fn codegen_non_tuple_expression(&mut self, expr: &Expression) -> ValueId {
self.codegen_expression(expr).into_leaf().eval(self)
let e = self.codegen_expression(expr);
e.into_leaf().eval(self)
}

/// Codegen for identifiers
Expand Down
Loading

0 comments on commit a3c9ad7

Please sign in to comment.