Merge remote-tracking branch 'refs/remotes/origin/develop' into develop
This commit is contained in:
commit
e1c5b6cd42
7 changed files with 94 additions and 4 deletions
|
@ -856,6 +856,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
||||||
true => T::from(1),
|
true => T::from(1),
|
||||||
false => T::from(0),
|
false => T::from(0),
|
||||||
}),
|
}),
|
||||||
|
BooleanExpression::FunctionCall(..) => unreachable!(),
|
||||||
BooleanExpression::IfElse(box condition, box consequence, box alternative) => self
|
BooleanExpression::IfElse(box condition, box consequence, box alternative) => self
|
||||||
.flatten_if_else_expression(
|
.flatten_if_else_expression(
|
||||||
symbols,
|
symbols,
|
||||||
|
|
|
@ -1292,6 +1292,14 @@ impl<'ast> Checker<'ast> {
|
||||||
arguments_checked,
|
arguments_checked,
|
||||||
)
|
)
|
||||||
.into()),
|
.into()),
|
||||||
|
Type::Boolean => Ok(BooleanExpression::FunctionCall(
|
||||||
|
FunctionKey {
|
||||||
|
id: f.id.clone(),
|
||||||
|
signature: f.signature.clone(),
|
||||||
|
},
|
||||||
|
arguments_checked,
|
||||||
|
)
|
||||||
|
.into()),
|
||||||
Type::Struct(members) => Ok(StructExpressionInner::FunctionCall(
|
Type::Struct(members) => Ok(StructExpressionInner::FunctionCall(
|
||||||
FunctionKey {
|
FunctionKey {
|
||||||
id: f.id.clone(),
|
id: f.id.clone(),
|
||||||
|
@ -1310,7 +1318,6 @@ impl<'ast> Checker<'ast> {
|
||||||
)
|
)
|
||||||
.annotate(*array_type.ty.clone(), array_type.size.clone())
|
.annotate(*array_type.ty.clone(), array_type.size.clone())
|
||||||
.into()),
|
.into()),
|
||||||
_ => unimplemented!(),
|
|
||||||
},
|
},
|
||||||
n => Err(Error {
|
n => Err(Error {
|
||||||
pos: Some(pos),
|
pos: Some(pos),
|
||||||
|
@ -1478,12 +1485,31 @@ impl<'ast> Checker<'ast> {
|
||||||
}),
|
}),
|
||||||
(f, t, _) => Ok(ArrayExpressionInner::Value(
|
(f, t, _) => Ok(ArrayExpressionInner::Value(
|
||||||
(f..t)
|
(f..t)
|
||||||
.map(|i| {
|
.map(|i| match inner_type.clone() {
|
||||||
FieldElementExpression::Select(
|
Type::FieldElement => FieldElementExpression::Select(
|
||||||
box array.clone(),
|
box array.clone(),
|
||||||
box FieldElementExpression::Number(T::from(i)),
|
box FieldElementExpression::Number(T::from(i)),
|
||||||
)
|
)
|
||||||
.into()
|
.into(),
|
||||||
|
Type::Boolean => BooleanExpression::Select(
|
||||||
|
box array.clone(),
|
||||||
|
box FieldElementExpression::Number(T::from(i)),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
Type::Struct(struct_ty) => {
|
||||||
|
StructExpressionInner::Select(
|
||||||
|
box array.clone(),
|
||||||
|
box FieldElementExpression::Number(T::from(i)),
|
||||||
|
)
|
||||||
|
.annotate(struct_ty)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
Type::Array(array_ty) => ArrayExpressionInner::Select(
|
||||||
|
box array.clone(),
|
||||||
|
box FieldElementExpression::Number(T::from(i)),
|
||||||
|
)
|
||||||
|
.annotate(*array_ty.ty, array_ty.size)
|
||||||
|
.into(),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -238,6 +238,28 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inline calls which return a boolean element
|
||||||
|
fn fold_boolean_expression(
|
||||||
|
&mut self,
|
||||||
|
e: BooleanExpression<'ast, T>,
|
||||||
|
) -> BooleanExpression<'ast, T> {
|
||||||
|
match e {
|
||||||
|
BooleanExpression::FunctionCall(key, exps) => {
|
||||||
|
let exps: Vec<_> = exps.into_iter().map(|e| self.fold_expression(e)).collect();
|
||||||
|
|
||||||
|
match self.try_inline_call(&key, exps) {
|
||||||
|
Ok(mut ret) => match ret.pop().unwrap() {
|
||||||
|
TypedExpression::Boolean(e) => e,
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
Err((key, expressions)) => BooleanExpression::FunctionCall(key, expressions),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e => fold_boolean_expression(self, e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// inline calls which return an array
|
||||||
fn fold_array_expression_inner(
|
fn fold_array_expression_inner(
|
||||||
&mut self,
|
&mut self,
|
||||||
ty: &Type,
|
ty: &Type,
|
||||||
|
|
|
@ -347,6 +347,10 @@ pub fn fold_boolean_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
||||||
let e = f.fold_boolean_expression(e);
|
let e = f.fold_boolean_expression(e);
|
||||||
BooleanExpression::Not(box e)
|
BooleanExpression::Not(box e)
|
||||||
}
|
}
|
||||||
|
BooleanExpression::FunctionCall(key, exps) => {
|
||||||
|
let exps = exps.into_iter().map(|e| f.fold_expression(e)).collect();
|
||||||
|
BooleanExpression::FunctionCall(key, exps)
|
||||||
|
}
|
||||||
BooleanExpression::IfElse(box cond, box cons, box alt) => {
|
BooleanExpression::IfElse(box cond, box cons, box alt) => {
|
||||||
let cond = f.fold_boolean_expression(cond);
|
let cond = f.fold_boolean_expression(cond);
|
||||||
let cons = f.fold_boolean_expression(cons);
|
let cons = f.fold_boolean_expression(cons);
|
||||||
|
|
|
@ -649,6 +649,7 @@ pub enum BooleanExpression<'ast, T: Field> {
|
||||||
Box<BooleanExpression<'ast, T>>,
|
Box<BooleanExpression<'ast, T>>,
|
||||||
),
|
),
|
||||||
Member(Box<StructExpression<'ast, T>>, MemberId),
|
Member(Box<StructExpression<'ast, T>>, MemberId),
|
||||||
|
FunctionCall(FunctionKey<'ast>, Vec<TypedExpression<'ast, T>>),
|
||||||
Select(
|
Select(
|
||||||
Box<ArrayExpression<'ast, T>>,
|
Box<ArrayExpression<'ast, T>>,
|
||||||
Box<FieldElementExpression<'ast, T>>,
|
Box<FieldElementExpression<'ast, T>>,
|
||||||
|
@ -852,6 +853,16 @@ impl<'ast, T: Field> fmt::Display for BooleanExpression<'ast, T> {
|
||||||
BooleanExpression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs),
|
BooleanExpression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs),
|
||||||
BooleanExpression::Not(ref exp) => write!(f, "!{}", exp),
|
BooleanExpression::Not(ref exp) => write!(f, "!{}", exp),
|
||||||
BooleanExpression::Value(b) => write!(f, "{}", b),
|
BooleanExpression::Value(b) => write!(f, "{}", b),
|
||||||
|
BooleanExpression::FunctionCall(ref k, ref p) => {
|
||||||
|
write!(f, "{}(", k.id,)?;
|
||||||
|
for (i, param) in p.iter().enumerate() {
|
||||||
|
write!(f, "{}", param)?;
|
||||||
|
if i < p.len() - 1 {
|
||||||
|
write!(f, ", ")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write!(f, ")")
|
||||||
|
}
|
||||||
BooleanExpression::IfElse(ref condition, ref consequent, ref alternative) => write!(
|
BooleanExpression::IfElse(ref condition, ref consequent, ref alternative) => write!(
|
||||||
f,
|
f,
|
||||||
"if {} then {} else {} fi",
|
"if {} then {} else {} fi",
|
||||||
|
|
15
zokrates_core_test/tests/tests/complex_call.json
Normal file
15
zokrates_core_test/tests/tests/complex_call.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/complex_call.zok",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["1", "2", "0", "1", "2", "3", "4"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1", "1", "3", "4"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
zokrates_core_test/tests/tests/complex_call.zok
Normal file
11
zokrates_core_test/tests/tests/complex_call.zok
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
struct Foo {
|
||||||
|
bool[2] a
|
||||||
|
field b
|
||||||
|
}
|
||||||
|
|
||||||
|
def f(bool a, field b, Foo c, field[2] d) -> (Foo, field):
|
||||||
|
return Foo { a: [a, a], b: d[0] }, if c.a[0] then b + c.b else d[1] fi
|
||||||
|
|
||||||
|
def main(bool a, field b, Foo c, field[2] d) -> (Foo, field):
|
||||||
|
e, f = f(a, b, c, d)
|
||||||
|
return e, f
|
Loading…
Reference in a new issue