mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-10-26 07:00:35 +03:00
dep clean up, clippy, leo result
This commit is contained in:
parent
2d7963771f
commit
b1f93e95b3
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -1210,7 +1210,6 @@ dependencies = [
|
||||
name = "leo-ast"
|
||||
version = "1.5.3"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"criterion",
|
||||
"indexmap",
|
||||
"leo-errors",
|
||||
@ -1225,7 +1224,6 @@ dependencies = [
|
||||
name = "leo-compiler"
|
||||
version = "1.5.3"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bincode",
|
||||
"hex",
|
||||
"indexmap",
|
||||
@ -1257,7 +1255,6 @@ dependencies = [
|
||||
"snarkvm-utilities",
|
||||
"tempfile",
|
||||
"tendril",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@ -1351,7 +1348,6 @@ version = "1.5.3"
|
||||
name = "leo-package"
|
||||
version = "1.5.3"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"lazy_static",
|
||||
"leo-errors",
|
||||
"serde",
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Circuit, Identifier, IntegerType, Type};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use num_bigint::BigInt;
|
||||
@ -316,16 +316,56 @@ impl ConstInt {
|
||||
|
||||
pub fn parse(int_type: &IntegerType, value: &str, span: &Span) -> Result<ConstInt> {
|
||||
Ok(match int_type {
|
||||
IntegerType::I8 => ConstInt::I8(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::I16 => ConstInt::I16(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::I32 => ConstInt::I32(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::I64 => ConstInt::I64(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::I128 => ConstInt::I128(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::U8 => ConstInt::U8(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::U16 => ConstInt::U16(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::U32 => ConstInt::U32(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::U64 => ConstInt::U64(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::U128 => ConstInt::U128(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
IntegerType::I8 => ConstInt::I8(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::I16 => ConstInt::I16(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::I32 => ConstInt::I32(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::I64 => ConstInt::I64(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::I128 => ConstInt::I128(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::U8 => ConstInt::U8(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::U16 => ConstInt::U16(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::U32 => ConstInt::U32(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::U64 => ConstInt::U64(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
IntegerType::U128 => ConstInt::U128(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
use leo_ast::IntegerType;
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -97,6 +97,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayAccessExpression> for ArrayAccessExpression<'
|
||||
"array",
|
||||
type_.map(|x| x.to_string()).unwrap_or_else(|| "unknown".to_string()),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -114,9 +115,12 @@ impl<'a> FromAst<'a, leo_ast::ArrayAccessExpression> for ArrayAccessExpression<'
|
||||
.flatten()
|
||||
{
|
||||
if index >= array_len {
|
||||
return Err(
|
||||
AsgError::array_index_out_of_bounds(index, &array.span().cloned().unwrap_or_default()).into(),
|
||||
);
|
||||
return Err(AsgError::array_index_out_of_bounds(
|
||||
index,
|
||||
&array.span().cloned().unwrap_or_default(),
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -74,7 +74,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayInitExpression> for ArrayInitExpression<'a> {
|
||||
Some(PartialType::Array(item, dims)) => (item.map(|x| *x), dims),
|
||||
None => (None, None),
|
||||
Some(type_) => {
|
||||
return Err(AsgError::unexpected_type(type_, "array", &value.span).into());
|
||||
return Err(AsgError::unexpected_type(type_, "array", &value.span, new_backtrace()).into());
|
||||
}
|
||||
};
|
||||
let dimensions = value
|
||||
@ -84,19 +84,20 @@ impl<'a> FromAst<'a, leo_ast::ArrayInitExpression> for ArrayInitExpression<'a> {
|
||||
.map(|x| {
|
||||
Ok(x.value
|
||||
.parse::<usize>()
|
||||
.map_err(|_| AsgError::parse_dimension_error(&value.span))?)
|
||||
.map_err(|_| AsgError::parse_dimension_error(&value.span, new_backtrace()))?)
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let len = *dimensions
|
||||
.get(0)
|
||||
.ok_or_else(|| AsgError::parse_dimension_error(&value.span))?;
|
||||
.ok_or_else(|| AsgError::parse_dimension_error(&value.span, new_backtrace()))?;
|
||||
if let Some(expected_len) = expected_len {
|
||||
if expected_len != len {
|
||||
return Err(AsgError::unexpected_type(
|
||||
format!("array of length {}", expected_len),
|
||||
format!("array of length {}", len),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -111,6 +112,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayInitExpression> for ArrayInitExpression<'a> {
|
||||
format!("array of length {}", dimension),
|
||||
format!("array of length {}", len),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -120,7 +122,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayInitExpression> for ArrayInitExpression<'a> {
|
||||
}
|
||||
None => None,
|
||||
Some(type_) => {
|
||||
return Err(AsgError::unexpected_type("array", type_, &value.span).into());
|
||||
return Err(AsgError::unexpected_type("array", type_, &value.span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
use leo_ast::SpreadOrExpression;
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -109,7 +109,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayInlineExpression> for ArrayInlineExpression<'
|
||||
Some(PartialType::Array(item, dims)) => (item.map(|x| *x), dims),
|
||||
None => (None, None),
|
||||
Some(type_) => {
|
||||
return Err(AsgError::unexpected_type(type_, "array", &value.span).into());
|
||||
return Err(AsgError::unexpected_type(type_, "array", &value.span, new_backtrace()).into());
|
||||
}
|
||||
};
|
||||
|
||||
@ -174,6 +174,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayInlineExpression> for ArrayInlineExpression<'
|
||||
.unwrap_or("unknown"),
|
||||
type_.map(|x| x.to_string()).unwrap_or_else(|| "unknown".to_string()),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -189,6 +190,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayInlineExpression> for ArrayInlineExpression<'
|
||||
format!("array of length {}", expected_len),
|
||||
format!("array of length {}", len),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
use leo_ast::IntegerType;
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -108,7 +108,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
Some(PartialType::Array(element, len)) => (Some(PartialType::Array(element, None)), len),
|
||||
None => (None, None),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, "array", &value.span).into());
|
||||
return Err(AsgError::unexpected_type(x, "array", &value.span, new_backtrace()).into());
|
||||
}
|
||||
};
|
||||
let array = <&Expression<'a>>::from_ast(scope, &*value.array, expected_array)?;
|
||||
@ -120,6 +120,7 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
"array",
|
||||
type_.map(|x| x.to_string()).unwrap_or_else(|| "unknown".to_string()),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -155,7 +156,9 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
} else {
|
||||
value.span.clone()
|
||||
};
|
||||
return Err(AsgError::array_index_out_of_bounds(inner_value, &error_span).into());
|
||||
return Err(
|
||||
AsgError::array_index_out_of_bounds(inner_value, &error_span, new_backtrace()).into(),
|
||||
);
|
||||
} else if let Some(left) = const_left {
|
||||
if left > inner_value {
|
||||
let error_span = if let Some(right) = right {
|
||||
@ -163,7 +166,9 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
} else {
|
||||
value.span.clone()
|
||||
};
|
||||
return Err(AsgError::array_index_out_of_bounds(inner_value, &error_span).into());
|
||||
return Err(
|
||||
AsgError::array_index_out_of_bounds(inner_value, &error_span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,9 +188,13 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
if let Some(length) = length {
|
||||
if length != expected_len {
|
||||
let concrete_type = Type::Array(parent_element, length);
|
||||
return Err(
|
||||
AsgError::unexpected_type(expected_type.as_ref().unwrap(), concrete_type, &value.span).into(),
|
||||
);
|
||||
return Err(AsgError::unexpected_type(
|
||||
expected_type.as_ref().unwrap(),
|
||||
concrete_type,
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
if let Some(left_value) = const_left {
|
||||
@ -195,13 +204,13 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
|
||||
} else {
|
||||
value.span.clone()
|
||||
};
|
||||
return Err(AsgError::array_index_out_of_bounds(left_value, &error_span).into());
|
||||
return Err(AsgError::array_index_out_of_bounds(left_value, &error_span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
length = Some(expected_len);
|
||||
}
|
||||
if length.is_none() {
|
||||
return Err(AsgError::unknown_array_size(&value.span).into());
|
||||
return Err(AsgError::unknown_array_size(&value.span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
Ok(ArrayRangeAccessExpression {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
pub use leo_ast::{BinaryOperation, BinaryOperationClass};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -123,7 +123,7 @@ impl<'a> FromAst<'a, leo_ast::BinaryExpression> for BinaryExpression<'a> {
|
||||
BinaryOperationClass::Boolean => match expected_type {
|
||||
Some(PartialType::Type(Type::Boolean)) | None => None,
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, Type::Boolean, &value.span).into());
|
||||
return Err(AsgError::unexpected_type(x, Type::Boolean, &value.span, new_backtrace()).into());
|
||||
}
|
||||
},
|
||||
BinaryOperationClass::Numeric => match expected_type {
|
||||
@ -131,7 +131,9 @@ impl<'a> FromAst<'a, leo_ast::BinaryExpression> for BinaryExpression<'a> {
|
||||
Some(x @ PartialType::Type(Type::Field)) => Some(x),
|
||||
Some(x @ PartialType::Type(Type::Group)) => Some(x),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, "integer, field, or group", &value.span).into());
|
||||
return Err(
|
||||
AsgError::unexpected_type(x, "integer, field, or group", &value.span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
None => None,
|
||||
},
|
||||
@ -184,6 +186,7 @@ impl<'a> FromAst<'a, leo_ast::BinaryExpression> for BinaryExpression<'a> {
|
||||
"integer",
|
||||
type_.map(|x| x.to_string()).unwrap_or_else(|| "unknown".to_string()),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -192,14 +195,14 @@ impl<'a> FromAst<'a, leo_ast::BinaryExpression> for BinaryExpression<'a> {
|
||||
BinaryOperation::And | BinaryOperation::Or => match left_type {
|
||||
Some(Type::Boolean) | None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, Type::Boolean, &value.span).into());
|
||||
return Err(AsgError::unexpected_type(x, Type::Boolean, &value.span, new_backtrace()).into());
|
||||
}
|
||||
},
|
||||
BinaryOperation::Eq | BinaryOperation::Ne => (), // all types allowed
|
||||
_ => match left_type {
|
||||
Some(Type::Integer(_)) | None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, "integer", &value.span).into());
|
||||
return Err(AsgError::unexpected_type(x, "integer", &value.span, new_backtrace()).into());
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -210,11 +213,11 @@ impl<'a> FromAst<'a, leo_ast::BinaryExpression> for BinaryExpression<'a> {
|
||||
match (left_type, right_type) {
|
||||
(Some(left_type), Some(right_type)) => {
|
||||
if !left_type.is_assignable_from(&right_type) {
|
||||
return Err(AsgError::unexpected_type(left_type, right_type, &value.span).into());
|
||||
return Err(AsgError::unexpected_type(left_type, right_type, &value.span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
(None, None) => {
|
||||
return Err(AsgError::unexpected_type("any type", "unknown type", &value.span).into());
|
||||
return Err(AsgError::unexpected_type("any type", "unknown type", &value.span, new_backtrace()).into());
|
||||
}
|
||||
(_, _) => (),
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ use crate::{
|
||||
Type,
|
||||
};
|
||||
pub use leo_ast::{BinaryOperation, Node as AstNode};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -94,7 +94,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
None,
|
||||
scope
|
||||
.resolve_function(&name.name)
|
||||
.ok_or_else(|| AsgError::unresolved_function(&name.name, &name.span))?,
|
||||
.ok_or_else(|| AsgError::unresolved_function(&name.name, &name.span, new_backtrace()))?,
|
||||
),
|
||||
leo_ast::Expression::CircuitMemberAccess(leo_ast::CircuitMemberAccessExpression {
|
||||
circuit: ast_circuit,
|
||||
@ -109,28 +109,41 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
"circuit",
|
||||
type_.map(|x| x.to_string()).unwrap_or_else(|| "unknown".to_string()),
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
let circuit_name = circuit.name.borrow().name.clone();
|
||||
let member = circuit.members.borrow();
|
||||
let member = member
|
||||
.get(name.name.as_ref())
|
||||
.ok_or_else(|| AsgError::unresolved_circuit_member(&circuit_name, &name.name, span))?;
|
||||
let member = member.get(name.name.as_ref()).ok_or_else(|| {
|
||||
AsgError::unresolved_circuit_member(&circuit_name, &name.name, span, new_backtrace())
|
||||
})?;
|
||||
match member {
|
||||
CircuitMember::Function(body) => {
|
||||
if body.qualifier == FunctionQualifier::Static {
|
||||
return Err(AsgError::circuit_static_call_invalid(&circuit_name, &name.name, span).into());
|
||||
return Err(AsgError::circuit_static_call_invalid(
|
||||
&circuit_name,
|
||||
&name.name,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
} else if body.qualifier == FunctionQualifier::MutSelfRef && !target.is_mut_ref() {
|
||||
return Err(
|
||||
AsgError::circuit_member_mut_call_invalid(circuit_name, &name.name, span).into(),
|
||||
);
|
||||
return Err(AsgError::circuit_member_mut_call_invalid(
|
||||
circuit_name,
|
||||
&name.name,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
(Some(target), *body)
|
||||
}
|
||||
CircuitMember::Variable(_) => {
|
||||
return Err(AsgError::circuit_variable_call(circuit_name, &name.name, span).into());
|
||||
return Err(
|
||||
AsgError::circuit_variable_call(circuit_name, &name.name, span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,27 +153,35 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
span,
|
||||
}) => {
|
||||
let circuit = if let leo_ast::Expression::Identifier(circuit_name) = &**ast_circuit {
|
||||
scope
|
||||
.resolve_circuit(&circuit_name.name)
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&circuit_name.name, &circuit_name.span))?
|
||||
scope.resolve_circuit(&circuit_name.name).ok_or_else(|| {
|
||||
AsgError::unresolved_circuit(&circuit_name.name, &circuit_name.span, new_backtrace())
|
||||
})?
|
||||
} else {
|
||||
return Err(AsgError::unexpected_type("circuit", "unknown", span).into());
|
||||
return Err(AsgError::unexpected_type("circuit", "unknown", span, new_backtrace()).into());
|
||||
};
|
||||
let circuit_name = circuit.name.borrow().name.clone();
|
||||
|
||||
let member = circuit.members.borrow();
|
||||
let member = member
|
||||
.get(name.name.as_ref())
|
||||
.ok_or_else(|| AsgError::unresolved_circuit_member(&circuit_name, &name.name, span))?;
|
||||
let member = member.get(name.name.as_ref()).ok_or_else(|| {
|
||||
AsgError::unresolved_circuit_member(&circuit_name, &name.name, span, new_backtrace())
|
||||
})?;
|
||||
match member {
|
||||
CircuitMember::Function(body) => {
|
||||
if body.qualifier != FunctionQualifier::Static {
|
||||
return Err(AsgError::circuit_member_call_invalid(circuit_name, &name.name, span).into());
|
||||
return Err(AsgError::circuit_member_call_invalid(
|
||||
circuit_name,
|
||||
&name.name,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
(None, *body)
|
||||
}
|
||||
CircuitMember::Variable(_) => {
|
||||
return Err(AsgError::circuit_variable_call(circuit_name, &name.name, span).into());
|
||||
return Err(
|
||||
AsgError::circuit_variable_call(circuit_name, &name.name, span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,6 +189,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
return Err(AsgError::illegal_ast_structure(
|
||||
"non Identifier/CircuitMemberAccess/CircuitStaticFunctionAccess as call target",
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -175,7 +197,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
if let Some(expected) = expected_type {
|
||||
let output: Type = function.output.clone();
|
||||
if !expected.matches(&output) {
|
||||
return Err(AsgError::unexpected_type(expected, output, &value.span).into());
|
||||
return Err(AsgError::unexpected_type(expected, output, &value.span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
if value.arguments.len() != function.arguments.len() {
|
||||
@ -183,6 +205,7 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
function.arguments.len(),
|
||||
value.arguments.len(),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -195,14 +218,14 @@ impl<'a> FromAst<'a, leo_ast::CallExpression> for CallExpression<'a> {
|
||||
let argument = argument.get().borrow();
|
||||
let converted = <&Expression<'a>>::from_ast(scope, expr, Some(argument.type_.clone().partial()))?;
|
||||
if argument.const_ && !converted.is_consty() {
|
||||
return Err(AsgError::unexpected_nonconst(expr.span()).into());
|
||||
return Err(AsgError::unexpected_nonconst(expr.span(), new_backtrace()).into());
|
||||
}
|
||||
Ok(Cell::new(converted))
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
if function.is_test() {
|
||||
return Err(AsgError::call_test_function(&value.span).into());
|
||||
return Err(AsgError::call_test_function(&value.span, new_backtrace()).into());
|
||||
}
|
||||
Ok(CallExpression {
|
||||
parent: Cell::new(None),
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
pub use leo_ast::UnaryOperation;
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -80,7 +80,7 @@ impl<'a> FromAst<'a, leo_ast::CastExpression> for CastExpression<'a> {
|
||||
let target_type = scope.resolve_ast_type(&value.target_type, &value.span)?;
|
||||
if let Some(expected_type) = &expected_type {
|
||||
if !expected_type.matches(&target_type) {
|
||||
return Err(AsgError::unexpected_type(expected_type, target_type, &value.span).into());
|
||||
return Err(AsgError::unexpected_type(expected_type, target_type, &value.span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ use crate::{
|
||||
Type,
|
||||
};
|
||||
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
use std::cell::Cell;
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -111,6 +111,7 @@ impl<'a> FromAst<'a, leo_ast::CircuitMemberAccessExpression> for CircuitAccessEx
|
||||
"circuit",
|
||||
x.map(|x| x.to_string()).unwrap_or_else(|| "unknown".to_string()),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -123,7 +124,9 @@ impl<'a> FromAst<'a, leo_ast::CircuitMemberAccessExpression> for CircuitAccessEx
|
||||
if let CircuitMember::Variable(type_) = &member {
|
||||
let type_: Type = type_.clone();
|
||||
if !expected_type.matches(&type_) {
|
||||
return Err(AsgError::unexpected_type(expected_type, type_, &value.span).into());
|
||||
return Err(
|
||||
AsgError::unexpected_type(expected_type, type_, &value.span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
} // used by call expression
|
||||
}
|
||||
@ -143,15 +146,20 @@ impl<'a> FromAst<'a, leo_ast::CircuitMemberAccessExpression> for CircuitAccessEx
|
||||
CircuitMember::Variable(expected_type.clone()),
|
||||
);
|
||||
} else {
|
||||
return Err(
|
||||
AsgError::input_ref_needs_type(&circuit.name.borrow().name, &value.name.name, &value.span).into(),
|
||||
);
|
||||
return Err(AsgError::input_ref_needs_type(
|
||||
&circuit.name.borrow().name,
|
||||
&value.name.name,
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
} else {
|
||||
return Err(AsgError::unresolved_circuit_member(
|
||||
&circuit.name.borrow().name,
|
||||
&value.name.name,
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -175,14 +183,14 @@ impl<'a> FromAst<'a, leo_ast::CircuitStaticFunctionAccessExpression> for Circuit
|
||||
let circuit = match &*value.circuit {
|
||||
leo_ast::Expression::Identifier(name) => scope
|
||||
.resolve_circuit(&name.name)
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&name.name, &name.span))?,
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&name.name, &name.span, new_backtrace()))?,
|
||||
_ => {
|
||||
return Err(AsgError::unexpected_type("circuit", "unknown", &value.span).into());
|
||||
return Err(AsgError::unexpected_type("circuit", "unknown", &value.span, new_backtrace()).into());
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(expected_type) = expected_type {
|
||||
return Err(AsgError::unexpected_type(expected_type, "none", &value.span).into());
|
||||
return Err(AsgError::unexpected_type(expected_type, "none", &value.span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
if let Some(CircuitMember::Function(_)) = circuit.members.borrow().get(value.name.name.as_ref()) {
|
||||
@ -192,6 +200,7 @@ impl<'a> FromAst<'a, leo_ast::CircuitStaticFunctionAccessExpression> for Circuit
|
||||
&circuit.name.borrow().name,
|
||||
&value.name.name,
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ use crate::{
|
||||
Type,
|
||||
};
|
||||
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use std::cell::Cell;
|
||||
@ -96,12 +96,18 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
) -> Result<CircuitInitExpression<'a>> {
|
||||
let circuit = scope
|
||||
.resolve_circuit(&value.name.name)
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&value.name.name, &value.name.span))?;
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&value.name.name, &value.name.span, new_backtrace()))?;
|
||||
match expected_type {
|
||||
Some(PartialType::Type(Type::Circuit(expected_circuit))) if expected_circuit == circuit => (),
|
||||
None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, circuit.name.borrow().name.to_string(), &value.span).into());
|
||||
return Err(AsgError::unexpected_type(
|
||||
x,
|
||||
circuit.name.borrow().name.to_string(),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
let members: IndexMap<&str, (&Identifier, Option<&leo_ast::Expression>)> = value
|
||||
@ -117,9 +123,13 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
let circuit_members = circuit.members.borrow();
|
||||
for (name, member) in circuit_members.iter() {
|
||||
if defined_variables.contains(name) {
|
||||
return Err(
|
||||
AsgError::overridden_circuit_member(&circuit.name.borrow().name, name, &value.span).into(),
|
||||
);
|
||||
return Err(AsgError::overridden_circuit_member(
|
||||
&circuit.name.borrow().name,
|
||||
name,
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
defined_variables.insert(name.clone());
|
||||
let type_: Type = if let CircuitMember::Variable(type_) = &member {
|
||||
@ -139,17 +149,25 @@ impl<'a> FromAst<'a, leo_ast::CircuitInitExpression> for CircuitInitExpression<'
|
||||
};
|
||||
values.push(((*identifier).clone(), Cell::new(received)));
|
||||
} else {
|
||||
return Err(
|
||||
AsgError::missing_circuit_member(&circuit.name.borrow().name, name, &value.span).into(),
|
||||
);
|
||||
return Err(AsgError::missing_circuit_member(
|
||||
&circuit.name.borrow().name,
|
||||
name,
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
|
||||
for (name, (identifier, _expression)) in members.iter() {
|
||||
if circuit_members.get(*name).is_none() {
|
||||
return Err(
|
||||
AsgError::extra_circuit_member(&circuit.name.borrow().name, name, &identifier.span).into(),
|
||||
);
|
||||
return Err(AsgError::extra_circuit_member(
|
||||
&circuit.name.borrow().name,
|
||||
name,
|
||||
&identifier.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ use crate::{
|
||||
Type,
|
||||
};
|
||||
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -85,7 +85,7 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
match expected_type.map(PartialType::full).flatten() {
|
||||
Some(Type::Address) | None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, Type::Address, span).into());
|
||||
return Err(AsgError::unexpected_type(x, Type::Address, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
Constant {
|
||||
@ -98,7 +98,7 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
match expected_type.map(PartialType::full).flatten() {
|
||||
Some(Type::Boolean) | None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, Type::Boolean, span).into());
|
||||
return Err(AsgError::unexpected_type(x, Type::Boolean, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
Constant {
|
||||
@ -107,7 +107,7 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
value: ConstValue::Boolean(
|
||||
value
|
||||
.parse::<bool>()
|
||||
.map_err(|_| AsgError::invalid_boolean(value, span))?,
|
||||
.map_err(|_| AsgError::invalid_boolean(value, span, new_backtrace()))?,
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -115,7 +115,7 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
match expected_type.map(PartialType::full).flatten() {
|
||||
Some(Type::Char) | None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, Type::Char, value.span()).into());
|
||||
return Err(AsgError::unexpected_type(x, Type::Char, value.span(), new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,20 +129,24 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
match expected_type.map(PartialType::full).flatten() {
|
||||
Some(Type::Field) | None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, Type::Field, span).into());
|
||||
return Err(AsgError::unexpected_type(x, Type::Field, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
Constant {
|
||||
parent: Cell::new(None),
|
||||
span: Some(span.clone()),
|
||||
value: ConstValue::Field(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
value: ConstValue::Field(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
}
|
||||
}
|
||||
Group(value) => {
|
||||
match expected_type.map(PartialType::full).flatten() {
|
||||
Some(Type::Group) | None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, Type::Group, value.span()).into());
|
||||
return Err(AsgError::unexpected_type(x, Type::Group, value.span(), new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
Constant {
|
||||
@ -159,7 +163,7 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
}
|
||||
}
|
||||
Implicit(value, span) => match expected_type {
|
||||
None => return Err(AsgError::unresolved_type("unknown", span).into()),
|
||||
None => return Err(AsgError::unresolved_type("unknown", span, new_backtrace()).into()),
|
||||
Some(PartialType::Integer(Some(sub_type), _)) | Some(PartialType::Integer(None, Some(sub_type))) => {
|
||||
Constant {
|
||||
parent: Cell::new(None),
|
||||
@ -170,7 +174,11 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
Some(PartialType::Type(Type::Field)) => Constant {
|
||||
parent: Cell::new(None),
|
||||
span: Some(span.clone()),
|
||||
value: ConstValue::Field(value.parse().map_err(|_| AsgError::invalid_int(value, span))?),
|
||||
value: ConstValue::Field(
|
||||
value
|
||||
.parse()
|
||||
.map_err(|_| AsgError::invalid_int(value, span, new_backtrace()))?,
|
||||
),
|
||||
},
|
||||
Some(PartialType::Type(Type::Group)) => Constant {
|
||||
parent: Cell::new(None),
|
||||
@ -183,7 +191,7 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
value: ConstValue::Address(value.clone()),
|
||||
},
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, "unknown", span).into());
|
||||
return Err(AsgError::unexpected_type(x, "unknown", span, new_backtrace()).into());
|
||||
}
|
||||
},
|
||||
Integer(int_type, value, span) => {
|
||||
@ -192,7 +200,7 @@ impl<'a> FromAst<'a, leo_ast::ValueExpression> for Constant<'a> {
|
||||
Some(PartialType::Integer(None, Some(_))) => (),
|
||||
None => (),
|
||||
Some(x) => {
|
||||
return Err(AsgError::unexpected_type(x, int_type, span).into());
|
||||
return Err(AsgError::unexpected_type(x, int_type, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
Constant {
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -91,7 +91,7 @@ impl<'a> FromAst<'a, leo_ast::TernaryExpression> for TernaryExpression<'a> {
|
||||
let right = if_false.get().get_type().unwrap().into();
|
||||
|
||||
if left != right {
|
||||
return Err(AsgError::ternary_different_types(left, right, &value.span).into());
|
||||
return Err(AsgError::ternary_different_types(left, right, &value.span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
Ok(TernaryExpression {
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -80,7 +80,7 @@ impl<'a> FromAst<'a, leo_ast::TupleAccessExpression> for TupleAccessExpression<'
|
||||
.index
|
||||
.value
|
||||
.parse::<usize>()
|
||||
.map_err(|_| AsgError::parse_index_error(&value.span))?;
|
||||
.map_err(|_| AsgError::parse_index_error(&value.span, new_backtrace()))?;
|
||||
|
||||
let mut expected_tuple = vec![None; index + 1];
|
||||
expected_tuple[index] = expected_type;
|
||||
@ -95,6 +95,7 @@ impl<'a> FromAst<'a, leo_ast::TupleAccessExpression> for TupleAccessExpression<'
|
||||
.map(|x| x.to_string())
|
||||
.unwrap_or_else(|| "unknown".to_string()),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -90,6 +90,7 @@ impl<'a> FromAst<'a, leo_ast::TupleInitExpression> for TupleInitExpression<'a> {
|
||||
"tuple",
|
||||
x.map(|x| x.to_string()).unwrap_or_else(|| "unknown".to_string()),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -103,6 +104,7 @@ impl<'a> FromAst<'a, leo_ast::TupleInitExpression> for TupleInitExpression<'a> {
|
||||
format!("tuple of length {}", tuple_types.len()),
|
||||
format!("tuple of length {}", value.elements.len()),
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Type};
|
||||
pub use leo_ast::UnaryOperation;
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -95,7 +95,7 @@ impl<'a> FromAst<'a, leo_ast::UnaryExpression> for UnaryExpression<'a> {
|
||||
UnaryOperation::Not => match expected_type.map(|x| x.full()).flatten() {
|
||||
Some(Type::Boolean) | None => Some(Type::Boolean),
|
||||
Some(type_) => {
|
||||
return Err(AsgError::unexpected_type(type_, Type::Boolean, &value.span).into());
|
||||
return Err(AsgError::unexpected_type(type_, Type::Boolean, &value.span, new_backtrace()).into());
|
||||
}
|
||||
},
|
||||
UnaryOperation::Negate => match expected_type.map(|x| x.full()).flatten() {
|
||||
@ -104,14 +104,20 @@ impl<'a> FromAst<'a, leo_ast::UnaryExpression> for UnaryExpression<'a> {
|
||||
Some(Type::Field) => Some(Type::Field),
|
||||
None => None,
|
||||
Some(type_) => {
|
||||
return Err(AsgError::unexpected_type(type_, "integer, group, field", &value.span).into());
|
||||
return Err(AsgError::unexpected_type(
|
||||
type_,
|
||||
"integer, group, field",
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
},
|
||||
UnaryOperation::BitNot => match expected_type.map(|x| x.full()).flatten() {
|
||||
Some(type_ @ Type::Integer(_)) => Some(type_),
|
||||
None => None,
|
||||
Some(type_) => {
|
||||
return Err(AsgError::unexpected_type(type_, "integer", &value.span).into());
|
||||
return Err(AsgError::unexpected_type(type_, "integer", &value.span, new_backtrace()).into());
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -126,7 +132,7 @@ impl<'a> FromAst<'a, leo_ast::UnaryExpression> for UnaryExpression<'a> {
|
||||
})
|
||||
.unwrap_or(false);
|
||||
if is_expr_unsigned {
|
||||
return Err(AsgError::unsigned_negation(&value.span).into());
|
||||
return Err(AsgError::unsigned_negation(&value.span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
Ok(UnaryExpression {
|
||||
|
@ -29,7 +29,7 @@ use crate::{
|
||||
Variable,
|
||||
};
|
||||
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -143,6 +143,7 @@ impl<'a> FromAst<'a, leo_ast::Identifier> for &'a Expression<'a> {
|
||||
return Err(AsgError::illegal_input_variable_reference(
|
||||
"attempted to reference input when none is in scope",
|
||||
&value.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -157,7 +158,7 @@ impl<'a> FromAst<'a, leo_ast::Identifier> for &'a Expression<'a> {
|
||||
value: ConstValue::Address(value.name.clone()),
|
||||
})));
|
||||
}
|
||||
return Err(AsgError::unresolved_reference(&value.name, &value.span).into());
|
||||
return Err(AsgError::unresolved_reference(&value.name, &value.span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -172,9 +173,9 @@ impl<'a> FromAst<'a, leo_ast::Identifier> for &'a Expression<'a> {
|
||||
if let Some(expected_type) = expected_type {
|
||||
let type_ = expression
|
||||
.get_type()
|
||||
.ok_or_else(|| AsgError::unresolved_reference(&value.name, &value.span))?;
|
||||
.ok_or_else(|| AsgError::unresolved_reference(&value.name, &value.span, new_backtrace()))?;
|
||||
if !expected_type.matches(&type_) {
|
||||
return Err(AsgError::unexpected_type(expected_type, type_, &value.span).into());
|
||||
return Err(AsgError::unexpected_type(expected_type, type_, &value.span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Function, Identifier, Node, Scope, Type};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use std::cell::RefCell;
|
||||
@ -71,9 +71,13 @@ impl<'a> Circuit<'a> {
|
||||
for member in value.members.iter() {
|
||||
if let leo_ast::CircuitMember::CircuitVariable(name, type_) = member {
|
||||
if members.contains_key(name.name.as_ref()) {
|
||||
return Err(
|
||||
AsgError::redefined_circuit_member(&value.circuit_name.name, &name.name, &name.span).into(),
|
||||
);
|
||||
return Err(AsgError::redefined_circuit_member(
|
||||
&value.circuit_name.name,
|
||||
&name.name,
|
||||
&name.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
members.insert(
|
||||
name.name.to_string(),
|
||||
@ -100,13 +104,14 @@ impl<'a> Circuit<'a> {
|
||||
&value.circuit_name.name,
|
||||
&function.identifier.name,
|
||||
&function.identifier.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
let asg_function = Function::init(new_scope, function)?;
|
||||
asg_function.circuit.replace(Some(circuit));
|
||||
if asg_function.is_test() {
|
||||
return Err(AsgError::circuit_test_function(&function.identifier.span).into());
|
||||
return Err(AsgError::circuit_test_function(&function.identifier.span, new_backtrace()).into());
|
||||
}
|
||||
members.insert(
|
||||
function.identifier.name.to_string(),
|
||||
|
@ -29,7 +29,7 @@ use crate::{
|
||||
use indexmap::IndexMap;
|
||||
pub use leo_ast::Annotation;
|
||||
use leo_ast::FunctionInput;
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
@ -107,7 +107,7 @@ impl<'a> Function<'a> {
|
||||
}
|
||||
}
|
||||
if qualifier != FunctionQualifier::Static && scope.circuit_self.get().is_none() {
|
||||
return Err(AsgError::invalid_self_in_global(&value.span).into());
|
||||
return Err(AsgError::invalid_self_in_global(&value.span, new_backtrace()).into());
|
||||
}
|
||||
let function = scope.context.alloc_function(Function {
|
||||
id: scope.context.get_id(),
|
||||
@ -151,12 +151,16 @@ impl<'a> Function<'a> {
|
||||
let main_block = BlockStatement::from_ast(self.scope, &value.block, None)?;
|
||||
let mut director = MonoidalDirector::new(ReturnPathReducer::new());
|
||||
if !director.reduce_block(&main_block).0 && !self.output.is_unit() {
|
||||
return Err(AsgError::function_missing_return(&self.name.borrow().name, &value.span).into());
|
||||
return Err(
|
||||
AsgError::function_missing_return(&self.name.borrow().name, &value.span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
|
||||
#[allow(clippy::never_loop)] // TODO @Protryon: How should we return multiple errors?
|
||||
for (span, error) in director.reducer().errors {
|
||||
return Err(AsgError::function_return_validation(&self.name.borrow().name, error, &span).into());
|
||||
return Err(
|
||||
AsgError::function_return_validation(&self.name.borrow().name, error, &span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
|
||||
self.body
|
||||
|
@ -26,7 +26,7 @@ pub use function::*;
|
||||
|
||||
use crate::{node::FromAst, ArenaNode, AsgContext, DefinitionStatement, ImportResolver, Input, Scope, Statement};
|
||||
use leo_ast::{Identifier, PackageAccess, PackageOrPackages};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use std::cell::{Cell, RefCell};
|
||||
@ -164,7 +164,7 @@ impl<'a> Program<'a> {
|
||||
)? {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return Err(AsgError::unresolved_import(pretty_package, &Span::default()).into());
|
||||
return Err(AsgError::unresolved_import(pretty_package, &Span::default(), new_backtrace()).into());
|
||||
}
|
||||
};
|
||||
|
||||
@ -196,7 +196,12 @@ impl<'a> Program<'a> {
|
||||
} else if let Some(global_const) = resolved_package.global_consts.get(&name) {
|
||||
imported_global_consts.insert(name.clone(), *global_const);
|
||||
} else {
|
||||
return Err(AsgError::unresolved_import(format!("{}.{}", pretty_package, name), &span).into());
|
||||
return Err(AsgError::unresolved_import(
|
||||
format!("{}.{}", pretty_package, name),
|
||||
&span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
ImportSymbol::Alias(name, alias) => {
|
||||
@ -207,7 +212,12 @@ impl<'a> Program<'a> {
|
||||
} else if let Some(global_const) = resolved_package.global_consts.get(&name) {
|
||||
imported_global_consts.insert(alias.clone(), *global_const);
|
||||
} else {
|
||||
return Err(AsgError::unresolved_import(format!("{}.{}", pretty_package, name), &span).into());
|
||||
return Err(AsgError::unresolved_import(
|
||||
format!("{}.{}", pretty_package, name),
|
||||
&span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -298,7 +308,7 @@ impl<'a> Program<'a> {
|
||||
let name = name.name.to_string();
|
||||
|
||||
if functions.contains_key(&name) {
|
||||
return Err(AsgError::duplicate_function_definition(name, &function.span).into());
|
||||
return Err(AsgError::duplicate_function_definition(name, &function.span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
functions.insert(name, asg_function);
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{AsgContext, Circuit, DefinitionStatement, Function, Input, Type, Variable};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use std::cell::{Cell, RefCell};
|
||||
@ -189,7 +189,7 @@ impl<'a> Scope<'a> {
|
||||
let dimension = dimension
|
||||
.value
|
||||
.parse::<usize>()
|
||||
.map_err(|_| AsgError::parse_index_error(span))?;
|
||||
.map_err(|_| AsgError::parse_index_error(span, new_backtrace()))?;
|
||||
item = Box::new(Type::Array(item, dimension));
|
||||
}
|
||||
*item
|
||||
@ -202,15 +202,15 @@ impl<'a> Scope<'a> {
|
||||
),
|
||||
Circuit(name) if name.name.as_ref() == "Self" => Type::Circuit(
|
||||
self.resolve_circuit_self()
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&name.name, &name.span))?,
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&name.name, &name.span, new_backtrace()))?,
|
||||
),
|
||||
SelfType => Type::Circuit(
|
||||
self.resolve_circuit_self()
|
||||
.ok_or_else(|| AsgError::reference_self_outside_circuit(span))?,
|
||||
.ok_or_else(|| AsgError::reference_self_outside_circuit(span, new_backtrace()))?,
|
||||
),
|
||||
Circuit(name) => Type::Circuit(
|
||||
self.resolve_circuit(&name.name)
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&name.name, &name.span))?,
|
||||
.ok_or_else(|| AsgError::unresolved_circuit(&name.name, &name.span, new_backtrace()))?,
|
||||
),
|
||||
})
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ use crate::{
|
||||
};
|
||||
pub use leo_ast::AssignOperation;
|
||||
use leo_ast::AssigneeAccess as AstAssigneeAccess;
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -78,17 +78,18 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
return Err(AsgError::illegal_input_variable_reference(
|
||||
"attempted to reference input when none is in scope",
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
} else {
|
||||
scope
|
||||
.resolve_variable(name)
|
||||
.ok_or_else(|| AsgError::unresolved_reference(name, span))?
|
||||
.ok_or_else(|| AsgError::unresolved_reference(name, span, new_backtrace()))?
|
||||
};
|
||||
|
||||
if !variable.borrow().mutable {
|
||||
return Err(AsgError::immutable_assignment(name, &statement.span).into());
|
||||
return Err(AsgError::immutable_assignment(name, &statement.span, new_backtrace()).into());
|
||||
}
|
||||
let mut target_type: Option<PartialType> = Some(variable.borrow().type_.clone().into());
|
||||
|
||||
@ -123,13 +124,23 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
) {
|
||||
let left = match left {
|
||||
ConstValue::Int(x) => x.to_usize().ok_or_else(|| {
|
||||
AsgError::invalid_assign_index(name, x.to_string(), &statement.span)
|
||||
AsgError::invalid_assign_index(
|
||||
name,
|
||||
x.to_string(),
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
})?,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
let right = match right {
|
||||
ConstValue::Int(x) => x.to_usize().ok_or_else(|| {
|
||||
AsgError::invalid_assign_index(name, x.to_string(), &statement.span)
|
||||
AsgError::invalid_assign_index(
|
||||
name,
|
||||
x.to_string(),
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
})?,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
@ -141,12 +152,13 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
left,
|
||||
right,
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => return Err(AsgError::index_into_non_array(name, &statement.span).into()),
|
||||
_ => return Err(AsgError::index_into_non_array(name, &statement.span, new_backtrace()).into()),
|
||||
}
|
||||
|
||||
AssignAccess::ArrayRange(Cell::new(left), Cell::new(right))
|
||||
@ -154,7 +166,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
AstAssigneeAccess::ArrayIndex(index) => {
|
||||
target_type = match target_type.clone() {
|
||||
Some(PartialType::Array(item, _)) => item.map(|x| *x),
|
||||
_ => return Err(AsgError::index_into_non_array(name, &statement.span).into()),
|
||||
_ => return Err(AsgError::index_into_non_array(name, &statement.span, new_backtrace()).into()),
|
||||
};
|
||||
AssignAccess::ArrayIndex(Cell::new(<&Expression<'a>>::from_ast(
|
||||
scope,
|
||||
@ -166,13 +178,12 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
let index = index
|
||||
.value
|
||||
.parse::<usize>()
|
||||
.map_err(|_| AsgError::parse_index_error(span))?;
|
||||
.map_err(|_| AsgError::parse_index_error(span, new_backtrace()))?;
|
||||
target_type = match target_type {
|
||||
Some(PartialType::Tuple(types)) => types
|
||||
.get(index)
|
||||
.cloned()
|
||||
.ok_or_else(|| AsgError::tuple_index_out_of_bounds(index, &statement.span))?,
|
||||
_ => return Err(AsgError::index_into_non_tuple(name, &statement.span).into()),
|
||||
Some(PartialType::Tuple(types)) => types.get(index).cloned().ok_or_else(|| {
|
||||
AsgError::tuple_index_out_of_bounds(index, &statement.span, new_backtrace())
|
||||
})?,
|
||||
_ => return Err(AsgError::index_into_non_tuple(name, &statement.span, new_backtrace()).into()),
|
||||
};
|
||||
AssignAccess::Tuple(index)
|
||||
}
|
||||
@ -187,13 +198,19 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
&circuit.name.borrow().name,
|
||||
&name.name,
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let x = match &member {
|
||||
CircuitMember::Variable(type_) => type_.clone(),
|
||||
CircuitMember::Function(_) => {
|
||||
return Err(AsgError::illegal_function_assign(&name.name, &statement.span).into());
|
||||
return Err(AsgError::illegal_function_assign(
|
||||
&name.name,
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
Some(x.partial())
|
||||
@ -202,6 +219,7 @@ impl<'a> FromAst<'a, leo_ast::AssignStatement> for &'a Statement<'a> {
|
||||
return Err(AsgError::index_into_non_tuple(
|
||||
&statement.assignee.identifier.name,
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, ExpressionNode, FromAst, InnerVariable, Node, PartialType, Scope, Statement, Type, Variable};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
@ -71,7 +71,7 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ,");
|
||||
|
||||
return Err(AsgError::invalid_const_assign(var_names, &statement.span).into());
|
||||
return Err(AsgError::invalid_const_assign(var_names, &statement.span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
let type_ = type_.or_else(|| value.get_type());
|
||||
@ -83,6 +83,7 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
return Err(AsgError::illegal_ast_structure(
|
||||
"cannot have 0 variable names in destructuring tuple",
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -100,6 +101,7 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
format!("{}-ary tuple", statement.variable_names.len()),
|
||||
type_.map(|x| x.to_string()).unwrap_or_else(|| "unknown".to_string()),
|
||||
&statement.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -110,7 +112,9 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
variables.push(&*scope.context.alloc_variable(RefCell::new(InnerVariable {
|
||||
id: scope.context.get_id(),
|
||||
name: variable.identifier.clone(),
|
||||
type_: type_.ok_or_else(|| AsgError::unresolved_type(&variable.identifier.name, &statement.span))?,
|
||||
type_: type_.ok_or_else(|| {
|
||||
AsgError::unresolved_type(&variable.identifier.name, &statement.span, new_backtrace())
|
||||
})?,
|
||||
mutable: variable.mutable,
|
||||
const_: false,
|
||||
declaration: crate::VariableDeclaration::Definition,
|
||||
@ -123,7 +127,7 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
let mut variables = scope.variables.borrow_mut();
|
||||
let var_name = variable.borrow().name.name.to_string();
|
||||
if variables.contains_key(&var_name) {
|
||||
return Err(AsgError::duplicate_variable_definition(var_name, &statement.span).into());
|
||||
return Err(AsgError::duplicate_variable_definition(var_name, &statement.span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
variables.insert(var_name, *variable);
|
||||
|
@ -17,7 +17,7 @@
|
||||
use leo_ast::IntegerType;
|
||||
|
||||
use crate::{Expression, ExpressionNode, FromAst, InnerVariable, Node, PartialType, Scope, Statement, Variable};
|
||||
use leo_errors::{AsgError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AsgError, Result, Span};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
@ -50,10 +50,14 @@ impl<'a> FromAst<'a, leo_ast::IterationStatement> for &'a Statement<'a> {
|
||||
|
||||
// Return an error if start or stop is not constant.
|
||||
if !start.is_consty() {
|
||||
return Err(AsgError::unexpected_nonconst(&start.span().cloned().unwrap_or_default()).into());
|
||||
return Err(
|
||||
AsgError::unexpected_nonconst(&start.span().cloned().unwrap_or_default(), new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
if !stop.is_consty() {
|
||||
return Err(AsgError::unexpected_nonconst(&stop.span().cloned().unwrap_or_default()).into());
|
||||
return Err(
|
||||
AsgError::unexpected_nonconst(&stop.span().cloned().unwrap_or_default(), new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
|
||||
let variable = scope.context.alloc_variable(RefCell::new(InnerVariable {
|
||||
@ -61,7 +65,7 @@ impl<'a> FromAst<'a, leo_ast::IterationStatement> for &'a Statement<'a> {
|
||||
name: statement.variable.clone(),
|
||||
type_: start
|
||||
.get_type()
|
||||
.ok_or_else(|| AsgError::unresolved_type(&statement.variable.name, &statement.span))?,
|
||||
.ok_or_else(|| AsgError::unresolved_type(&statement.variable.name, &statement.span, new_backtrace()))?,
|
||||
mutable: false,
|
||||
const_: true,
|
||||
declaration: crate::VariableDeclaration::IterationDefinition,
|
||||
|
@ -25,9 +25,6 @@ version = "1.5.3"
|
||||
path = "../errors"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.backtrace]
|
||||
version = "0.3.61"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.7.0"
|
||||
features = [ "serde-1" ]
|
||||
|
@ -62,9 +62,7 @@ pub use self::types::*;
|
||||
mod node;
|
||||
pub use node::*;
|
||||
|
||||
use leo_errors::{AstError, Result};
|
||||
|
||||
use backtrace::Backtrace;
|
||||
use leo_errors::{new_backtrace, AstError, Result};
|
||||
|
||||
/// The abstract syntax tree (AST) for a Leo program.
|
||||
///
|
||||
@ -101,30 +99,30 @@ impl Ast {
|
||||
/// Serializes the ast into a JSON string.
|
||||
pub fn to_json_string(&self) -> Result<String> {
|
||||
Ok(serde_json::to_string_pretty(&self.ast)
|
||||
.map_err(|e| AstError::failed_to_convert_ast_to_json_string(&e, Backtrace::new()))?)
|
||||
.map_err(|e| AstError::failed_to_convert_ast_to_json_string(&e, new_backtrace()))?)
|
||||
}
|
||||
|
||||
/// Serializes the ast into a JSON file.
|
||||
pub fn to_json_file(&self, mut path: std::path::PathBuf, file_name: &str) -> Result<()> {
|
||||
path.push(file_name);
|
||||
let file = std::fs::File::create(&path)
|
||||
.map_err(|e| AstError::failed_to_create_ast_json_file(&path, &e, Backtrace::new()))?;
|
||||
.map_err(|e| AstError::failed_to_create_ast_json_file(&path, &e, new_backtrace()))?;
|
||||
let writer = std::io::BufWriter::new(file);
|
||||
Ok(serde_json::to_writer_pretty(writer, &self.ast)
|
||||
.map_err(|e| AstError::failed_to_write_ast_to_json_file(&path, &e, Backtrace::new()))?)
|
||||
.map_err(|e| AstError::failed_to_write_ast_to_json_file(&path, &e, new_backtrace()))?)
|
||||
}
|
||||
|
||||
/// Deserializes the JSON string into a ast.
|
||||
pub fn from_json_string(json: &str) -> Result<Self> {
|
||||
let ast: Program = serde_json::from_str(json)
|
||||
.map_err(|e| AstError::failed_to_read_json_string_to_ast(&e, Backtrace::new()))?;
|
||||
let ast: Program =
|
||||
serde_json::from_str(json).map_err(|e| AstError::failed_to_read_json_string_to_ast(&e, new_backtrace()))?;
|
||||
Ok(Self { ast })
|
||||
}
|
||||
|
||||
/// Deserializes the JSON string into a ast from a file.
|
||||
pub fn from_json_file(path: std::path::PathBuf) -> Result<Self> {
|
||||
let data = std::fs::read_to_string(&path)
|
||||
.map_err(|e| AstError::failed_to_read_json_file(&path, &e, Backtrace::new()))?;
|
||||
.map_err(|e| AstError::failed_to_read_json_file(&path, &e, new_backtrace()))?;
|
||||
Self::from_json_string(&data)
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::*;
|
||||
use leo_errors::{AstError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AstError, Result, Span};
|
||||
|
||||
/// Replace Self when it is in a enclosing circuit type.
|
||||
/// Error when Self is outside an enclosing circuit type.
|
||||
@ -469,7 +469,7 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
match new {
|
||||
Type::Array(type_, mut dimensions) => {
|
||||
if dimensions.is_zero() {
|
||||
return Err(AstError::invalid_array_dimension_size(span).into());
|
||||
return Err(AstError::invalid_array_dimension_size(span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
let mut next = Type::Array(type_, ArrayDimensions(vec![dimensions.remove_last().unwrap()]));
|
||||
@ -486,14 +486,16 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
|
||||
Ok(array)
|
||||
}
|
||||
Type::SelfType if !self.in_circuit => Err(AstError::big_self_outside_of_circuit(span).into()),
|
||||
Type::SelfType if !self.in_circuit => {
|
||||
Err(AstError::big_self_outside_of_circuit(span, new_backtrace()).into())
|
||||
}
|
||||
_ => Ok(new.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
fn reduce_string(&mut self, string: &[Char], span: &Span) -> Result<Expression> {
|
||||
if string.is_empty() {
|
||||
return Err(AstError::empty_string(span).into());
|
||||
return Err(AstError::empty_string(span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
let mut elements = Vec::new();
|
||||
@ -552,7 +554,7 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
element: Expression,
|
||||
) -> Result<ArrayInitExpression> {
|
||||
if array_init.dimensions.is_zero() {
|
||||
return Err(AstError::invalid_array_dimension_size(&array_init.span).into());
|
||||
return Err(AstError::invalid_array_dimension_size(&array_init.span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
let element = Box::new(element);
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
use crate::*;
|
||||
use indexmap::IndexMap;
|
||||
use leo_errors::{AstError, Result, Span};
|
||||
use leo_errors::{new_backtrace, AstError, Result, Span};
|
||||
|
||||
pub struct ReconstructingDirector<R: ReconstructingReducer> {
|
||||
reducer: R,
|
||||
@ -386,7 +386,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
match &console_function_call.function {
|
||||
ConsoleFunction::Error(_) => ConsoleFunction::Error(formatted),
|
||||
ConsoleFunction::Log(_) => ConsoleFunction::Log(formatted),
|
||||
_ => return Err(AstError::impossible_console_assert_call(&args.span).into()),
|
||||
_ => return Err(AstError::impossible_console_assert_call(&args.span, new_backtrace()).into()),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -84,9 +84,6 @@ default-features = false
|
||||
[dependencies.snarkvm-utilities]
|
||||
version = "0.7.4"
|
||||
|
||||
[dependencies.backtrace]
|
||||
version = "0.3.61"
|
||||
|
||||
[dependencies.bincode]
|
||||
version = "1.3"
|
||||
|
||||
@ -109,9 +106,6 @@ version = "1.0"
|
||||
[dependencies.sha2]
|
||||
version = "0.9"
|
||||
|
||||
[dependencies.thiserror]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.tracing]
|
||||
version = "0.1"
|
||||
|
||||
|
@ -27,7 +27,7 @@ use crate::{
|
||||
pub use leo_asg::{new_context, AsgContext as Context, AsgContext};
|
||||
use leo_asg::{Asg, AsgPass, Program as AsgProgram};
|
||||
use leo_ast::{Input, MainInput, Program as AstProgram};
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
use leo_parser::parse_ast;
|
||||
@ -37,7 +37,6 @@ use snarkvm_dpc::testnet1::{instantiated::Components, parameters::SystemParamete
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::{ConstraintSynthesizer, ConstraintSystem, SynthesisError};
|
||||
|
||||
use backtrace::Backtrace;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{
|
||||
fs,
|
||||
@ -114,7 +113,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
context: AsgContext<'a>,
|
||||
options: Option<CompilerOptions>,
|
||||
ast_snapshot_options: Option<AstSnapshotOptions>,
|
||||
) -> Result<Self, LeoError> {
|
||||
) -> Result<Self> {
|
||||
let mut compiler = Self::new(
|
||||
package_name,
|
||||
main_file_path,
|
||||
@ -153,7 +152,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
context: AsgContext<'a>,
|
||||
options: Option<CompilerOptions>,
|
||||
ast_snapshot_options: Option<AstSnapshotOptions>,
|
||||
) -> Result<Self, LeoError> {
|
||||
) -> Result<Self> {
|
||||
let mut compiler = Self::new(
|
||||
package_name,
|
||||
main_file_path,
|
||||
@ -181,7 +180,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
input_path: &Path,
|
||||
state_string: &str,
|
||||
state_path: &Path,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
let input_syntax_tree = LeoInputParser::parse_file(input_string).map_err(|mut e| {
|
||||
e.set_path(
|
||||
input_path.to_str().unwrap_or_default(),
|
||||
@ -224,10 +223,10 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
///
|
||||
/// Parses and stores all programs imported by the main program file.
|
||||
///
|
||||
pub fn parse_program(&mut self) -> Result<(), LeoError> {
|
||||
pub fn parse_program(&mut self) -> Result<()> {
|
||||
// Load the program file.
|
||||
let content = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(self.main_file_path.clone(), e, Backtrace::new()))?;
|
||||
.map_err(|e| CompilerError::file_read_error(self.main_file_path.clone(), e, new_backtrace()))?;
|
||||
|
||||
self.parse_program_from_string(&content)
|
||||
}
|
||||
@ -236,7 +235,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
/// Equivalent to parse_and_check_program but uses the given program_string instead of a main
|
||||
/// file path.
|
||||
///
|
||||
pub fn parse_program_from_string(&mut self, program_string: &str) -> Result<(), LeoError> {
|
||||
pub fn parse_program_from_string(&mut self, program_string: &str) -> Result<()> {
|
||||
// Use the parser to construct the abstract syntax tree (ast).
|
||||
|
||||
let mut ast: leo_ast::Ast = parse_ast(self.main_file_path.to_str().unwrap_or_default(), program_string)?;
|
||||
@ -287,7 +286,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
///
|
||||
/// Run compiler optimization passes on the program in asg format.
|
||||
///
|
||||
fn do_asg_passes(&mut self) -> Result<(), LeoError> {
|
||||
fn do_asg_passes(&mut self) -> Result<()> {
|
||||
assert!(self.asg.is_some());
|
||||
|
||||
// Do constant folding.
|
||||
@ -308,24 +307,24 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
///
|
||||
/// Synthesizes the circuit with program input to verify correctness.
|
||||
///
|
||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(&self, cs: &mut CS) -> Result<Output, LeoError> {
|
||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(&self, cs: &mut CS) -> Result<Output> {
|
||||
generate_constraints::<F, G, CS>(cs, self.asg.as_ref().unwrap(), &self.program_input)
|
||||
}
|
||||
|
||||
///
|
||||
/// Synthesizes the circuit for test functions with program input.
|
||||
///
|
||||
pub fn compile_test_constraints(self, input_pairs: InputPairs) -> Result<(u32, u32), LeoError> {
|
||||
pub fn compile_test_constraints(self, input_pairs: InputPairs) -> Result<(u32, u32)> {
|
||||
generate_test_constraints::<F, G>(self.asg.as_ref().unwrap(), input_pairs, &self.output_directory)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a SHA256 checksum of the program file.
|
||||
///
|
||||
pub fn checksum(&self) -> Result<String, LeoError> {
|
||||
pub fn checksum(&self) -> Result<String> {
|
||||
// Read in the main file as string
|
||||
let unparsed_file = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(self.main_file_path.clone(), e, Backtrace::new()))?;
|
||||
.map_err(|e| CompilerError::file_read_error(self.main_file_path.clone(), e, new_backtrace()))?;
|
||||
|
||||
// Hash the file contents
|
||||
let mut hasher = Sha256::new();
|
||||
@ -340,10 +339,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
///
|
||||
/// Verifies the input to the program.
|
||||
///
|
||||
pub fn verify_local_data_commitment(
|
||||
&self,
|
||||
system_parameters: &SystemParameters<Components>,
|
||||
) -> Result<bool, LeoError> {
|
||||
pub fn verify_local_data_commitment(&self, system_parameters: &SystemParameters<Components>) -> Result<bool> {
|
||||
// TODO CONVERT STATE ERROR TO LEO ERROR
|
||||
let result = verify_local_data_commitment(system_parameters, &self.program_input).unwrap();
|
||||
// .map_err(|e| SnarkVMError::new(e))?;
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{get_indicator_value, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Expression;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -31,7 +31,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
indicator: &Boolean,
|
||||
expression: &'a Expression<'a>,
|
||||
span: &Span,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
// Evaluate assert expression
|
||||
let assert_expression = self.enforce_expression(cs, expression)?;
|
||||
|
||||
@ -45,13 +45,14 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let result_option = match assert_expression {
|
||||
ConstrainedValue::Boolean(boolean) => boolean.get_value(),
|
||||
_ => {
|
||||
return Err(CompilerError::console_assertion_must_be_boolean(span).into());
|
||||
return Err(CompilerError::console_assertion_must_be_boolean(span, new_backtrace()).into());
|
||||
}
|
||||
};
|
||||
let result_bool = result_option.ok_or_else(|| CompilerError::console_assertion_depends_on_input(span))?;
|
||||
let result_bool =
|
||||
result_option.ok_or_else(|| CompilerError::console_assertion_depends_on_input(span, new_backtrace()))?;
|
||||
|
||||
if !result_bool {
|
||||
return Err(CompilerError::console_assertion_failed(span).into());
|
||||
return Err(CompilerError::console_assertion_failed(span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, statement::get_indicator_value, GroupType};
|
||||
use leo_asg::{ConsoleFunction, ConsoleStatement};
|
||||
use leo_errors::LeoError;
|
||||
use leo_errors::Result;
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -30,7 +30,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
indicator: &Boolean,
|
||||
console: &ConsoleStatement<'a>,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
match &console.function {
|
||||
ConsoleFunction::Assert(expression) => {
|
||||
self.evaluate_console_assert(
|
||||
|
@ -18,13 +18,13 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, GroupType};
|
||||
use leo_asg::{CharValue, ConsoleArgs};
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
|
||||
impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
pub fn format<CS: ConstraintSystem<F>>(&mut self, cs: &mut CS, args: &ConsoleArgs<'a>) -> Result<String, LeoError> {
|
||||
pub fn format<CS: ConstraintSystem<F>>(&mut self, cs: &mut CS, args: &ConsoleArgs<'a>) -> Result<String> {
|
||||
let mut out = Vec::new();
|
||||
let mut in_container = false;
|
||||
let mut substring = String::new();
|
||||
@ -55,6 +55,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
arg_index + 1,
|
||||
args.parameters.len(),
|
||||
&args.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -68,12 +69,20 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
substring.push('}');
|
||||
escape_right_bracket = true;
|
||||
} else {
|
||||
return Err(CompilerError::console_fmt_expected_escaped_right_brace(&args.span).into());
|
||||
return Err(CompilerError::console_fmt_expected_escaped_right_brace(
|
||||
&args.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ if in_container => {
|
||||
return Err(CompilerError::console_fmt_expected_left_or_right_brace(&args.span).into());
|
||||
return Err(CompilerError::console_fmt_expected_left_or_right_brace(
|
||||
&args.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
_ => substring.push(*scalar),
|
||||
},
|
||||
@ -91,6 +100,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
arg_index,
|
||||
args.parameters.len(),
|
||||
&args.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -19,11 +19,10 @@
|
||||
use crate::{ConstrainedProgram, GroupType, Output, OutputFile};
|
||||
use leo_asg::Program;
|
||||
use leo_ast::Input;
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
|
||||
use backtrace::Backtrace;
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::{ConstraintSystem, TestConstraintSystem};
|
||||
use std::path::Path;
|
||||
@ -32,7 +31,7 @@ pub fn generate_constraints<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSy
|
||||
cs: &mut CS,
|
||||
program: &Program<'a>,
|
||||
input: &Input,
|
||||
) -> Result<Output, LeoError> {
|
||||
) -> Result<Output> {
|
||||
let mut resolved_program = ConstrainedProgram::<F, G>::new(program.clone());
|
||||
|
||||
for (_, global_const) in program.global_consts.iter() {
|
||||
@ -49,7 +48,7 @@ pub fn generate_constraints<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSy
|
||||
let result = resolved_program.enforce_main_function(cs, function, input)?;
|
||||
Ok(result)
|
||||
}
|
||||
_ => Err(CompilerError::no_main_function(Backtrace::new()).into()),
|
||||
_ => Err(CompilerError::no_main_function(new_backtrace()).into()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +56,7 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
program: &Program<'a>,
|
||||
input: InputPairs,
|
||||
output_directory: &Path,
|
||||
) -> Result<(u32, u32), LeoError> {
|
||||
) -> Result<(u32, u32)> {
|
||||
let mut resolved_program = ConstrainedProgram::<F, G>::new(program.clone());
|
||||
let program_name = program.name.clone();
|
||||
|
||||
@ -104,11 +103,11 @@ pub fn generate_test_constraints<'a, F: PrimeField, G: GroupType<F>>(
|
||||
{
|
||||
Some(pair) => pair.to_owned(),
|
||||
None => {
|
||||
return Err(CompilerError::invalid_test_context(file_name, Backtrace::new()).into());
|
||||
return Err(CompilerError::invalid_test_context(file_name, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
None => default.ok_or_else(|| CompilerError::no_test_input(Backtrace::new()))?,
|
||||
None => default.ok_or_else(|| CompilerError::no_test_input(new_backtrace()))?,
|
||||
};
|
||||
|
||||
// parse input files to abstract syntax trees
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces an arithmetic `+` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -27,7 +27,7 @@ pub fn enforce_add<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(ConstrainedValue::Integer(num_1.add(cs, num_2, span)?))
|
||||
@ -38,6 +38,10 @@ pub fn enforce_add<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
(ConstrainedValue::Group(point_1), ConstrainedValue::Group(point_2)) => {
|
||||
Ok(ConstrainedValue::Group(point_1.add(cs, &point_2, span)?))
|
||||
}
|
||||
(val_1, val_2) => return Err(CompilerError::incompatible_types(format!("{} + {}", val_1, val_2), span).into()),
|
||||
(val_1, val_2) => {
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} + {}", val_1, val_2), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,13 +17,13 @@
|
||||
//! Enforces a logical `!` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
|
||||
pub fn evaluate_bit_not<'a, F: PrimeField, G: GroupType<F>>(
|
||||
value: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
return Err(CompilerError::cannot_evaluate_expression(format!("!{}", value), span).into());
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
return Err(CompilerError::cannot_evaluate_expression(format!("!{}", value), span, new_backtrace()).into());
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces an arithmetic `/` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -27,7 +27,7 @@ pub fn enforce_div<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(ConstrainedValue::Integer(num_1.div(cs, num_2, span)?))
|
||||
@ -36,7 +36,9 @@ pub fn enforce_div<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
Ok(ConstrainedValue::Field(field_1.div(cs, &field_2, span)?))
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(CompilerError::incompatible_types(format!("{} / {}", val_1, val_2,), span).into());
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} / {}", val_1, val_2,), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces an arithmetic `*` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -27,7 +27,7 @@ pub fn enforce_mul<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(ConstrainedValue::Integer(num_1.mul(cs, num_2, span)?))
|
||||
@ -35,6 +35,10 @@ pub fn enforce_mul<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||
Ok(ConstrainedValue::Field(field_1.mul(cs, &field_2, span)?))
|
||||
}
|
||||
(val_1, val_2) => return Err(CompilerError::incompatible_types(format!("{} * {}", val_1, val_2), span).into()),
|
||||
(val_1, val_2) => {
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} * {}", val_1, val_2), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a unary negate `-` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -26,11 +26,11 @@ pub fn enforce_negate<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F
|
||||
cs: &mut CS,
|
||||
value: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
match value {
|
||||
ConstrainedValue::Integer(integer) => Ok(ConstrainedValue::Integer(integer.negate(cs, span)?)),
|
||||
ConstrainedValue::Field(field) => Ok(ConstrainedValue::Field(field.negate(cs, span)?)),
|
||||
ConstrainedValue::Group(group) => Ok(ConstrainedValue::Group(group.negate(cs, span)?)),
|
||||
value => return Err(CompilerError::incompatible_types(format!("-{}", value), span).into()),
|
||||
value => return Err(CompilerError::incompatible_types(format!("-{}", value), span, new_backtrace()).into()),
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces an arithmetic `**` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -27,13 +27,15 @@ pub fn enforce_pow<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(ConstrainedValue::Integer(num_1.pow(cs, num_2, span)?))
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(CompilerError::incompatible_types(format!("{} ** {}", val_1, val_2,), span).into());
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} ** {}", val_1, val_2,), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces an arithmetic `-` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -27,7 +27,7 @@ pub fn enforce_sub<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(ConstrainedValue::Integer(num_1.sub(cs, num_2, span)?))
|
||||
@ -38,6 +38,10 @@ pub fn enforce_sub<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
(ConstrainedValue::Group(point_1), ConstrainedValue::Group(point_2)) => {
|
||||
Ok(ConstrainedValue::Group(point_1.sub(cs, &point_2, span)?))
|
||||
}
|
||||
(val_1, val_2) => return Err(CompilerError::incompatible_types(format!("{} - {}", val_1, val_2), span).into()),
|
||||
(val_1, val_2) => {
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} - {}", val_1, val_2), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
GroupType,
|
||||
};
|
||||
use leo_asg::{ConstInt, Expression};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{
|
||||
@ -45,7 +45,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
index_resolved: &Integer,
|
||||
array_len: u32,
|
||||
span: &Span,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
let bounds_check = evaluate_lt::<F, G, CS>(
|
||||
cs,
|
||||
ConstrainedValue::Integer(index_resolved.clone()),
|
||||
@ -62,7 +62,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let mut unique_namespace = cs.ns(|| namespace_string);
|
||||
bounds_check
|
||||
.enforce_equal(&mut unique_namespace, &Boolean::Constant(true))
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("array bounds check", e, span))?;
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("array bounds check", e, span, new_backtrace()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -73,28 +73,28 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
array: &'a Expression<'a>,
|
||||
index: &'a Expression<'a>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let mut array = match self.enforce_expression(cs, array)? {
|
||||
ConstrainedValue::Array(array) => array,
|
||||
value => return Err(CompilerError::undefined_array(value.to_string(), span).into()),
|
||||
value => return Err(CompilerError::undefined_array(value.to_string(), span, new_backtrace()).into()),
|
||||
};
|
||||
|
||||
let index_resolved = self.enforce_index(cs, index, span)?;
|
||||
if let Some(resolved) = index_resolved.to_usize() {
|
||||
if resolved >= array.len() {
|
||||
return Err(CompilerError::array_index_out_of_bounds(resolved, span).into());
|
||||
return Err(CompilerError::array_index_out_of_bounds(resolved, span, new_backtrace()).into());
|
||||
}
|
||||
Ok(array[resolved].to_owned())
|
||||
} else {
|
||||
if array.is_empty() {
|
||||
return Err(CompilerError::array_index_out_of_bounds(0, span).into());
|
||||
return Err(CompilerError::array_index_out_of_bounds(0, span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
{
|
||||
let array_len: u32 = array
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| CompilerError::array_length_out_of_bounds(span))?;
|
||||
.map_err(|_| CompilerError::array_length_out_of_bounds(span, new_backtrace()))?;
|
||||
self.array_bounds_check(cs, &index_resolved, array_len, span)?;
|
||||
}
|
||||
|
||||
@ -105,17 +105,19 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
|
||||
let index_bounded = i
|
||||
.try_into()
|
||||
.map_err(|_| CompilerError::array_index_out_of_legal_bounds(span))?;
|
||||
.map_err(|_| CompilerError::array_index_out_of_legal_bounds(span, new_backtrace()))?;
|
||||
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(|_| CompilerError::cannot_evaluate_expression("==", span))?;
|
||||
.map_err(|_| CompilerError::cannot_evaluate_expression("==", span, new_backtrace()))?;
|
||||
|
||||
let unique_namespace =
|
||||
cs.ns(|| format!("select array access {} {}:{}", i, span.line_start, span.col_start));
|
||||
let value =
|
||||
ConstrainedValue::conditionally_select(unique_namespace, &index_comparison, &item, ¤t_value)
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("conditional select", e, span))?;
|
||||
.map_err(|e| {
|
||||
CompilerError::cannot_enforce_expression("conditional select", e, span, new_backtrace())
|
||||
})?;
|
||||
current_value = value;
|
||||
}
|
||||
Ok(current_value)
|
||||
@ -131,10 +133,10 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
right: Option<&'a Expression<'a>>,
|
||||
length: usize,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let array = match self.enforce_expression(cs, array)? {
|
||||
ConstrainedValue::Array(array) => array,
|
||||
value => return Err(CompilerError::undefined_array(value, span).into()),
|
||||
value => return Err(CompilerError::undefined_array(value, span, new_backtrace()).into()),
|
||||
};
|
||||
|
||||
let from_resolved = match left {
|
||||
@ -147,7 +149,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let index_bounded: u32 = array
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| CompilerError::array_length_out_of_bounds(span))?;
|
||||
.map_err(|_| CompilerError::array_length_out_of_bounds(span, new_backtrace()))?;
|
||||
Integer::new(&ConstInt::U32(index_bounded))
|
||||
} // Array slice ends at array length
|
||||
};
|
||||
@ -159,10 +161,10 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
};
|
||||
Ok(if let Some((left, right)) = const_dimensions {
|
||||
if right - left != length {
|
||||
return Err(CompilerError::array_invalid_slice_length(span).into());
|
||||
return Err(CompilerError::array_invalid_slice_length(span, new_backtrace()).into());
|
||||
}
|
||||
if right > array.len() {
|
||||
return Err(CompilerError::array_index_out_of_bounds(right, span).into());
|
||||
return Err(CompilerError::array_index_out_of_bounds(right, span, new_backtrace()).into());
|
||||
}
|
||||
ConstrainedValue::Array(array[left..right].to_owned())
|
||||
} else {
|
||||
@ -184,7 +186,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let mut unique_namespace = cs.ns(|| namespace_string);
|
||||
calc_len
|
||||
.enforce_equal(&mut unique_namespace, &Integer::new(&ConstInt::U32(length as u32)))
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("array length check", e, span))?;
|
||||
.map_err(|e| {
|
||||
CompilerError::cannot_enforce_expression("array length check", e, span, new_backtrace())
|
||||
})?;
|
||||
}
|
||||
{
|
||||
let bounds_check = evaluate_le::<F, G, _>(
|
||||
@ -204,7 +208,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let mut unique_namespace = cs.ns(|| namespace_string);
|
||||
bounds_check
|
||||
.enforce_equal(&mut unique_namespace, &Boolean::Constant(true))
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("array bounds check", e, span))?;
|
||||
.map_err(|e| {
|
||||
CompilerError::cannot_enforce_expression("array bounds check", e, span, new_backtrace())
|
||||
})?;
|
||||
}
|
||||
let mut windows = array.windows(length);
|
||||
let mut result = ConstrainedValue::Array(vec![]);
|
||||
@ -233,7 +239,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let unique_namespace =
|
||||
unique_namespace.ns(|| format!("array index {} {}:{}", i, span.line_start, span.col_start));
|
||||
result = ConstrainedValue::conditionally_select(unique_namespace, &equality, &array_value, &result)
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("conditional select", e, span))?;
|
||||
.map_err(|e| {
|
||||
CompilerError::cannot_enforce_expression("conditional select", e, span, new_backtrace())
|
||||
})?;
|
||||
}
|
||||
result
|
||||
})
|
||||
|
@ -20,7 +20,7 @@ use std::cell::Cell;
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Expression;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -32,7 +32,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
array: &[(Cell<&'a Expression<'a>>, bool)],
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let expected_dimension: Option<usize> = None;
|
||||
|
||||
let mut result = vec![];
|
||||
@ -52,7 +52,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
if let Some(dimension) = expected_dimension {
|
||||
// Return an error if the expected dimension != the actual dimension.
|
||||
if dimension != result.len() {
|
||||
return Err(CompilerError::unexpected_array_length(dimension, result.len(), span).into());
|
||||
return Err(
|
||||
CompilerError::unexpected_array_length(dimension, result.len(), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +70,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
element_expression: &'a Expression<'a>,
|
||||
actual_size: usize,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let mut value = self.enforce_expression(cs, element_expression)?;
|
||||
|
||||
// Allocate the array.
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType, Integer};
|
||||
use leo_asg::Expression;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -29,10 +29,10 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
index: &'a Expression<'a>,
|
||||
span: &Span,
|
||||
) -> Result<Integer, LeoError> {
|
||||
) -> Result<Integer> {
|
||||
match self.enforce_expression(cs, index)? {
|
||||
ConstrainedValue::Integer(number) => Ok(number),
|
||||
value => Err(CompilerError::invalid_index_expression(value, span).into()),
|
||||
value => Err(CompilerError::invalid_index_expression(value, span, new_backtrace()).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Expression;
|
||||
use leo_errors::LeoError;
|
||||
use leo_errors::Result;
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -32,7 +32,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
left: &'a Expression<'a>,
|
||||
right: &'a Expression<'a>,
|
||||
) -> Result<ConstrainedValuePair<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValuePair<'a, F, G>> {
|
||||
let resolved_left = {
|
||||
let mut left_namespace = cs.ns(|| "left".to_string());
|
||||
self.enforce_expression(&mut left_namespace, left)?
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::{CircuitAccessExpression, Node};
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -29,7 +29,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
expr: &CircuitAccessExpression<'a>,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
if let Some(target) = expr.target.get() {
|
||||
//todo: we can prob pass values by ref here to avoid copying the entire circuit on access
|
||||
let target_value = self.enforce_expression(cs, target)?;
|
||||
@ -43,18 +43,27 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
expr.circuit.get().name.borrow(),
|
||||
&expr.member.name,
|
||||
&expr.member.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
value => {
|
||||
return Err(
|
||||
CompilerError::undefined_circuit(value, &target.span().cloned().unwrap_or_default()).into(),
|
||||
);
|
||||
return Err(CompilerError::undefined_circuit(
|
||||
value,
|
||||
&target.span().cloned().unwrap_or_default(),
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Err(CompilerError::invalid_circuit_static_member_access(&expr.member.name, &expr.member.span).into())
|
||||
Err(CompilerError::invalid_circuit_static_member_access(
|
||||
&expr.member.name,
|
||||
&expr.member.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ use crate::{
|
||||
GroupType,
|
||||
};
|
||||
use leo_asg::{CircuitInitExpression, CircuitMember};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -33,7 +33,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
expr: &CircuitInitExpression<'a>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let circuit = expr.circuit.get();
|
||||
let members = circuit.members.borrow();
|
||||
|
||||
@ -50,7 +50,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
resolved_members.push(ConstrainedCircuitMember(name.clone(), variable_value));
|
||||
}
|
||||
_ => {
|
||||
return Err(CompilerError::expected_circuit_member(name, span).into());
|
||||
return Err(CompilerError::expected_circuit_member(name, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Expression;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::traits::select::CondSelectGadget;
|
||||
@ -34,11 +34,16 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
first: &'a Expression<'a>,
|
||||
second: &'a Expression<'a>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let conditional_value = match self.enforce_expression(cs, conditional)? {
|
||||
ConstrainedValue::Boolean(resolved) => resolved,
|
||||
value => {
|
||||
return Err(CompilerError::conditional_boolean_expression_fails_to_resolve_to_bool(value, span).into());
|
||||
return Err(CompilerError::conditional_boolean_expression_fails_to_resolve_to_bool(
|
||||
value,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
||||
@ -55,7 +60,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
|
||||
Ok(
|
||||
ConstrainedValue::conditionally_select(unique_namespace, &conditional_value, &first_value, &second_value)
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("conditional select", e, span))?,
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("conditional select", e, span, new_backtrace()))?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ use crate::{
|
||||
GroupType,
|
||||
};
|
||||
use leo_asg::{expression::*, ConstValue, Expression, Node};
|
||||
use leo_errors::{LeoError, Span};
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -39,7 +39,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
value: &'a ConstValue<'a>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
Ok(match value {
|
||||
ConstValue::Address(value) => ConstrainedValue::Address(Address::constant(value.to_string(), span)?),
|
||||
ConstValue::Boolean(value) => ConstrainedValue::Boolean(Boolean::Constant(*value)),
|
||||
@ -93,7 +93,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
expression: &'a Expression<'a>,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let span = &expression.span().cloned().unwrap_or_default();
|
||||
match expression {
|
||||
// Cast
|
||||
|
@ -19,7 +19,7 @@ use std::cell::Cell;
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, CoreCircuit, GroupType};
|
||||
|
||||
use leo_asg::{Expression, Function};
|
||||
use leo_errors::{LeoError, Span};
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -35,7 +35,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
target: Option<&'a Expression<'a>>,
|
||||
arguments: &[Cell<&'a Expression<'a>>],
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let target_value = target.map(|target| self.enforce_expression(cs, target)).transpose()?;
|
||||
|
||||
// Get the value of each core function argument
|
||||
|
@ -20,7 +20,7 @@ use std::cell::Cell;
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::{Expression, Function};
|
||||
use leo_errors::{LeoError, Span};
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -34,7 +34,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
target: Option<&'a Expression<'a>>,
|
||||
arguments: &[Cell<&'a Expression<'a>>],
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let name_unique = || {
|
||||
format!(
|
||||
"function call {} {}:{}",
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a logical `&&` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -28,7 +28,7 @@ pub fn enforce_and<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let name = format!("{} && {}", left, right);
|
||||
|
||||
if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
|
||||
@ -37,10 +37,10 @@ pub fn enforce_and<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
&left_bool,
|
||||
&right_bool,
|
||||
)
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("&&", e, span))?;
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("&&", e, span, new_backtrace()))?;
|
||||
|
||||
return Ok(ConstrainedValue::Boolean(result));
|
||||
}
|
||||
|
||||
Err(CompilerError::cannot_evaluate_expression(name, span).into())
|
||||
Err(CompilerError::cannot_evaluate_expression(name, span, new_backtrace()).into())
|
||||
}
|
||||
|
@ -17,16 +17,18 @@
|
||||
//! Enforces a logical `!` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
|
||||
pub fn evaluate_not<'a, F: PrimeField, G: GroupType<F>>(
|
||||
value: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
match value {
|
||||
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
|
||||
value => return Err(CompilerError::cannot_evaluate_expression(format!("!{}", value), span).into()),
|
||||
value => {
|
||||
return Err(CompilerError::cannot_evaluate_expression(format!("!{}", value), span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a logical `||` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -28,7 +28,7 @@ pub fn enforce_or<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let name = format!("{} || {}", left, right);
|
||||
|
||||
if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
|
||||
@ -37,10 +37,10 @@ pub fn enforce_or<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
&left_bool,
|
||||
&right_bool,
|
||||
)
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("||", e, span))?;
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("||", e, span, new_backtrace()))?;
|
||||
|
||||
return Ok(ConstrainedValue::Boolean(result));
|
||||
}
|
||||
|
||||
Err(CompilerError::cannot_evaluate_expression(name, span).into())
|
||||
Err(CompilerError::cannot_evaluate_expression(name, span, new_backtrace()).into())
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a relational `==` operator in a resolved Leo program.
|
||||
|
||||
use crate::{enforce_and, value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{boolean::Boolean, traits::eq::EvaluateEqGadget};
|
||||
@ -28,7 +28,7 @@ pub fn evaluate_eq<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let namespace_string = format!("evaluate {} == {} {}:{}", left, right, span.line_start, span.col_start);
|
||||
let constraint_result = match (left, right) {
|
||||
(ConstrainedValue::Address(address_1), ConstrainedValue::Address(address_2)) => {
|
||||
@ -75,11 +75,14 @@ pub fn evaluate_eq<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
return Ok(current);
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(CompilerError::incompatible_types(format!("{} == {}", val_1, val_2,), span).into());
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} == {}", val_1, val_2,), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression("==", span))?;
|
||||
let boolean =
|
||||
constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression("==", span, new_backtrace()))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a relational `>=` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::traits::bits::ComparatorGadget;
|
||||
@ -28,18 +28,21 @@ pub fn evaluate_ge<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let unique_namespace = cs.ns(|| format!("evaluate {} >= {} {}:{}", left, right, span.line_start, span.col_start));
|
||||
let constraint_result = match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.greater_than_or_equal(unique_namespace, &num_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(CompilerError::incompatible_types(format!("{} >= {}", val_1, val_2), span).into());
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} >= {}", val_1, val_2), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression(">=", span))?;
|
||||
let boolean =
|
||||
constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression(">=", span, new_backtrace()))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a relational `>` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::traits::bits::ComparatorGadget;
|
||||
@ -28,18 +28,21 @@ pub fn evaluate_gt<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let unique_namespace = cs.ns(|| format!("evaluate {} > {} {}:{}", left, right, span.line_start, span.col_start));
|
||||
let constraint_result = match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.greater_than(unique_namespace, &num_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(CompilerError::incompatible_types(format!("{} > {}", val_1, val_2), span).into());
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} > {}", val_1, val_2), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression(">", span))?;
|
||||
let boolean =
|
||||
constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression(">", span, new_backtrace()))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a relational `<=` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::traits::bits::ComparatorGadget;
|
||||
@ -28,18 +28,21 @@ pub fn evaluate_le<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let unique_namespace = cs.ns(|| format!("evaluate {} <= {} {}:{}", left, right, span.line_start, span.col_start));
|
||||
let constraint_result = match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.less_than_or_equal(unique_namespace, &num_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(CompilerError::incompatible_types(format!("{} <= {}", val_1, val_2), span).into());
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} <= {}", val_1, val_2), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression("<=", span))?;
|
||||
let boolean =
|
||||
constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression("<=", span, new_backtrace()))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a relational `<` operator in a resolved Leo program.
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::traits::bits::EvaluateLtGadget;
|
||||
@ -28,18 +28,21 @@ pub fn evaluate_lt<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
left: ConstrainedValue<'a, F, G>,
|
||||
right: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let unique_namespace = cs.ns(|| format!("evaluate {} < {} {}:{}", left, right, span.line_start, span.col_start));
|
||||
let constraint_result = match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.less_than(unique_namespace, &num_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(CompilerError::incompatible_types(format!("{} < {}", val_1, val_2), span).into());
|
||||
return Err(
|
||||
CompilerError::incompatible_types(format!("{} < {}", val_1, val_2), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression("<", span))?;
|
||||
let boolean =
|
||||
constraint_result.map_err(|_| CompilerError::cannot_evaluate_expression("<", span, new_backtrace()))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Expression;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -31,17 +31,17 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
tuple: &'a Expression<'a>,
|
||||
index: usize,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Get the tuple values.
|
||||
let tuple = match self.enforce_expression(cs, tuple)? {
|
||||
ConstrainedValue::Tuple(tuple) => tuple,
|
||||
value => return Err(CompilerError::undefined_array(value, span).into()),
|
||||
value => return Err(CompilerError::undefined_array(value, span, new_backtrace()).into()),
|
||||
};
|
||||
|
||||
// Check for out of bounds access.
|
||||
if index > tuple.len() - 1 {
|
||||
// probably safe to be a panic here
|
||||
return Err(CompilerError::tuple_index_out_of_bounds(index, span).into());
|
||||
return Err(CompilerError::tuple_index_out_of_bounds(index, span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
Ok(tuple[index].to_owned())
|
||||
|
@ -20,7 +20,7 @@ use std::cell::Cell;
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Expression;
|
||||
use leo_errors::LeoError;
|
||||
use leo_errors::Result;
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -31,7 +31,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
tuple: &[Cell<&'a Expression<'a>>],
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let mut result = Vec::with_capacity(tuple.len());
|
||||
for expression in tuple.iter() {
|
||||
result.push(self.enforce_expression(cs, expression.get())?);
|
||||
|
@ -18,13 +18,13 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::VariableRef;
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
|
||||
impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
/// Enforce a variable expression by getting the resolved value
|
||||
pub fn evaluate_ref(&mut self, variable_ref: &VariableRef) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
pub fn evaluate_ref(&mut self, variable_ref: &VariableRef) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Evaluate the identifier name in the current function scope
|
||||
let span = variable_ref.span.clone();
|
||||
let variable = variable_ref.variable.borrow();
|
||||
@ -32,9 +32,12 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let result_value = if let Some(value) = self.get(variable.id) {
|
||||
value.clone()
|
||||
} else {
|
||||
return Err(
|
||||
CompilerError::undefined_identifier(&variable.name.clone().name, &span.unwrap_or_default()).into(),
|
||||
);
|
||||
return Err(CompilerError::undefined_identifier(
|
||||
&variable.name.clone().name,
|
||||
&span.unwrap_or_default(),
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
// todo: probably can be a panic here instead
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
|
||||
use leo_asg::{Expression, Function, FunctionQualifier};
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
use std::cell::Cell;
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
@ -33,7 +33,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
function: &'a Function<'a>,
|
||||
target: Option<&'a Expression<'a>>,
|
||||
arguments: &[Cell<&'a Expression<'a>>],
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let target_value = target.map(|target| self.enforce_expression(cs, target)).transpose()?;
|
||||
|
||||
let self_var = if let Some(target) = &target_value {
|
||||
@ -52,6 +52,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&function.name.borrow().name.to_string(),
|
||||
"arguments length invalid",
|
||||
&function.span.clone().unwrap_or_default(),
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
|
||||
use leo_asg::Type;
|
||||
use leo_ast::InputValue;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -34,14 +34,20 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
array_len: usize,
|
||||
input_value: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Build the array value using the expected types.
|
||||
let mut array_value = vec![];
|
||||
|
||||
match input_value {
|
||||
Some(InputValue::Array(arr)) => {
|
||||
if array_len != arr.len() {
|
||||
return Err(CompilerError::invalid_input_array_dimensions(arr.len(), array_len, span).into());
|
||||
return Err(CompilerError::invalid_input_array_dimensions(
|
||||
arr.len(),
|
||||
array_len,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
// Allocate each value in the current row
|
||||
@ -66,7 +72,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(CompilerError::invalid_function_input_array(input_value.unwrap(), span).into());
|
||||
return Err(
|
||||
CompilerError::invalid_function_input_array(input_value.unwrap(), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
use crate::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType};
|
||||
use leo_asg::{Circuit, CircuitMember, Type};
|
||||
use leo_ast::{Identifier, Input};
|
||||
use leo_errors::{LeoError, Span};
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -35,7 +35,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
span: &Span,
|
||||
expected_type: &'a Circuit<'a>,
|
||||
input: &Input,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Create an identifier for each input variable
|
||||
|
||||
let registers_name = Identifier {
|
||||
|
@ -17,7 +17,7 @@
|
||||
use crate::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType};
|
||||
use leo_asg::{Circuit, CircuitMember};
|
||||
use leo_ast::{Identifier, InputValue, Parameter};
|
||||
use leo_errors::{AsgError, LeoError};
|
||||
use leo_errors::{new_backtrace, AsgError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -31,7 +31,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
identifier: Identifier,
|
||||
expected_type: &'a Circuit<'a>,
|
||||
section: IndexMap<Parameter, Option<InputValue>>,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let mut members = Vec::with_capacity(section.len());
|
||||
|
||||
// Allocate each section definition as a circuit member value
|
||||
@ -43,7 +43,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
};
|
||||
let declared_type = self.asg.scope.resolve_ast_type(¶meter.type_, ¶meter.span)?;
|
||||
if !expected_type.is_assignable_from(&declared_type) {
|
||||
return Err(AsgError::unexpected_type(expected_type, declared_type, &identifier.span).into());
|
||||
return Err(
|
||||
AsgError::unexpected_type(expected_type, declared_type, &identifier.span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
let member_name = parameter.variable.clone();
|
||||
let member_value = self.allocate_main_function_input(
|
||||
|
@ -33,7 +33,7 @@ use crate::{
|
||||
};
|
||||
use leo_asg::{ConstInt, Type};
|
||||
use leo_ast::{Char, InputValue};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -47,7 +47,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
name: &str,
|
||||
input_option: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
match type_ {
|
||||
Type::Address => Ok(Address::from_input(cs, name, input_option, span)?),
|
||||
Type::Boolean => Ok(bool_from_input(cs, name, input_option, span)?),
|
||||
@ -77,8 +77,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
name: &str,
|
||||
input_option: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
let input = input_option.ok_or_else(|| CompilerError::function_input_not_found("main", name, span))?;
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let input =
|
||||
input_option.ok_or_else(|| CompilerError::function_input_not_found("main", name, span, new_backtrace()))?;
|
||||
|
||||
match (type_, input) {
|
||||
(Type::Address, InputValue::Address(addr)) => Ok(ConstrainedValue::Address(Address::constant(addr, span)?)),
|
||||
@ -108,15 +109,25 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let parsed_type = parsed.get_int_type();
|
||||
let input_type = input_type.into();
|
||||
if std::mem::discriminant(&parsed_type) != std::mem::discriminant(&input_type) {
|
||||
return Err(
|
||||
CompilerError::integer_value_integer_type_mismatch(input_type, parsed_type, span).into(),
|
||||
);
|
||||
return Err(CompilerError::integer_value_integer_type_mismatch(
|
||||
input_type,
|
||||
parsed_type,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
Ok(ConstrainedValue::Integer(Integer::new(&parsed)))
|
||||
}
|
||||
(Type::Array(type_, arr_len), InputValue::Array(values)) => {
|
||||
if *arr_len != values.len() {
|
||||
return Err(CompilerError::invalid_input_array_dimensions(*arr_len, values.len(), span).into());
|
||||
return Err(CompilerError::invalid_input_array_dimensions(
|
||||
*arr_len,
|
||||
values.len(),
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::Array(
|
||||
@ -128,7 +139,13 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
}
|
||||
(Type::Tuple(types), InputValue::Tuple(values)) => {
|
||||
if values.len() != types.len() {
|
||||
return Err(CompilerError::input_tuple_size_mismatch(types.len(), values.len(), span).into());
|
||||
return Err(CompilerError::input_tuple_size_mismatch(
|
||||
types.len(),
|
||||
values.len(),
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::Tuple(
|
||||
@ -144,7 +161,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
(Type::Circuit(_), _) => unimplemented!("main function input not implemented for type {}", type_), // Should not happen.
|
||||
|
||||
// Return an error if the input type and input value do not match.
|
||||
(_, input) => Err(CompilerError::input_variable_type_mismatch(type_, input, name, span).into()),
|
||||
(_, input) => {
|
||||
Err(CompilerError::input_variable_type_mismatch(type_, input, name, span, new_backtrace()).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
|
||||
use leo_asg::Type;
|
||||
use leo_ast::InputValue;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -33,13 +33,19 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
types: &[Type],
|
||||
input_value: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let mut tuple_values = vec![];
|
||||
|
||||
match input_value {
|
||||
Some(InputValue::Tuple(values)) => {
|
||||
if values.len() != types.len() {
|
||||
return Err(CompilerError::input_tuple_size_mismatch(types.len(), values.len(), span).into());
|
||||
return Err(CompilerError::input_tuple_size_mismatch(
|
||||
types.len(),
|
||||
values.len(),
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
// Allocate each value in the tuple.
|
||||
@ -58,7 +64,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(CompilerError::invalid_function_input_tuple(input_value.unwrap(), span).into());
|
||||
return Err(
|
||||
CompilerError::invalid_function_input_tuple(input_value.unwrap(), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ use crate::{program::ConstrainedProgram, GroupType, Output};
|
||||
|
||||
use leo_asg::{Expression, Function, FunctionQualifier};
|
||||
use leo_ast::Input;
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
use std::cell::Cell;
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
@ -32,7 +32,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
function: &'a Function<'a>,
|
||||
input: &Input,
|
||||
) -> Result<Output, LeoError> {
|
||||
) -> Result<Output> {
|
||||
let registers = input.get_registers();
|
||||
|
||||
// Iterate over main function input variables and allocate new values
|
||||
@ -66,7 +66,12 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
) {
|
||||
// If variable is in both [main] and [constants] sections - error.
|
||||
(_, Some(_), Some(_)) => {
|
||||
return Err(CompilerError::double_input_declaration(name, &input_variable.name.span).into());
|
||||
return Err(CompilerError::double_input_declaration(
|
||||
name,
|
||||
&input_variable.name.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
// If input option is found in [main] section and input is not const.
|
||||
(false, Some(input_option), _) => self.allocate_main_function_input(
|
||||
@ -86,15 +91,21 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
)?,
|
||||
// Function argument is const, input is not.
|
||||
(true, Some(_), None) => {
|
||||
return Err(
|
||||
CompilerError::expected_const_input_variable(name, &input_variable.name.span).into(),
|
||||
);
|
||||
return Err(CompilerError::expected_const_input_variable(
|
||||
name,
|
||||
&input_variable.name.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
// Input is const, function argument is not.
|
||||
(false, None, Some(_)) => {
|
||||
return Err(
|
||||
CompilerError::expected_non_const_input_variable(name, &input_variable.name.span).into(),
|
||||
);
|
||||
return Err(CompilerError::expected_non_const_input_variable(
|
||||
name,
|
||||
&input_variable.name.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
// When not found - Error out.
|
||||
(_, _, _) => {
|
||||
@ -102,6 +113,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
function.name.borrow().name.to_string(),
|
||||
name,
|
||||
&input_variable.name.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ use leo_asg::{
|
||||
TupleAccessExpression,
|
||||
Variable,
|
||||
};
|
||||
use leo_errors::LeoError;
|
||||
use leo_errors::Result;
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -41,7 +41,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
fn prepare_mut_access(
|
||||
out: &mut Vec<AssignAccess<'a>>,
|
||||
expr: &'a Expression<'a>,
|
||||
) -> Result<Option<&'a Variable<'a>>, LeoError> {
|
||||
) -> Result<Option<&'a Variable<'a>>> {
|
||||
match expr {
|
||||
Expression::ArrayRangeAccess(ArrayRangeAccessExpression { array, left, right, .. }) => {
|
||||
let inner = Self::prepare_mut_access(out, array.get())?;
|
||||
@ -85,7 +85,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
assignee: &'a Expression<'a>,
|
||||
target_value: ConstrainedValue<'a, F, G>,
|
||||
indicator: &Boolean,
|
||||
) -> Result<bool, LeoError> {
|
||||
) -> Result<bool> {
|
||||
let mut accesses = vec![];
|
||||
let target = Self::prepare_mut_access(&mut accesses, assignee)?;
|
||||
if target.is_none() {
|
||||
|
@ -19,7 +19,7 @@
|
||||
use crate::{get_indicator_value, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
|
||||
use leo_asg::Type;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{boolean::Boolean, traits::select::CondSelectGadget};
|
||||
@ -35,7 +35,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
expected_return: &Type<'a>,
|
||||
results: Vec<(Boolean, ConstrainedValue<'a, F, G>)>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Initialize empty return value.
|
||||
let mut return_value = None;
|
||||
|
||||
@ -55,7 +55,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
if get_indicator_value(&indicator) {
|
||||
// Error if we already have a return value.
|
||||
if return_value.is_some() {
|
||||
return Err(CompilerError::statement_multiple_returns(span).into());
|
||||
return Err(CompilerError::statement_multiple_returns(span, new_backtrace()).into());
|
||||
} else {
|
||||
// Set the function return value.
|
||||
return_value = Some(result);
|
||||
@ -79,7 +79,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&result,
|
||||
value,
|
||||
)
|
||||
.map_err(|_| CompilerError::statement_select_fail(result, value, span))?,
|
||||
.map_err(|_| CompilerError::statement_select_fail(result, value, span, new_backtrace()))?,
|
||||
);
|
||||
} else {
|
||||
return_value = Some(result); // we ignore indicator for default -- questionable
|
||||
@ -89,7 +89,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
if expected_return.is_unit() {
|
||||
Ok(ConstrainedValue::Tuple(vec![]))
|
||||
} else {
|
||||
Ok(return_value.ok_or_else(|| CompilerError::statement_no_returns(expected_return.to_string(), span))?)
|
||||
Ok(return_value.ok_or_else(|| {
|
||||
CompilerError::statement_no_returns(expected_return.to_string(), span, new_backtrace())
|
||||
})?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ pub use self::output_bytes::*;
|
||||
use crate::{Char, CharType, ConstrainedValue, GroupType, REGISTERS_VARIABLE_NAME};
|
||||
use leo_asg::Program;
|
||||
use leo_ast::{Parameter, Registers};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
|
||||
@ -89,7 +89,7 @@ impl Output {
|
||||
registers: &Registers,
|
||||
value: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
) -> Result<Self> {
|
||||
let return_values = match value {
|
||||
ConstrainedValue::Tuple(tuple) => tuple,
|
||||
value => vec![value],
|
||||
@ -106,7 +106,7 @@ impl Output {
|
||||
|
||||
// Return an error if we do not have enough return registers
|
||||
if register_values.len() < return_values.len() {
|
||||
return Err(CompilerError::output_not_enough_registers(span).into());
|
||||
return Err(CompilerError::output_not_enough_registers(span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
let mut registers = BTreeMap::new();
|
||||
@ -119,7 +119,13 @@ impl Output {
|
||||
let return_value_type = value.to_type(span)?;
|
||||
|
||||
if !register_type.is_assignable_from(&return_value_type) {
|
||||
return Err(CompilerError::output_mismatched_types(register_type, return_value_type, span).into());
|
||||
return Err(CompilerError::output_mismatched_types(
|
||||
register_type,
|
||||
return_value_type,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let value = match value {
|
||||
|
@ -17,7 +17,7 @@
|
||||
use crate::{ConstrainedValue, GroupType, REGISTERS_VARIABLE_NAME};
|
||||
use leo_asg::Program;
|
||||
use leo_ast::{Parameter, Registers};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
|
||||
@ -38,7 +38,7 @@ impl OutputBytes {
|
||||
value: ConstrainedValue<'a, F, G>,
|
||||
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
) -> Result<Self> {
|
||||
let return_values = match value {
|
||||
ConstrainedValue::Tuple(values) => values,
|
||||
value => vec![value],
|
||||
@ -55,7 +55,7 @@ impl OutputBytes {
|
||||
|
||||
// Return an error if we do not have enough return registers
|
||||
if register_values.len() < return_values.len() {
|
||||
return Err(CompilerError::output_not_enough_registers(span).into());
|
||||
return Err(CompilerError::output_not_enough_registers(span, new_backtrace()).into());
|
||||
}
|
||||
|
||||
// Manually construct result string
|
||||
@ -73,7 +73,13 @@ impl OutputBytes {
|
||||
let return_value_type = value.to_type(span)?;
|
||||
|
||||
if !register_type.is_assignable_from(&return_value_type) {
|
||||
return Err(CompilerError::output_mismatched_types(register_type, return_value_type, span).into());
|
||||
return Err(CompilerError::output_mismatched_types(
|
||||
register_type,
|
||||
return_value_type,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let value = value.to_string();
|
||||
|
@ -16,9 +16,7 @@
|
||||
|
||||
//! The `program.out` file.
|
||||
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
|
||||
use backtrace::Backtrace;
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
@ -45,25 +43,25 @@ impl OutputFile {
|
||||
}
|
||||
|
||||
/// Writes output to a file.
|
||||
pub fn write(&self, path: &Path, bytes: &[u8]) -> Result<(), LeoError> {
|
||||
pub fn write(&self, path: &Path, bytes: &[u8]) -> Result<()> {
|
||||
// create output file
|
||||
let path = self.setup_file_path(path);
|
||||
let mut file = File::create(&path).map_err(|e| CompilerError::output_file_io_error(e, Backtrace::new()))?;
|
||||
let mut file = File::create(&path).map_err(|e| CompilerError::output_file_io_error(e, new_backtrace()))?;
|
||||
|
||||
Ok(file
|
||||
.write_all(bytes)
|
||||
.map_err(|e| CompilerError::output_file_io_error(e, Backtrace::new()))?)
|
||||
.map_err(|e| CompilerError::output_file_io_error(e, new_backtrace()))?)
|
||||
}
|
||||
|
||||
/// Removes the output file at the given path if it exists. Returns `true` on success,
|
||||
/// `false` if the file doesn't exist, and `Error` if the file system fails during operation.
|
||||
pub fn remove(&self, path: &Path) -> Result<bool, LeoError> {
|
||||
pub fn remove(&self, path: &Path) -> Result<bool> {
|
||||
let path = self.setup_file_path(path);
|
||||
if !path.exists() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
fs::remove_file(&path).map_err(|_| CompilerError::output_file_cannot_remove(path, Backtrace::new()))?;
|
||||
fs::remove_file(&path).map_err(|_| CompilerError::output_file_cannot_remove(path, new_backtrace()))?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
use crate::{CombineAstAsgDirector, CombinerOptions};
|
||||
use leo_asg::Program as AsgProgram;
|
||||
use leo_ast::{Ast, Program as AstProgram, ReconstructingReducer};
|
||||
use leo_errors::LeoError;
|
||||
use leo_errors::Result;
|
||||
|
||||
macro_rules! phase {
|
||||
($phase_name:ident, $function:item) => {
|
||||
@ -50,7 +50,7 @@ macro_rules! phase {
|
||||
}
|
||||
|
||||
impl $phase_name {
|
||||
pub fn phase_ast(&self, ast: &AstProgram, asg: &AsgProgram) -> Result<Ast, LeoError> {
|
||||
pub fn phase_ast(&self, ast: &AstProgram, asg: &AsgProgram) -> Result<Ast> {
|
||||
Ok(Ast::new(CombineAstAsgDirector::new(Self::default(), Options{})
|
||||
.reduce_program(ast, asg)?))
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ use leo_ast::{
|
||||
UnaryExpression as AstUnaryExpression,
|
||||
ValueExpression,
|
||||
};
|
||||
use leo_errors::{AstError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, AstError, Result, Span};
|
||||
use tendril::StrTendril;
|
||||
|
||||
pub trait CombinerOptions {
|
||||
@ -116,7 +116,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
Self { ast_reducer, options }
|
||||
}
|
||||
|
||||
pub fn reduce_type(&mut self, ast: &AstType, asg: &AsgType, span: &Span) -> Result<AstType, LeoError> {
|
||||
pub fn reduce_type(&mut self, ast: &AstType, asg: &AsgType, span: &Span) -> Result<AstType> {
|
||||
let new = match (ast, asg) {
|
||||
(AstType::Array(ast_type, ast_dimensions), AsgType::Array(asg_type, asg_dimensions)) => {
|
||||
if self.options.type_inference_enabled() {
|
||||
@ -147,7 +147,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
self.ast_reducer.reduce_type(ast, new, span)
|
||||
}
|
||||
|
||||
pub fn reduce_expression(&mut self, ast: &AstExpression, asg: &AsgExpression) -> Result<AstExpression, LeoError> {
|
||||
pub fn reduce_expression(&mut self, ast: &AstExpression, asg: &AsgExpression) -> Result<AstExpression> {
|
||||
let new = match (ast, asg) {
|
||||
(AstExpression::Value(value), AsgExpression::Constant(const_)) => self.reduce_value(value, const_)?,
|
||||
(AstExpression::Binary(ast), AsgExpression::Binary(asg)) => {
|
||||
@ -202,7 +202,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstArrayAccessExpression,
|
||||
asg: &AsgArrayAccessExpression,
|
||||
) -> Result<AstArrayAccessExpression, LeoError> {
|
||||
) -> Result<AstArrayAccessExpression> {
|
||||
let array = self.reduce_expression(&ast.array, asg.array.get())?;
|
||||
let index = self.reduce_expression(&ast.index, asg.index.get())?;
|
||||
|
||||
@ -213,7 +213,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstArrayInitExpression,
|
||||
asg: &AsgArrayInitExpression,
|
||||
) -> Result<AstArrayInitExpression, LeoError> {
|
||||
) -> Result<AstArrayInitExpression> {
|
||||
let element = self.reduce_expression(&ast.element, asg.element.get())?;
|
||||
|
||||
self.ast_reducer.reduce_array_init(ast, element)
|
||||
@ -223,7 +223,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstArrayInlineExpression,
|
||||
asg: &AsgArrayInlineExpression,
|
||||
) -> Result<AstArrayInlineExpression, LeoError> {
|
||||
) -> Result<AstArrayInlineExpression> {
|
||||
let mut elements = vec![];
|
||||
for (ast_element, asg_element) in ast.elements.iter().zip(asg.elements.iter()) {
|
||||
let reduced_element = match ast_element {
|
||||
@ -245,7 +245,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstArrayRangeAccessExpression,
|
||||
asg: &AsgArrayRangeAccessExpression,
|
||||
) -> Result<AstArrayRangeAccessExpression, LeoError> {
|
||||
) -> Result<AstArrayRangeAccessExpression> {
|
||||
let array = self.reduce_expression(&ast.array, asg.array.get())?;
|
||||
let left = match (ast.left.as_ref(), asg.left.get()) {
|
||||
(Some(ast_left), Some(asg_left)) => Some(self.reduce_expression(ast_left, asg_left)?),
|
||||
@ -263,18 +263,14 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstBinaryExpression,
|
||||
asg: &AsgBinaryExpression,
|
||||
) -> Result<AstBinaryExpression, LeoError> {
|
||||
) -> Result<AstBinaryExpression> {
|
||||
let left = self.reduce_expression(&ast.left, asg.left.get())?;
|
||||
let right = self.reduce_expression(&ast.right, asg.right.get())?;
|
||||
|
||||
self.ast_reducer.reduce_binary(ast, left, right, ast.op.clone())
|
||||
}
|
||||
|
||||
pub fn reduce_call(
|
||||
&mut self,
|
||||
ast: &AstCallExpression,
|
||||
asg: &AsgCallExpression,
|
||||
) -> Result<AstCallExpression, LeoError> {
|
||||
pub fn reduce_call(&mut self, ast: &AstCallExpression, asg: &AsgCallExpression) -> Result<AstCallExpression> {
|
||||
// TODO FIGURE IT OUT
|
||||
// let function = self.reduce_expression(&ast.function, asg.function.get())?;
|
||||
// let target = asg.target.get().map(|exp| self.reduce_expression())
|
||||
@ -288,11 +284,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
self.ast_reducer.reduce_call(ast, *ast.function.clone(), arguments)
|
||||
}
|
||||
|
||||
pub fn reduce_cast(
|
||||
&mut self,
|
||||
ast: &AstCastExpression,
|
||||
asg: &AsgCastExpression,
|
||||
) -> Result<AstCastExpression, LeoError> {
|
||||
pub fn reduce_cast(&mut self, ast: &AstCastExpression, asg: &AsgCastExpression) -> Result<AstCastExpression> {
|
||||
let inner = self.reduce_expression(&ast.inner, asg.inner.get())?;
|
||||
let target_type = self.reduce_type(&ast.target_type, &asg.target_type, &ast.span)?;
|
||||
|
||||
@ -303,7 +295,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &CircuitMemberAccessExpression,
|
||||
_asg: &AsgCircuitAccessExpression,
|
||||
) -> Result<CircuitMemberAccessExpression, LeoError> {
|
||||
) -> Result<CircuitMemberAccessExpression> {
|
||||
// let circuit = self.reduce_expression(&circuit_member_access.circuit)?;
|
||||
// let name = self.reduce_identifier(&circuit_member_access.name)?;
|
||||
// let target = input.target.get().map(|e| self.reduce_expression(e));
|
||||
@ -316,7 +308,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &CircuitStaticFunctionAccessExpression,
|
||||
_asg: &AsgCircuitAccessExpression,
|
||||
) -> Result<CircuitStaticFunctionAccessExpression, LeoError> {
|
||||
) -> Result<CircuitStaticFunctionAccessExpression> {
|
||||
// let circuit = self.reduce_expression(&circuit_member_access.circuit)?;
|
||||
// let name = self.reduce_identifier(&circuit_member_access.name)?;
|
||||
// let target = input.target.get().map(|e| self.reduce_expression(e));
|
||||
@ -329,7 +321,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &CircuitImpliedVariableDefinition,
|
||||
asg: &AsgExpression,
|
||||
) -> Result<CircuitImpliedVariableDefinition, LeoError> {
|
||||
) -> Result<CircuitImpliedVariableDefinition> {
|
||||
let expression = ast
|
||||
.expression
|
||||
.as_ref()
|
||||
@ -344,7 +336,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstCircuitInitExpression,
|
||||
asg: &AsgCircuitInitExpression,
|
||||
) -> Result<AstCircuitInitExpression, LeoError> {
|
||||
) -> Result<AstCircuitInitExpression> {
|
||||
let mut members = vec![];
|
||||
for (ast_member, asg_member) in ast.members.iter().zip(asg.values.iter()) {
|
||||
members.push(self.reduce_circuit_implied_variable_definition(ast_member, asg_member.1.get())?);
|
||||
@ -357,7 +349,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstTernaryExpression,
|
||||
asg: &AsgTernaryExpression,
|
||||
) -> Result<AstTernaryExpression, LeoError> {
|
||||
) -> Result<AstTernaryExpression> {
|
||||
let condition = self.reduce_expression(&ast.condition, asg.condition.get())?;
|
||||
let if_true = self.reduce_expression(&ast.if_true, asg.if_true.get())?;
|
||||
let if_false = self.reduce_expression(&ast.if_false, asg.if_false.get())?;
|
||||
@ -369,7 +361,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstTupleAccessExpression,
|
||||
asg: &AsgTupleAccessExpression,
|
||||
) -> Result<AstTupleAccessExpression, LeoError> {
|
||||
) -> Result<AstTupleAccessExpression> {
|
||||
let tuple = self.reduce_expression(&ast.tuple, asg.tuple_ref.get())?;
|
||||
|
||||
self.ast_reducer.reduce_tuple_access(ast, tuple)
|
||||
@ -379,7 +371,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstTupleInitExpression,
|
||||
asg: &AsgTupleInitExpression,
|
||||
) -> Result<AstTupleInitExpression, LeoError> {
|
||||
) -> Result<AstTupleInitExpression> {
|
||||
let mut elements = vec![];
|
||||
for (ast_element, asg_element) in ast.elements.iter().zip(asg.elements.iter()) {
|
||||
let element = self.reduce_expression(ast_element, asg_element.get())?;
|
||||
@ -389,17 +381,13 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
self.ast_reducer.reduce_tuple_init(ast, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_unary(
|
||||
&mut self,
|
||||
ast: &AstUnaryExpression,
|
||||
asg: &AsgUnaryExpression,
|
||||
) -> Result<AstUnaryExpression, LeoError> {
|
||||
pub fn reduce_unary(&mut self, ast: &AstUnaryExpression, asg: &AsgUnaryExpression) -> Result<AstUnaryExpression> {
|
||||
let inner = self.reduce_expression(&ast.inner, asg.inner.get())?;
|
||||
|
||||
self.ast_reducer.reduce_unary(ast, inner, ast.op.clone())
|
||||
}
|
||||
|
||||
pub fn reduce_value(&mut self, ast: &ValueExpression, asg: &AsgConstant) -> Result<AstExpression, LeoError> {
|
||||
pub fn reduce_value(&mut self, ast: &ValueExpression, asg: &AsgConstant) -> Result<AstExpression> {
|
||||
let mut new = ast.clone();
|
||||
|
||||
if self.options.type_inference_enabled() {
|
||||
@ -448,11 +436,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
self.ast_reducer.reduce_value(ast, AstExpression::Value(new))
|
||||
}
|
||||
|
||||
pub fn reduce_variable_ref(
|
||||
&mut self,
|
||||
ast: &ValueExpression,
|
||||
_asg: &AsgVariableRef,
|
||||
) -> Result<ValueExpression, LeoError> {
|
||||
pub fn reduce_variable_ref(&mut self, ast: &ValueExpression, _asg: &AsgVariableRef) -> Result<ValueExpression> {
|
||||
// TODO FIGURE IT OUT
|
||||
let new = match ast {
|
||||
// ValueExpression::Group(group_value) => {
|
||||
@ -469,7 +453,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast_statement: &AstStatement,
|
||||
asg_statement: &AsgStatement,
|
||||
) -> Result<AstStatement, LeoError> {
|
||||
) -> Result<AstStatement> {
|
||||
let new = match (ast_statement, asg_statement) {
|
||||
(AstStatement::Assign(ast), AsgStatement::Assign(asg)) => {
|
||||
AstStatement::Assign(Box::new(self.reduce_assign(ast, asg)?))
|
||||
@ -499,11 +483,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
self.ast_reducer.reduce_statement(ast_statement, new)
|
||||
}
|
||||
|
||||
pub fn reduce_assign_access(
|
||||
&mut self,
|
||||
ast: &AstAssignAccess,
|
||||
asg: &AsgAssignAccess,
|
||||
) -> Result<AstAssignAccess, LeoError> {
|
||||
pub fn reduce_assign_access(&mut self, ast: &AstAssignAccess, asg: &AsgAssignAccess) -> Result<AstAssignAccess> {
|
||||
let new = match (ast, asg) {
|
||||
(AstAssignAccess::ArrayRange(ast_left, ast_right), AsgAssignAccess::ArrayRange(asg_left, asg_right)) => {
|
||||
let left = match (ast_left.as_ref(), asg_left.get()) {
|
||||
@ -527,7 +507,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
self.ast_reducer.reduce_assignee_access(ast, new)
|
||||
}
|
||||
|
||||
pub fn reduce_assignee(&mut self, ast: &Assignee, asg: &[AsgAssignAccess]) -> Result<Assignee, LeoError> {
|
||||
pub fn reduce_assignee(&mut self, ast: &Assignee, asg: &[AsgAssignAccess]) -> Result<Assignee> {
|
||||
let mut accesses = vec![];
|
||||
for (ast_access, asg_access) in ast.accesses.iter().zip(asg) {
|
||||
accesses.push(self.reduce_assign_access(ast_access, asg_access)?);
|
||||
@ -536,22 +516,14 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
self.ast_reducer.reduce_assignee(ast, ast.identifier.clone(), accesses)
|
||||
}
|
||||
|
||||
pub fn reduce_assign(
|
||||
&mut self,
|
||||
ast: &AstAssignStatement,
|
||||
asg: &AsgAssignStatement,
|
||||
) -> Result<AstAssignStatement, LeoError> {
|
||||
pub fn reduce_assign(&mut self, ast: &AstAssignStatement, asg: &AsgAssignStatement) -> Result<AstAssignStatement> {
|
||||
let assignee = self.reduce_assignee(&ast.assignee, &asg.target_accesses)?;
|
||||
let value = self.reduce_expression(&ast.value, asg.value.get())?;
|
||||
|
||||
self.ast_reducer.reduce_assign(ast, assignee, value)
|
||||
}
|
||||
|
||||
pub fn reduce_block(
|
||||
&mut self,
|
||||
ast: &AstBlockStatement,
|
||||
asg: &AsgBlockStatement,
|
||||
) -> Result<AstBlockStatement, LeoError> {
|
||||
pub fn reduce_block(&mut self, ast: &AstBlockStatement, asg: &AsgBlockStatement) -> Result<AstBlockStatement> {
|
||||
let mut statements = vec![];
|
||||
for (ast_statement, asg_statement) in ast.statements.iter().zip(asg.statements.iter()) {
|
||||
statements.push(self.reduce_statement(ast_statement, asg_statement.get())?);
|
||||
@ -564,15 +536,13 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstConditionalStatement,
|
||||
asg: &AsgConditionalStatement,
|
||||
) -> Result<AstConditionalStatement, LeoError> {
|
||||
) -> Result<AstConditionalStatement> {
|
||||
let condition = self.reduce_expression(&ast.condition, asg.condition.get())?;
|
||||
let block;
|
||||
if let AsgStatement::Block(asg_block) = asg.result.get() {
|
||||
block = self.reduce_block(&ast.block, asg_block)?;
|
||||
} else {
|
||||
return Err(LeoError::from(AstError::asg_statement_not_block(
|
||||
asg.span.as_ref().unwrap(),
|
||||
)));
|
||||
return Err(AstError::asg_statement_not_block(asg.span.as_ref().unwrap(), new_backtrace()).into());
|
||||
}
|
||||
let next = match (ast.next.as_ref(), asg.next.get()) {
|
||||
(Some(ast_next), Some(asg_next)) => Some(self.reduce_statement(ast_next, asg_next)?),
|
||||
@ -586,7 +556,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstConsoleStatement,
|
||||
asg: &AsgConsoleStatement,
|
||||
) -> Result<AstConsoleStatement, LeoError> {
|
||||
) -> Result<AstConsoleStatement> {
|
||||
let function = match (&ast.function, &asg.function) {
|
||||
(AstConsoleFunction::Assert(ast_expression), AsgConsoleFunction::Assert(asg_expression)) => {
|
||||
AstConsoleFunction::Assert(self.reduce_expression(ast_expression, asg_expression.get())?)
|
||||
@ -610,9 +580,9 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
AstConsoleFunction::Error(_) => AstConsoleFunction::Error(args),
|
||||
AstConsoleFunction::Log(_) => AstConsoleFunction::Log(args),
|
||||
_ => {
|
||||
return Err(LeoError::from(AstError::impossible_console_assert_call(
|
||||
&ast_console_args.span,
|
||||
)));
|
||||
return Err(
|
||||
AstError::impossible_console_assert_call(&ast_console_args.span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -626,7 +596,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstDefinitionStatement,
|
||||
asg: &AsgDefinitionStatement,
|
||||
) -> Result<AstDefinitionStatement, LeoError> {
|
||||
) -> Result<AstDefinitionStatement> {
|
||||
let type_;
|
||||
|
||||
if asg.variables.len() > 1 {
|
||||
@ -664,7 +634,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstExpressionStatement,
|
||||
asg: &AsgExpressionStatement,
|
||||
) -> Result<AstExpressionStatement, LeoError> {
|
||||
) -> Result<AstExpressionStatement> {
|
||||
let inner_expression = self.reduce_expression(&ast.expression, asg.expression.get())?;
|
||||
self.ast_reducer.reduce_expression_statement(ast, inner_expression)
|
||||
}
|
||||
@ -673,37 +643,27 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstIterationStatement,
|
||||
asg: &AsgIterationStatement,
|
||||
) -> Result<AstIterationStatement, LeoError> {
|
||||
) -> Result<AstIterationStatement> {
|
||||
let start = self.reduce_expression(&ast.start, asg.start.get())?;
|
||||
let stop = self.reduce_expression(&ast.stop, asg.stop.get())?;
|
||||
let block;
|
||||
if let AsgStatement::Block(asg_block) = asg.body.get() {
|
||||
block = self.reduce_block(&ast.block, asg_block)?;
|
||||
} else {
|
||||
return Err(LeoError::from(AstError::asg_statement_not_block(
|
||||
asg.span.as_ref().unwrap(),
|
||||
)));
|
||||
return Err(AstError::asg_statement_not_block(asg.span.as_ref().unwrap(), new_backtrace()).into());
|
||||
}
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_iteration(ast, ast.variable.clone(), start, stop, block)
|
||||
}
|
||||
|
||||
pub fn reduce_return(
|
||||
&mut self,
|
||||
ast: &AstReturnStatement,
|
||||
asg: &AsgReturnStatement,
|
||||
) -> Result<AstReturnStatement, LeoError> {
|
||||
pub fn reduce_return(&mut self, ast: &AstReturnStatement, asg: &AsgReturnStatement) -> Result<AstReturnStatement> {
|
||||
let expression = self.reduce_expression(&ast.expression, asg.expression.get())?;
|
||||
|
||||
self.ast_reducer.reduce_return(ast, expression)
|
||||
}
|
||||
|
||||
pub fn reduce_program(
|
||||
&mut self,
|
||||
ast: &leo_ast::Program,
|
||||
asg: &leo_asg::Program,
|
||||
) -> Result<leo_ast::Program, LeoError> {
|
||||
pub fn reduce_program(&mut self, ast: &leo_ast::Program, asg: &leo_asg::Program) -> Result<leo_ast::Program> {
|
||||
self.ast_reducer.swap_in_circuit();
|
||||
let mut circuits = IndexMap::new();
|
||||
for ((ast_ident, ast_circuit), (_asg_ident, asg_circuit)) in ast.circuits.iter().zip(&asg.circuits) {
|
||||
@ -732,7 +692,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn reduce_function(&mut self, ast: &AstFunction, asg: &AsgFunction) -> Result<AstFunction, LeoError> {
|
||||
pub fn reduce_function(&mut self, ast: &AstFunction, asg: &AsgFunction) -> Result<AstFunction> {
|
||||
let output = ast
|
||||
.output
|
||||
.as_ref()
|
||||
@ -765,7 +725,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
&mut self,
|
||||
ast: &AstCircuitMember,
|
||||
asg: &AsgCircuitMember,
|
||||
) -> Result<AstCircuitMember, LeoError> {
|
||||
) -> Result<AstCircuitMember> {
|
||||
let new = match (ast, asg) {
|
||||
(AstCircuitMember::CircuitVariable(identifier, ast_type), AsgCircuitMember::Variable(asg_type)) => {
|
||||
AstCircuitMember::CircuitVariable(
|
||||
@ -782,7 +742,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
|
||||
self.ast_reducer.reduce_circuit_member(ast, new)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit(&mut self, ast: &AstCircuit, asg: &AsgCircuit) -> Result<AstCircuit, LeoError> {
|
||||
pub fn reduce_circuit(&mut self, ast: &AstCircuit, asg: &AsgCircuit) -> Result<AstCircuit> {
|
||||
let mut members = vec![];
|
||||
for (ast_member, asg_member) in ast.members.iter().zip(asg.members.borrow().iter()) {
|
||||
members.push(self.reduce_circuit_member(ast_member, asg_member.1)?);
|
||||
|
@ -17,7 +17,7 @@
|
||||
use super::CoreCircuit;
|
||||
use crate::{ConstrainedValue, GroupType, Integer};
|
||||
use leo_asg::Function;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{
|
||||
@ -55,20 +55,22 @@ impl<'a, F: PrimeField, G: GroupType<F>> CoreCircuit<'a, F, G> for Blake2s {
|
||||
span: &Span,
|
||||
target: Option<ConstrainedValue<'a, F, G>>,
|
||||
mut arguments: Vec<ConstrainedValue<'a, F, G>>,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
assert_eq!(arguments.len(), 2); // asg enforced
|
||||
assert!(function.name.borrow().name.as_ref() == "hash"); // asg enforced
|
||||
assert!(target.is_none()); // asg enforced
|
||||
let input = unwrap_argument(arguments.remove(1));
|
||||
let seed = unwrap_argument(arguments.remove(0));
|
||||
|
||||
let digest = Blake2sGadget::check_evaluation_gadget(cs.ns(|| "blake2s hash"), &seed[..], &input[..])
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("Blake2s check evaluation gadget", e, span))?;
|
||||
let digest =
|
||||
Blake2sGadget::check_evaluation_gadget(cs.ns(|| "blake2s hash"), &seed[..], &input[..]).map_err(|e| {
|
||||
CompilerError::cannot_enforce_expression("Blake2s check evaluation gadget", e, span, new_backtrace())
|
||||
})?;
|
||||
|
||||
Ok(ConstrainedValue::Array(
|
||||
digest
|
||||
.to_bytes(cs)
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("Vec<UInt8> ToBytes", e, span))?
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("Vec<UInt8> ToBytes", e, span, new_backtrace()))?
|
||||
.into_iter()
|
||||
.map(Integer::U8)
|
||||
.map(ConstrainedValue::Integer)
|
||||
|
@ -19,7 +19,7 @@ pub use blake2s::*;
|
||||
|
||||
use crate::{ConstrainedValue, GroupType};
|
||||
use leo_asg::Function;
|
||||
use leo_errors::{LeoError, Span};
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -32,7 +32,7 @@ pub trait CoreCircuit<'a, F: PrimeField, G: GroupType<F>>: Send + Sync {
|
||||
span: &Span,
|
||||
target: Option<ConstrainedValue<'a, F, G>>,
|
||||
arguments: Vec<ConstrainedValue<'a, F, G>>,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError>;
|
||||
) -> Result<ConstrainedValue<'a, F, G>>;
|
||||
}
|
||||
|
||||
pub fn resolve_core_circuit<'a, F: PrimeField, G: GroupType<F>>(name: &str) -> impl CoreCircuit<'a, F, G> {
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{arithmetic::*, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::{AssignOperation, AssignStatement};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{boolean::Boolean, traits::select::CondSelectGadget};
|
||||
@ -31,7 +31,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
indicator: &Boolean,
|
||||
statement: &AssignStatement<'a>,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
// Get the name of the variable we are assigning to
|
||||
let new_value = self.enforce_expression(cs, statement.value.get())?;
|
||||
|
||||
@ -48,7 +48,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
target: &mut ConstrainedValue<'a, F, G>,
|
||||
new_value: ConstrainedValue<'a, F, G>,
|
||||
span: &Span,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
let new_value = match operation {
|
||||
AssignOperation::Assign => new_value,
|
||||
AssignOperation::Add => enforce_add(cs, target.clone(), new_value, span)?,
|
||||
@ -59,7 +59,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
_ => unimplemented!("unimplemented assign operator"),
|
||||
};
|
||||
let selected_value = ConstrainedValue::conditionally_select(cs.ns(|| scope), condition, &new_value, target)
|
||||
.map_err(|_| CompilerError::statement_select_fail(new_value, target.clone(), span))?;
|
||||
.map_err(|_| CompilerError::statement_select_fail(new_value, target.clone(), span, new_backtrace()))?;
|
||||
|
||||
*target = selected_value;
|
||||
Ok(())
|
||||
|
@ -20,7 +20,7 @@ use std::convert::TryInto;
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType, Integer};
|
||||
use leo_asg::{ConstInt, Expression, Node};
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::traits::{eq::EvaluateEqGadget, select::CondSelectGadget};
|
||||
@ -34,7 +34,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
mut context: ResolverContext<'a, 'b, F, G>,
|
||||
index: &'a Expression<'a>,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
let input_len = context.input.len();
|
||||
|
||||
let index_resolved = self.enforce_index(cs, index, &context.span)?;
|
||||
@ -43,10 +43,13 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
ConstrainedValue::Array(input) => {
|
||||
if let Some(index) = index_resolved.to_usize() {
|
||||
if index >= input.len() {
|
||||
Err(
|
||||
CompilerError::statement_array_assign_index_bounds(index, input.len(), &context.span)
|
||||
.into(),
|
||||
Err(CompilerError::statement_array_assign_index_bounds(
|
||||
index,
|
||||
input.len(),
|
||||
&context.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into())
|
||||
} else {
|
||||
let target = input.get_mut(index).unwrap();
|
||||
if context.remaining_accesses.is_empty() {
|
||||
@ -62,7 +65,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let array_len: u32 = input
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| CompilerError::array_length_out_of_bounds(&span))?;
|
||||
.map_err(|_| CompilerError::array_length_out_of_bounds(&span, new_backtrace()))?;
|
||||
self.array_bounds_check(cs, &index_resolved, array_len, &span)?;
|
||||
}
|
||||
|
||||
@ -75,11 +78,11 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
|
||||
let index_bounded = i
|
||||
.try_into()
|
||||
.map_err(|_| CompilerError::array_index_out_of_legal_bounds(&span))?;
|
||||
.map_err(|_| CompilerError::array_index_out_of_legal_bounds(&span, new_backtrace()))?;
|
||||
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(|_| CompilerError::cannot_evaluate_expression("==", &span))?;
|
||||
.map_err(|_| CompilerError::cannot_evaluate_expression("==", &span, new_backtrace()))?;
|
||||
|
||||
let mut unique_namespace = cs.ns(|| {
|
||||
format!(
|
||||
@ -112,21 +115,32 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&temp_item,
|
||||
item,
|
||||
)
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("conditional select", e, &span))?;
|
||||
.map_err(|e| {
|
||||
CompilerError::cannot_enforce_expression(
|
||||
"conditional select",
|
||||
e,
|
||||
&span,
|
||||
new_backtrace(),
|
||||
)
|
||||
})?;
|
||||
*item = value;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
_ => Err(CompilerError::statement_array_assign_interior_index(&context.span).into()),
|
||||
_ => Err(CompilerError::statement_array_assign_interior_index(&context.span, new_backtrace()).into()),
|
||||
}
|
||||
} else if context.from_range && input_len != 0 {
|
||||
context.from_range = false;
|
||||
if let Some(index) = index_resolved.to_usize() {
|
||||
if index >= input_len {
|
||||
return Err(
|
||||
CompilerError::statement_array_assign_index_bounds(index, input_len, &context.span).into(),
|
||||
);
|
||||
return Err(CompilerError::statement_array_assign_index_bounds(
|
||||
index,
|
||||
input_len,
|
||||
&context.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
let target = context.input.remove(index);
|
||||
|
||||
@ -144,7 +158,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
.input
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| CompilerError::array_length_out_of_bounds(&span))?;
|
||||
.map_err(|_| CompilerError::array_length_out_of_bounds(&span, new_backtrace()))?;
|
||||
self.array_bounds_check(cs, &index_resolved, array_len, &span)?;
|
||||
}
|
||||
|
||||
@ -157,11 +171,11 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
|
||||
let index_bounded = i
|
||||
.try_into()
|
||||
.map_err(|_| CompilerError::array_index_out_of_legal_bounds(&span))?;
|
||||
.map_err(|_| CompilerError::array_index_out_of_legal_bounds(&span, new_backtrace()))?;
|
||||
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(|_| CompilerError::cannot_evaluate_expression("==", &span))?;
|
||||
.map_err(|_| CompilerError::cannot_evaluate_expression("==", &span, new_backtrace()))?;
|
||||
|
||||
let mut unique_namespace = cs.ns(|| {
|
||||
format!(
|
||||
@ -190,13 +204,15 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
};
|
||||
let value =
|
||||
ConstrainedValue::conditionally_select(unique_namespace, &index_comparison, &temp_item, item)
|
||||
.map_err(|e| CompilerError::cannot_enforce_expression("conditional select", e, &span))?;
|
||||
.map_err(|e| {
|
||||
CompilerError::cannot_enforce_expression("conditional select", e, &span, new_backtrace())
|
||||
})?;
|
||||
**item = value;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Err(CompilerError::statement_array_assign_interior_index(&context.span).into())
|
||||
Err(CompilerError::statement_array_assign_interior_index(&context.span, new_backtrace()).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Expression;
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -32,13 +32,13 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
mut context: ResolverContext<'a, 'b, F, G>,
|
||||
start: Option<&'a Expression<'a>>,
|
||||
stop: Option<&'a Expression<'a>>,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
let start_index = start
|
||||
.map(|start| self.enforce_index(cs, start, &context.span))
|
||||
.transpose()?
|
||||
.map(|x| {
|
||||
x.to_usize()
|
||||
.ok_or_else(|| CompilerError::statement_array_assign_index_const(&context.span))
|
||||
.ok_or_else(|| CompilerError::statement_array_assign_index_const(&context.span, new_backtrace()))
|
||||
})
|
||||
.transpose()?;
|
||||
let stop_index = stop
|
||||
@ -46,7 +46,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
.transpose()?
|
||||
.map(|x| {
|
||||
x.to_usize()
|
||||
.ok_or_else(|| CompilerError::statement_array_assign_index_const(&context.span))
|
||||
.ok_or_else(|| CompilerError::statement_array_assign_index_const(&context.span, new_backtrace()))
|
||||
})
|
||||
.transpose()?;
|
||||
let start_index = start_index.unwrap_or(0);
|
||||
@ -75,7 +75,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(CompilerError::statement_array_assign_index(&context.span).into()),
|
||||
_ => Err(CompilerError::statement_array_assign_index(&context.span, new_backtrace()).into()),
|
||||
}
|
||||
} else {
|
||||
// range of a range
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::Identifier;
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -29,9 +29,9 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
mut context: ResolverContext<'a, 'b, F, G>,
|
||||
name: &Identifier,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
if context.input.len() != 1 {
|
||||
return Err(CompilerError::statement_array_assign_interior_index(&context.span).into());
|
||||
return Err(CompilerError::statement_array_assign_interior_index(&context.span, new_backtrace()).into());
|
||||
}
|
||||
match context.input.remove(0) {
|
||||
ConstrainedValue::CircuitExpression(_variable, members) => {
|
||||
@ -45,12 +45,15 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
}
|
||||
None => {
|
||||
// Throw an error if the circuit variable does not exist in the circuit
|
||||
Err(CompilerError::statement_undefined_circuit_variable(name, &context.span).into())
|
||||
Err(
|
||||
CompilerError::statement_undefined_circuit_variable(name, &context.span, new_backtrace())
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Throw an error if the circuit definition does not exist in the file
|
||||
x => Err(CompilerError::undefined_circuit(x, &context.span).into()),
|
||||
x => Err(CompilerError::undefined_circuit(x, &context.span, new_backtrace()).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::{AssignAccess, AssignOperation, AssignStatement};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -45,7 +45,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
context: &ResolverContext<'a, 'b, F, G>,
|
||||
target: &mut ConstrainedValue<'a, F, G>,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
Self::enforce_assign_operation(
|
||||
cs,
|
||||
context.indicator,
|
||||
@ -61,7 +61,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
mut context: ResolverContext<'a, 'b, F, G>,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
if context.remaining_accesses.is_empty() {
|
||||
if context.input.len() != 1 {
|
||||
panic!("invalid non-array-context multi-value assignment");
|
||||
@ -90,7 +90,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
assignee: &AssignStatement<'a>,
|
||||
target_value: ConstrainedValue<'a, F, G>,
|
||||
indicator: &Boolean,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
let span = assignee.span.clone().unwrap_or_default();
|
||||
let variable = assignee.target_variable.get().borrow();
|
||||
|
||||
@ -109,18 +109,16 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn check_range_index(
|
||||
start_index: usize,
|
||||
stop_index: usize,
|
||||
len: usize,
|
||||
span: &Span,
|
||||
) -> Result<(), LeoError> {
|
||||
pub(crate) fn check_range_index(start_index: usize, stop_index: usize, len: usize, span: &Span) -> Result<()> {
|
||||
if stop_index < start_index {
|
||||
Err(CompilerError::statement_array_assign_range_order(start_index, stop_index, len, span).into())
|
||||
Err(
|
||||
CompilerError::statement_array_assign_range_order(start_index, stop_index, len, span, new_backtrace())
|
||||
.into(),
|
||||
)
|
||||
} else if start_index > len {
|
||||
Err(CompilerError::statement_array_assign_index_bounds(start_index, len, span).into())
|
||||
Err(CompilerError::statement_array_assign_index_bounds(start_index, len, span, new_backtrace()).into())
|
||||
} else if stop_index > len {
|
||||
Err(CompilerError::statement_array_assign_index_bounds(stop_index, len, span).into())
|
||||
Err(CompilerError::statement_array_assign_index_bounds(stop_index, len, span, new_backtrace()).into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -28,20 +28,26 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
cs: &mut CS,
|
||||
mut context: ResolverContext<'a, 'b, F, G>,
|
||||
index: usize,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
if context.input.len() != 1 {
|
||||
return Err(CompilerError::statement_array_assign_interior_index(&context.span).into());
|
||||
return Err(CompilerError::statement_array_assign_interior_index(&context.span, new_backtrace()).into());
|
||||
}
|
||||
match context.input.remove(0) {
|
||||
ConstrainedValue::Tuple(old) => {
|
||||
if index > old.len() {
|
||||
Err(CompilerError::statement_tuple_assign_index_bounds(index, old.len(), &context.span).into())
|
||||
Err(CompilerError::statement_tuple_assign_index_bounds(
|
||||
index,
|
||||
old.len(),
|
||||
&context.span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into())
|
||||
} else {
|
||||
context.input = vec![&mut old[index]];
|
||||
self.resolve_target_access(cs, context)
|
||||
}
|
||||
}
|
||||
_ => Err(CompilerError::statement_tuple_assign_index(&context.span).into()),
|
||||
_ => Err(CompilerError::statement_tuple_assign_index(&context.span, new_backtrace()).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ use crate::{
|
||||
StatementResult,
|
||||
};
|
||||
use leo_asg::ConditionalStatement;
|
||||
use leo_errors::CompilerError;
|
||||
use leo_errors::{new_backtrace, CompilerError};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
@ -60,6 +60,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
return Err(CompilerError::conditional_boolean_expression_fails_to_resolve_to_bool(
|
||||
value.to_string(),
|
||||
&span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -77,7 +78,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
outer_indicator,
|
||||
&inner_indicator,
|
||||
)
|
||||
.map_err(|_| CompilerError::statement_indicator_calculation(branch_1_name, &span))?;
|
||||
.map_err(|_| CompilerError::statement_indicator_calculation(branch_1_name, &span, new_backtrace()))?;
|
||||
|
||||
let mut results = vec![];
|
||||
|
||||
@ -98,7 +99,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
outer_indicator,
|
||||
&inner_indicator,
|
||||
)
|
||||
.map_err(|_| CompilerError::statement_indicator_calculation(branch_2_name, &span))?;
|
||||
.map_err(|_| CompilerError::statement_indicator_calculation(branch_2_name, &span, new_backtrace()))?;
|
||||
|
||||
// Evaluate branch 2
|
||||
let mut branch_2_result = match statement.next.get() {
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, ConstrainedValue, GroupType};
|
||||
use leo_asg::{DefinitionStatement, Variable};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -29,12 +29,13 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
variable_names: &[&'a Variable<'a>],
|
||||
values: Vec<ConstrainedValue<'a, F, G>>,
|
||||
span: &Span,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
if values.len() != variable_names.len() {
|
||||
return Err(CompilerError::statement_invalid_number_of_definitions(
|
||||
values.len(),
|
||||
variable_names.len(),
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
@ -51,7 +52,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
statement: &DefinitionStatement<'a>,
|
||||
) -> Result<(), LeoError> {
|
||||
) -> Result<()> {
|
||||
let num_variables = statement.variables.len();
|
||||
let expression = self.enforce_expression(cs, statement.value.get())?;
|
||||
|
||||
@ -66,7 +67,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
// ConstrainedValue::Return(values) => values,
|
||||
ConstrainedValue::Tuple(values) => values,
|
||||
value => {
|
||||
return Err(CompilerError::statement_multiple_definition(value, &span).into());
|
||||
return Err(CompilerError::statement_multiple_definition(value, &span, new_backtrace()).into());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
StatementResult,
|
||||
};
|
||||
use leo_asg::IterationStatement;
|
||||
use leo_errors::CompilerError;
|
||||
use leo_errors::{new_backtrace, CompilerError};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{boolean::Boolean, integers::uint::UInt32};
|
||||
@ -47,11 +47,11 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
let from = self
|
||||
.enforce_index(cs, statement.start.get(), &span)?
|
||||
.to_usize()
|
||||
.ok_or_else(|| CompilerError::statement_loop_index_const(&span))?;
|
||||
.ok_or_else(|| CompilerError::statement_loop_index_const(&span, new_backtrace()))?;
|
||||
let to = self
|
||||
.enforce_index(cs, statement.stop.get(), &span)?
|
||||
.to_usize()
|
||||
.ok_or_else(|| CompilerError::statement_loop_index_const(&span))?;
|
||||
.ok_or_else(|| CompilerError::statement_loop_index_const(&span, new_backtrace()))?;
|
||||
|
||||
let iter: Box<dyn Iterator<Item = usize>> = match (from < to, statement.inclusive) {
|
||||
(true, true) => Box::new(from..=to),
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::ReturnStatement;
|
||||
use leo_errors::LeoError;
|
||||
use leo_errors::Result;
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
@ -28,7 +28,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
statement: &ReturnStatement<'a>,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
let result = self.enforce_expression(cs, statement.expression.get())?;
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -18,13 +18,13 @@
|
||||
|
||||
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_asg::{Node, Statement};
|
||||
use leo_errors::{CompilerError, LeoError};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::boolean::Boolean;
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
|
||||
pub type StatementResult<T> = Result<T, LeoError>;
|
||||
pub type StatementResult<T> = Result<T>;
|
||||
pub type IndicatorAndConstrainedValue<'a, T, U> = (Boolean, ConstrainedValue<'a, T, U>);
|
||||
|
||||
impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
@ -82,9 +82,11 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(
|
||||
CompilerError::statement_unassigned(&statement.span.clone().unwrap_or_default()).into(),
|
||||
);
|
||||
return Err(CompilerError::statement_unassigned(
|
||||
&statement.span.clone().unwrap_or_default(),
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
use leo_asg::*;
|
||||
use leo_ast::{Ast, Program};
|
||||
use leo_errors::LeoError;
|
||||
use leo_errors::Result;
|
||||
|
||||
use leo_synthesizer::{CircuitSynthesizer, SerializedCircuit, SummarizedCircuit};
|
||||
use leo_test_framework::{
|
||||
@ -66,7 +66,7 @@ fn hash(input: String) -> String {
|
||||
pub(crate) fn parse_program(
|
||||
program_string: &str,
|
||||
theorem_options: Option<AstSnapshotOptions>,
|
||||
) -> Result<EdwardsTestCompiler, LeoError> {
|
||||
) -> Result<EdwardsTestCompiler> {
|
||||
let mut compiler = new_compiler("compiler-test".into(), theorem_options);
|
||||
|
||||
compiler.parse_program_from_string(program_string)?;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{ConstrainedValue, GroupType, IntegerTrait};
|
||||
use leo_ast::InputValue;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_dpc::{account::Address as AleoAddress, testnet1::instantiated::Components};
|
||||
use snarkvm_fields::PrimeField;
|
||||
@ -41,9 +41,9 @@ pub struct Address {
|
||||
}
|
||||
|
||||
impl Address {
|
||||
pub(crate) fn constant(address: String, span: &Span) -> Result<Self, LeoError> {
|
||||
let address =
|
||||
AleoAddress::from_str(&address).map_err(|e| CompilerError::address_value_account_error(e, span))?;
|
||||
pub(crate) fn constant(address: String, span: &Span) -> Result<Self> {
|
||||
let address = AleoAddress::from_str(&address)
|
||||
.map_err(|e| CompilerError::address_value_account_error(e, span, new_backtrace()))?;
|
||||
|
||||
let mut address_bytes = vec![];
|
||||
address.write_le(&mut address_bytes).unwrap();
|
||||
@ -65,14 +65,14 @@ impl Address {
|
||||
name: &str,
|
||||
input_value: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Check that the input value is the correct type
|
||||
let address_value = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Address(string) = input {
|
||||
Some(string)
|
||||
} else {
|
||||
return Err(CompilerError::address_value_invalid_address(name, span).into());
|
||||
return Err(CompilerError::address_value_invalid_address(name, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
@ -82,7 +82,7 @@ impl Address {
|
||||
cs.ns(|| format!("`{}: address` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| address_value.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| CompilerError::address_value_missing_address(span))?;
|
||||
.map_err(|_| CompilerError::address_value_missing_address(span, new_backtrace()))?;
|
||||
|
||||
Ok(ConstrainedValue::Address(address))
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{value::ConstrainedValue, GroupType};
|
||||
use leo_ast::InputValue;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{boolean::Boolean, traits::alloc::AllocGadget};
|
||||
@ -29,12 +29,12 @@ pub(crate) fn allocate_bool<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||
name: &str,
|
||||
option: Option<bool>,
|
||||
span: &Span,
|
||||
) -> Result<Boolean, LeoError> {
|
||||
) -> Result<Boolean> {
|
||||
Ok(Boolean::alloc(
|
||||
cs.ns(|| format!("`{}: bool` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| CompilerError::boolean_value_missing_boolean(format!("{}: bool", name), span))?)
|
||||
.map_err(|_| CompilerError::boolean_value_missing_boolean(format!("{}: bool", name), span, new_backtrace()))?)
|
||||
}
|
||||
|
||||
pub(crate) fn bool_from_input<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
@ -42,14 +42,14 @@ pub(crate) fn bool_from_input<'a, F: PrimeField, G: GroupType<F>, CS: Constraint
|
||||
name: &str,
|
||||
input_value: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Check that the input value is the correct type
|
||||
let option = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Boolean(bool) = input {
|
||||
Some(bool)
|
||||
} else {
|
||||
return Err(CompilerError::boolean_value_invalid_boolean(name, span).into());
|
||||
return Err(CompilerError::boolean_value_invalid_boolean(name, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
|
@ -21,7 +21,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use leo_ast::InputValue;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{
|
||||
@ -48,12 +48,7 @@ pub struct Char<F: PrimeField> {
|
||||
}
|
||||
|
||||
impl<F: PrimeField> Char<F> {
|
||||
pub fn constant<CS: ConstraintSystem<F>>(
|
||||
cs: CS,
|
||||
character: CharType,
|
||||
field: String,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
pub fn constant<CS: ConstraintSystem<F>>(cs: CS, character: CharType, field: String, span: &Span) -> Result<Self> {
|
||||
Ok(Self {
|
||||
character,
|
||||
field: FieldType::constant(cs, field, span)?,
|
||||
@ -148,7 +143,7 @@ pub(crate) fn char_from_input<'a, F: PrimeField, G: GroupType<F>, CS: Constraint
|
||||
name: &str,
|
||||
input_value: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Check that the parameter value is the correct type
|
||||
let option = match input_value {
|
||||
Some(input) => {
|
||||
@ -160,7 +155,7 @@ pub(crate) fn char_from_input<'a, F: PrimeField, G: GroupType<F>, CS: Constraint
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(CompilerError::char_value_invalid_char(input, span).into());
|
||||
return Err(CompilerError::char_value_invalid_char(input, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
None => (CharType::Scalar(0 as char), None),
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! A data type that represents a field value
|
||||
|
||||
use crate::number_string_typing;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::{
|
||||
@ -46,76 +46,74 @@ impl<F: PrimeField> FieldType<F> {
|
||||
}
|
||||
|
||||
/// Returns a new `FieldType` from the given `String` or returns a `FieldError`.
|
||||
pub fn constant<CS: ConstraintSystem<F>>(cs: CS, string: String, span: &Span) -> Result<Self, LeoError> {
|
||||
pub fn constant<CS: ConstraintSystem<F>>(cs: CS, string: String, span: &Span) -> Result<Self> {
|
||||
let number_info = number_string_typing(&string);
|
||||
|
||||
let value = match number_info {
|
||||
(number, neg) if neg => {
|
||||
-F::from_str(&number).map_err(|_| CompilerError::field_value_invalid_field(string.clone(), span))?
|
||||
}
|
||||
(number, _) => {
|
||||
F::from_str(&number).map_err(|_| CompilerError::field_value_invalid_field(string.clone(), span))?
|
||||
}
|
||||
(number, neg) if neg => -F::from_str(&number)
|
||||
.map_err(|_| CompilerError::field_value_invalid_field(string.clone(), span, new_backtrace()))?,
|
||||
(number, _) => F::from_str(&number)
|
||||
.map_err(|_| CompilerError::field_value_invalid_field(string.clone(), span, new_backtrace()))?,
|
||||
};
|
||||
|
||||
let value = FpGadget::alloc_constant(cs, || Ok(value))
|
||||
.map_err(|_| CompilerError::field_value_invalid_field(string, span))?;
|
||||
.map_err(|_| CompilerError::field_value_invalid_field(string, span, new_backtrace()))?;
|
||||
|
||||
Ok(FieldType(value))
|
||||
}
|
||||
|
||||
/// Returns a new `FieldType` by calling the `FpGadget` `negate` function.
|
||||
pub fn negate<CS: ConstraintSystem<F>>(&self, cs: CS, span: &Span) -> Result<Self, LeoError> {
|
||||
pub fn negate<CS: ConstraintSystem<F>>(&self, cs: CS, span: &Span) -> Result<Self> {
|
||||
let result = self
|
||||
.0
|
||||
.negate(cs)
|
||||
.map_err(|e| CompilerError::field_value_negate_operation(e, span))?;
|
||||
.map_err(|e| CompilerError::field_value_negate_operation(e, span, new_backtrace()))?;
|
||||
|
||||
Ok(FieldType(result))
|
||||
}
|
||||
|
||||
/// Returns a new `FieldType` by calling the `FpGadget` `add` function.
|
||||
pub fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self, LeoError> {
|
||||
pub fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self> {
|
||||
let value = self
|
||||
.0
|
||||
.add(cs, &other.0)
|
||||
.map_err(|e| CompilerError::field_value_binary_operation("+", e, span))?;
|
||||
.map_err(|e| CompilerError::field_value_binary_operation("+", e, span, new_backtrace()))?;
|
||||
|
||||
Ok(FieldType(value))
|
||||
}
|
||||
|
||||
/// Returns a new `FieldType` by calling the `FpGadget` `sub` function.
|
||||
pub fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self, LeoError> {
|
||||
pub fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self> {
|
||||
let value = self
|
||||
.0
|
||||
.sub(cs, &other.0)
|
||||
.map_err(|e| CompilerError::field_value_binary_operation("-", e, span))?;
|
||||
.map_err(|e| CompilerError::field_value_binary_operation("-", e, span, new_backtrace()))?;
|
||||
|
||||
Ok(FieldType(value))
|
||||
}
|
||||
|
||||
/// Returns a new `FieldType` by calling the `FpGadget` `mul` function.
|
||||
pub fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self, LeoError> {
|
||||
pub fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self> {
|
||||
let value = self
|
||||
.0
|
||||
.mul(cs, &other.0)
|
||||
.map_err(|e| CompilerError::field_value_binary_operation("*", e, span))?;
|
||||
.map_err(|e| CompilerError::field_value_binary_operation("*", e, span, new_backtrace()))?;
|
||||
|
||||
Ok(FieldType(value))
|
||||
}
|
||||
|
||||
/// Returns a new `FieldType` by calling the `FpGadget` `inverse` function.
|
||||
pub fn inverse<CS: ConstraintSystem<F>>(&self, cs: CS, span: &Span) -> Result<Self, LeoError> {
|
||||
pub fn inverse<CS: ConstraintSystem<F>>(&self, cs: CS, span: &Span) -> Result<Self> {
|
||||
let value = self
|
||||
.0
|
||||
.inverse(cs)
|
||||
.map_err(|e| CompilerError::field_value_binary_operation("inv", e, span))?;
|
||||
.map_err(|e| CompilerError::field_value_binary_operation("inv", e, span, new_backtrace()))?;
|
||||
|
||||
Ok(FieldType(value))
|
||||
}
|
||||
|
||||
/// Returns a new `FieldType` by calling the `FpGadget` `div` function.
|
||||
pub fn div<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self, span: &Span) -> Result<Self, LeoError> {
|
||||
pub fn div<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self, span: &Span) -> Result<Self> {
|
||||
let inverse = other.inverse(cs.ns(|| "division inverse"), span)?;
|
||||
|
||||
self.mul(cs, &inverse, span)
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{number_string_typing, value::ConstrainedValue, FieldType, GroupType};
|
||||
use leo_ast::InputValue;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::traits::alloc::AllocGadget;
|
||||
@ -29,7 +29,7 @@ pub(crate) fn allocate_field<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||
name: &str,
|
||||
option: Option<String>,
|
||||
span: &Span,
|
||||
) -> Result<FieldType<F>, LeoError> {
|
||||
) -> Result<FieldType<F>> {
|
||||
match option {
|
||||
Some(string) => {
|
||||
let number_info = number_string_typing(&string);
|
||||
@ -40,20 +40,23 @@ pub(crate) fn allocate_field<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||
|| Some(number).ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map(|value| value.negate(cs, span))
|
||||
.map_err(|_| CompilerError::field_value_missing_field(format!("{}: field", name), span))?,
|
||||
.map_err(|_| {
|
||||
CompilerError::field_value_missing_field(format!("{}: field", name), span, new_backtrace())
|
||||
})?,
|
||||
(number, _) => Ok(FieldType::alloc(
|
||||
cs.ns(|| format!("`{}: field` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| Some(number).ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| {
|
||||
LeoError::from(CompilerError::field_value_missing_field(
|
||||
format!("{}: field", name),
|
||||
span,
|
||||
))
|
||||
CompilerError::field_value_missing_field(format!("{}: field", name), span, new_backtrace())
|
||||
})?),
|
||||
}
|
||||
}
|
||||
None => return Err(CompilerError::field_value_missing_field(format!("{}: field", name), span).into()),
|
||||
None => {
|
||||
return Err(
|
||||
CompilerError::field_value_missing_field(format!("{}: field", name), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,14 +65,14 @@ pub(crate) fn field_from_input<'a, F: PrimeField, G: GroupType<F>, CS: Constrain
|
||||
name: &str,
|
||||
input_value: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Check that the parameter value is the correct type
|
||||
let option = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Field(string) = input {
|
||||
Some(string)
|
||||
} else {
|
||||
return Err(CompilerError::field_value_invalid_field(input, span).into());
|
||||
return Err(CompilerError::field_value_invalid_field(input, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! A data type that represents members in the group formed by the set of affine points on a curve.
|
||||
|
||||
use leo_asg::GroupValue;
|
||||
use leo_errors::{LeoError, Span};
|
||||
use leo_errors::{Result, Span};
|
||||
|
||||
use snarkvm_fields::{Field, One};
|
||||
use snarkvm_gadgets::{
|
||||
@ -45,13 +45,13 @@ pub trait GroupType<F: Field>:
|
||||
+ ToBitsBEGadget<F>
|
||||
+ ToBytesGadget<F>
|
||||
{
|
||||
fn constant(value: &GroupValue, span: &Span) -> Result<Self, LeoError>;
|
||||
fn constant(value: &GroupValue, span: &Span) -> Result<Self>;
|
||||
|
||||
fn to_allocated<CS: ConstraintSystem<F>>(&self, cs: CS, span: &Span) -> Result<Self, LeoError>;
|
||||
fn to_allocated<CS: ConstraintSystem<F>>(&self, cs: CS, span: &Span) -> Result<Self>;
|
||||
|
||||
fn negate<CS: ConstraintSystem<F>>(&self, cs: CS, span: &Span) -> Result<Self, LeoError>;
|
||||
fn negate<CS: ConstraintSystem<F>>(&self, cs: CS, span: &Span) -> Result<Self>;
|
||||
|
||||
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self, LeoError>;
|
||||
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self>;
|
||||
|
||||
fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self, LeoError>;
|
||||
fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self>;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
use crate::{ConstrainedValue, GroupType};
|
||||
use leo_asg::GroupValue;
|
||||
use leo_ast::InputValue;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_r1cs::{ConstraintSystem, SynthesisError};
|
||||
@ -29,12 +29,12 @@ pub(crate) fn allocate_group<F: PrimeField, G: GroupType<F>, CS: ConstraintSyste
|
||||
name: &str,
|
||||
option: Option<GroupValue>,
|
||||
span: &Span,
|
||||
) -> Result<G, LeoError> {
|
||||
) -> Result<G> {
|
||||
Ok(G::alloc(
|
||||
cs.ns(|| format!("`{}: group` {}:{}", name, span.line_start, span.col_start)),
|
||||
|| option.ok_or(SynthesisError::AssignmentMissing),
|
||||
)
|
||||
.map_err(|_| CompilerError::group_value_missing_group(format!("{}: group", name), span))?)
|
||||
.map_err(|_| CompilerError::group_value_missing_group(format!("{}: group", name), span, new_backtrace()))?)
|
||||
}
|
||||
|
||||
pub(crate) fn group_from_input<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
@ -42,14 +42,14 @@ pub(crate) fn group_from_input<'a, F: PrimeField, G: GroupType<F>, CS: Constrain
|
||||
name: &str,
|
||||
input_value: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<ConstrainedValue<'a, F, G>, LeoError> {
|
||||
) -> Result<ConstrainedValue<'a, F, G>> {
|
||||
// Check that the parameter value is the correct type
|
||||
let option = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Group(string) = input {
|
||||
Some(string)
|
||||
} else {
|
||||
return Err(CompilerError::group_value_missing_group(input, span).into());
|
||||
return Err(CompilerError::group_value_missing_group(input, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{number_string_typing, GroupType};
|
||||
use leo_asg::{GroupCoordinate, GroupValue};
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_curves::{
|
||||
edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq},
|
||||
@ -53,32 +53,32 @@ pub enum EdwardsGroupType {
|
||||
}
|
||||
|
||||
impl GroupType<Fq> for EdwardsGroupType {
|
||||
fn constant(group: &GroupValue, span: &Span) -> Result<Self, LeoError> {
|
||||
fn constant(group: &GroupValue, span: &Span) -> Result<Self> {
|
||||
let value = Self::edwards_affine_from_value(group, span)?;
|
||||
|
||||
Ok(EdwardsGroupType::Constant(value))
|
||||
}
|
||||
|
||||
fn to_allocated<CS: ConstraintSystem<Fq>>(&self, mut cs: CS, span: &Span) -> Result<Self, LeoError> {
|
||||
fn to_allocated<CS: ConstraintSystem<Fq>>(&self, mut cs: CS, span: &Span) -> Result<Self> {
|
||||
Ok(self
|
||||
.allocated(cs.ns(|| format!("allocate affine point {}:{}", span.line_start, span.col_start)))
|
||||
.map(|ebg| EdwardsGroupType::Allocated(Box::new(ebg)))
|
||||
.map_err(|e| CompilerError::group_value_synthesis_error(e, span))?)
|
||||
.map_err(|e| CompilerError::group_value_synthesis_error(e, span, new_backtrace()))?)
|
||||
}
|
||||
|
||||
fn negate<CS: ConstraintSystem<Fq>>(&self, cs: CS, span: &Span) -> Result<Self, LeoError> {
|
||||
fn negate<CS: ConstraintSystem<Fq>>(&self, cs: CS, span: &Span) -> Result<Self> {
|
||||
match self {
|
||||
EdwardsGroupType::Constant(group) => Ok(EdwardsGroupType::Constant(group.neg())),
|
||||
EdwardsGroupType::Allocated(group) => {
|
||||
let result = <EdwardsBls12Gadget as GroupGadget<Affine<EdwardsParameters>, Fq>>::negate(group, cs)
|
||||
.map_err(|e| CompilerError::group_value_negate_operation(e, span))?;
|
||||
.map_err(|e| CompilerError::group_value_negate_operation(e, span, new_backtrace()))?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add<CS: ConstraintSystem<Fq>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self, LeoError> {
|
||||
fn add<CS: ConstraintSystem<Fq>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self> {
|
||||
match (self, other) {
|
||||
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||
Ok(EdwardsGroupType::Constant(self_value.add(other_value)))
|
||||
@ -90,7 +90,7 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
cs,
|
||||
other_value,
|
||||
)
|
||||
.map_err(|e| CompilerError::group_value_binary_operation("+", e, span))?;
|
||||
.map_err(|e| CompilerError::group_value_binary_operation("+", e, span, new_backtrace()))?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||
}
|
||||
@ -100,13 +100,13 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(
|
||||
allocated_value
|
||||
.add_constant(cs, constant_value)
|
||||
.map_err(|e| CompilerError::group_value_binary_operation("+", e, span))?,
|
||||
.map_err(|e| CompilerError::group_value_binary_operation("+", e, span, new_backtrace()))?,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sub<CS: ConstraintSystem<Fq>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self, LeoError> {
|
||||
fn sub<CS: ConstraintSystem<Fq>>(&self, cs: CS, other: &Self, span: &Span) -> Result<Self> {
|
||||
match (self, other) {
|
||||
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||
Ok(EdwardsGroupType::Constant(self_value.sub(other_value)))
|
||||
@ -118,7 +118,7 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
cs,
|
||||
other_value,
|
||||
)
|
||||
.map_err(|e| CompilerError::group_value_binary_operation("-", e, span))?;
|
||||
.map_err(|e| CompilerError::group_value_binary_operation("-", e, span, new_backtrace()))?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||
}
|
||||
@ -128,7 +128,7 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(
|
||||
allocated_value
|
||||
.sub_constant(cs, constant_value)
|
||||
.map_err(|e| CompilerError::group_value_binary_operation("-", e, span))?,
|
||||
.map_err(|e| CompilerError::group_value_binary_operation("-", e, span, new_backtrace()))?,
|
||||
)))
|
||||
}
|
||||
}
|
||||
@ -136,14 +136,14 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
}
|
||||
|
||||
impl EdwardsGroupType {
|
||||
pub fn edwards_affine_from_value(value: &GroupValue, span: &Span) -> Result<EdwardsAffine, LeoError> {
|
||||
pub fn edwards_affine_from_value(value: &GroupValue, span: &Span) -> Result<EdwardsAffine> {
|
||||
match value {
|
||||
GroupValue::Single(number, ..) => Self::edwards_affine_from_single(number, span),
|
||||
GroupValue::Tuple(x, y) => Self::edwards_affine_from_tuple(x, y, span),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_single(number: &str, span: &Span) -> Result<EdwardsAffine, LeoError> {
|
||||
pub fn edwards_affine_from_single(number: &str, span: &Span) -> Result<EdwardsAffine> {
|
||||
let number_info = number_string_typing(number);
|
||||
|
||||
if number_info.0.eq("0") {
|
||||
@ -151,12 +151,10 @@ impl EdwardsGroupType {
|
||||
} else {
|
||||
let one = edwards_affine_one();
|
||||
let number_value = match number_info {
|
||||
(number, neg) if neg => {
|
||||
-Fp256::from_str(&number).map_err(|_| CompilerError::group_value_n_group(number, span))?
|
||||
}
|
||||
(number, _) => {
|
||||
Fp256::from_str(&number).map_err(|_| CompilerError::group_value_n_group(number, span))?
|
||||
}
|
||||
(number, neg) if neg => -Fp256::from_str(&number)
|
||||
.map_err(|_| CompilerError::group_value_n_group(number, span, new_backtrace()))?,
|
||||
(number, _) => Fp256::from_str(&number)
|
||||
.map_err(|_| CompilerError::group_value_n_group(number, span, new_backtrace()))?,
|
||||
};
|
||||
|
||||
let result: EdwardsAffine = one.mul(number_value);
|
||||
@ -165,11 +163,7 @@ impl EdwardsGroupType {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_tuple(
|
||||
x: &GroupCoordinate,
|
||||
y: &GroupCoordinate,
|
||||
span: &Span,
|
||||
) -> Result<EdwardsAffine, LeoError> {
|
||||
pub fn edwards_affine_from_tuple(x: &GroupCoordinate, y: &GroupCoordinate, span: &Span) -> Result<EdwardsAffine> {
|
||||
let x = x.clone();
|
||||
let y = y.clone();
|
||||
|
||||
@ -207,7 +201,11 @@ impl EdwardsGroupType {
|
||||
Self::edwards_affine_from_y_str(number_string_typing(&y_string), span, None, span)
|
||||
}
|
||||
// Invalid
|
||||
(x, y) => return Err(CompilerError::group_value_invalid_group(format!("({}, {})", x, y), span).into()),
|
||||
(x, y) => {
|
||||
return Err(
|
||||
CompilerError::group_value_invalid_group(format!("({}, {})", x, y), span, new_backtrace()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,18 +214,18 @@ impl EdwardsGroupType {
|
||||
x_span: &Span,
|
||||
greatest: Option<bool>,
|
||||
element_span: &Span,
|
||||
) -> Result<EdwardsAffine, LeoError> {
|
||||
) -> Result<EdwardsAffine> {
|
||||
let x = match x_info {
|
||||
(x_str, neg) if neg => {
|
||||
-Fq::from_str(&x_str).map_err(|_| CompilerError::group_value_x_invalid(x_str, x_span))?
|
||||
}
|
||||
(x_str, _) => Fq::from_str(&x_str).map_err(|_| CompilerError::group_value_x_invalid(x_str, x_span))?,
|
||||
(x_str, neg) if neg => -Fq::from_str(&x_str)
|
||||
.map_err(|_| CompilerError::group_value_x_invalid(x_str, x_span, new_backtrace()))?,
|
||||
(x_str, _) => Fq::from_str(&x_str)
|
||||
.map_err(|_| CompilerError::group_value_x_invalid(x_str, x_span, new_backtrace()))?,
|
||||
};
|
||||
|
||||
match greatest {
|
||||
// Sign provided
|
||||
Some(greatest) => Ok(EdwardsAffine::from_x_coordinate(x, greatest)
|
||||
.ok_or_else(|| CompilerError::group_value_x_recover(element_span))?),
|
||||
.ok_or_else(|| CompilerError::group_value_x_recover(element_span, new_backtrace()))?),
|
||||
// Sign inferred
|
||||
None => {
|
||||
// Attempt to recover with a sign_low bit.
|
||||
@ -241,7 +239,7 @@ impl EdwardsGroupType {
|
||||
}
|
||||
|
||||
// Otherwise return error.
|
||||
Err(CompilerError::group_value_x_recover(element_span).into())
|
||||
Err(CompilerError::group_value_x_recover(element_span, new_backtrace()).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,18 +249,18 @@ impl EdwardsGroupType {
|
||||
y_span: &Span,
|
||||
greatest: Option<bool>,
|
||||
element_span: &Span,
|
||||
) -> Result<EdwardsAffine, LeoError> {
|
||||
) -> Result<EdwardsAffine> {
|
||||
let y = match y_info {
|
||||
(y_str, neg) if neg => {
|
||||
-Fq::from_str(&y_str).map_err(|_| CompilerError::group_value_y_invalid(y_str, y_span))?
|
||||
}
|
||||
(y_str, _) => Fq::from_str(&y_str).map_err(|_| CompilerError::group_value_y_invalid(y_str, y_span))?,
|
||||
(y_str, neg) if neg => -Fq::from_str(&y_str)
|
||||
.map_err(|_| CompilerError::group_value_y_invalid(y_str, y_span, new_backtrace()))?,
|
||||
(y_str, _) => Fq::from_str(&y_str)
|
||||
.map_err(|_| CompilerError::group_value_y_invalid(y_str, y_span, new_backtrace()))?,
|
||||
};
|
||||
|
||||
match greatest {
|
||||
// Sign provided
|
||||
Some(greatest) => Ok(EdwardsAffine::from_y_coordinate(y, greatest)
|
||||
.ok_or_else(|| CompilerError::group_value_y_recover(element_span))?),
|
||||
.ok_or_else(|| CompilerError::group_value_y_recover(element_span, new_backtrace()))?),
|
||||
// Sign inferred
|
||||
None => {
|
||||
// Attempt to recover with a sign_low bit.
|
||||
@ -276,7 +274,7 @@ impl EdwardsGroupType {
|
||||
}
|
||||
|
||||
// Otherwise return error.
|
||||
Err(CompilerError::group_value_y_recover(element_span).into())
|
||||
Err(CompilerError::group_value_y_recover(element_span, new_backtrace()).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -287,19 +285,19 @@ impl EdwardsGroupType {
|
||||
x_span: &Span,
|
||||
y_span: &Span,
|
||||
element_span: &Span,
|
||||
) -> Result<EdwardsAffine, LeoError> {
|
||||
) -> Result<EdwardsAffine> {
|
||||
let x = match x_info {
|
||||
(x_str, neg) if neg => {
|
||||
-Fq::from_str(&x_str).map_err(|_| CompilerError::group_value_x_invalid(x_str, x_span))?
|
||||
}
|
||||
(x_str, _) => Fq::from_str(&x_str).map_err(|_| CompilerError::group_value_x_invalid(x_str, x_span))?,
|
||||
(x_str, neg) if neg => -Fq::from_str(&x_str)
|
||||
.map_err(|_| CompilerError::group_value_x_invalid(x_str, x_span, new_backtrace()))?,
|
||||
(x_str, _) => Fq::from_str(&x_str)
|
||||
.map_err(|_| CompilerError::group_value_x_invalid(x_str, x_span, new_backtrace()))?,
|
||||
};
|
||||
|
||||
let y = match y_info {
|
||||
(y_str, neg) if neg => {
|
||||
-Fq::from_str(&y_str).map_err(|_| CompilerError::group_value_y_invalid(y_str, y_span))?
|
||||
}
|
||||
(y_str, _) => Fq::from_str(&y_str).map_err(|_| CompilerError::group_value_y_invalid(y_str, y_span))?,
|
||||
(y_str, neg) if neg => -Fq::from_str(&y_str)
|
||||
.map_err(|_| CompilerError::group_value_y_invalid(y_str, y_span, new_backtrace()))?,
|
||||
(y_str, _) => Fq::from_str(&y_str)
|
||||
.map_err(|_| CompilerError::group_value_y_invalid(y_str, y_span, new_backtrace()))?,
|
||||
};
|
||||
|
||||
let element = EdwardsAffine::new(x, y);
|
||||
@ -307,7 +305,7 @@ impl EdwardsGroupType {
|
||||
if element.is_on_curve() {
|
||||
Ok(element)
|
||||
} else {
|
||||
Err(CompilerError::group_value_not_on_curve(element, element_span).into())
|
||||
Err(CompilerError::group_value_not_on_curve(element, element_span, new_backtrace()).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
use crate::IntegerTrait;
|
||||
use leo_asg::{ConstInt, IntegerType};
|
||||
use leo_ast::InputValue;
|
||||
use leo_errors::{CompilerError, LeoError, Span};
|
||||
use leo_errors::{new_backtrace, CompilerError, Result, Span};
|
||||
|
||||
use snarkvm_fields::{Field, PrimeField};
|
||||
use snarkvm_gadgets::{
|
||||
@ -132,7 +132,7 @@ impl Integer {
|
||||
name: &str,
|
||||
option: Option<String>,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
) -> Result<Self> {
|
||||
Ok(match integer_type {
|
||||
IntegerType::U8 => allocate_type!(u8, UInt8, Integer::U8, cs, name, option, span),
|
||||
IntegerType::U16 => allocate_type!(u16, UInt16, Integer::U16, cs, name, option, span),
|
||||
@ -154,20 +154,24 @@ impl Integer {
|
||||
name: &str,
|
||||
integer_value: Option<InputValue>,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
) -> Result<Self> {
|
||||
// Check that the input value is the correct type
|
||||
let option = match integer_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Integer(type_, number) = input {
|
||||
let asg_type = IntegerType::from(type_);
|
||||
if std::mem::discriminant(&asg_type) != std::mem::discriminant(integer_type) {
|
||||
return Err(
|
||||
CompilerError::integer_value_integer_type_mismatch(integer_type, asg_type, span).into(),
|
||||
);
|
||||
return Err(CompilerError::integer_value_integer_type_mismatch(
|
||||
integer_type,
|
||||
asg_type,
|
||||
span,
|
||||
new_backtrace(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
Some(number)
|
||||
} else {
|
||||
return Err(CompilerError::integer_value_invalid_integer(input, span).into());
|
||||
return Err(CompilerError::integer_value_invalid_integer(input, span, new_backtrace()).into());
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
@ -176,22 +180,17 @@ impl Integer {
|
||||
Self::allocate_type(cs, integer_type, name, option, span)
|
||||
}
|
||||
|
||||
pub fn negate<F: PrimeField, CS: ConstraintSystem<F>>(self, cs: &mut CS, span: &Span) -> Result<Self, LeoError> {
|
||||
pub fn negate<F: PrimeField, CS: ConstraintSystem<F>>(self, cs: &mut CS, span: &Span) -> Result<Self> {
|
||||
let unique_namespace = format!("enforce -{} {}:{}", self, span.line_start, span.col_start);
|
||||
|
||||
let a = self;
|
||||
|
||||
let result = match_signed_integer!(a, span => a.neg(cs.ns(|| unique_namespace)));
|
||||
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_negate_operation(span))?)
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_negate_operation(span, new_backtrace()))?)
|
||||
}
|
||||
|
||||
pub fn add<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
other: Self,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
pub fn add<F: PrimeField, CS: ConstraintSystem<F>>(self, cs: &mut CS, other: Self, span: &Span) -> Result<Self> {
|
||||
let unique_namespace = format!("enforce {} + {} {}:{}", self, other, span.line_start, span.col_start);
|
||||
|
||||
let a = self;
|
||||
@ -199,15 +198,10 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), span => a.add(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("+", span))?)
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("+", span, new_backtrace()))?)
|
||||
}
|
||||
|
||||
pub fn sub<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
other: Self,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
pub fn sub<F: PrimeField, CS: ConstraintSystem<F>>(self, cs: &mut CS, other: Self, span: &Span) -> Result<Self> {
|
||||
let unique_namespace = format!("enforce {} - {} {}:{}", self, other, span.line_start, span.col_start);
|
||||
|
||||
let a = self;
|
||||
@ -215,15 +209,10 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), span => a.sub(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("-", span))?)
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("-", span, new_backtrace()))?)
|
||||
}
|
||||
|
||||
pub fn mul<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
other: Self,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
pub fn mul<F: PrimeField, CS: ConstraintSystem<F>>(self, cs: &mut CS, other: Self, span: &Span) -> Result<Self> {
|
||||
let unique_namespace = format!("enforce {} * {} {}:{}", self, other, span.line_start, span.col_start);
|
||||
|
||||
let a = self;
|
||||
@ -231,15 +220,10 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), span => a.mul(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("*", span))?)
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("*", span, new_backtrace()))?)
|
||||
}
|
||||
|
||||
pub fn div<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
other: Self,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
pub fn div<F: PrimeField, CS: ConstraintSystem<F>>(self, cs: &mut CS, other: Self, span: &Span) -> Result<Self> {
|
||||
let unique_namespace = format!("enforce {} ÷ {} {}:{}", self, other, span.line_start, span.col_start);
|
||||
|
||||
let a = self;
|
||||
@ -247,15 +231,10 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), span => a.div(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("÷", span))?)
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("÷", span, new_backtrace()))?)
|
||||
}
|
||||
|
||||
pub fn pow<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
other: Self,
|
||||
span: &Span,
|
||||
) -> Result<Self, LeoError> {
|
||||
pub fn pow<F: PrimeField, CS: ConstraintSystem<F>>(self, cs: &mut CS, other: Self, span: &Span) -> Result<Self> {
|
||||
let unique_namespace = format!("enforce {} ** {} {}:{}", self, other, span.line_start, span.col_start);
|
||||
|
||||
let a = self;
|
||||
@ -263,7 +242,7 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), span => a.pow(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("**", span))?)
|
||||
Ok(result.ok_or_else(|| CompilerError::integer_value_binary_operation("**", span, new_backtrace()))?)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,21 +55,31 @@ macro_rules! match_unsigned_integer {
|
||||
macro_rules! match_signed_integer {
|
||||
($integer: ident, $span: ident => $expression: expr) => {
|
||||
match $integer {
|
||||
Integer::I8($integer) => Some(Integer::I8(
|
||||
$expression.map_err(|e| CompilerError::integer_value_signed(e, $span))?,
|
||||
)),
|
||||
Integer::I16($integer) => Some(Integer::I16(
|
||||
$expression.map_err(|e| CompilerError::integer_value_signed(e, $span))?,
|
||||
)),
|
||||
Integer::I32($integer) => Some(Integer::I32(
|
||||
$expression.map_err(|e| CompilerError::integer_value_signed(e, $span))?,
|
||||
)),
|
||||
Integer::I64($integer) => Some(Integer::I64(
|
||||
$expression.map_err(|e| CompilerError::integer_value_signed(e, $span))?,
|
||||
)),
|
||||
Integer::I128($integer) => Some(Integer::I128(
|
||||
$expression.map_err(|e| CompilerError::integer_value_signed(e, $span))?,
|
||||
)),
|
||||
Integer::I8($integer) => {
|
||||
Some(Integer::I8($expression.map_err(|e| {
|
||||
CompilerError::integer_value_signed(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
Integer::I16($integer) => {
|
||||
Some(Integer::I16($expression.map_err(|e| {
|
||||
CompilerError::integer_value_signed(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
Integer::I32($integer) => {
|
||||
Some(Integer::I32($expression.map_err(|e| {
|
||||
CompilerError::integer_value_signed(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
Integer::I64($integer) => {
|
||||
Some(Integer::I64($expression.map_err(|e| {
|
||||
CompilerError::integer_value_signed(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
Integer::I128($integer) => {
|
||||
Some(Integer::I128($expression.map_err(|e| {
|
||||
CompilerError::integer_value_signed(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
|
||||
_ => None,
|
||||
}
|
||||
@ -100,37 +110,57 @@ macro_rules! match_integers {
|
||||
macro_rules! match_integers_span {
|
||||
(($a: ident, $b: ident), $span: ident => $expression:expr) => {
|
||||
match ($a, $b) {
|
||||
(Integer::U8($a), Integer::U8($b)) => Some(Integer::U8(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::U16($a), Integer::U16($b)) => Some(Integer::U16(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::U32($a), Integer::U32($b)) => Some(Integer::U32(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::U64($a), Integer::U64($b)) => Some(Integer::U64(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::U128($a), Integer::U128($b)) => Some(Integer::U128(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::U8($a), Integer::U8($b)) => {
|
||||
Some(Integer::U8($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(Integer::U16($a), Integer::U16($b)) => {
|
||||
Some(Integer::U16($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(Integer::U32($a), Integer::U32($b)) => {
|
||||
Some(Integer::U32($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(Integer::U64($a), Integer::U64($b)) => {
|
||||
Some(Integer::U64($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(Integer::U128($a), Integer::U128($b)) => {
|
||||
Some(Integer::U128($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
|
||||
(Integer::I8($a), Integer::I8($b)) => Some(Integer::I8(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::I16($a), Integer::I16($b)) => Some(Integer::I16(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::I32($a), Integer::I32($b)) => Some(Integer::I32(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::I64($a), Integer::I64($b)) => Some(Integer::I64(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::I128($a), Integer::I128($b)) => Some(Integer::I128(
|
||||
$expression.map_err(|e| CompilerError::integer_value_unsigned(e, $span))?,
|
||||
)),
|
||||
(Integer::I8($a), Integer::I8($b)) => {
|
||||
Some(Integer::I8($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(Integer::I16($a), Integer::I16($b)) => {
|
||||
Some(Integer::I16($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(Integer::I32($a), Integer::I32($b)) => {
|
||||
Some(Integer::I32($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(Integer::I64($a), Integer::I64($b)) => {
|
||||
Some(Integer::I64($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(Integer::I128($a), Integer::I128($b)) => {
|
||||
Some(Integer::I128($expression.map_err(|e| {
|
||||
CompilerError::integer_value_unsigned(e, $span, new_backtrace())
|
||||
})?))
|
||||
}
|
||||
(_, _) => None,
|
||||
}
|
||||
};
|
||||
@ -141,7 +171,7 @@ macro_rules! allocate_type {
|
||||
let option = $option
|
||||
.map(|s| {
|
||||
s.parse::<$rust_ty>()
|
||||
.map_err(|_| CompilerError::integer_value_invalid_integer(s, $span))
|
||||
.map_err(|_| CompilerError::integer_value_invalid_integer(s, $span, new_backtrace()))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
@ -161,6 +191,7 @@ macro_rules! allocate_type {
|
||||
CompilerError::integer_value_missing_integer(
|
||||
format!("{}: {}", $name.to_string(), stringify!($rust_ty)),
|
||||
$span,
|
||||
new_backtrace(),
|
||||
)
|
||||
})?;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user