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),
|
||||
false => T::from(0),
|
||||
}),
|
||||
BooleanExpression::FunctionCall(..) => unreachable!(),
|
||||
BooleanExpression::IfElse(box condition, box consequence, box alternative) => self
|
||||
.flatten_if_else_expression(
|
||||
symbols,
|
||||
|
|
|
@ -1292,6 +1292,14 @@ impl<'ast> Checker<'ast> {
|
|||
arguments_checked,
|
||||
)
|
||||
.into()),
|
||||
Type::Boolean => Ok(BooleanExpression::FunctionCall(
|
||||
FunctionKey {
|
||||
id: f.id.clone(),
|
||||
signature: f.signature.clone(),
|
||||
},
|
||||
arguments_checked,
|
||||
)
|
||||
.into()),
|
||||
Type::Struct(members) => Ok(StructExpressionInner::FunctionCall(
|
||||
FunctionKey {
|
||||
id: f.id.clone(),
|
||||
|
@ -1310,7 +1318,6 @@ impl<'ast> Checker<'ast> {
|
|||
)
|
||||
.annotate(*array_type.ty.clone(), array_type.size.clone())
|
||||
.into()),
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
n => Err(Error {
|
||||
pos: Some(pos),
|
||||
|
@ -1478,12 +1485,31 @@ impl<'ast> Checker<'ast> {
|
|||
}),
|
||||
(f, t, _) => Ok(ArrayExpressionInner::Value(
|
||||
(f..t)
|
||||
.map(|i| {
|
||||
FieldElementExpression::Select(
|
||||
.map(|i| match inner_type.clone() {
|
||||
Type::FieldElement => FieldElementExpression::Select(
|
||||
box array.clone(),
|
||||
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(),
|
||||
)
|
||||
|
|
|
@ -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(
|
||||
&mut self,
|
||||
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);
|
||||
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) => {
|
||||
let cond = f.fold_boolean_expression(cond);
|
||||
let cons = f.fold_boolean_expression(cons);
|
||||
|
|
|
@ -649,6 +649,7 @@ pub enum BooleanExpression<'ast, T: Field> {
|
|||
Box<BooleanExpression<'ast, T>>,
|
||||
),
|
||||
Member(Box<StructExpression<'ast, T>>, MemberId),
|
||||
FunctionCall(FunctionKey<'ast>, Vec<TypedExpression<'ast, T>>),
|
||||
Select(
|
||||
Box<ArrayExpression<'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::Not(ref exp) => write!(f, "!{}", exp),
|
||||
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!(
|
||||
f,
|
||||
"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