move to non breaking nightly, fix conflicts
This commit is contained in:
commit
43b2a1d350
33 changed files with 285 additions and 266 deletions
1
changelogs/unreleased/997-dark64
Normal file
1
changelogs/unreleased/997-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Make field to uint casts truncate values bigger than uint max
|
|
@ -1 +1 @@
|
|||
nightly-2021-04-25
|
||||
nightly-2021-09-01
|
|
@ -1,2 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2021-04-25"
|
||||
channel = "nightly-2021-09-01"
|
|
@ -0,0 +1,5 @@
|
|||
from "EMBED" import unpack
|
||||
|
||||
def main():
|
||||
bool[2] bits = unpack(4) // we need 3 bits to unpack 4
|
||||
return
|
|
@ -195,7 +195,7 @@ mod tests {
|
|||
let interpreter = ir::Interpreter::default();
|
||||
|
||||
let _ = interpreter
|
||||
.execute(&artifacts.prog(), &[Bn128Field::from(0)])
|
||||
.execute(artifacts.prog(), &[Bn128Field::from(0)])
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ mod tests {
|
|||
|
||||
let interpreter = ir::Interpreter::default();
|
||||
|
||||
let res = interpreter.execute(&artifacts.prog(), &[Bn128Field::from(0)]);
|
||||
let res = interpreter.execute(artifacts.prog(), &[Bn128Field::from(0)]);
|
||||
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ fn cli_export_verifier<T: SolidityCompatibleField, S: SolidityCompatibleScheme<T
|
|||
let mut writer = BufWriter::new(output_file);
|
||||
|
||||
writer
|
||||
.write_all(&verifier.as_bytes())
|
||||
.write_all(verifier.as_bytes())
|
||||
.map_err(|_| "Failed writing output to file".to_string())?;
|
||||
|
||||
println!("Verifier exported to '{}'", output_path.display());
|
||||
|
|
|
@ -603,7 +603,6 @@ impl<'ast> From<pest::PostfixExpression<'ast>> for absy::ExpressionNode<'ast> {
|
|||
|
||||
// pest::PostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but absy::ExpressionNode
|
||||
// is recursive, so it is `Select(Call(a, 34), 42)`. We apply this transformation here
|
||||
|
||||
// we start with the base, and we fold the array of accesses by wrapping the current value
|
||||
expression
|
||||
.accesses
|
||||
|
@ -652,7 +651,7 @@ impl<'ast> From<pest::DecimalLiteralExpression<'ast>> for absy::ExpressionNode<'
|
|||
match expression.suffix {
|
||||
Some(suffix) => match suffix {
|
||||
pest::DecimalSuffix::Field(_) => absy::Expression::FieldConstant(
|
||||
BigUint::parse_bytes(&expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||
BigUint::parse_bytes(expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||
),
|
||||
pest::DecimalSuffix::U64(_) => {
|
||||
absy::Expression::U64Constant(expression.value.span.as_str().parse().unwrap())
|
||||
|
@ -669,7 +668,7 @@ impl<'ast> From<pest::DecimalLiteralExpression<'ast>> for absy::ExpressionNode<'
|
|||
}
|
||||
.span(expression.span),
|
||||
None => absy::Expression::IntConstant(
|
||||
BigUint::parse_bytes(&expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||
BigUint::parse_bytes(expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||
)
|
||||
.span(expression.span),
|
||||
}
|
||||
|
@ -682,16 +681,16 @@ impl<'ast> From<pest::HexLiteralExpression<'ast>> for absy::ExpressionNode<'ast>
|
|||
|
||||
match expression.value {
|
||||
pest::HexNumberExpression::U64(e) => {
|
||||
absy::Expression::U64Constant(u64::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||
absy::Expression::U64Constant(u64::from_str_radix(e.span.as_str(), 16).unwrap())
|
||||
}
|
||||
pest::HexNumberExpression::U32(e) => {
|
||||
absy::Expression::U32Constant(u32::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||
absy::Expression::U32Constant(u32::from_str_radix(e.span.as_str(), 16).unwrap())
|
||||
}
|
||||
pest::HexNumberExpression::U16(e) => {
|
||||
absy::Expression::U16Constant(u16::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||
absy::Expression::U16Constant(u16::from_str_radix(e.span.as_str(), 16).unwrap())
|
||||
}
|
||||
pest::HexNumberExpression::U8(e) => {
|
||||
absy::Expression::U8Constant(u8::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||
absy::Expression::U8Constant(u8::from_str_radix(e.span.as_str(), 16).unwrap())
|
||||
}
|
||||
}
|
||||
.span(expression.span)
|
||||
|
@ -838,7 +837,7 @@ mod tests {
|
|||
#[test]
|
||||
fn return_forty_two() {
|
||||
let source = "def main() -> field: return 42";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
let expected: absy::Module = absy::Module {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: &source[4..8],
|
||||
|
@ -869,7 +868,7 @@ mod tests {
|
|||
#[test]
|
||||
fn return_true() {
|
||||
let source = "def main() -> bool: return true";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
let expected: absy::Module = absy::Module {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: &source[4..8],
|
||||
|
@ -898,7 +897,7 @@ mod tests {
|
|||
#[test]
|
||||
fn arguments() {
|
||||
let source = "def main(private field a, bool b) -> field: return 42";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
|
||||
let expected: absy::Module = absy::Module {
|
||||
symbols: vec";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
assert_eq!(
|
||||
absy::Module::from(ast),
|
||||
wrap(absy::Expression::FunctionCall(
|
||||
|
@ -1147,7 +1146,8 @@ mod tests {
|
|||
fn call_call_result() {
|
||||
// a call after a call should be accepted
|
||||
let source = "def main(): return a(2)(3)";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
assert_eq!(
|
||||
absy::Module::from(ast),
|
||||
wrap(absy::Expression::FunctionCall(
|
||||
|
@ -1167,7 +1167,7 @@ mod tests {
|
|||
fn declarations() {
|
||||
use self::pest::Span;
|
||||
|
||||
let span = Span::new(&"", 0, 0).unwrap();
|
||||
let span = Span::new("", 0, 0).unwrap();
|
||||
|
||||
// For different definitions, we generate declarations
|
||||
// Case 1: `id = expr` where `expr` is not a function call
|
||||
|
@ -1186,7 +1186,7 @@ mod tests {
|
|||
expression: pest::Expression::Literal(pest::LiteralExpression::DecimalLiteral(
|
||||
pest::DecimalLiteralExpression {
|
||||
value: pest::DecimalNumber {
|
||||
span: Span::new(&"1", 0, 1).unwrap(),
|
||||
span: Span::new("1", 0, 1).unwrap(),
|
||||
},
|
||||
suffix: None,
|
||||
span: span.clone(),
|
||||
|
|
|
@ -243,7 +243,7 @@ fn check_with_arena<'ast, T: Field, E: Into<imports::Error>>(
|
|||
|
||||
log::debug!("Parse program with entry file {}", location.display());
|
||||
|
||||
let compiled = parse_program::<T, E>(source, location, resolver, &arena)?;
|
||||
let compiled = parse_program::<T, E>(source, location, resolver, arena)?;
|
||||
|
||||
log::debug!("Check semantics");
|
||||
|
||||
|
@ -271,7 +271,7 @@ pub fn parse_program<'ast, T: Field, E: Into<imports::Error>>(
|
|||
) -> Result<Program<'ast>, CompileErrors> {
|
||||
let mut modules = HashMap::new();
|
||||
|
||||
let main = parse_module::<T, E>(&source, location.clone(), resolver, &mut modules, &arena)?;
|
||||
let main = parse_module::<T, E>(source, location.clone(), resolver, &mut modules, arena)?;
|
||||
|
||||
modules.insert(location.clone(), main);
|
||||
|
||||
|
@ -290,7 +290,7 @@ pub fn parse_module<'ast, T: Field, E: Into<imports::Error>>(
|
|||
) -> Result<Module<'ast>, CompileErrors> {
|
||||
log::debug!("Generate pest AST for {}", location.display());
|
||||
|
||||
let ast = pest::generate_ast(&source)
|
||||
let ast = pest::generate_ast(source)
|
||||
.map_err(|e| CompileErrors::from(CompileErrorInner::from(e).in_file(&location)))?;
|
||||
|
||||
log::debug!("Process macros for {}", location.display());
|
||||
|
@ -309,7 +309,7 @@ pub fn parse_module<'ast, T: Field, E: Into<imports::Error>>(
|
|||
location.clone(),
|
||||
resolver,
|
||||
modules,
|
||||
&arena,
|
||||
arena,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2202,7 +2202,10 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
|
||||
// convert the exponent to bytes, big endian
|
||||
let ebytes_be = e.to_be_bytes();
|
||||
|
||||
// convert the bytes to bits, remove leading zeroes (we only need powers up to the highest non-zero bit)
|
||||
#[allow(clippy::needless_collect)]
|
||||
// collecting is required as we then reverse
|
||||
let ebits_be: Vec<_> = ebytes_be
|
||||
.iter()
|
||||
.flat_map(|byte| (0..8).rev().map(move |i| byte & (1 << i) != 0)) // byte to bit, big endian
|
||||
|
|
|
@ -231,7 +231,7 @@ impl Importer {
|
|||
new_location.clone(),
|
||||
resolver,
|
||||
modules,
|
||||
&arena,
|
||||
arena,
|
||||
)?;
|
||||
|
||||
assert!(modules.insert(new_location.clone(), compiled).is_none());
|
||||
|
@ -239,7 +239,7 @@ impl Importer {
|
|||
};
|
||||
|
||||
SymbolDeclaration {
|
||||
id: &alias,
|
||||
id: alias,
|
||||
symbol: Symbol::There(
|
||||
SymbolImport::with_id_in_module(symbol.id, new_location)
|
||||
.start_end(pos.0, pos.1),
|
||||
|
|
|
@ -10,20 +10,13 @@ pub type ExecutionResult<T> = Result<Witness<T>, Error>;
|
|||
|
||||
impl<T: Field> Prog<T> {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Interpreter {
|
||||
/// Whether we should try to give out-of-range bit decompositions when the input is not a single summand.
|
||||
/// Used to do targetted testing of `<` flattening, making sure the bit decomposition we base the result on is unique.
|
||||
should_try_out_of_range: bool,
|
||||
}
|
||||
|
||||
impl Default for Interpreter {
|
||||
fn default() -> Interpreter {
|
||||
Interpreter {
|
||||
should_try_out_of_range: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpreter {
|
||||
pub fn try_out_of_range() -> Interpreter {
|
||||
Interpreter {
|
||||
|
@ -34,7 +27,7 @@ impl Interpreter {
|
|||
|
||||
impl Interpreter {
|
||||
pub fn execute<T: Field>(&self, program: &Prog<T>, inputs: &[T]) -> ExecutionResult<T> {
|
||||
self.check_inputs(&program, &inputs)?;
|
||||
self.check_inputs(program, inputs)?;
|
||||
let mut witness = BTreeMap::new();
|
||||
witness.insert(FlatVariable::one(), T::one());
|
||||
|
||||
|
@ -274,8 +267,8 @@ impl<T: Field> LinComb<T> {
|
|||
|
||||
impl<T: Field> QuadComb<T> {
|
||||
pub fn evaluate(&self, witness: &BTreeMap<FlatVariable, T>) -> Result<T, EvaluationError> {
|
||||
let left = self.left.evaluate(&witness)?;
|
||||
let right = self.right.evaluate(&witness)?;
|
||||
let left = self.left.evaluate(witness)?;
|
||||
let right = self.right.evaluate(witness)?;
|
||||
Ok(left * right)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ impl<T: Field> Folder<T> for RedefinitionOptimizer<T> {
|
|||
match lc
|
||||
.0
|
||||
.iter()
|
||||
.any(|(variable, _)| self.substitution.get(&variable).is_some())
|
||||
.any(|(variable, _)| self.substitution.get(variable).is_some())
|
||||
{
|
||||
true =>
|
||||
// for each summand, check if it is equal to a linear term in our substitution, otherwise keep it as is
|
||||
|
|
|
@ -126,7 +126,7 @@ impl NonUniversalBackend<Bw6_761Field, GM17> for Ark {
|
|||
.vk
|
||||
.query
|
||||
.iter()
|
||||
.map(|g1| parse_g1::<Bw6_761Field>(g1))
|
||||
.map(parse_g1::<Bw6_761Field>)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
|
|
|
@ -228,8 +228,8 @@ mod parse {
|
|||
let raw_e = e.to_string();
|
||||
let captures = G1_REGEX.captures(&raw_e).unwrap();
|
||||
G1Affine(
|
||||
captures.name(&"x").unwrap().as_str().to_string(),
|
||||
captures.name(&"y").unwrap().as_str().to_string(),
|
||||
captures.name("x").unwrap().as_str().to_string(),
|
||||
captures.name("y").unwrap().as_str().to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -240,12 +240,12 @@ mod parse {
|
|||
let captures = G2_REGEX.captures(&raw_e).unwrap();
|
||||
G2Affine(
|
||||
(
|
||||
captures.name(&"x0").unwrap().as_str().to_string(),
|
||||
captures.name(&"x1").unwrap().as_str().to_string(),
|
||||
captures.name("x0").unwrap().as_str().to_string(),
|
||||
captures.name("x1").unwrap().as_str().to_string(),
|
||||
),
|
||||
(
|
||||
captures.name(&"y0").unwrap().as_str().to_string(),
|
||||
captures.name(&"y1").unwrap().as_str().to_string(),
|
||||
captures.name("y0").unwrap().as_str().to_string(),
|
||||
captures.name("y1").unwrap().as_str().to_string(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ mod parse {
|
|||
pub fn parse_fr<T: BellmanFieldExtensions>(e: &<T::BellmanEngine as ScalarEngine>::Fr) -> Fr {
|
||||
let raw_e = e.to_string();
|
||||
let captures = FR_REGEX.captures(&raw_e).unwrap();
|
||||
captures.name(&"x").unwrap().as_str().to_string()
|
||||
captures.name("x").unwrap().as_str().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ impl<'ast, T: Field> FunctionQuery<'ast, T> {
|
|||
.inputs
|
||||
.iter()
|
||||
.zip(func.signature.inputs.iter())
|
||||
.all(|(input_ty, sig_ty)| input_ty.can_be_specialized_to(&sig_ty))
|
||||
.all(|(input_ty, sig_ty)| input_ty.can_be_specialized_to(sig_ty))
|
||||
&& self.outputs.len() == func.signature.outputs.len()
|
||||
&& self
|
||||
.outputs
|
||||
|
@ -242,7 +242,7 @@ impl<'ast, T: Field> FunctionQuery<'ast, T> {
|
|||
.all(|(output_ty, sig_ty)| {
|
||||
output_ty
|
||||
.as_ref()
|
||||
.map(|output_ty| output_ty.can_be_specialized_to(&sig_ty))
|
||||
.map(|output_ty| output_ty.can_be_specialized_to(sig_ty))
|
||||
.unwrap_or(true)
|
||||
})
|
||||
}
|
||||
|
@ -378,7 +378,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
let ty = self.check_declaration_type(
|
||||
c.value.ty.clone(),
|
||||
module_id,
|
||||
&state,
|
||||
state,
|
||||
&BTreeMap::default(),
|
||||
&mut HashSet::default(),
|
||||
)?;
|
||||
|
@ -396,11 +396,10 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
UExpression::try_from_typed(checked_expr, &bitwidth).map(TypedExpression::from)
|
||||
}
|
||||
DeclarationType::Array(ref array_ty) => {
|
||||
ArrayExpression::try_from_typed(checked_expr, &array_ty).map(TypedExpression::from)
|
||||
ArrayExpression::try_from_typed(checked_expr, array_ty).map(TypedExpression::from)
|
||||
}
|
||||
DeclarationType::Struct(ref struct_ty) => {
|
||||
StructExpression::try_from_typed(checked_expr, &struct_ty)
|
||||
.map(TypedExpression::from)
|
||||
StructExpression::try_from_typed(checked_expr, struct_ty).map(TypedExpression::from)
|
||||
}
|
||||
DeclarationType::Int => Err(checked_expr), // Integers cannot be assigned
|
||||
}
|
||||
|
@ -1822,7 +1821,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
let arguments_types: Vec<_> =
|
||||
arguments_checked.iter().map(|a| a.get_type()).collect();
|
||||
|
||||
let query = FunctionQuery::new(&fun_id, &generics_checked, &arguments_types, &assignee_types);
|
||||
let query = FunctionQuery::new(fun_id, &generics_checked, &arguments_types, &assignee_types);
|
||||
|
||||
let functions = self.find_functions(&query);
|
||||
|
||||
|
@ -1868,7 +1867,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
let pos = assignee.pos();
|
||||
// check that the assignee is declared
|
||||
match assignee.value {
|
||||
Assignee::Identifier(variable_name) => match self.get_key_value_scope(&variable_name) {
|
||||
Assignee::Identifier(variable_name) => match self.get_key_value_scope(variable_name) {
|
||||
Some((id, ty)) => match id.is_constant() {
|
||||
true => Err(ErrorInner {
|
||||
pos: Some(assignee.pos()),
|
||||
|
@ -2004,7 +2003,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
Expression::Identifier(name) => {
|
||||
// check that `id` is defined in the scope
|
||||
match self
|
||||
.get_key_value_scope(&name)
|
||||
.get_key_value_scope(name)
|
||||
.map(|(x, y)| (x.clone(), y.clone()))
|
||||
{
|
||||
Some((id, ty)) => match ty {
|
||||
|
@ -2384,7 +2383,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
// outside of multidef, function calls must have a single return value
|
||||
// we use type inference to determine the type of the return, so we don't specify it
|
||||
let query =
|
||||
FunctionQuery::new(&fun_id, &generics_checked, &arguments_types, &[None]);
|
||||
FunctionQuery::new(fun_id, &generics_checked, &arguments_types, &[None]);
|
||||
|
||||
let functions = self.find_functions(&query);
|
||||
|
||||
|
@ -2397,7 +2396,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
|
||||
let signature = f.signature;
|
||||
|
||||
let arguments_checked = arguments_checked.into_iter().zip(signature.inputs.iter()).map(|(a, t)| TypedExpression::align_to_type(a, &t)).collect::<Result<Vec<_>, _>>().map_err(|e| ErrorInner {
|
||||
let arguments_checked = arguments_checked.into_iter().zip(signature.inputs.iter()).map(|(a, t)| TypedExpression::align_to_type(a, t)).collect::<Result<Vec<_>, _>>().map_err(|e| ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!("Expected function call argument to be of type {}, found {}", e.1, e.0)
|
||||
})?;
|
||||
|
@ -3346,7 +3345,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
fn exit_scope(&mut self) {
|
||||
let current_level = self.level;
|
||||
self.scope
|
||||
.retain(|ref scoped_variable, _| scoped_variable.level < current_level);
|
||||
.retain(|scoped_variable, _| scoped_variable.level < current_level);
|
||||
self.level -= 1;
|
||||
}
|
||||
}
|
||||
|
@ -3873,22 +3872,20 @@ mod tests {
|
|||
.get(&*MODULE_ID)
|
||||
.unwrap()
|
||||
.functions_iter()
|
||||
.find(|d| d.key
|
||||
.any(|d| d.key
|
||||
== DeclarationFunctionKey::with_location((*MODULE_ID).clone(), "foo")
|
||||
.signature(DeclarationSignature::new()))
|
||||
.is_some());
|
||||
.signature(DeclarationSignature::new())));
|
||||
|
||||
assert!(state
|
||||
.typed_modules
|
||||
.get(&*MODULE_ID)
|
||||
.unwrap()
|
||||
.functions_iter()
|
||||
.find(|d| d.key
|
||||
.any(|d| d.key
|
||||
== DeclarationFunctionKey::with_location((*MODULE_ID).clone(), "foo")
|
||||
.signature(
|
||||
DeclarationSignature::new().inputs(vec![DeclarationType::FieldElement])
|
||||
))
|
||||
.is_some());
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -22,6 +22,7 @@ pub type Constants<'ast, T> = HashMap<Identifier<'ast>, TypedExpression<'ast, T>
|
|||
pub enum Error {
|
||||
Type(String),
|
||||
AssertionFailed(String),
|
||||
ValueTooLarge(String),
|
||||
OutOfBounds(u128, u128),
|
||||
NonConstantExponent(String),
|
||||
}
|
||||
|
@ -31,6 +32,7 @@ impl fmt::Display for Error {
|
|||
match self {
|
||||
Error::Type(s) => write!(f, "{}", s),
|
||||
Error::AssertionFailed(s) => write!(f, "{}", s),
|
||||
Error::ValueTooLarge(s) => write!(f, "{}", s),
|
||||
Error::OutOfBounds(index, size) => write!(
|
||||
f,
|
||||
"Out of bounds index ({} >= {}) found during static analysis",
|
||||
|
@ -79,7 +81,7 @@ impl<'ast, 'a, T: Field> Propagator<'ast, 'a, T> {
|
|||
.map(|c| Ok((var, c)))
|
||||
.unwrap_or(Err(var)),
|
||||
TypedAssignee::Select(box assignee, box index) => {
|
||||
match self.try_get_constant_mut(&assignee) {
|
||||
match self.try_get_constant_mut(assignee) {
|
||||
Ok((variable, constant)) => match index.as_inner() {
|
||||
UExpressionInner::Value(n) => match constant {
|
||||
TypedExpression::Array(a) => match a.as_inner_mut() {
|
||||
|
@ -101,7 +103,7 @@ impl<'ast, 'a, T: Field> Propagator<'ast, 'a, T> {
|
|||
e => e,
|
||||
}
|
||||
}
|
||||
TypedAssignee::Member(box assignee, m) => match self.try_get_constant_mut(&assignee) {
|
||||
TypedAssignee::Member(box assignee, m) => match self.try_get_constant_mut(assignee) {
|
||||
Ok((v, c)) => {
|
||||
let ty = assignee.get_type();
|
||||
|
||||
|
@ -381,47 +383,47 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
match arguments.iter().all(|a| a.is_constant()) {
|
||||
true => {
|
||||
let r: Option<TypedExpression<'ast, T>> = match embed {
|
||||
FlatEmbed::BitArrayLe => None, // todo
|
||||
FlatEmbed::U64FromBits => Some(process_u_from_bits(
|
||||
FlatEmbed::BitArrayLe => Ok(None), // todo
|
||||
FlatEmbed::U64FromBits => Ok(Some(process_u_from_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B64,
|
||||
)),
|
||||
FlatEmbed::U32FromBits => Some(process_u_from_bits(
|
||||
))),
|
||||
FlatEmbed::U32FromBits => Ok(Some(process_u_from_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B32,
|
||||
)),
|
||||
FlatEmbed::U16FromBits => Some(process_u_from_bits(
|
||||
))),
|
||||
FlatEmbed::U16FromBits => Ok(Some(process_u_from_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B16,
|
||||
)),
|
||||
FlatEmbed::U8FromBits => Some(process_u_from_bits(
|
||||
))),
|
||||
FlatEmbed::U8FromBits => Ok(Some(process_u_from_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B8,
|
||||
)),
|
||||
FlatEmbed::U64ToBits => Some(process_u_to_bits(
|
||||
))),
|
||||
FlatEmbed::U64ToBits => Ok(Some(process_u_to_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B64,
|
||||
)),
|
||||
FlatEmbed::U32ToBits => Some(process_u_to_bits(
|
||||
))),
|
||||
FlatEmbed::U32ToBits => Ok(Some(process_u_to_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B32,
|
||||
)),
|
||||
FlatEmbed::U16ToBits => Some(process_u_to_bits(
|
||||
))),
|
||||
FlatEmbed::U16ToBits => Ok(Some(process_u_to_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B16,
|
||||
)),
|
||||
FlatEmbed::U8ToBits => Some(process_u_to_bits(
|
||||
))),
|
||||
FlatEmbed::U8ToBits => Ok(Some(process_u_to_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B8,
|
||||
)),
|
||||
))),
|
||||
FlatEmbed::Unpack => {
|
||||
assert_eq!(assignees.len(), 1);
|
||||
assert_eq!(arguments.len(), 1);
|
||||
|
@ -429,46 +431,55 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
let bit_width = generics[0];
|
||||
|
||||
match FieldElementExpression::try_from(arguments[0].clone())
|
||||
.unwrap()
|
||||
match FieldElementExpression::<T>::try_from(
|
||||
arguments[0].clone(),
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
FieldElementExpression::Number(num) => {
|
||||
let mut num = num;
|
||||
let mut acc = num.clone();
|
||||
let mut res = vec![];
|
||||
|
||||
for i in (0..bit_width as usize).rev() {
|
||||
if T::from(2).pow(i) <= num {
|
||||
num = num - T::from(2).pow(i);
|
||||
if T::from(2).pow(i) <= acc {
|
||||
acc = acc - T::from(2).pow(i);
|
||||
res.push(true);
|
||||
} else {
|
||||
res.push(false);
|
||||
}
|
||||
}
|
||||
assert_eq!(num, T::zero());
|
||||
|
||||
Some(
|
||||
ArrayExpressionInner::Value(
|
||||
res.into_iter()
|
||||
.map(|v| {
|
||||
BooleanExpression::Value(v).into()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
)
|
||||
.annotate(Type::Boolean, bit_width)
|
||||
.into(),
|
||||
)
|
||||
if acc != T::zero() {
|
||||
Err(Error::ValueTooLarge(format!(
|
||||
"Cannot unpack `{}` to `{}`: value is too large",
|
||||
num, assignees.first().unwrap().get_type()
|
||||
)))
|
||||
} else {
|
||||
Ok(Some(
|
||||
ArrayExpressionInner::Value(
|
||||
res.into_iter()
|
||||
.map(|v| {
|
||||
BooleanExpression::Value(v)
|
||||
.into()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
)
|
||||
.annotate(Type::Boolean, bit_width)
|
||||
.into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => unreachable!("should be a field value"),
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "bellman")]
|
||||
FlatEmbed::Sha256Round => None,
|
||||
FlatEmbed::Sha256Round => Ok(None),
|
||||
#[cfg(feature = "ark")]
|
||||
FlatEmbed::SnarkVerifyBls12377 => None,
|
||||
};
|
||||
FlatEmbed::SnarkVerifyBls12377 => Ok(None),
|
||||
}?;
|
||||
|
||||
match r {
|
||||
Ok(match r {
|
||||
// if the function call returns a constant
|
||||
Some(expr) => {
|
||||
let mut assignees = assignees;
|
||||
|
@ -494,9 +505,11 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
assignee, expr,
|
||||
),
|
||||
],
|
||||
None => vec![TypedStatement::Definition(
|
||||
assignee, expr,
|
||||
)],
|
||||
None => {
|
||||
vec![TypedStatement::Definition(
|
||||
assignee, expr,
|
||||
)]
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -534,7 +547,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
)],
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
false => {
|
||||
// if the function arguments are not constant, invalidate the cache
|
||||
|
@ -548,7 +561,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
let invalidations = assignees.iter().flat_map(|assignee| {
|
||||
let v = self
|
||||
.try_get_constant_mut(&assignee)
|
||||
.try_get_constant_mut(assignee)
|
||||
.map(|(v, _)| v)
|
||||
.unwrap_or_else(|v| v);
|
||||
match self.constants.remove(&v.id) {
|
||||
|
@ -559,7 +572,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
}
|
||||
});
|
||||
|
||||
invalidations.chain(std::iter::once(def)).collect()
|
||||
Ok(invalidations.chain(std::iter::once(def)).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -590,7 +603,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
let invalidations = assignees.iter().flat_map(|assignee| {
|
||||
let v = self
|
||||
.try_get_constant_mut(&assignee)
|
||||
.try_get_constant_mut(assignee)
|
||||
.map(|(v, _)| v)
|
||||
.unwrap_or_else(|v| v);
|
||||
match self.constants.remove(&v.id) {
|
||||
|
@ -601,9 +614,9 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
}
|
||||
});
|
||||
|
||||
invalidations.chain(std::iter::once(def)).collect()
|
||||
Ok(invalidations.chain(std::iter::once(def)).collect())
|
||||
}
|
||||
};
|
||||
}?;
|
||||
|
||||
Ok(statements)
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ fn get_canonical_function<'ast, T: Field>(
|
|||
.unwrap();
|
||||
|
||||
match &s.symbol {
|
||||
TypedFunctionSymbol::There(key) => get_canonical_function(key.clone(), &program),
|
||||
TypedFunctionSymbol::There(key) => get_canonical_function(key.clone(), program),
|
||||
_ => s.clone(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ fn register<'ast>(
|
|||
) {
|
||||
for (id, key, value) in substitute
|
||||
.iter()
|
||||
.filter_map(|(id, version)| with.get(&id).map(|to| (id, version, to)))
|
||||
.filter_map(|(id, version)| with.get(id).map(|to| (id, version, to)))
|
||||
.filter(|(_, key, value)| key != value)
|
||||
{
|
||||
let sub = substitutions.0.entry(id.clone()).or_default();
|
||||
|
@ -235,8 +235,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
generics,
|
||||
arguments,
|
||||
ty,
|
||||
&self.program,
|
||||
&mut self.versions,
|
||||
self.program,
|
||||
self.versions,
|
||||
);
|
||||
|
||||
match res {
|
||||
|
@ -354,8 +354,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
generics,
|
||||
arguments,
|
||||
&types,
|
||||
&self.program,
|
||||
&mut self.versions,
|
||||
self.program,
|
||||
self.versions,
|
||||
) {
|
||||
Ok(Output::Complete((statements, expressions))) => {
|
||||
assert_eq!(v.len(), expressions.len());
|
||||
|
@ -420,7 +420,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
self.versions.values_mut().for_each(|v| *v += 1);
|
||||
|
||||
// add this set of versions to the substitution, pointing to the versions before the loop
|
||||
register(&mut self.substitutions, &self.versions, &versions_before);
|
||||
register(self.substitutions, self.versions, &versions_before);
|
||||
|
||||
// the versions after the loop are found by applying an offset of 2 to the versions before the loop
|
||||
let versions_after = versions_before
|
||||
|
@ -429,7 +429,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
.map(|(k, v)| (k, v + 2))
|
||||
.collect();
|
||||
|
||||
let mut transformer = ShallowTransformer::with_versions(&mut self.versions);
|
||||
let mut transformer = ShallowTransformer::with_versions(self.versions);
|
||||
|
||||
if to - from > MAX_FOR_LOOP_SIZE {
|
||||
return Err(Error::LoopTooLarge(to.saturating_sub(*from)));
|
||||
|
@ -454,7 +454,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
|
||||
// we know the final versions of the variables after full unrolling of the loop
|
||||
// the versions after the loop need to point to these, so we add to the substitutions
|
||||
register(&mut self.substitutions, &versions_after, &self.versions);
|
||||
register(self.substitutions, &versions_after, self.versions);
|
||||
|
||||
// we may have found new for loops when unrolling this one, which means new backed up versions
|
||||
// we insert these in our backup list and update our cursor
|
||||
|
@ -573,7 +573,7 @@ fn reduce_function<'ast, T: Field>(
|
|||
|
||||
loop {
|
||||
let mut reducer = Reducer::new(
|
||||
&program,
|
||||
program,
|
||||
&mut versions,
|
||||
&mut substitutions,
|
||||
for_loop_versions,
|
||||
|
|
|
@ -28,7 +28,7 @@ impl fmt::Display for Error {
|
|||
impl UnconstrainedVariableDetector {
|
||||
pub fn detect<T: Field>(p: &Prog<T>) -> Result<(), Error> {
|
||||
let mut instance = Self::default();
|
||||
instance.visit_module(&p);
|
||||
instance.visit_module(p);
|
||||
|
||||
if instance.variables.is_empty() {
|
||||
Ok(())
|
||||
|
@ -118,39 +118,39 @@ mod tests {
|
|||
// (1 * ~one) * (1 * ~one + (-1) * _1) == 1 * ~out_0
|
||||
// return ~out_0
|
||||
|
||||
let _0 = FlatParameter::private(FlatVariable::new(0));
|
||||
let _1 = FlatVariable::new(1);
|
||||
let _2 = FlatVariable::new(2);
|
||||
let v_0 = FlatParameter::private(FlatVariable::new(0));
|
||||
let v_1 = FlatVariable::new(1);
|
||||
let v_2 = FlatVariable::new(2);
|
||||
|
||||
let out_0 = FlatVariable::public(0);
|
||||
let one = FlatVariable::one();
|
||||
|
||||
let p: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![_0],
|
||||
arguments: vec![v_0],
|
||||
statements: vec![
|
||||
Statement::Directive(Directive {
|
||||
inputs: vec![(LinComb::summand(-42, one) + LinComb::summand(1, _0.id)).into()],
|
||||
outputs: vec![_1, _2],
|
||||
inputs: vec![(LinComb::summand(-42, one) + LinComb::summand(1, v_0.id)).into()],
|
||||
outputs: vec![v_1, v_2],
|
||||
solver: Solver::ConditionEq,
|
||||
}),
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(-42, one) + LinComb::summand(1, _0.id),
|
||||
LinComb::summand(1, _2),
|
||||
LinComb::summand(-42, one) + LinComb::summand(1, v_0.id),
|
||||
LinComb::summand(1, v_2),
|
||||
),
|
||||
LinComb::summand(1, _1),
|
||||
LinComb::summand(1, v_1),
|
||||
),
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(1, one) + LinComb::summand(-1, _1),
|
||||
LinComb::summand(-42, one) + LinComb::summand(1, _0.id),
|
||||
LinComb::summand(1, one) + LinComb::summand(-1, v_1),
|
||||
LinComb::summand(-42, one) + LinComb::summand(1, v_0.id),
|
||||
),
|
||||
LinComb::zero(),
|
||||
),
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(1, one),
|
||||
LinComb::summand(1, one) + LinComb::summand(-1, _1),
|
||||
LinComb::summand(1, one) + LinComb::summand(-1, v_1),
|
||||
),
|
||||
LinComb::summand(1, out_0),
|
||||
),
|
||||
|
|
|
@ -597,7 +597,7 @@ impl<'ast, T: Field> ArrayExpression<'ast, T> {
|
|||
inline_array
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
TypedExpressionOrSpread::align_to_type(v, &target_array_ty).map_err(
|
||||
TypedExpressionOrSpread::align_to_type(v, target_array_ty).map_err(
|
||||
|(e, _)| match e {
|
||||
TypedExpressionOrSpread::Expression(e) => e,
|
||||
TypedExpressionOrSpread::Spread(a) => {
|
||||
|
@ -620,7 +620,7 @@ impl<'ast, T: Field> ArrayExpression<'ast, T> {
|
|||
GType::Int => Ok(ArrayExpressionInner::Repeat(box e, box count)
|
||||
.annotate(Type::Int, array_ty.size)),
|
||||
// try to align the repeated element to the target type
|
||||
t => TypedExpression::align_to_type(e, &t)
|
||||
t => TypedExpression::align_to_type(e, t)
|
||||
.map(|e| {
|
||||
let ty = e.get_type().clone();
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ impl<'ast, T: Field> TypedFunctionSymbol<'ast, T> {
|
|||
.find(|d| d.key == *key)
|
||||
.unwrap()
|
||||
.symbol
|
||||
.signature(&modules),
|
||||
.signature(modules),
|
||||
TypedFunctionSymbol::Flat(flat_fun) => flat_fun.typed_signature(),
|
||||
}
|
||||
}
|
||||
|
@ -1588,7 +1588,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for FieldElementExpression<'ast, T> {
|
|||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
&self
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
|
@ -1609,7 +1609,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for BooleanExpression<'ast, T> {
|
|||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
&self
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
|
@ -1693,7 +1693,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for IntExpression<'ast, T> {
|
|||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
&self
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
|
|
|
@ -301,7 +301,7 @@ impl<S: fmt::Display> fmt::Display for GArrayType<S> {
|
|||
) -> fmt::Result {
|
||||
acc.push(&t.size);
|
||||
match &*t.ty {
|
||||
GType::Array(array_type) => fmt_aux(f, &array_type, acc),
|
||||
GType::Array(array_type) => fmt_aux(f, array_type, acc),
|
||||
t => {
|
||||
write!(f, "{}", t)?;
|
||||
for i in acc {
|
||||
|
@ -314,7 +314,7 @@ impl<S: fmt::Display> fmt::Display for GArrayType<S> {
|
|||
|
||||
let acc = vec![];
|
||||
|
||||
fmt_aux(f, &self, acc)
|
||||
fmt_aux(f, self, acc)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ impl<S> GStructType<S> {
|
|||
}
|
||||
|
||||
fn location(&self) -> &StructLocation {
|
||||
&self.location.as_ref().unwrap_or(&self.canonical_location)
|
||||
self.location.as_ref().unwrap_or(&self.canonical_location)
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
|
@ -1009,7 +1009,7 @@ pub fn specialize_declaration_type<
|
|||
Ok(match decl_ty {
|
||||
DeclarationType::Int => unreachable!(),
|
||||
DeclarationType::Array(t0) => {
|
||||
let ty = box specialize_declaration_type(*t0.ty, &generics)?;
|
||||
let ty = box specialize_declaration_type(*t0.ty, generics)?;
|
||||
let size = match t0.size {
|
||||
DeclarationConstant::Generic(s) => generics.0.get(&s).cloned().ok_or(s),
|
||||
DeclarationConstant::Concrete(s) => Ok(s.into()),
|
||||
|
@ -1085,7 +1085,7 @@ pub mod signature {
|
|||
|
||||
impl<S: Ord> Ord for GSignature<S> {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.partial_cmp(&other).unwrap()
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ fn lt_field() {
|
|||
|
||||
assert!(interpreter
|
||||
.execute(
|
||||
&res.prog(),
|
||||
res.prog(),
|
||||
&[Bn128Field::from(10000), Bn128Field::from(5555)]
|
||||
)
|
||||
.is_err());
|
||||
|
@ -70,7 +70,7 @@ fn lt_uint() {
|
|||
|
||||
assert!(interpreter
|
||||
.execute(
|
||||
&res.prog(),
|
||||
res.prog(),
|
||||
&[Bn128Field::from(10000), Bn128Field::from(5555)]
|
||||
)
|
||||
.is_err());
|
||||
|
@ -112,7 +112,7 @@ fn unpack256() {
|
|||
let interpreter = Interpreter::try_out_of_range();
|
||||
|
||||
assert!(interpreter
|
||||
.execute(&res.prog(), &[Bn128Field::from(0)])
|
||||
.execute(res.prog(), &[Bn128Field::from(0)])
|
||||
.is_err());
|
||||
}
|
||||
|
||||
|
@ -152,6 +152,6 @@ fn unpack256_unchecked() {
|
|||
let interpreter = Interpreter::try_out_of_range();
|
||||
|
||||
assert!(interpreter
|
||||
.execute(&res.prog(), &[Bn128Field::from(0)])
|
||||
.execute(res.prog(), &[Bn128Field::from(0)])
|
||||
.is_ok());
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ pub fn generate_verify_constraints(
|
|||
let num_instance_variables = cs.num_instance_variables();
|
||||
let input_indices = fp_vars
|
||||
.iter()
|
||||
.map(|f| var_to_index(&f, 0))
|
||||
.map(|f| var_to_index(f, 0))
|
||||
.collect::<Vec<usize>>();
|
||||
|
||||
let proof_indices: Vec<usize> = vec![
|
||||
|
|
|
@ -803,7 +803,7 @@ mod ast {
|
|||
match self {
|
||||
Expression::Binary(b) => &b.span,
|
||||
Expression::Identifier(i) => &i.span,
|
||||
Expression::Literal(c) => &c.span(),
|
||||
Expression::Literal(c) => c.span(),
|
||||
Expression::Ternary(t) => &t.span,
|
||||
Expression::Postfix(p) => &p.span,
|
||||
Expression::InlineArray(a) => &a.span,
|
||||
|
@ -1092,57 +1092,57 @@ mod tests {
|
|||
def main() -> (field): return 1 + 1
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![
|
||||
SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
span: Span::new(source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
span: Span::new(source, 0, 29).unwrap()
|
||||
})),
|
||||
SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
span: Span::new(source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
span: Span::new(source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::add(
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 59, 60).unwrap()
|
||||
span: Span::new(source, 59, 60).unwrap()
|
||||
},
|
||||
suffix: None,
|
||||
span: Span::new(&source, 59, 60).unwrap()
|
||||
span: Span::new(source, 59, 60).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 63, 64).unwrap()
|
||||
span: Span::new(source, 63, 64).unwrap()
|
||||
},
|
||||
suffix: None,
|
||||
span: Span::new(&source, 63, 64).unwrap()
|
||||
span: Span::new(source, 63, 64).unwrap()
|
||||
}
|
||||
)),
|
||||
Span::new(&source, 59, 64).unwrap()
|
||||
Span::new(source, 59, 64).unwrap()
|
||||
)],
|
||||
span: Span::new(&source, 52, 64).unwrap(),
|
||||
span: Span::new(source, 52, 64).unwrap(),
|
||||
})],
|
||||
span: Span::new(&source, 29, source.len()).unwrap(),
|
||||
span: Span::new(source, 29, source.len()).unwrap(),
|
||||
})
|
||||
],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 65).unwrap()
|
||||
span: Span::new(source, 0, 65).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1153,27 +1153,27 @@ mod tests {
|
|||
def main() -> (field): return 1 + 2 * 3 ** 4
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![
|
||||
SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
span: Span::new(source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
span: Span::new(source, 0, 29).unwrap()
|
||||
})),
|
||||
SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
span: Span::new(source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
span: Span::new(source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::add(
|
||||
|
@ -1181,9 +1181,9 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 59, 60).unwrap()
|
||||
span: Span::new(source, 59, 60).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 59, 60).unwrap()
|
||||
span: Span::new(source, 59, 60).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::mul(
|
||||
|
@ -1191,9 +1191,9 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 63, 64).unwrap()
|
||||
span: Span::new(source, 63, 64).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 63, 64).unwrap()
|
||||
span: Span::new(source, 63, 64).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::pow(
|
||||
|
@ -1201,33 +1201,33 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 67, 68).unwrap()
|
||||
span: Span::new(source, 67, 68).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 67, 68).unwrap()
|
||||
span: Span::new(source, 67, 68).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 72, 73).unwrap()
|
||||
span: Span::new(source, 72, 73).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 72, 73).unwrap()
|
||||
span: Span::new(source, 72, 73).unwrap()
|
||||
}
|
||||
)),
|
||||
Span::new(&source, 67, 73).unwrap()
|
||||
Span::new(source, 67, 73).unwrap()
|
||||
),
|
||||
Span::new(&source, 63, 73).unwrap()
|
||||
Span::new(source, 63, 73).unwrap()
|
||||
),
|
||||
Span::new(&source, 59, 73).unwrap()
|
||||
Span::new(source, 59, 73).unwrap()
|
||||
)],
|
||||
span: Span::new(&source, 52, 73).unwrap(),
|
||||
span: Span::new(source, 52, 73).unwrap(),
|
||||
})],
|
||||
span: Span::new(&source, 29, 74).unwrap(),
|
||||
span: Span::new(source, 29, 74).unwrap(),
|
||||
})
|
||||
],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 74).unwrap()
|
||||
span: Span::new(source, 0, 74).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1238,27 +1238,27 @@ mod tests {
|
|||
def main() -> (field): return if 1 then 2 else 3 fi
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![
|
||||
SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
span: Span::new(source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
span: Span::new(source, 0, 29).unwrap()
|
||||
})),
|
||||
SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
span: Span::new(source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
span: Span::new(source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::if_else(
|
||||
|
@ -1266,38 +1266,38 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 62, 63).unwrap()
|
||||
span: Span::new(source, 62, 63).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 62, 63).unwrap()
|
||||
span: Span::new(source, 62, 63).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 69, 70).unwrap()
|
||||
span: Span::new(source, 69, 70).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 69, 70).unwrap()
|
||||
span: Span::new(source, 69, 70).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 76, 77).unwrap()
|
||||
span: Span::new(source, 76, 77).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 76, 77).unwrap()
|
||||
span: Span::new(source, 76, 77).unwrap()
|
||||
}
|
||||
)),
|
||||
Span::new(&source, 59, 80).unwrap()
|
||||
Span::new(source, 59, 80).unwrap()
|
||||
)],
|
||||
span: Span::new(&source, 52, 80).unwrap(),
|
||||
span: Span::new(source, 52, 80).unwrap(),
|
||||
})],
|
||||
span: Span::new(&source, 29, 81).unwrap(),
|
||||
span: Span::new(source, 29, 81).unwrap(),
|
||||
})
|
||||
],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 81).unwrap()
|
||||
span: Span::new(source, 0, 81).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1307,35 +1307,35 @@ mod tests {
|
|||
let source = r#"def main() -> (field): return (1)
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 4, 8).unwrap()
|
||||
span: Span::new(source, 4, 8).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 15, 20).unwrap()
|
||||
span: Span::new(source, 15, 20).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 31, 32).unwrap()
|
||||
span: Span::new(source, 31, 32).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 31, 32).unwrap()
|
||||
span: Span::new(source, 31, 32).unwrap()
|
||||
}
|
||||
))],
|
||||
span: Span::new(&source, 23, 33).unwrap(),
|
||||
span: Span::new(source, 23, 33).unwrap(),
|
||||
})],
|
||||
span: Span::new(&source, 0, 34).unwrap(),
|
||||
span: Span::new(source, 0, 34).unwrap(),
|
||||
})],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 34).unwrap()
|
||||
span: Span::new(source, 0, 34).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1345,44 +1345,44 @@ mod tests {
|
|||
let source = r#"def main() -> (field): field a, b = foo(1, 2 + 3)
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 4, 8).unwrap()
|
||||
span: Span::new(source, 4, 8).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 15, 20).unwrap()
|
||||
span: Span::new(source, 15, 20).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Definition(DefinitionStatement {
|
||||
lhs: vec![
|
||||
TypedIdentifierOrAssignee::TypedIdentifier(TypedIdentifier {
|
||||
ty: Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 23, 28).unwrap()
|
||||
span: Span::new(source, 23, 28).unwrap()
|
||||
})),
|
||||
identifier: IdentifierExpression {
|
||||
value: String::from("a"),
|
||||
span: Span::new(&source, 29, 30).unwrap(),
|
||||
span: Span::new(source, 29, 30).unwrap(),
|
||||
},
|
||||
span: Span::new(&source, 23, 30).unwrap()
|
||||
span: Span::new(source, 23, 30).unwrap()
|
||||
}),
|
||||
TypedIdentifierOrAssignee::Assignee(Assignee {
|
||||
id: IdentifierExpression {
|
||||
value: String::from("b"),
|
||||
span: Span::new(&source, 32, 33).unwrap(),
|
||||
span: Span::new(source, 32, 33).unwrap(),
|
||||
},
|
||||
accesses: vec![],
|
||||
span: Span::new(&source, 32, 34).unwrap()
|
||||
span: Span::new(source, 32, 34).unwrap()
|
||||
}),
|
||||
],
|
||||
expression: Expression::Postfix(PostfixExpression {
|
||||
base: Box::new(Expression::Identifier(IdentifierExpression {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 36, 39).unwrap()
|
||||
span: Span::new(source, 36, 39).unwrap()
|
||||
})),
|
||||
accesses: vec![Access::Call(CallAccess {
|
||||
explicit_generics: None,
|
||||
|
@ -1392,9 +1392,9 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 40, 41).unwrap()
|
||||
span: Span::new(source, 40, 41).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 40, 41).unwrap()
|
||||
span: Span::new(source, 40, 41).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::add(
|
||||
|
@ -1402,35 +1402,35 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 43, 44).unwrap()
|
||||
span: Span::new(source, 43, 44).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 43, 44).unwrap()
|
||||
span: Span::new(source, 43, 44).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 47, 48).unwrap()
|
||||
span: Span::new(source, 47, 48).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 47, 48).unwrap()
|
||||
span: Span::new(source, 47, 48).unwrap()
|
||||
}
|
||||
)),
|
||||
Span::new(&source, 43, 48).unwrap()
|
||||
Span::new(source, 43, 48).unwrap()
|
||||
),
|
||||
],
|
||||
span: Span::new(&source, 40, 48).unwrap()
|
||||
span: Span::new(source, 40, 48).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 39, 49).unwrap()
|
||||
span: Span::new(source, 39, 49).unwrap()
|
||||
})],
|
||||
span: Span::new(&source, 36, 49).unwrap(),
|
||||
span: Span::new(source, 36, 49).unwrap(),
|
||||
}),
|
||||
span: Span::new(&source, 23, 49).unwrap()
|
||||
span: Span::new(source, 23, 49).unwrap()
|
||||
})],
|
||||
span: Span::new(&source, 0, 50).unwrap(),
|
||||
span: Span::new(source, 0, 50).unwrap(),
|
||||
})],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 50).unwrap()
|
||||
span: Span::new(source, 0, 50).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1453,8 +1453,8 @@ mod tests {
|
|||
assert(a.member == 1)
|
||||
return a
|
||||
"#;
|
||||
let res = generate_ast(&source);
|
||||
println!("{:#?}", generate_ast(&source));
|
||||
let res = generate_ast(source);
|
||||
println!("{:#?}", generate_ast(source));
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from "EMBED" import unpack, u16_from_bits
|
||||
from "field" import FIELD_SIZE_IN_BITS
|
||||
import "utils/pack/bool/unpack"
|
||||
import "utils/casts/u16_from_bits"
|
||||
|
||||
def main(field i) -> u16:
|
||||
bool[16] bits = unpack(i)
|
||||
return u16_from_bits(bits)
|
||||
def main(field input) -> u16:
|
||||
bool[FIELD_SIZE_IN_BITS] bits = unpack(input)
|
||||
return u16_from_bits(bits[FIELD_SIZE_IN_BITS-16..])
|
|
@ -1,5 +1,7 @@
|
|||
from "EMBED" import unpack, u32_from_bits
|
||||
from "field" import FIELD_SIZE_IN_BITS
|
||||
import "utils/pack/bool/unpack"
|
||||
import "utils/casts/u32_from_bits"
|
||||
|
||||
def main(field i) -> u32:
|
||||
bool[32] bits = unpack(i)
|
||||
return u32_from_bits(bits)
|
||||
def main(field input) -> u32:
|
||||
bool[FIELD_SIZE_IN_BITS] bits = unpack(input)
|
||||
return u32_from_bits(bits[FIELD_SIZE_IN_BITS-32..])
|
|
@ -1,5 +1,7 @@
|
|||
from "EMBED" import unpack, u64_from_bits
|
||||
from "field" import FIELD_SIZE_IN_BITS
|
||||
import "utils/pack/bool/unpack"
|
||||
import "utils/casts/u64_from_bits"
|
||||
|
||||
def main(field i) -> u64:
|
||||
bool[64] bits = unpack(i)
|
||||
return u64_from_bits(bits)
|
||||
def main(field input) -> u64:
|
||||
bool[FIELD_SIZE_IN_BITS] bits = unpack(input)
|
||||
return u64_from_bits(bits[FIELD_SIZE_IN_BITS-64..])
|
|
@ -1,5 +1,7 @@
|
|||
from "EMBED" import unpack, u8_from_bits
|
||||
from "field" import FIELD_SIZE_IN_BITS
|
||||
import "utils/pack/bool/unpack"
|
||||
import "utils/casts/u8_from_bits"
|
||||
|
||||
def main(field i) -> u8:
|
||||
bool[8] bits = unpack(i)
|
||||
return u8_from_bits(bits)
|
||||
def main(field input) -> u8:
|
||||
bool[FIELD_SIZE_IN_BITS] bits = unpack(input)
|
||||
return u8_from_bits(bits[FIELD_SIZE_IN_BITS-8..])
|
|
@ -4,11 +4,11 @@
|
|||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["0", "1", "18446744073709551615", "42", "0", "1", "4294967295", "42", "0", "1", "65535", "42", "0", "1", "255", "42"]
|
||||
"values": ["0", "1", "18446744073709551615", "18446744073709551616", "18446744073709551658", "0", "1", "4294967295", "4294967296", "4294967338", "0", "1", "65535", "65536", "65578", "0", "1", "255", "256", "298"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["0", "1", "18446744073709551615", "42", "0", "1", "4294967295", "42", "0", "1", "65535", "42", "0", "1", "255", "42"]
|
||||
"values": ["0", "1", "18446744073709551615", "0", "42", "0", "1", "4294967295", "0", "42", "0", "1", "65535", "0", "42", "0", "1", "255", "0", "42"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ import "utils/casts/field_to_u32"
|
|||
import "utils/casts/field_to_u16"
|
||||
import "utils/casts/field_to_u8"
|
||||
|
||||
def main(field[4] a, field[4] b, field[4] c, field[4] d) -> (u64[4], u32[4], u16[4], u8[4]):
|
||||
u64[4] e = [0; 4]
|
||||
u32[4] f = [0; 4]
|
||||
u16[4] g = [0; 4]
|
||||
u8[4] h = [0; 4]
|
||||
def main(field[5] a, field[5] b, field[5] c, field[5] d) -> (u64[5], u32[5], u16[5], u8[5]):
|
||||
u64[5] e = [0; 5]
|
||||
u32[5] f = [0; 5]
|
||||
u16[5] g = [0; 5]
|
||||
u8[5] h = [0; 5]
|
||||
|
||||
for u32 i in 0..4 do
|
||||
for u32 i in 0..5 do
|
||||
e[i] = field_to_u64(a[i])
|
||||
f[i] = field_to_u32(b[i])
|
||||
g[i] = field_to_u16(c[i])
|
||||
|
|
|
@ -157,15 +157,14 @@ fn compile_and_run<T: Field>(t: Tests) {
|
|||
if let Some(target_count) = t.max_constraint_count {
|
||||
let count = bin.constraint_count();
|
||||
|
||||
if count > target_count {
|
||||
panic!(
|
||||
"{} exceeded max constraint count (actual={}, max={}, p={:.2}% of max)",
|
||||
entry_point.display(),
|
||||
count,
|
||||
target_count,
|
||||
(count as f32) / (target_count as f32) * 100_f32
|
||||
);
|
||||
}
|
||||
assert!(
|
||||
count <= target_count,
|
||||
"{} exceeded max constraint count (actual={}, max={}, p={:.2}% of max)",
|
||||
entry_point.display(),
|
||||
count,
|
||||
target_count,
|
||||
(count as f32) / (target_count as f32) * 100_f32
|
||||
);
|
||||
};
|
||||
|
||||
let interpreter = zokrates_core::ir::Interpreter::default();
|
||||
|
|
|
@ -13,7 +13,7 @@ pub fn write_tests(base: &str) {
|
|||
let mut writer = BufWriter::new(test_file);
|
||||
|
||||
for p in glob(base.join("**/*.json").to_str().unwrap()).unwrap() {
|
||||
write_test(&mut writer, &p.unwrap(), &base);
|
||||
write_test(&mut writer, &p.unwrap(), base);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue