propagate embed call in reducer
This commit is contained in:
parent
633ee82547
commit
066d3533d8
6 changed files with 44 additions and 14 deletions
1
changelogs/unreleased/1313-schaeff
Normal file
1
changelogs/unreleased/1313-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Propagate embed call
|
|
@ -55,7 +55,7 @@ impl fmt::Display for Error {
|
|||
pub struct Propagator<'ast, T> {
|
||||
// constants keeps track of constant expressions
|
||||
// we currently do not support partially constant expressions: `field [x, 1][1]` is not considered constant, `field [0, 1][1]` is
|
||||
constants: Constants<'ast, T>,
|
||||
pub constants: Constants<'ast, T>,
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Propagator<'ast, T> {
|
||||
|
|
|
@ -213,6 +213,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
|
||||
let return_value = self.fold_expression(return_value)?;
|
||||
|
||||
let return_value = self.propagator.fold_expression(return_value)?;
|
||||
|
||||
Ok(FunctionCallOrExpression::Expression(
|
||||
E::from(return_value).into_inner(),
|
||||
))
|
||||
|
@ -226,22 +228,28 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
FunctionCallExpression::<_, E>::new(e.function_key, generics, arguments)
|
||||
))),
|
||||
Err(InlineError::Flat(embed, generics, output_type)) => {
|
||||
let identifier = self.ssa.issue_next_identifier(CoreIdentifier::Call(0));
|
||||
let identifier = self.ssa.issue_next_identifier(CoreIdentifier::Call);
|
||||
|
||||
let var = Variable::new(identifier.clone(), output_type);
|
||||
|
||||
let v: TypedAssignee<'ast, T> = var.clone().into();
|
||||
|
||||
self.statement_buffer.push(
|
||||
TypedStatement::embed_call_definition(
|
||||
v,
|
||||
EmbedCall::new(embed, generics, arguments),
|
||||
)
|
||||
.span(span),
|
||||
);
|
||||
Ok(FunctionCallOrExpression::Expression(
|
||||
E::identifier(identifier).span(span),
|
||||
))
|
||||
let definition = TypedStatement::embed_call_definition(
|
||||
v,
|
||||
EmbedCall::new(embed, generics, arguments),
|
||||
)
|
||||
.span(span);
|
||||
|
||||
let definition = self.propagator.fold_statement(definition)?;
|
||||
|
||||
self.statement_buffer.extend(definition);
|
||||
|
||||
let e = match self.propagator.constants.get(&identifier) {
|
||||
Some(v) => E::try_from(v.clone()).unwrap().into_inner(),
|
||||
None => E::identifier(identifier),
|
||||
};
|
||||
|
||||
Ok(FunctionCallOrExpression::Expression(e.span(span)))
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ pub type SourceIdentifier<'ast> = std::borrow::Cow<'ast, str>;
|
|||
pub enum CoreIdentifier<'ast> {
|
||||
#[serde(borrow)]
|
||||
Source(ShadowedIdentifier<'ast>),
|
||||
Call(usize),
|
||||
Call,
|
||||
Constant(CanonicalConstantIdentifier<'ast>),
|
||||
Condition(usize),
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ impl<'ast> fmt::Display for CoreIdentifier<'ast> {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
CoreIdentifier::Source(s) => write!(f, "{}", s),
|
||||
CoreIdentifier::Call(i) => write!(f, "#CALL_RETURN_AT_INDEX_{}", i),
|
||||
CoreIdentifier::Call => write!(f, "#CALL_RETURN"),
|
||||
CoreIdentifier::Constant(c) => write!(f, "{}/{}", c.module.display(), c.id),
|
||||
CoreIdentifier::Condition(i) => write!(f, "#CONDITION_{}", i),
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/constants/propagate_embed.zok",
|
||||
"max_constraint_count": 2,
|
||||
"tests": []
|
||||
}
|
16
zokrates_core_test/tests/tests/constants/propagate_embed.zok
Normal file
16
zokrates_core_test/tests/tests/constants/propagate_embed.zok
Normal file
|
@ -0,0 +1,16 @@
|
|||
import "utils/casts/field_to_u32";
|
||||
from "EMBED" import unpack;
|
||||
|
||||
def foo<N>() -> field {
|
||||
return 1;
|
||||
}
|
||||
|
||||
def main() -> field {
|
||||
u32 N = field_to_u32(1);
|
||||
for u32 i in 0..N {
|
||||
log("{}", i);
|
||||
}
|
||||
bool[1] B = unpack(1);
|
||||
u32 P = B[0] ? 1 : 0;
|
||||
return foo::<N>() + foo::<P>();
|
||||
}
|
Loading…
Reference in a new issue