mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 02:31:44 +03:00
Merge pull request #1074 from AleoHQ/bug/ternery-and-canonicalization-fixes
Bug-Fix: Canonicalization, Array Init, Array Indexing
This commit is contained in:
commit
2e0dab122b
@ -54,8 +54,8 @@ impl<'a> ExpressionNode<'a> for ArrayInitExpression<'a> {
|
||||
}
|
||||
|
||||
fn const_value(&self) -> Option<ConstValue> {
|
||||
// not implemented due to performance concerns
|
||||
None
|
||||
let element = self.element.get().const_value()?;
|
||||
Some(ConstValue::Array(vec![element; self.len]))
|
||||
}
|
||||
|
||||
fn is_consty(&self) -> bool {
|
||||
|
@ -593,19 +593,13 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
value: Expression,
|
||||
) -> Result<AssignStatement, ReducerError> {
|
||||
match value {
|
||||
Expression::Binary(binary_expr) if assign.operation == AssignOperation::Assign => Ok(AssignStatement {
|
||||
operation: AssignOperation::Assign,
|
||||
assignee,
|
||||
value: Expression::Binary(binary_expr),
|
||||
span: assign.span.clone(),
|
||||
}),
|
||||
Expression::Binary(binary_expr) if assign.operation != AssignOperation::Assign => {
|
||||
value if assign.operation != AssignOperation::Assign => {
|
||||
let left = self.canonicalize_accesses(
|
||||
Expression::Identifier(assignee.identifier.clone()),
|
||||
&assignee.accesses,
|
||||
&assign.span,
|
||||
)?;
|
||||
let right = Box::new(Expression::Binary(binary_expr));
|
||||
let right = Box::new(value);
|
||||
let op = self.compound_operation_converstion(&assign.operation)?;
|
||||
|
||||
let new_value = Expression::Binary(BinaryExpression {
|
||||
@ -622,36 +616,12 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
span: assign.span.clone(),
|
||||
})
|
||||
}
|
||||
Expression::Value(value_expr) if assign.operation != AssignOperation::Assign => {
|
||||
let left = self.canonicalize_accesses(
|
||||
Expression::Identifier(assignee.identifier.clone()),
|
||||
&assignee.accesses,
|
||||
&assign.span,
|
||||
)?;
|
||||
let right = Box::new(Expression::Value(value_expr));
|
||||
let op = self.compound_operation_converstion(&assign.operation)?;
|
||||
|
||||
let new_value = Expression::Binary(BinaryExpression {
|
||||
left,
|
||||
right,
|
||||
op,
|
||||
span: assign.span.clone(),
|
||||
});
|
||||
|
||||
Ok(AssignStatement {
|
||||
operation: AssignOperation::Assign,
|
||||
assignee,
|
||||
value: new_value,
|
||||
span: assign.span.clone(),
|
||||
})
|
||||
}
|
||||
Expression::ArrayInline(_) => Ok(AssignStatement {
|
||||
value => Ok(AssignStatement {
|
||||
operation: AssignOperation::Assign,
|
||||
assignee,
|
||||
value,
|
||||
span: assign.span.clone(),
|
||||
}),
|
||||
_ => Ok(assign.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use crate::{
|
||||
errors::{ExpressionError, StatementError},
|
||||
errors::{ExpressionError, IntegerError, StatementError},
|
||||
program::ConstrainedProgram,
|
||||
value::ConstrainedValue,
|
||||
GroupType,
|
||||
@ -40,85 +40,122 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
mut context: ResolverContext<'a, 'b, F, G>,
|
||||
index: &'a Expression<'a>,
|
||||
) -> Result<(), StatementError> {
|
||||
if context.input.len() != 1 {
|
||||
return Err(StatementError::array_assign_interior_index(&context.span));
|
||||
}
|
||||
let input = match context.input.remove(0) {
|
||||
ConstrainedValue::Array(old) => old,
|
||||
_ => return Err(StatementError::array_assign_index(&context.span)),
|
||||
};
|
||||
let input_len = context.input.len();
|
||||
|
||||
let index_resolved = self.enforce_index(cs, index, &context.span)?;
|
||||
if let Some(index) = index_resolved.to_usize() {
|
||||
if index >= input.len() {
|
||||
Err(StatementError::array_assign_index_bounds(
|
||||
index,
|
||||
input.len(),
|
||||
&context.span,
|
||||
))
|
||||
} else {
|
||||
let target = input.get_mut(index).unwrap();
|
||||
if !context.from_range && input_len == 1 {
|
||||
match context.input.remove(0) {
|
||||
ConstrainedValue::Array(input) => {
|
||||
if let Some(index) = index_resolved.to_usize() {
|
||||
if index >= input.len() {
|
||||
Err(StatementError::array_assign_index_bounds(
|
||||
index,
|
||||
input.len(),
|
||||
&context.span,
|
||||
))
|
||||
} else {
|
||||
let target = input.get_mut(index).unwrap();
|
||||
if let ConstrainedValue::Integer(int) = target {
|
||||
println!("RTAAI T {}", int);
|
||||
}
|
||||
if context.remaining_accesses.is_empty() {
|
||||
self.enforce_assign_context(cs, &context, target)
|
||||
} else {
|
||||
context.input = vec![target];
|
||||
self.resolve_target_access(cs, context)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let span = index.span().cloned().unwrap_or_default();
|
||||
{
|
||||
let array_len: u32 = input
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| ExpressionError::array_length_out_of_bounds(&span))?;
|
||||
self.array_bounds_check(cs, &&index_resolved, array_len, &span)?;
|
||||
}
|
||||
|
||||
for (i, item) in input.iter_mut().enumerate() {
|
||||
let namespace_string = format!(
|
||||
"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(())
|
||||
}
|
||||
}
|
||||
_ => Err(StatementError::array_assign_interior_index(&context.span)),
|
||||
}
|
||||
} else if context.from_range && input_len != 0 {
|
||||
if let Some(index) = index_resolved.to_usize() {
|
||||
if index >= input_len {
|
||||
return Err(StatementError::array_assign_index_bounds(
|
||||
index,
|
||||
input_len,
|
||||
&context.span,
|
||||
));
|
||||
}
|
||||
let target = context.input.remove(index);
|
||||
|
||||
if context.remaining_accesses.is_empty() {
|
||||
self.enforce_assign_context(cs, &context, target)
|
||||
} else {
|
||||
context.input = vec![target];
|
||||
self.resolve_target_access(cs, context)
|
||||
}
|
||||
} else {
|
||||
let span = index.span().cloned().unwrap_or_default();
|
||||
|
||||
Err(StatementError::from(IntegerError::invalid_integer(
|
||||
index_resolved.to_string(),
|
||||
&span,
|
||||
)))
|
||||
}
|
||||
} else {
|
||||
let span = index.span().cloned().unwrap_or_default();
|
||||
{
|
||||
let array_len: u32 = input
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| ExpressionError::array_length_out_of_bounds(&span))?;
|
||||
self.array_bounds_check(cs, &&index_resolved, array_len, &span)?;
|
||||
}
|
||||
|
||||
for (i, item) in input.iter_mut().enumerate() {
|
||||
let namespace_string = format!(
|
||||
"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,
|
||||
};
|
||||
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(())
|
||||
Err(StatementError::array_assign_interior_index(&context.span))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
start: Option<&'a Expression<'a>>,
|
||||
stop: Option<&'a Expression<'a>>,
|
||||
) -> Result<(), StatementError> {
|
||||
context.from_range = true;
|
||||
|
||||
let start_index = start
|
||||
.map(|start| self.enforce_index(cs, start, &context.span))
|
||||
.transpose()?
|
||||
|
@ -35,6 +35,7 @@ struct ResolverContext<'a, 'b, F: PrimeField, G: GroupType<F>> {
|
||||
remaining_accesses: &'b [&'b AssignAccess<'a>],
|
||||
indicator: &'b Boolean,
|
||||
operation: AssignOperation,
|
||||
from_range: bool,
|
||||
}
|
||||
|
||||
impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
@ -68,8 +69,10 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
self.enforce_assign_context(cs, &context, input)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let access = context.remaining_accesses[context.remaining_accesses.len() - 1];
|
||||
context.remaining_accesses = &context.remaining_accesses[..context.remaining_accesses.len() - 1];
|
||||
|
||||
match access {
|
||||
AssignAccess::ArrayRange(start, stop) => {
|
||||
self.resolve_target_access_array_range(cs, context, start.get(), stop.get())
|
||||
@ -99,6 +102,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
remaining_accesses: &accesses[..],
|
||||
indicator,
|
||||
operation: assignee.operation,
|
||||
from_range: false,
|
||||
})?;
|
||||
*self.get_mut(variable.id).unwrap() = target;
|
||||
Ok(())
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,10 @@ function main() {
|
||||
x += 20;
|
||||
console.assert(x == 30u32);
|
||||
|
||||
let w = 3u32;
|
||||
w += x;
|
||||
console.assert(w == 33u32);
|
||||
|
||||
let y = [1u8, 2u8];
|
||||
y[0] += 3u8;
|
||||
console.assert(y[0] == 4u8);
|
||||
|
@ -718,11 +718,450 @@
|
||||
"content": " x = \"test1\" == \"test2\";"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Definition": {
|
||||
"declaration_type": "Let",
|
||||
"variable_names": [
|
||||
{
|
||||
"mutable": true,
|
||||
"identifier": "{\"name\":\"z\",\"span\":\"{\\\"line_start\\\":6,\\\"line_stop\\\":6,\\\"col_start\\\":9,\\\"col_stop\\\":10,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" let z = [1u8, 2u8, 3u8, 4u8];\\\"}\"}",
|
||||
"span": {
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 9,
|
||||
"col_stop": 10,
|
||||
"path": "",
|
||||
"content": " let z = [1u8, 2u8, 3u8, 4u8];"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type_": null,
|
||||
"value": {
|
||||
"ArrayInline": {
|
||||
"elements": [
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"1",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 14,
|
||||
"col_stop": 17,
|
||||
"path": "",
|
||||
"content": " let z = [1u8, 2u8, 3u8, 4u8];"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"2",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 19,
|
||||
"col_stop": 22,
|
||||
"path": "",
|
||||
"content": " let z = [1u8, 2u8, 3u8, 4u8];"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"3",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 24,
|
||||
"col_stop": 27,
|
||||
"path": "",
|
||||
"content": " let z = [1u8, 2u8, 3u8, 4u8];"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Integer": [
|
||||
"U8",
|
||||
"4",
|
||||
{
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 29,
|
||||
"col_stop": 32,
|
||||
"path": "",
|
||||
"content": " let z = [1u8, 2u8, 3u8, 4u8];"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 13,
|
||||
"col_stop": 33,
|
||||
"path": "",
|
||||
"content": " let z = [1u8, 2u8, 3u8, 4u8];"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 6,
|
||||
"line_stop": 6,
|
||||
"col_start": 5,
|
||||
"col_stop": 33,
|
||||
"path": "",
|
||||
"content": " let z = [1u8, 2u8, 3u8, 4u8];"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"operation": "Assign",
|
||||
"assignee": {
|
||||
"identifier": "{\"name\":\"z\",\"span\":\"{\\\"line_start\\\":7,\\\"line_stop\\\":7,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" z[0..\\\\\\\"test\\\\\\\" == \\\\\\\"test\\\\\\\"? 2 : 2] = x[0..2];\\\"}\"}",
|
||||
"accesses": [
|
||||
{
|
||||
"ArrayRange": [
|
||||
{
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"0",
|
||||
{
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 7,
|
||||
"col_stop": 8,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Ternary": {
|
||||
"condition": {
|
||||
"Binary": {
|
||||
"left": {
|
||||
"ArrayInline": {
|
||||
"elements": [
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Char": {
|
||||
"character": {
|
||||
"Scalar": 116
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 11,
|
||||
"col_stop": 12,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Char": {
|
||||
"character": {
|
||||
"Scalar": 101
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 12,
|
||||
"col_stop": 13,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Char": {
|
||||
"character": {
|
||||
"Scalar": 115
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 13,
|
||||
"col_stop": 14,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Char": {
|
||||
"character": {
|
||||
"Scalar": 116
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 14,
|
||||
"col_stop": 15,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 10,
|
||||
"col_stop": 16,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"ArrayInline": {
|
||||
"elements": [
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Char": {
|
||||
"character": {
|
||||
"Scalar": 116
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 21,
|
||||
"col_stop": 22,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Char": {
|
||||
"character": {
|
||||
"Scalar": 101
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 22,
|
||||
"col_stop": 23,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Char": {
|
||||
"character": {
|
||||
"Scalar": 115
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 23,
|
||||
"col_stop": 24,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Expression": {
|
||||
"Value": {
|
||||
"Char": {
|
||||
"character": {
|
||||
"Scalar": 116
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 24,
|
||||
"col_stop": 25,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 20,
|
||||
"col_stop": 26,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
},
|
||||
"op": "Eq",
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 10,
|
||||
"col_stop": 26,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
},
|
||||
"if_true": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"2",
|
||||
{
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 28,
|
||||
"col_stop": 29,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"if_false": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"2",
|
||||
{
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 32,
|
||||
"col_stop": 33,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 10,
|
||||
"col_stop": 33,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 5,
|
||||
"col_stop": 34,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"ArrayRangeAccess": {
|
||||
"array": {
|
||||
"Identifier": "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":7,\\\"line_stop\\\":7,\\\"col_start\\\":37,\\\"col_stop\\\":38,\\\"path\\\":\\\"\\\",\\\"content\\\":\\\" z[0..\\\\\\\"test\\\\\\\" == \\\\\\\"test\\\\\\\"? 2 : 2] = x[0..2];\\\"}\"}"
|
||||
},
|
||||
"left": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"0",
|
||||
{
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 39,
|
||||
"col_stop": 40,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Implicit": [
|
||||
"2",
|
||||
{
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 42,
|
||||
"col_stop": 43,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 37,
|
||||
"col_stop": 44,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"line_start": 7,
|
||||
"line_stop": 7,
|
||||
"col_start": 5,
|
||||
"col_stop": 44,
|
||||
"path": "",
|
||||
"content": " z[0..\"test\" == \"test\"? 2 : 2] = x[0..2];"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 6,
|
||||
"line_stop": 8,
|
||||
"col_start": 17,
|
||||
"col_stop": 2,
|
||||
"path": "",
|
||||
@ -731,11 +1170,11 @@
|
||||
},
|
||||
"span": {
|
||||
"line_start": 1,
|
||||
"line_stop": 6,
|
||||
"line_stop": 8,
|
||||
"col_start": 1,
|
||||
"col_stop": 2,
|
||||
"path": "",
|
||||
"content": "function main() {\n...\n}\n\n\n"
|
||||
"content": "function main() {\n...\n}\n\n\n\n\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,6 @@ function main() {
|
||||
s[..2] = "he";
|
||||
let x = false;
|
||||
x = "test1" == "test2";
|
||||
let z = [1u8, 2u8, 3u8, 4u8];
|
||||
z[0.."test" == "test"? 2 : 2] = x[0..2];
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ mod cli_tests {
|
||||
let path = Some(dir.path("new"));
|
||||
|
||||
assert!(run_cmd("leo new test", &path).is_ok());
|
||||
assert!(run_cmd("leo new test", &path).is_err()); // 2nd time
|
||||
assert!(run_cmd("leo new test", &path).is_err()); // 2nd time
|
||||
assert!(run_cmd("leo new wrong_name", &path).is_err());
|
||||
}
|
||||
|
||||
|
23
tests/compiler/array/complex_access.leo
Normal file
23
tests/compiler/array/complex_access.leo
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
input_file:
|
||||
- input/complex_access.in
|
||||
*/
|
||||
|
||||
function main (a: [u8; 8], b: [[u8; 3]; 3], c: [(u8, u32); 1]) -> bool {
|
||||
a[2..6][1] = 87;
|
||||
a[2..3] = [42u8];
|
||||
a[6..][0] = 43u8;
|
||||
|
||||
b[0..2][0] = [1u8; 3];
|
||||
b[1..][1][1..2][0] = 126;
|
||||
b[1..][0] = [42, 43, 44];
|
||||
|
||||
c[..1][0].1 = 1;
|
||||
|
||||
return
|
||||
a == [1u8, 2, 42, 87, 5, 6, 43, 8]
|
||||
&& b == [[1u8, 1, 1], [42, 43, 44], [7, 126, 9]]
|
||||
&& c == [(0u8, 1u32)];
|
||||
}
|
7
tests/compiler/array/input/complex_access.in
Normal file
7
tests/compiler/array/input/complex_access.in
Normal file
@ -0,0 +1,7 @@
|
||||
[main]
|
||||
a: [u8; 8] = [1u8, 2, 3, 4, 5, 6, 7, 8];
|
||||
b: [[u8; 3]; 3] = [[1u8, 2, 3], [4, 5, 6], [7, 8, 9]];
|
||||
c: [(u8, u32); 1] = [(0u8, 0u32)];
|
||||
|
||||
[registers]
|
||||
out: bool = true;
|
10
tests/compiler/array/ternary_in_array.leo
Normal file
10
tests/compiler/array/ternary_in_array.leo
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
input_file: input/three_ones.in
|
||||
*/
|
||||
|
||||
function main (a: [u8; 3]) -> bool {
|
||||
let y = a[0..[0u8; 2] == [0u8; 2]? 2u8 : 2u8];
|
||||
return y == [1u8, 1];
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- circuit:
|
||||
num_public_variables: 0
|
||||
num_private_variables: 239
|
||||
num_constraints: 239
|
||||
at: 61be39f73914fdb4059c5d5e5776840262ab56dc414aa09106ddfee1d27ba174
|
||||
bt: 3f2d18346ecde92782f60a29649e187402d8f2059cf934b31f5606c4d4381883
|
||||
ct: db5fb9e237a13bca372ce7d3f232661fdf07c8ae7ef3d99517438a3532f59a41
|
||||
output:
|
||||
- input_file: input/complex_access.in
|
||||
output:
|
||||
registers:
|
||||
out:
|
||||
type: bool
|
||||
value: "true"
|
@ -0,0 +1,18 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- circuit:
|
||||
num_public_variables: 0
|
||||
num_private_variables: 39
|
||||
num_constraints: 39
|
||||
at: 6f3ffff33f4e513211e7a55cc9edcab3bc2d2a146c2b280981308bb69165f86f
|
||||
bt: adde6ad1b603a50c986ec99b6edcc972138bb6239e58a1b88e931bc0165b2e8e
|
||||
ct: 867e3f6ee1f26af954e7868633a595d319267d91afc5d7e2074fe641fabde1d6
|
||||
output:
|
||||
- input_file: input/three_ones.in
|
||||
output:
|
||||
registers:
|
||||
x:
|
||||
type: bool
|
||||
value: "true"
|
@ -4,11 +4,11 @@ expectation: Pass
|
||||
outputs:
|
||||
- circuit:
|
||||
num_public_variables: 0
|
||||
num_private_variables: 1087
|
||||
num_constraints: 1350
|
||||
at: aae29cb6b4a71a5cf49d3de006b415b9a7818a2e23191819692e8d2ee69d8be2
|
||||
bt: 11262f31fcaa7950be43eded328287305e7cbcb73c19455808f08f38116cfdd6
|
||||
ct: 01dfba9e0754ad9890117694c9b03f4646642140aa7b6c393b2e264e701c323e
|
||||
num_private_variables: 1277
|
||||
num_constraints: 1604
|
||||
at: c5d2d5bbb85d0f7ba48170fdb652aff057db6d1babf378d8a548af874e0734ff
|
||||
bt: 726f3c39d11da5bc8487b8b7228a55cb7819a47a9b674d41f9c756c6927fb55a
|
||||
ct: 7c4917152b59cb9caa30bad7d5119a3e36c40f7a783fdb8ff602dd5447573cc7
|
||||
output:
|
||||
- input_file: input/index1.in
|
||||
output:
|
||||
|
Loading…
Reference in New Issue
Block a user