1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

add support for ifelse array access, clean up semantic treatment

This commit is contained in:
schaeff 2019-01-18 18:56:56 +01:00
parent e20f104c40
commit b74e0b6dc6
2 changed files with 50 additions and 24 deletions

View file

@ -864,7 +864,30 @@ impl Flattener {
FieldElementArrayExpression::FunctionCall(..) => {
unimplemented!("please use intermediate variables for now")
}
FieldElementArrayExpression::IfElse(..) => unimplemented!(""),
FieldElementArrayExpression::IfElse(
condition,
consequence,
alternative,
) => {
// [if cond then [a, b] else [c, d]][1] == if cond then [a, b][1] else [c, d][1]
self.flatten_field_expression(
functions_flattened,
arguments_flattened,
statements_flattened,
FieldElementExpression::IfElse(
condition,
box FieldElementExpression::Select(
consequence,
box FieldElementExpression::Number(n.clone()),
),
box FieldElementExpression::Select(
alternative,
box FieldElementExpression::Number(n),
),
),
)
.apply_recursive_substitution(&self.substitution)
}
},
e => {
let size = array.size();

View file

@ -540,29 +540,32 @@ impl Checker {
let consequence_checked = self.check_expression(&consequence)?;
let alternative_checked = self.check_expression(&alternative)?;
match (condition_checked, consequence_checked, alternative_checked) {
(TypedExpression::Boolean(condition), TypedExpression::FieldElement(consequence), TypedExpression::FieldElement(alternative)) => {
Ok(FieldElementExpression::IfElse(box condition, box consequence, box alternative).into())
},
(TypedExpression::Boolean(condition), TypedExpression::FieldElementArray(consequence), TypedExpression::FieldElementArray(alternative)) => {
assert!(consequence.get_type() == alternative.get_type());
Ok(FieldElementArrayExpression::IfElse(box condition, box consequence, box alternative).into())
},
(condition, consequence, alternative) =>
Err(
Error {
message:
format!("if {{condition}} then {{consequence}} else {{alternative}} should have types {}, {}, {}, found {}, {}, {}",
Type::Boolean,
Type::FieldElement,
Type::FieldElement,
condition.get_type(),
consequence.get_type(),
alternative.get_type(),
)
}
)
}
match condition_checked {
TypedExpression::Boolean(condition) => {
let consequence_type = consequence_checked.get_type();
let alternative_type = alternative_checked.get_type();
match consequence_type == alternative_type {
true => match (consequence_checked, alternative_checked) {
(TypedExpression::FieldElement(consequence), TypedExpression::FieldElement(alternative)) => {
Ok(FieldElementExpression::IfElse(box condition, box consequence, box alternative).into())
},
(TypedExpression::FieldElementArray(consequence), TypedExpression::FieldElementArray(alternative)) => {
Ok(FieldElementArrayExpression::IfElse(box condition, box consequence, box alternative).into())
},
_ => unimplemented!()
}
false => Err(Error {
message: format!("{{consequence}} and {{alternative}} in `if/else` expression should have the same type, found {}, {}", consequence_type, alternative_type)
})
}
}
c => Err(Error {
message: format!(
"{{condition}} after `if` should be a boolean, found {}",
c.get_type()
),
}),
}
}
&Expression::Number(ref n) => Ok(FieldElementExpression::Number(n.clone()).into()),
&Expression::FunctionCall(ref fun_id, ref arguments) => {