convert expressions to span with error

This commit is contained in:
collin 2020-06-19 21:38:36 -07:00
parent 3d1fe9cc4b
commit f3e81184c1
7 changed files with 381 additions and 223 deletions

View File

@ -15,6 +15,7 @@ use leo_types::{
Integer,
IntegerType,
RangeOrExpression,
Span,
SpreadOrExpression,
Type,
};
@ -61,6 +62,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
cs: &mut CS,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -74,13 +76,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.enforce_add_expression(cs, val_1, val_2)
self.enforce_add_expression(cs, val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_add_expression(cs, val_1, val_2)
self.enforce_add_expression(cs, val_1, val_2, span)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} + {}", val_1, val_2,))),
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} + {}", val_1, val_2),
span,
)),
}
}
@ -89,6 +94,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
cs: &mut CS,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -102,13 +108,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.enforce_sub_expression(cs, val_1, val_2)
self.enforce_sub_expression(cs, val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_sub_expression(cs, val_1, val_2)
self.enforce_sub_expression(cs, val_1, val_2, span)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} - {}", val_1, val_2,))),
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} - {}", val_1, val_2),
span,
)),
}
}
@ -117,6 +126,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
cs: &mut CS,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -127,13 +137,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.enforce_mul_expression(cs, val_1, val_2)
self.enforce_mul_expression(cs, val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_mul_expression(cs, val_1, val_2)
self.enforce_mul_expression(cs, val_1, val_2, span)
}
(val_1, val_2) => {
return Err(ExpressionError::incompatible_types(
format!("{} * {}", val_1, val_2),
span,
));
}
(val_1, val_2) => return Err(ExpressionError::IncompatibleTypes(format!("{} * {}", val_1, val_2,))),
}
}
@ -142,6 +157,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
cs: &mut CS,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -152,13 +168,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.enforce_div_expression(cs, val_1, val_2)
self.enforce_div_expression(cs, val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_div_expression(cs, val_1, val_2)
self.enforce_div_expression(cs, val_1, val_2, span)
}
(val_1, val_2) => {
return Err(ExpressionError::incompatible_types(
format!("{} / {}", val_1, val_2,),
span,
));
}
(val_1, val_2) => return Err(ExpressionError::IncompatibleTypes(format!("{} / {}", val_1, val_2,))),
}
}
@ -167,6 +188,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
cs: &mut CS,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -174,13 +196,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.enforce_pow_expression(cs, val_1, val_2)
self.enforce_pow_expression(cs, val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_pow_expression(cs, val_1, val_2)
self.enforce_pow_expression(cs, val_1, val_2, span)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} * {}", val_1, val_2,))),
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} ** {}", val_1, val_2,),
span,
)),
}
}
@ -190,6 +215,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
cs: &mut CS,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let mut expression_namespace = cs.ns(|| format!("evaluate {} == {}", left.to_string(), right.to_string()));
let result_bool = match (left, right) {
@ -207,13 +233,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
return self.evaluate_eq_expression(&mut expression_namespace, val_1, val_2);
return self.evaluate_eq_expression(&mut expression_namespace, val_1, val_2, span);
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
return self.evaluate_eq_expression(&mut expression_namespace, val_1, val_2);
return self.evaluate_eq_expression(&mut expression_namespace, val_1, val_2, span);
}
(val_1, val_2) => {
return Err(ExpressionError::incompatible_types(
format!("{} == {}", val_1, val_2,),
span,
));
}
(val_1, val_2) => return Err(ExpressionError::IncompatibleTypes(format!("{} == {}", val_1, val_2,))),
};
Ok(ConstrainedValue::Boolean(result_bool))
@ -224,6 +255,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
&mut self,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -236,16 +268,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.evaluate_ge_expression(val_1, val_2)
self.evaluate_ge_expression(val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.evaluate_ge_expression(val_1, val_2)
self.evaluate_ge_expression(val_1, val_2, span)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
"{} >= {}, values must be fields",
val_1, val_2
))),
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} >= {}", val_1, val_2),
span,
)),
}
}
@ -254,6 +286,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
&mut self,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -266,16 +299,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.evaluate_gt_expression(val_1, val_2)
self.evaluate_gt_expression(val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.evaluate_gt_expression(val_1, val_2)
self.evaluate_gt_expression(val_1, val_2, span)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
"{} > {}, values must be fields",
val_1, val_2
))),
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} > {}", val_1, val_2),
span,
)),
}
}
@ -284,6 +317,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
&mut self,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -296,16 +330,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.evaluate_le_expression(val_1, val_2)
self.evaluate_le_expression(val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.evaluate_le_expression(val_1, val_2)
self.evaluate_le_expression(val_1, val_2, span)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
"{} <= {}, values must be fields",
val_1, val_2
))),
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} <= {}", val_1, val_2),
span,
)),
}
}
@ -314,6 +348,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
&mut self,
left: ConstrainedValue<F, G>,
right: ConstrainedValue<F, G>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
@ -326,16 +361,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
self.evaluate_lt_expression(val_1, val_2)
self.evaluate_lt_expression(val_1, val_2, span)
}
(val_1, ConstrainedValue::Unresolved(string)) => {
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.evaluate_lt_expression(val_1, val_2)
self.evaluate_lt_expression(val_1, val_2, span)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
"{} < {}, values must be fields",
val_1, val_2,
))),
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} < {}", val_1, val_2,),
span,
)),
}
}
@ -349,6 +384,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
first: Expression,
second: Expression,
third: Expression,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let resolved_first = match self.enforce_expression(
cs,
@ -358,7 +394,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
first,
)? {
ConstrainedValue::Boolean(resolved) => resolved,
value => return Err(ExpressionError::IfElseConditional(value.to_string())),
value => return Err(ExpressionError::conditional_boolean(value.to_string(), span)),
};
let resolved_second =
@ -382,7 +418,10 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
let result = G::conditionally_select(cs, &resolved_first, &ge_1, &ge_2)?;
Ok(ConstrainedValue::Group(result))
}
(_, _) => unimplemented!("statements.conditional select gadget not implemented between given types"),
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("ternary between {} and {}", val_1, val_2),
span,
)),
}
}
@ -394,6 +433,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
function_scope: String,
expected_types: &Vec<Type>,
array: Vec<Box<SpreadOrExpression>>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Check explicit array type dimension if given
let mut expected_types = expected_types.clone();
@ -404,7 +444,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Type::Array(ref _type, ref dimensions) => {
expected_types = vec![expected_types[0].inner_dimension(dimensions)];
}
ref _type => return Err(ExpressionError::IncompatibleTypes(_type.to_string())),
ref _type => {
return Err(ExpressionError::unexpected_array(
expected_types[0].to_string(),
_type.to_string(),
span,
));
}
}
}
@ -418,13 +464,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Some(value) => match value {
ConstrainedValue::Array(array) => result.extend(array.clone()),
value => {
return Err(ExpressionError::InvalidSpread(value.to_string()));
return Err(ExpressionError::invalid_spread(value.to_string(), span));
}
},
None => return Err(ExpressionError::UndefinedArray(identifier.name)),
None => return Err(ExpressionError::undefined_array(identifier.name, span)),
}
}
value => return Err(ExpressionError::InvalidSpread(value.to_string())),
value => return Err(ExpressionError::invalid_spread(value.to_string(), span)),
},
SpreadOrExpression::Expression(expression) => {
result.push(self.enforce_expression(
@ -441,9 +487,10 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Check expected_dimensions if given
if !expected_dimensions.is_empty() {
if expected_dimensions[expected_dimensions.len() - 1] != result.len() {
return Err(ExpressionError::InvalidLength(
return Err(ExpressionError::invalid_length(
expected_dimensions[expected_dimensions.len() - 1],
result.len(),
span,
));
}
}
@ -457,11 +504,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
file_scope: String,
function_scope: String,
index: Expression,
span: Span,
) -> Result<usize, ExpressionError> {
let expected_types = vec![Type::IntegerType(IntegerType::U32)];
match self.enforce_expression_value(cs, file_scope.clone(), function_scope.clone(), &expected_types, index)? {
ConstrainedValue::Integer(number) => Ok(number.to_usize()),
value => Err(ExpressionError::InvalidIndex(value.to_string())),
value => Err(ExpressionError::invalid_index(value.to_string(), span)),
}
}
@ -473,6 +521,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
expected_types: &Vec<Type>,
array: Box<Expression>,
index: RangeOrExpression,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let array = match self.enforce_expression_value(
cs,
@ -482,7 +531,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*array,
)? {
ConstrainedValue::Array(array) => array,
value => return Err(ExpressionError::InvalidArrayAccess(value.to_string())),
value => return Err(ExpressionError::undefined_array(value.to_string(), span)),
};
match index {
@ -498,7 +547,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Ok(ConstrainedValue::Array(array[from_resolved..to_resolved].to_owned()))
}
RangeOrExpression::Expression(index) => {
let index_resolved = self.enforce_index(cs, file_scope, function_scope, index)?;
let index_resolved = self.enforce_index(cs, file_scope, function_scope, index, span)?;
Ok(array[index_resolved].to_owned())
}
}
@ -511,6 +560,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
function_scope: String,
identifier: Identifier,
members: Vec<CircuitFieldDefinition>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let mut program_identifier = new_scope(file_scope.clone(), identifier.to_string());
@ -541,7 +591,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
resolved_members.push(ConstrainedCircuitMember(identifier, field_value))
}
None => return Err(ExpressionError::ExpectedCircuitMember(identifier.to_string())),
None => return Err(ExpressionError::expected_circuit_member(identifier.to_string(), span)),
}
}
CircuitMember::CircuitFunction(_static, function) => {
@ -563,7 +613,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
resolved_members,
))
} else {
Err(ExpressionError::UndefinedCircuit(identifier.to_string()))
Err(ExpressionError::undefined_circuit(identifier.to_string(), span))
}
}
@ -575,6 +625,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
expected_types: &Vec<Type>,
circuit_identifier: Box<Expression>,
circuit_member: Identifier,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let (circuit_name, members) = match self.enforce_expression_value(
cs,
@ -584,7 +635,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*circuit_identifier.clone(),
)? {
ConstrainedValue::CircuitExpression(name, members) => (name, members),
value => return Err(ExpressionError::InvalidCircuitAccess(value.to_string())),
value => return Err(ExpressionError::undefined_circuit(value.to_string(), span)),
};
let matched_member = members.clone().into_iter().find(|member| member.0 == circuit_member);
@ -609,15 +660,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
}
ConstrainedValue::Static(value) => {
return Err(ExpressionError::InvalidStaticAccess(value.to_string()));
return Err(ExpressionError::invalid_static_access(value.to_string(), span));
}
_ => {}
}
Ok(member.1)
}
None => Err(ExpressionError::UndefinedMemberAccess(
None => Err(ExpressionError::undefined_member_access(
circuit_name.to_string(),
circuit_member.to_string(),
span,
)),
}
}
@ -630,6 +682,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
expected_types: &Vec<Type>,
circuit_identifier: Box<Expression>,
circuit_member: Identifier,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Get defined circuit
let circuit = match self.enforce_expression(
@ -640,7 +693,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*circuit_identifier.clone(),
)? {
ConstrainedValue::CircuitDefinition(circuit_definition) => circuit_definition,
value => return Err(ExpressionError::InvalidCircuitAccess(value.to_string())),
value => return Err(ExpressionError::undefined_circuit(value.to_string(), span)),
};
// Find static circuit function
@ -655,13 +708,17 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
if _static {
function
} else {
return Err(ExpressionError::InvalidMemberAccess(function.function_name.to_string()));
return Err(ExpressionError::invalid_member_access(
function.function_name.to_string(),
span,
));
}
}
_ => {
return Err(ExpressionError::UndefinedStaticAccess(
return Err(ExpressionError::undefined_member_access(
circuit.identifier.to_string(),
circuit_member.to_string(),
span,
));
}
};
@ -677,6 +734,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
expected_types: &Vec<Type>,
function: Box<Expression>,
arguments: Vec<Expression>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let function_value = self.enforce_expression(
cs,
@ -696,7 +754,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
(outer_scope, function.clone())
}
value => return Err(ExpressionError::UndefinedFunction(value.to_string())),
value => return Err(ExpressionError::undefined_function(value.to_string(), span)),
};
match self.enforce_function(cs, outer_scope, function_scope, function_call, arguments) {
@ -707,7 +765,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Ok(ConstrainedValue::Return(return_values))
}
}
Ok(_) => Err(ExpressionError::FunctionDidNotReturn(function.to_string())),
Ok(_) => Err(ExpressionError::function_no_return(function.to_string(), span)),
Err(error) => Err(ExpressionError::from(Box::new(error))),
}
}
@ -783,7 +841,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Expression::Implicit(value) => Self::enforce_number_implicit(expected_types, value),
// Binary operations
Expression::Add(left, right) => {
Expression::Add(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -793,9 +851,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
self.enforce_add_expression(cs, resolved_left, resolved_right)
self.enforce_add_expression(cs, resolved_left, resolved_right, span)
}
Expression::Sub(left, right) => {
Expression::Sub(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -805,9 +863,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
self.enforce_sub_expression(cs, resolved_left, resolved_right)
self.enforce_sub_expression(cs, resolved_left, resolved_right, span)
}
Expression::Mul(left, right) => {
Expression::Mul(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -817,9 +875,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
self.enforce_mul_expression(cs, resolved_left, resolved_right)
self.enforce_mul_expression(cs, resolved_left, resolved_right, span)
}
Expression::Div(left, right) => {
Expression::Div(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -829,9 +887,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
self.enforce_div_expression(cs, resolved_left, resolved_right)
self.enforce_div_expression(cs, resolved_left, resolved_right, span)
}
Expression::Pow(left, right) => {
Expression::Pow(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -841,7 +899,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
self.enforce_pow_expression(cs, resolved_left, resolved_right)
self.enforce_pow_expression(cs, resolved_left, resolved_right, span)
}
// Boolean operations
@ -852,7 +910,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
expected_types,
*expression,
)?)?),
Expression::Or(left, right) => {
Expression::Or(left, right, _span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -864,7 +922,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Ok(self.enforce_or(cs, resolved_left, resolved_right)?)
}
Expression::And(left, right) => {
Expression::And(left, right, _span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -876,7 +934,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Ok(self.enforce_and(cs, resolved_left, resolved_right)?)
}
Expression::Eq(left, right) => {
Expression::Eq(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -886,9 +944,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
Ok(self.evaluate_eq_expression(cs, resolved_left, resolved_right)?)
Ok(self.evaluate_eq_expression(cs, resolved_left, resolved_right, span)?)
}
Expression::Ge(left, right) => {
Expression::Ge(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -898,9 +956,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
Ok(self.evaluate_ge_expression(resolved_left, resolved_right)?)
Ok(self.evaluate_ge_expression(resolved_left, resolved_right, span)?)
}
Expression::Gt(left, right) => {
Expression::Gt(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -910,9 +968,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
Ok(self.evaluate_gt_expression(resolved_left, resolved_right)?)
Ok(self.evaluate_gt_expression(resolved_left, resolved_right, span)?)
}
Expression::Le(left, right) => {
Expression::Le(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -922,9 +980,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
Ok(self.evaluate_le_expression(resolved_left, resolved_right)?)
Ok(self.evaluate_le_expression(resolved_left, resolved_right, span)?)
}
Expression::Lt(left, right) => {
Expression::Lt(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,
file_scope.clone(),
@ -934,11 +992,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*right,
)?;
Ok(self.evaluate_lt_expression(resolved_left, resolved_right)?)
Ok(self.evaluate_lt_expression(resolved_left, resolved_right, span)?)
}
// Conditionals
Expression::IfElse(first, second, third) => self.enforce_conditional_expression(
Expression::IfElse(first, second, third, span) => self.enforce_conditional_expression(
cs,
file_scope,
function_scope,
@ -946,21 +1004,28 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
*first,
*second,
*third,
span,
),
// Arrays
Expression::Array(array) => {
self.enforce_array_expression(cs, file_scope, function_scope, expected_types, array)
}
Expression::ArrayAccess(array, index) => {
self.enforce_array_access_expression(cs, file_scope, function_scope, expected_types, array, *index)
Expression::Array(array, span) => {
self.enforce_array_expression(cs, file_scope, function_scope, expected_types, array, span)
}
Expression::ArrayAccess(array, index, span) => self.enforce_array_access_expression(
cs,
file_scope,
function_scope,
expected_types,
array,
*index,
span,
),
// Circuits
Expression::Circuit(circuit_name, members) => {
self.enforce_circuit_expression(cs, file_scope, function_scope, circuit_name, members)
Expression::Circuit(circuit_name, members, span) => {
self.enforce_circuit_expression(cs, file_scope, function_scope, circuit_name, members, span)
}
Expression::CircuitMemberAccess(circuit_variable, circuit_member) => self
Expression::CircuitMemberAccess(circuit_variable, circuit_member, span) => self
.enforce_circuit_access_expression(
cs,
file_scope,
@ -968,8 +1033,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
expected_types,
circuit_variable,
circuit_member,
span,
),
Expression::CircuitStaticFunctionAccess(circuit_identifier, circuit_member) => self
Expression::CircuitStaticFunctionAccess(circuit_identifier, circuit_member, span) => self
.enforce_circuit_static_access_expression(
cs,
file_scope,
@ -977,16 +1043,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
expected_types,
circuit_identifier,
circuit_member,
span,
),
// Functions
Expression::FunctionCall(function, arguments) => self.enforce_function_call_expression(
Expression::FunctionCall(function, arguments, span) => self.enforce_function_call_expression(
cs,
file_scope,
function_scope,
expected_types,
function,
arguments,
span,
),
}
}

View File

@ -69,7 +69,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Resolve index so we know if we are assigning to a single value or a range of values
match range_or_expression {
RangeOrExpression::Expression(index) => {
let index = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), index)?;
let index = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), index, span.clone())?;
// Modify the single value of the array in place
match self.get_mutable_assignee(name, span.clone())? {

View File

@ -6,20 +6,12 @@ use std::num::ParseIntError;
#[derive(Debug, Error)]
pub enum ExpressionError {
// Identifiers
#[error("Identifier \"{}\" not found", _0)]
UndefinedIdentifier(String),
#[error("{}", _0)]
Error(#[from] FormattedError),
// Types
#[error("{}", _0)]
BooleanError(#[from] BooleanError),
#[error("{}", _0)]
IncompatibleTypes(String),
#[error("{}", _0)]
IntegerError(#[from] IntegerError),
@ -35,54 +27,8 @@ pub enum ExpressionError {
#[error("{}", _0)]
ValueError(#[from] ValueError),
// Arrays
#[error("Cannot access array {}", _0)]
InvalidArrayAccess(String),
#[error("Index must resolve to an integer, got {}", _0)]
InvalidIndex(String),
#[error("Expected array length {}, got {}", _0, _1)]
InvalidLength(usize, usize),
#[error("Spread should contain an array, got {}", _0)]
InvalidSpread(String),
#[error("Array {} must be declared before it is used in an inline expression", _0)]
UndefinedArray(String),
// Circuits
#[error("Expected circuit member {}", _0)]
ExpectedCircuitMember(String),
#[error("Cannot access circuit {}", _0)]
InvalidCircuitAccess(String),
#[error("Non-static member {} must be accessed using `.` syntax", _0)]
InvalidMemberAccess(String),
#[error("Static member {} must be accessed using `::` syntax", _0)]
InvalidStaticAccess(String),
#[error("Circuit {} must be declared before it is used in an inline expression", _0)]
UndefinedCircuit(String),
#[error("Circuit {} has no member {}", _0, _1)]
UndefinedMemberAccess(String, String),
#[error("Circuit {} has no static member {}", _0, _1)]
UndefinedStaticAccess(String, String),
// Functions
#[error("Inline function call to {} did not return", _0)]
FunctionDidNotReturn(String),
#[error("{}", _0)]
FunctionError(#[from] Box<FunctionError>),
#[error("Function {} must be declared before it is used in an inline expression", _0)]
UndefinedFunction(String),
// Conditionals
#[error("If, else statements.conditional must resolve to a boolean, got {}", _0)]
IfElseConditional(String),
@ -96,9 +42,105 @@ impl ExpressionError {
ExpressionError::Error(FormattedError::new_from_span(message, span))
}
pub fn conditional_boolean(actual: String, span: Span) -> Self {
let message = format!("If, else conditional must resolve to a boolean, found `{}`", actual);
Self::new_from_span(message, span)
}
pub fn expected_circuit_member(expected: String, span: Span) -> Self {
let message = format!("Expected circuit member `{}`, not found", expected);
Self::new_from_span(message, span)
}
pub fn unexpected_array(expected: String, actual: String, span: Span) -> Self {
let message = format!("expected type `{}`, found array with elements `{}`", expected, actual);
Self::new_from_span(message, span)
}
pub fn incompatible_types(operation: String, span: Span) -> Self {
let message = format!("no implementation for `{}`", operation);
Self::new_from_span(message, span)
}
pub fn invalid_index(actual: String, span: Span) -> Self {
let message = format!("Index must resolve to an integer, found `{}`", actual);
Self::new_from_span(message, span)
}
pub fn invalid_length(expected: usize, actual: usize, span: Span) -> Self {
let message = format!("Expected array length {}, found one with length {}", expected, actual);
Self::new_from_span(message, span)
}
pub fn invalid_spread(actual: String, span: Span) -> Self {
let message = format!("Spread should contain an array, found `{}`", actual);
Self::new_from_span(message, span)
}
pub fn invalid_member_access(member: String, span: Span) -> Self {
let message = format!("Non-static member `{}` must be accessed using `.` syntax", member);
Self::new_from_span(message, span)
}
pub fn invalid_static_access(member: String, span: Span) -> Self {
let message = format!("Static member `{}` must be accessed using `::` syntax", member);
Self::new_from_span(message, span)
}
pub fn function_no_return(function: String, span: Span) -> Self {
let message = format!("Inline function call to `{}` did not return", function);
Self::new_from_span(message, span)
}
pub fn undefined_array(actual: String, span: Span) -> Self {
let message = format!("Array `{}` must be declared before it is used in an expression", actual);
Self::new_from_span(message, span)
}
pub fn undefined_circuit(actual: String, span: Span) -> Self {
let message = format!(
"Circuit `{}` must be declared before it is used in an expression",
actual
);
Self::new_from_span(message, span)
}
pub fn undefined_identifier(identifier: Identifier) -> Self {
let message = format!("cannot find value `{}` in this scope", identifier.name);
Self::new_from_span(message, identifier.span)
}
pub fn undefined_function(function: String, span: Span) -> Self {
let message = format!(
"Function `{}` must be declared before it is used in an inline expression",
function
);
Self::new_from_span(message, span)
}
pub fn undefined_member_access(circuit: String, member: String, span: Span) -> Self {
let message = format!("Circuit `{}` has no member `{}`", circuit, member);
Self::new_from_span(message, span)
}
pub fn undefined_static_access(circuit: String, member: String, span: Span) -> Self {
let message = format!("Circuit `{}` has no static member `{}`", circuit, member);
Self::new_from_span(message, span)
}
}

View File

@ -39,20 +39,20 @@ impl StatementError {
}
pub fn assertion_failed(left: String, right: String, span: Span) -> Self {
let message = format!("Assertion {} == {} failed", left, right);
let message = format!("Assertion `{} == {}` failed", left, right);
Self::new_from_span(message, span)
}
pub fn conditional_boolean(actual: String, span: Span) -> Self {
let message = format!("If, else conditional must resolve to a boolean, got {}", actual);
let message = format!("If, else conditional must resolve to a boolean, found `{}`", actual);
Self::new_from_span(message, span)
}
pub fn invalid_number_of_definitions(expected: usize, actual: usize, span: Span) -> Self {
let message = format!(
"Multiple definition statement expected {} return values, got {}",
"Multiple definition statement expected {} return values, found {} values",
expected, actual
);
@ -61,7 +61,7 @@ impl StatementError {
pub fn invalid_number_of_returns(expected: usize, actual: usize, span: Span) -> Self {
let message = format!(
"Function return statement expected {} return values, got {}",
"Function return statement expected {} return values, found {} values",
expected, actual
);
@ -69,20 +69,20 @@ impl StatementError {
}
pub fn immutable_assign(name: String, span: Span) -> Self {
let message = format!("Cannot assign to immutable variable {}", name);
let message = format!("Cannot assign to immutable variable `{}`", name);
Self::new_from_span(message, span)
}
pub fn immutable_circuit_function(name: String, span: Span) -> Self {
let message = format!("Cannot mutate circuit function, {}", name);
let message = format!("Cannot mutate circuit function, `{}`", name);
Self::new_from_span(message, span)
}
pub fn select_fail(first: String, second: String, span: Span) -> Self {
let message = format!(
"Conditional select gadget failed to select between {} or {}",
"Conditional select gadget failed to select between `{}` or `{}`",
first, second
);
@ -90,25 +90,25 @@ impl StatementError {
}
pub fn unassigned(name: String, span: Span) -> Self {
let message = format!("Expected assignment of return values for expression {}", name);
let message = format!("Expected assignment of return values for expression `{}`", name);
Self::new_from_span(message, span)
}
pub fn undefined_variable(name: String, span: Span) -> Self {
let message = format!("Attempted to assign to unknown variable {}", name);
let message = format!("Attempted to assign to unknown variable `{}`", name);
Self::new_from_span(message, span)
}
pub fn undefined_circuit(name: String, span: Span) -> Self {
let message = format!("Attempted to assign to unknown circuit {}", name);
let message = format!("Attempted to assign to unknown circuit `{}`", name);
Self::new_from_span(message, span)
}
pub fn undefined_circuit_object(name: String, span: Span) -> Self {
let message = format!("Attempted to assign to unknown circuit object {}", name);
let message = format!("Attempted to assign to unknown circuit object `{}`", name);
Self::new_from_span(message, span)
}

View File

@ -1,6 +1,6 @@
use pest::{Position, Span as AstSpan};
#[derive(Clone, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Span {
/// text of input string
pub text: String,

View File

@ -1,4 +1,4 @@
use crate::{CircuitFieldDefinition, Identifier, Integer, RangeOrExpression, SpreadOrExpression};
use crate::{CircuitFieldDefinition, Identifier, Integer, RangeOrExpression, Span, SpreadOrExpression};
use leo_ast::{
access::{Access, AssigneeAccess},
common::{Assignee, Identifier as AstIdentifier},
@ -34,36 +34,36 @@ pub enum Expression {
Implicit(String),
// Number operations
Add(Box<Expression>, Box<Expression>),
Sub(Box<Expression>, Box<Expression>),
Mul(Box<Expression>, Box<Expression>),
Div(Box<Expression>, Box<Expression>),
Pow(Box<Expression>, Box<Expression>),
Add(Box<Expression>, Box<Expression>, Span),
Sub(Box<Expression>, Box<Expression>, Span),
Mul(Box<Expression>, Box<Expression>, Span),
Div(Box<Expression>, Box<Expression>, Span),
Pow(Box<Expression>, Box<Expression>, Span),
// Boolean operations
Not(Box<Expression>),
Or(Box<Expression>, Box<Expression>),
And(Box<Expression>, Box<Expression>),
Eq(Box<Expression>, Box<Expression>),
Ge(Box<Expression>, Box<Expression>),
Gt(Box<Expression>, Box<Expression>),
Le(Box<Expression>, Box<Expression>),
Lt(Box<Expression>, Box<Expression>),
Or(Box<Expression>, Box<Expression>, Span),
And(Box<Expression>, Box<Expression>, Span),
Eq(Box<Expression>, Box<Expression>, Span),
Ge(Box<Expression>, Box<Expression>, Span),
Gt(Box<Expression>, Box<Expression>, Span),
Le(Box<Expression>, Box<Expression>, Span),
Lt(Box<Expression>, Box<Expression>, Span),
// Conditionals
IfElse(Box<Expression>, Box<Expression>, Box<Expression>),
IfElse(Box<Expression>, Box<Expression>, Box<Expression>, Span),
// Arrays
Array(Vec<Box<SpreadOrExpression>>),
ArrayAccess(Box<Expression>, Box<RangeOrExpression>), // (array name, range)
Array(Vec<Box<SpreadOrExpression>>, Span),
ArrayAccess(Box<Expression>, Box<RangeOrExpression>, Span), // (array name, range)
// Circuits
Circuit(Identifier, Vec<CircuitFieldDefinition>),
CircuitMemberAccess(Box<Expression>, Identifier), // (declared circuit name, circuit member name)
CircuitStaticFunctionAccess(Box<Expression>, Identifier), // (defined circuit name, circuit static member name)
Circuit(Identifier, Vec<CircuitFieldDefinition>, Span),
CircuitMemberAccess(Box<Expression>, Identifier, Span), // (declared circuit name, circuit member name)
CircuitStaticFunctionAccess(Box<Expression>, Identifier, Span), // (defined circuit name, circuit static member name)
// Functions
FunctionCall(Box<Expression>, Vec<Expression>),
FunctionCall(Box<Expression>, Vec<Expression>, Span),
}
impl<'ast> Expression {
@ -94,29 +94,29 @@ impl<'ast> fmt::Display for Expression {
Expression::Implicit(ref value) => write!(f, "{}", value),
// Number operations
Expression::Add(ref left, ref right) => write!(f, "{} + {}", left, right),
Expression::Sub(ref left, ref right) => write!(f, "{} - {}", left, right),
Expression::Mul(ref left, ref right) => write!(f, "{} * {}", left, right),
Expression::Div(ref left, ref right) => write!(f, "{} / {}", left, right),
Expression::Pow(ref left, ref right) => write!(f, "{} ** {}", left, right),
Expression::Add(ref left, ref right, ref _span) => write!(f, "{} + {}", left, right),
Expression::Sub(ref left, ref right, ref _span) => write!(f, "{} - {}", left, right),
Expression::Mul(ref left, ref right, ref _span) => write!(f, "{} * {}", left, right),
Expression::Div(ref left, ref right, ref _span) => write!(f, "{} / {}", left, right),
Expression::Pow(ref left, ref right, ref _span) => write!(f, "{} ** {}", left, right),
// Boolean operations
Expression::Not(ref expression) => write!(f, "!{}", expression),
Expression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs),
Expression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs),
Expression::Eq(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
Expression::Ge(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs),
Expression::Gt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs),
Expression::Le(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs),
Expression::Lt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs),
Expression::Or(ref lhs, ref rhs, ref _span) => write!(f, "{} || {}", lhs, rhs),
Expression::And(ref lhs, ref rhs, ref _span) => write!(f, "{} && {}", lhs, rhs),
Expression::Eq(ref lhs, ref rhs, ref _span) => write!(f, "{} == {}", lhs, rhs),
Expression::Ge(ref lhs, ref rhs, ref _span) => write!(f, "{} >= {}", lhs, rhs),
Expression::Gt(ref lhs, ref rhs, ref _span) => write!(f, "{} > {}", lhs, rhs),
Expression::Le(ref lhs, ref rhs, ref _span) => write!(f, "{} <= {}", lhs, rhs),
Expression::Lt(ref lhs, ref rhs, ref _span) => write!(f, "{} < {}", lhs, rhs),
// Conditionals
Expression::IfElse(ref first, ref second, ref third) => {
Expression::IfElse(ref first, ref second, ref third, ref _span) => {
write!(f, "if {} then {} else {} fi", first, second, third)
}
// Arrays
Expression::Array(ref array) => {
Expression::Array(ref array, ref _span) => {
write!(f, "[")?;
for (i, e) in array.iter().enumerate() {
write!(f, "{}", e)?;
@ -126,10 +126,10 @@ impl<'ast> fmt::Display for Expression {
}
write!(f, "]")
}
Expression::ArrayAccess(ref array, ref index) => write!(f, "{}[{}]", array, index),
Expression::ArrayAccess(ref array, ref index, ref _span) => write!(f, "{}[{}]", array, index),
// Circuits
Expression::Circuit(ref var, ref members) => {
Expression::Circuit(ref var, ref members, ref _span) => {
write!(f, "{} {{", var)?;
for (i, member) in members.iter().enumerate() {
write!(f, "{}: {}", member.identifier, member.expression)?;
@ -139,13 +139,15 @@ impl<'ast> fmt::Display for Expression {
}
write!(f, "}}")
}
Expression::CircuitMemberAccess(ref circuit_name, ref member) => write!(f, "{}.{}", circuit_name, member),
Expression::CircuitStaticFunctionAccess(ref circuit_name, ref member) => {
Expression::CircuitMemberAccess(ref circuit_name, ref member, ref _span) => {
write!(f, "{}.{}", circuit_name, member)
}
Expression::CircuitStaticFunctionAccess(ref circuit_name, ref member, ref _span) => {
write!(f, "{}::{}", circuit_name, member)
}
// Function calls
Expression::FunctionCall(ref function, ref arguments) => {
Expression::FunctionCall(ref function, ref arguments, ref _span) => {
write!(f, "{}(", function,)?;
for (i, param) in arguments.iter().enumerate() {
write!(f, "{}", param)?;
@ -168,7 +170,7 @@ impl<'ast> From<CircuitInlineExpression<'ast>> for Expression {
.map(|member| CircuitFieldDefinition::from(member))
.collect::<Vec<CircuitFieldDefinition>>();
Expression::Circuit(variable, members)
Expression::Circuit(variable, members, Span::from(expression.span))
}
}
@ -185,9 +187,11 @@ impl<'ast> From<PostfixExpression<'ast>> for Expression {
.into_iter()
.fold(variable, |acc, access| match access {
// Handle array accesses
Access::Array(array) => {
Expression::ArrayAccess(Box::new(acc), Box::new(RangeOrExpression::from(array.expression)))
}
Access::Array(array) => Expression::ArrayAccess(
Box::new(acc),
Box::new(RangeOrExpression::from(array.expression)),
Span::from(array.span),
),
// Handle function calls
Access::Call(function) => Expression::FunctionCall(
@ -197,15 +201,20 @@ impl<'ast> From<PostfixExpression<'ast>> for Expression {
.into_iter()
.map(|expression| Expression::from(expression))
.collect(),
Span::from(function.span),
),
// Handle circuit member accesses
Access::Object(circuit_object) => {
Expression::CircuitMemberAccess(Box::new(acc), Identifier::from(circuit_object.identifier))
}
Access::StaticObject(circuit_object) => {
Expression::CircuitStaticFunctionAccess(Box::new(acc), Identifier::from(circuit_object.identifier))
}
Access::Object(circuit_object) => Expression::CircuitMemberAccess(
Box::new(acc),
Identifier::from(circuit_object.identifier),
Span::from(circuit_object.span),
),
Access::StaticObject(circuit_object) => Expression::CircuitStaticFunctionAccess(
Box::new(acc),
Identifier::from(circuit_object.identifier),
Span::from(circuit_object.span),
),
})
}
}
@ -236,12 +245,16 @@ impl<'ast> From<Assignee<'ast>> for Expression {
.accesses
.into_iter()
.fold(variable, |acc, access| match access {
AssigneeAccess::Member(circuit_member) => {
Expression::CircuitMemberAccess(Box::new(acc), Identifier::from(circuit_member.identifier))
}
AssigneeAccess::Array(array) => {
Expression::ArrayAccess(Box::new(acc), Box::new(RangeOrExpression::from(array.expression)))
}
AssigneeAccess::Member(circuit_member) => Expression::CircuitMemberAccess(
Box::new(acc),
Identifier::from(circuit_member.identifier),
Span::from(circuit_member.span),
),
AssigneeAccess::Array(array) => Expression::ArrayAccess(
Box::new(acc),
Box::new(RangeOrExpression::from(array.expression)),
Span::from(array.span),
),
})
}
}
@ -253,52 +266,64 @@ impl<'ast> From<BinaryExpression<'ast>> for Expression {
BinaryOperation::Or => Expression::Or(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::And => Expression::And(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Eq => Expression::Eq(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Ne => Expression::Not(Box::new(Expression::from(expression))),
BinaryOperation::Ge => Expression::Ge(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Gt => Expression::Gt(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Le => Expression::Le(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Lt => Expression::Lt(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
// Number operations
BinaryOperation::Add => Expression::Add(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Sub => Expression::Sub(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Mul => Expression::Mul(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Div => Expression::Div(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
BinaryOperation::Pow => Expression::Pow(
Box::new(Expression::from(*expression.left)),
Box::new(Expression::from(*expression.right)),
Span::from(expression.span),
),
}
}
@ -310,6 +335,7 @@ impl<'ast> From<TernaryExpression<'ast>> for Expression {
Box::new(Expression::from(*expression.first)),
Box::new(Expression::from(*expression.second)),
Box::new(Expression::from(*expression.third)),
Span::from(expression.span),
)
}
}
@ -322,6 +348,7 @@ impl<'ast> From<ArrayInlineExpression<'ast>> for Expression {
.into_iter()
.map(|s_or_e| Box::new(SpreadOrExpression::from(s_or_e)))
.collect(),
Span::from(array.span),
)
}
}
@ -331,7 +358,7 @@ impl<'ast> From<ArrayInitializerExpression<'ast>> for Expression {
let count = Expression::get_count(array.count);
let expression = Box::new(SpreadOrExpression::from(*array.expression));
Expression::Array(vec![expression; count])
Expression::Array(vec![expression; count], Span::from(array.span))
}
}

View File

@ -67,27 +67,47 @@ impl<'ast> From<AssignStatement<'ast>> for Statement {
match operation_assign {
AssignOperation::AddAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Add(Box::new(converted), Box::new(Expression::from(statement.expression))),
Expression::Add(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
Span::from(statement.span.clone()),
),
Span::from(statement.span),
),
AssignOperation::SubAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Sub(Box::new(converted), Box::new(Expression::from(statement.expression))),
Expression::Sub(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
Span::from(statement.span.clone()),
),
Span::from(statement.span),
),
AssignOperation::MulAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Mul(Box::new(converted), Box::new(Expression::from(statement.expression))),
Expression::Mul(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
Span::from(statement.span.clone()),
),
Span::from(statement.span),
),
AssignOperation::DivAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Div(Box::new(converted), Box::new(Expression::from(statement.expression))),
Expression::Div(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
Span::from(statement.span.clone()),
),
Span::from(statement.span),
),
AssignOperation::PowAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Pow(Box::new(converted), Box::new(Expression::from(statement.expression))),
Expression::Pow(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
Span::from(statement.span.clone()),
),
Span::from(statement.span),
),
AssignOperation::Assign(ref _assign) => unimplemented!("cannot assign twice to assign statement"),
@ -110,6 +130,7 @@ impl<'ast> From<MultipleAssignmentStatement<'ast>> for Statement {
Expression::FunctionCall(
Box::new(Expression::from(statement.function_name)),
statement.arguments.into_iter().map(|e| Expression::from(e)).collect(),
Span::from(statement.span.clone()),
),
Span::from(statement.span),
)