1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00
ZoKrates/zokrates_analysis/src/constant_argument_checker.rs
2022-12-01 21:07:42 +01:00

72 lines
2.4 KiB
Rust

use std::fmt;
use zokrates_ast::common::FlatEmbed;
use zokrates_ast::typed::{
result_folder::fold_statement, result_folder::ResultFolder, Constant, EmbedCall, TypedStatement,
};
use zokrates_ast::typed::{DefinitionRhs, TypedProgram};
use zokrates_field::Field;
pub struct ConstantArgumentChecker;
impl ConstantArgumentChecker {
pub fn check<T: Field>(p: TypedProgram<T>) -> Result<TypedProgram<T>, Error> {
ConstantArgumentChecker.fold_program(p)
}
}
#[derive(Debug)]
pub struct Error(String);
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantArgumentChecker {
type Error = Error;
fn fold_statement(
&mut self,
s: TypedStatement<'ast, T>,
) -> Result<Vec<TypedStatement<'ast, T>>, Self::Error> {
match s {
TypedStatement::Definition(assignee, DefinitionRhs::EmbedCall(embed_call)) => {
match embed_call {
EmbedCall {
embed: FlatEmbed::BitArrayLe,
..
} => {
let arguments = embed_call
.arguments
.into_iter()
.map(|a| self.fold_expression(a))
.collect::<Result<Vec<_>, _>>()?;
if arguments[1].is_constant() {
Ok(vec![TypedStatement::Definition(
assignee,
EmbedCall {
embed: FlatEmbed::BitArrayLe,
generics: embed_call.generics,
arguments,
}
.into(),
)])
} else {
Err(Error(format!(
"Cannot compare to a variable value, found `{}`",
arguments[1]
)))
}
}
embed_call => Ok(vec![TypedStatement::Definition(
assignee,
embed_call.into(),
)]),
}
}
s => fold_statement(self, s),
}
}
}