fix all the bugs for the new array indexes

This commit is contained in:
gluax 2021-06-29 20:55:48 -07:00
parent 2e0dab122b
commit bb63e13edf
8 changed files with 598 additions and 255 deletions

View File

@ -34,10 +34,4 @@ impl CombinerError {
Self::new_from_span(message, span) Self::new_from_span(message, span)
} }
pub fn illegal_compound_array_range(span: &Span) -> Self {
let message = "Illegal compound assignement with array range".to_string();
Self::new_from_span(message, span)
}
} }

View File

@ -55,6 +55,14 @@ impl Canonicalizer {
span: span.clone(), span: span.clone(),
})); }));
} }
AssigneeAccess::ArrayRange(start, stop) => {
left = Box::new(Expression::ArrayRangeAccess(ArrayRangeAccessExpression {
array: left,
left: start.map(Box::new),
right: stop.map(Box::new),
span: span.clone(),
}));
}
AssigneeAccess::Tuple(positive_number, _) => { AssigneeAccess::Tuple(positive_number, _) => {
left = Box::new(Expression::TupleAccess(TupleAccessExpression { left = Box::new(Expression::TupleAccess(TupleAccessExpression {
tuple: left, tuple: left,
@ -69,7 +77,6 @@ impl Canonicalizer {
span: span.clone(), span: span.clone(),
})); }));
} }
_ => return Err(ReducerError::from(CombinerError::illegal_compound_array_range(&span))),
} }
} }

View File

@ -19,7 +19,7 @@
use std::convert::TryInto; use std::convert::TryInto;
use crate::{ use crate::{
errors::{ExpressionError, IntegerError, StatementError}, errors::{ExpressionError, StatementError},
program::ConstrainedProgram, program::ConstrainedProgram,
value::ConstrainedValue, value::ConstrainedValue,
GroupType, GroupType,
@ -55,9 +55,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
)) ))
} else { } else {
let target = input.get_mut(index).unwrap(); let target = input.get_mut(index).unwrap();
if let ConstrainedValue::Integer(int) = target {
println!("RTAAI T {}", int);
}
if context.remaining_accesses.is_empty() { if context.remaining_accesses.is_empty() {
self.enforce_assign_context(cs, &context, target) self.enforce_assign_context(cs, &context, target)
} else { } else {
@ -130,6 +127,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
_ => Err(StatementError::array_assign_interior_index(&context.span)), _ => Err(StatementError::array_assign_interior_index(&context.span)),
} }
} else if context.from_range && input_len != 0 { } else if context.from_range && input_len != 0 {
context.from_range = false;
if let Some(index) = index_resolved.to_usize() { if let Some(index) = index_resolved.to_usize() {
if index >= input_len { if index >= input_len {
return Err(StatementError::array_assign_index_bounds( return Err(StatementError::array_assign_index_bounds(
@ -147,12 +145,63 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
self.resolve_target_access(cs, context) self.resolve_target_access(cs, context)
} }
} else { } else {
// index is input variable
let span = index.span().cloned().unwrap_or_default(); let span = index.span().cloned().unwrap_or_default();
{
let array_len: u32 = context
.input
.len()
.try_into()
.map_err(|_| ExpressionError::array_length_out_of_bounds(&span))?;
self.array_bounds_check(cs, &&index_resolved, array_len, &span)?;
}
Err(StatementError::from(IntegerError::invalid_integer( for (i, item) in context.input.iter_mut().enumerate() {
index_resolved.to_string(), let namespace_string = format!(
&span, "evaluate dyn array assignment eq {} {}:{}",
))) i, span.line_start, span.col_start
);
let eq_namespace = cs.ns(|| namespace_string);
let index_bounded = i
.try_into()
.map_err(|_| ExpressionError::array_index_out_of_legal_bounds(&span))?;
let const_index = ConstInt::U32(index_bounded).cast_to(&index_resolved.get_type());
let index_comparison = index_resolved
.evaluate_equal(eq_namespace, &Integer::new(&const_index))
.map_err(|_| ExpressionError::cannot_evaluate("==".to_string(), &span))?;
let mut unique_namespace = cs.ns(|| {
format!(
"select array dyn assignment {} {}:{}",
i, span.line_start, span.col_start
)
});
let temp_item = {
let mut item = item.clone();
let mut new_context = ResolverContext {
input: vec![&mut item],
span: context.span.clone(),
target_value: context.target_value.clone(),
remaining_accesses: context.remaining_accesses,
indicator: context.indicator,
operation: context.operation,
from_range: false,
};
if context.remaining_accesses.is_empty() {
let item = new_context.input.remove(0);
self.enforce_assign_context(&mut unique_namespace, &new_context, item)?;
} else {
self.resolve_target_access(&mut unique_namespace, new_context)?;
}
item
};
let value =
ConstrainedValue::conditionally_select(unique_namespace, &index_comparison, &temp_item, &item)
.map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, &span))?;
**item = value;
}
Ok(())
} }
} else { } else {
Err(StatementError::array_assign_interior_index(&context.span)) Err(StatementError::array_assign_interior_index(&context.span))

View File

@ -32,8 +32,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
start: Option<&'a Expression<'a>>, start: Option<&'a Expression<'a>>,
stop: Option<&'a Expression<'a>>, stop: Option<&'a Expression<'a>>,
) -> Result<(), StatementError> { ) -> Result<(), StatementError> {
context.from_range = true;
let start_index = start let start_index = start
.map(|start| self.enforce_index(cs, start, &context.span)) .map(|start| self.enforce_index(cs, start, &context.span))
.transpose()? .transpose()?
@ -52,8 +50,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
.transpose()?; .transpose()?;
let start_index = start_index.unwrap_or(0); let start_index = start_index.unwrap_or(0);
if context.input.len() == 1 { if !context.from_range {
// not a range of a range // not a range of a range
context.from_range = true;
match context.input.remove(0) { match context.input.remove(0) {
ConstrainedValue::Array(old) => { ConstrainedValue::Array(old) => {
let stop_index = stop_index.unwrap_or(old.len()); let stop_index = stop_index.unwrap_or(old.len());

File diff suppressed because it is too large Load Diff

View File

@ -16,9 +16,11 @@ function main() {
w += x; w += x;
console.assert(w == 33u32); console.assert(w == 33u32);
let y = [1u8, 2u8]; let y = [1u8, 2u8, 3, 4];
y[0] += 3u8; y[0] += 3u8;
y[0..3][1] *= 3;
console.assert(y[0] == 4u8); console.assert(y[0] == 4u8);
console.assert(y[1] == 6u8);
let z = (1u8, 2u8); let z = (1u8, 2u8);
z.1 += 3u8; z.1 += 3u8;

View File

@ -5,19 +5,25 @@ input_file:
- input/complex_access.in - input/complex_access.in
*/ */
function main (a: [u8; 8], b: [[u8; 3]; 3], c: [(u8, u32); 1]) -> bool { function main (a: [u8; 8], b: u32, c: [[u8; 3]; 3], d: [(u8, u32); 1], e: [u8; (3, 4)] ) -> bool {
a[d] = 93;
a[2..6][1] = 87; a[2..6][1] = 87;
a[2..6][1] *= 2;
a[2..3] = [42u8]; a[2..3] = [42u8];
a[6..][0] = 43u8; a[6..][0] = 43u8;
b[0..2][0] = [1u8; 3]; c[0..2][0] = [1u8; 3];
b[1..][1][1..2][0] = 126; c[1..][1][1..2][0] = 126;
b[1..][0] = [42, 43, 44]; c[1..][0] = [42, 43, 44];
c[..1][0].1 = 1; d[..1][0].1 = 1;
e[0..][0] = [22; 4];
e[0..][0][0] = 33;
return return
a == [1u8, 2, 42, 87, 5, 6, 43, 8] a == [93u8, 2, 42, 174, 5, 6, 43, 8]
&& b == [[1u8, 1, 1], [42, 43, 44], [7, 126, 9]] && c == [[1u8, 1, 1], [42, 43, 44], [7, 126, 9]]
&& c == [(0u8, 1u32)]; && d == [(0u8, 1u32)]
&& e == [[33u8, 22, 22, 22], [0, 0, 0, 0], [0, 0, 0, 0]];
} }

View File

@ -1,7 +1,9 @@
[main] [main]
a: [u8; 8] = [1u8, 2, 3, 4, 5, 6, 7, 8]; a: [u8; 8] = [1u8, 2, 3, 4, 5, 6, 7, 8];
b: [[u8; 3]; 3] = [[1u8, 2, 3], [4, 5, 6], [7, 8, 9]]; b: u32 = 1;
c: [(u8, u32); 1] = [(0u8, 0u32)]; c: [[u8; 3]; 3] = [[1u8, 2, 3], [4, 5, 6], [7, 8, 9]];
d: [(u8, u32); 1] = [(0u8, 0u32)];
e: [u8; (3, 4)] = [0u8; (3, 4)];
[registers] [registers]
out: bool = true; out: bool = true;