1
0
Fork 0
mirror of synced 2025-09-23 20:28:36 +00:00

Merge remote-tracking branch 'refs/remotes/origin/develop' into develop

This commit is contained in:
William Entriken 2020-01-07 20:39:09 -05:00
commit e1c5b6cd42
7 changed files with 94 additions and 4 deletions

View file

@ -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,

View file

@ -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(),
) )

View file

@ -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,

View file

@ -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);

View file

@ -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",

View 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"]
}
}
}
]
}

View 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