mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-29 13:14:05 +03:00
fix errors, focus on dynamic checks
This commit is contained in:
parent
8de889ada5
commit
e50029c466
@ -14,35 +14,42 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ast::expressions::array::SpreadOrExpression, Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
use leo_static_check::{SymbolTable, Type};
|
||||
use crate::{
|
||||
ast::expressions::array::SpreadOrExpression, Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode,
|
||||
};
|
||||
use leo_static_check::Type;
|
||||
use leo_typed::{Span, SpreadOrExpression as UnresolvedSpreadOrExpression};
|
||||
|
||||
impl Expression {
|
||||
/// Resolves an array expression
|
||||
///
|
||||
/// Returns a new array `Expression` from a given vector of `UnresolvedSpreadOrExpression`s.
|
||||
///
|
||||
/// Performs a lookup in the given function body's variable table if the expression contains
|
||||
/// user-defined variables.
|
||||
///
|
||||
pub(crate) fn array(
|
||||
table: &mut SymbolTable,
|
||||
expected_type: Option<Type>,
|
||||
frame: &Frame,
|
||||
type_: &Type,
|
||||
expressions: Vec<Box<UnresolvedSpreadOrExpression>>,
|
||||
span: Span,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
// Expressions should evaluate to array type or array element type
|
||||
let expected_element_type = if let Some(type_) = expected_type {
|
||||
let (element_type, dimensions) = type_.get_type_array(span.clone())?;
|
||||
|
||||
if dimensions[0] != expressions.len() {
|
||||
//throw array dimension mismatch error
|
||||
return Err(ExpressionError::invalid_length_array(
|
||||
dimensions[0],
|
||||
expressions.len(),
|
||||
span.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
Some(element_type.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
// // Expressions should evaluate to array type or array element type
|
||||
// let expected_element_type = if let Some(type_) = type_ {
|
||||
// let (element_type, dimensions) = type_.get_type_array(span.clone())?;
|
||||
//
|
||||
// if dimensions[0] != expressions.len() {
|
||||
// //throw array dimension mismatch error
|
||||
// return Err(ExpressionError::invalid_length_array(
|
||||
// dimensions[0],
|
||||
// expressions.len(),
|
||||
// span.clone(),
|
||||
// ));
|
||||
// }
|
||||
//
|
||||
// Some(element_type.clone())
|
||||
// } else {
|
||||
// None
|
||||
// };
|
||||
|
||||
// Store actual array element type
|
||||
let mut actual_element_type = None;
|
||||
@ -50,7 +57,7 @@ impl Expression {
|
||||
|
||||
// Resolve all array elements
|
||||
for expression in expressions {
|
||||
let expression_resolved = SpreadOrExpression::resolve(table, (expected_element_type.clone(), *expression))?;
|
||||
let expression_resolved = SpreadOrExpression::new(frame, type_, *expression)?;
|
||||
let expression_type = expression_resolved.type_().clone();
|
||||
|
||||
array.push(Box::new(expression_resolved));
|
||||
|
@ -13,30 +13,36 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ast::expressions::array::RangeOrExpression, Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
use leo_static_check::{SymbolTable, Type};
|
||||
use leo_typed::{Expression as UnresolvedExpression, RangeOrExpression as UnresolvedRangeOrExpression, Span};
|
||||
|
||||
impl Expression {
|
||||
/// Resolves an array access expression
|
||||
pub(crate) fn array_access(
|
||||
table: &mut SymbolTable,
|
||||
expected_type: Option<Type>,
|
||||
array: Box<UnresolvedExpression>,
|
||||
range: Box<UnresolvedRangeOrExpression>,
|
||||
span: Span,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
// Lookup the array in the symbol table.
|
||||
// We do not know the length from this context so `expected_type = None`.
|
||||
let array_resolved = Expression::resolve(table, (None, *array))?;
|
||||
|
||||
// Resolve the range or expression
|
||||
let range_resolved = RangeOrExpression::resolve(table, (expected_type, *range))?;
|
||||
|
||||
Ok(Expression {
|
||||
type_: range_resolved.type_().clone(),
|
||||
value: ExpressionValue::ArrayAccess(Box::new(array_resolved), Box::new(range_resolved), span),
|
||||
})
|
||||
}
|
||||
}
|
||||
//
|
||||
// use crate::{
|
||||
// ast::expressions::array::RangeOrExpression, Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode,
|
||||
// };
|
||||
// use leo_static_check::Type;
|
||||
// use leo_typed::{Expression as UnresolvedExpression, RangeOrExpression as UnresolvedRangeOrExpression, Span};
|
||||
//
|
||||
// impl Expression {
|
||||
// ///
|
||||
// /// Returns a new array `Expression` from a given array access.
|
||||
// ///
|
||||
// /// Performs a lookup in the given function body's variable table if the expression contains
|
||||
// /// user-defined variables.
|
||||
// ///
|
||||
// pub(crate) fn array_access(
|
||||
// frame: &Frame,
|
||||
// type_: &Type,
|
||||
// array: Box<UnresolvedExpression>,
|
||||
// range: Box<UnresolvedRangeOrExpression>,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, ExpressionError> {
|
||||
// // Lookup the array in the variable table.
|
||||
// let array_resolved = Expression::new(frame, type_, *array)?;
|
||||
//
|
||||
// // Resolve the range or expression
|
||||
// let range_resolved = RangeOrExpression::new(frame, type_, *range)?;
|
||||
//
|
||||
// Ok(Expression {
|
||||
// type_: range_resolved.type_().clone(),
|
||||
// value: ExpressionValue::ArrayAccess(Box::new(array_resolved), Box::new(range_resolved), span),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
@ -14,8 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, ExpressionError, ResolvedNode};
|
||||
use leo_static_check::{SymbolTable, Type};
|
||||
use crate::{Expression, ExpressionError, Frame, ResolvedNode};
|
||||
use leo_static_check::Type;
|
||||
use leo_typed::RangeOrExpression as UnresolvedRangeOrExpression;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -27,33 +27,35 @@ pub enum RangeOrExpression {
|
||||
}
|
||||
|
||||
impl RangeOrExpression {
|
||||
/// If this is a range, return an array type.
|
||||
/// If this is an expression, return a data type.
|
||||
pub(crate) fn type_(&self) -> &Type {
|
||||
match self {
|
||||
RangeOrExpression::Range(expresion, _expression) => expresion.type_(),
|
||||
RangeOrExpression::Expression(expression) => expression.type_(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// /// If this is a range, return an array type.
|
||||
// /// If this is an expression, return a data type.
|
||||
// pub(crate) fn type_(&self) -> &Type {
|
||||
// match self {
|
||||
// RangeOrExpression::Range(expresion, _expression) => expresion.type_(),
|
||||
// RangeOrExpression::Expression(expression) => expression.type_(),
|
||||
// }
|
||||
// }
|
||||
|
||||
impl ResolvedNode for RangeOrExpression {
|
||||
type Error = ExpressionError;
|
||||
type UnresolvedNode = (Option<Type>, UnresolvedRangeOrExpression);
|
||||
|
||||
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
|
||||
let expected_type = unresolved.0;
|
||||
let r_or_e = unresolved.1;
|
||||
|
||||
Ok(match r_or_e {
|
||||
///
|
||||
/// Returns a new `RangeOrExpression` from a given `UnresolvedRangeOrExpression`.
|
||||
///
|
||||
/// Performs a lookup in the given function body's variable table if the expression contains
|
||||
/// user-defined variables.
|
||||
///
|
||||
pub fn new(
|
||||
frame: &Frame,
|
||||
type_: &Type,
|
||||
unresolved_expression: UnresolvedRangeOrExpression,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
Ok(match unresolved_expression {
|
||||
UnresolvedRangeOrExpression::Range(from, to) => {
|
||||
let resolved_from = Expression::resolve(table, (expected_type.clone(), from.unwrap())).unwrap();
|
||||
let resolved_to = Expression::resolve(table, (expected_type, to.unwrap())).unwrap();
|
||||
let resolved_from = Expression::new(frame, type_, from.unwrap())?;
|
||||
let resolved_to = Expression::new(frame, type_, to.unwrap())?;
|
||||
// TODO: add check for range type and array type
|
||||
RangeOrExpression::Range(resolved_from, resolved_to)
|
||||
}
|
||||
UnresolvedRangeOrExpression::Expression(expression) => {
|
||||
let expression_resolved = Expression::resolve(table, (expected_type, expression)).unwrap();
|
||||
let expression_resolved = Expression::new(frame, type_, expression)?;
|
||||
// TODO: add check for array type
|
||||
RangeOrExpression::Expression(expression_resolved)
|
||||
}
|
||||
|
@ -14,8 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, ExpressionError, ResolvedNode};
|
||||
use leo_static_check::{SymbolTable, Type};
|
||||
use crate::{Expression, ExpressionError, Frame};
|
||||
use leo_static_check::Type;
|
||||
use leo_typed::SpreadOrExpression as UnresolvedSpreadOrExpression;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -33,24 +33,26 @@ impl SpreadOrExpression {
|
||||
SpreadOrExpression::Expression(expression) => expression.type_(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResolvedNode for SpreadOrExpression {
|
||||
type Error = ExpressionError;
|
||||
type UnresolvedNode = (Option<Type>, UnresolvedSpreadOrExpression);
|
||||
|
||||
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
|
||||
let expected_type = unresolved.0;
|
||||
let s_or_e = unresolved.1;
|
||||
|
||||
Ok(match s_or_e {
|
||||
///
|
||||
/// Returns a new `SpreadOrExpression` from a given `UnresolvedSpreadOrExpression`.
|
||||
///
|
||||
/// Performs a lookup in the given function body's variable table if the expression contains
|
||||
/// user-defined variables.
|
||||
///
|
||||
pub fn new(
|
||||
frame: &Frame,
|
||||
type_: &Type,
|
||||
unresolved_expression: UnresolvedSpreadOrExpression,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
Ok(match unresolved_expression {
|
||||
UnresolvedSpreadOrExpression::Spread(spread) => {
|
||||
let spread_resolved = Expression::resolve(table, (expected_type, spread)).unwrap();
|
||||
let spread_resolved = Expression::new(frame, type_, spread)?;
|
||||
// TODO: add check for array type or array element type
|
||||
SpreadOrExpression::Spread(spread_resolved)
|
||||
}
|
||||
UnresolvedSpreadOrExpression::Expression(expression) => {
|
||||
let expression_resolved = Expression::resolve(table, (expected_type, expression)).unwrap();
|
||||
let expression_resolved = Expression::new(frame, type_, expression)?;
|
||||
// TODO: add check for array type or array element type
|
||||
SpreadOrExpression::Expression(expression_resolved)
|
||||
}
|
||||
|
@ -13,66 +13,67 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
use crate::{CircuitVariableDefinition, Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
use leo_static_check::{SymbolTable, Type};
|
||||
use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier, Span};
|
||||
|
||||
impl Expression {
|
||||
///
|
||||
/// Resolves an inline circuit expression.
|
||||
///
|
||||
pub(crate) fn circuit(
|
||||
table: &mut SymbolTable,
|
||||
expected_type: Option<Type>,
|
||||
identifier: Identifier,
|
||||
variables: Vec<UnresolvedCircuitVariableDefinition>,
|
||||
span: Span,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
// Check expected type
|
||||
let type_ = Type::Circuit(identifier.clone());
|
||||
Type::check_type(&expected_type, &type_, span.clone())?;
|
||||
|
||||
// Lookup circuit in symbol table
|
||||
let circuit = table
|
||||
.get_circuit(&identifier.name)
|
||||
.ok_or(ExpressionError::undefined_circuit(identifier.clone()))?;
|
||||
|
||||
// Check the number of variables given
|
||||
let expected_variables = circuit.variables.clone();
|
||||
|
||||
if variables.len() != expected_variables.len() {
|
||||
return Err(ExpressionError::invalid_length_circuit_members(
|
||||
expected_variables.len(),
|
||||
variables.len(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
// Check the name and type for each circuit variable
|
||||
let mut variables_resolved = vec![];
|
||||
|
||||
for variable in variables {
|
||||
// Find variable by name
|
||||
let matched_variable = expected_variables
|
||||
.iter()
|
||||
.find(|expected| expected.identifier.eq(&variable.identifier));
|
||||
|
||||
let variable_type = match matched_variable {
|
||||
Some(variable_type) => variable_type,
|
||||
None => return Err(ExpressionError::undefined_circuit_variable(variable.identifier)),
|
||||
};
|
||||
|
||||
// Resolve the variable expression using the expected variable type
|
||||
let expected_variable_type = Some(variable_type.type_.clone());
|
||||
|
||||
let variable_resolved = CircuitVariableDefinition::resolve(table, (expected_variable_type, variable))?;
|
||||
|
||||
variables_resolved.push(variable_resolved);
|
||||
}
|
||||
|
||||
Ok(Expression {
|
||||
type_,
|
||||
value: ExpressionValue::Circuit(identifier, variables_resolved, span),
|
||||
})
|
||||
}
|
||||
}
|
||||
//
|
||||
// use crate::{CircuitVariableDefinition, Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
// use leo_static_check::{SymbolTable, Type};
|
||||
// use leo_typed::{CircuitVariableDefinition as UnresolvedCircuitVariableDefinition, Identifier, Span};
|
||||
//
|
||||
// impl Expression {
|
||||
// ///
|
||||
// /// Resolves an inline circuit expression.
|
||||
// ///
|
||||
// pub(crate) fn circuit(
|
||||
// table: &mut SymbolTable,
|
||||
// expected_type: Option<Type>,
|
||||
// identifier: Identifier,
|
||||
// variables: Vec<UnresolvedCircuitVariableDefinition>,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, ExpressionError> {
|
||||
// // Check expected type
|
||||
// let type_ = Type::Circuit(identifier.clone());
|
||||
// Type::check_type(&expected_type, &type_, span.clone())?;
|
||||
//
|
||||
// // Lookup circuit in symbol table
|
||||
// let circuit = table
|
||||
// .get_circuit(&identifier.name)
|
||||
// .ok_or(ExpressionError::undefined_circuit(identifier.clone()))?;
|
||||
//
|
||||
// // Check the number of variables given
|
||||
// let expected_variables = circuit.variables.clone();
|
||||
//
|
||||
// if variables.len() != expected_variables.len() {
|
||||
// return Err(ExpressionError::invalid_length_circuit_members(
|
||||
// expected_variables.len(),
|
||||
// variables.len(),
|
||||
// span,
|
||||
// ));
|
||||
// }
|
||||
//
|
||||
// // Check the name and type for each circuit variable
|
||||
// let mut variables_resolved = vec![];
|
||||
//
|
||||
// for variable in variables {
|
||||
// // Find variable by name
|
||||
// let matched_variable = expected_variables
|
||||
// .iter()
|
||||
// .find(|expected| expected.identifier.eq(&variable.identifier));
|
||||
//
|
||||
// let variable_type = match matched_variable {
|
||||
// Some(variable_type) => variable_type,
|
||||
// None => return Err(ExpressionError::undefined_circuit_variable(variable.identifier)),
|
||||
// };
|
||||
//
|
||||
// // Resolve the variable expression using the expected variable type
|
||||
// let expected_variable_type = Some(variable_type.type_.clone());
|
||||
//
|
||||
// let variable_resolved = CircuitVariableDefinition::resolve(table, (expected_variable_type, variable))?;
|
||||
//
|
||||
// variables_resolved.push(variable_resolved);
|
||||
// }
|
||||
//
|
||||
// Ok(Expression {
|
||||
// type_,
|
||||
// value: ExpressionValue::Circuit(identifier, variables_resolved, span),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
@ -13,67 +13,67 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
use leo_static_check::{Attribute, SymbolTable, Type};
|
||||
use leo_typed::{Expression as UnresolvedExpression, Identifier, Span};
|
||||
|
||||
impl Expression {
|
||||
/// Resolve the type of a circuit member
|
||||
pub(crate) fn circuit_access(
|
||||
table: &mut SymbolTable,
|
||||
expected_type: Option<Type>,
|
||||
circuit: Box<UnresolvedExpression>,
|
||||
member: Identifier,
|
||||
span: Span,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
// Lookup the circuit in the symbol table.
|
||||
// We do not know the exact circuit type from this context so `expected_type = None`.
|
||||
let circuit_resolved = Expression::resolve(table, (None, *circuit))?;
|
||||
let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?;
|
||||
|
||||
// Lookup the circuit type in the symbol table
|
||||
let circuit_type = table
|
||||
.get_circuit(&circuit_name.name)
|
||||
.ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?;
|
||||
|
||||
// Resolve the circuit member as a circuit variable
|
||||
let matched_variable = circuit_type
|
||||
.variables
|
||||
.iter()
|
||||
.find(|variable| variable.identifier.eq(&member));
|
||||
|
||||
let type_ = match matched_variable {
|
||||
// Return variable type
|
||||
Some(variable) => variable.type_.clone(),
|
||||
None => {
|
||||
// Resolve the circuit member as a circuit function
|
||||
let matched_function = circuit_type
|
||||
.functions
|
||||
.iter()
|
||||
.find(|function| function.function.identifier.eq(&member));
|
||||
|
||||
match matched_function {
|
||||
// Return function output type
|
||||
Some(function) => {
|
||||
// Check non-static method
|
||||
if function.attributes.contains(&Attribute::Static) {
|
||||
return Err(ExpressionError::invalid_static_member_access(member.name.clone(), span));
|
||||
}
|
||||
|
||||
function.function.output.type_.clone()
|
||||
}
|
||||
None => return Err(ExpressionError::undefined_circuit_function(member, span)),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Check type of circuit member
|
||||
Type::check_type(&expected_type, &type_, span.clone())?;
|
||||
|
||||
Ok(Expression {
|
||||
type_,
|
||||
value: ExpressionValue::CircuitMemberAccess(Box::new(circuit_resolved), member, span),
|
||||
})
|
||||
}
|
||||
}
|
||||
//
|
||||
// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
// use leo_static_check::{Attribute, SymbolTable, Type};
|
||||
// use leo_typed::{Expression as UnresolvedExpression, Identifier, Span};
|
||||
//
|
||||
// impl Expression {
|
||||
// /// Resolve the type of a circuit member
|
||||
// pub(crate) fn circuit_access(
|
||||
// table: &mut SymbolTable,
|
||||
// expected_type: Option<Type>,
|
||||
// circuit: Box<UnresolvedExpression>,
|
||||
// member: Identifier,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, ExpressionError> {
|
||||
// // Lookup the circuit in the symbol table.
|
||||
// // We do not know the exact circuit type from this context so `expected_type = None`.
|
||||
// let circuit_resolved = Expression::resolve(table, (None, *circuit))?;
|
||||
// let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?;
|
||||
//
|
||||
// // Lookup the circuit type in the symbol table
|
||||
// let circuit_type = table
|
||||
// .get_circuit(&circuit_name.name)
|
||||
// .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?;
|
||||
//
|
||||
// // Resolve the circuit member as a circuit variable
|
||||
// let matched_variable = circuit_type
|
||||
// .variables
|
||||
// .iter()
|
||||
// .find(|variable| variable.identifier.eq(&member));
|
||||
//
|
||||
// let type_ = match matched_variable {
|
||||
// // Return variable type
|
||||
// Some(variable) => variable.type_.clone(),
|
||||
// None => {
|
||||
// // Resolve the circuit member as a circuit function
|
||||
// let matched_function = circuit_type
|
||||
// .functions
|
||||
// .iter()
|
||||
// .find(|function| function.function.identifier.eq(&member));
|
||||
//
|
||||
// match matched_function {
|
||||
// // Return function output type
|
||||
// Some(function) => {
|
||||
// // Check non-static method
|
||||
// if function.attributes.contains(&Attribute::Static) {
|
||||
// return Err(ExpressionError::invalid_static_member_access(member.name.clone(), span));
|
||||
// }
|
||||
//
|
||||
// function.function.output.type_.clone()
|
||||
// }
|
||||
// None => return Err(ExpressionError::undefined_circuit_function(member, span)),
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// // Check type of circuit member
|
||||
// Type::check_type(&expected_type, &type_, span.clone())?;
|
||||
//
|
||||
// Ok(Expression {
|
||||
// type_,
|
||||
// value: ExpressionValue::CircuitMemberAccess(Box::new(circuit_resolved), member, span),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
@ -13,54 +13,54 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
use leo_static_check::{Attribute, SymbolTable, Type};
|
||||
use leo_typed::{Expression as UnresolvedExpression, Identifier, Span};
|
||||
|
||||
impl Expression {
|
||||
/// Resolve the type of a static circuit member
|
||||
pub(crate) fn circuit_static_access(
|
||||
table: &mut SymbolTable,
|
||||
expected_type: Option<Type>,
|
||||
circuit: Box<UnresolvedExpression>,
|
||||
member: Identifier,
|
||||
span: Span,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
// Lookup the circuit in the symbol table.
|
||||
// We do not know the exact circuit type from this context so `expected_type = None`.
|
||||
let circuit_resolved = Expression::resolve(table, (None, *circuit))?;
|
||||
let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?;
|
||||
|
||||
// Lookup the circuit type in the symbol table
|
||||
let circuit_type = table
|
||||
.get_circuit(&circuit_name.name)
|
||||
.ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?;
|
||||
|
||||
// Resolve the circuit member as a circuit function
|
||||
let matched_function = circuit_type
|
||||
.functions
|
||||
.iter()
|
||||
.find(|function| function.function.identifier.eq(&member));
|
||||
|
||||
let type_ = match matched_function {
|
||||
Some(function) => {
|
||||
// Check static method
|
||||
if function.attributes.contains(&Attribute::Static) {
|
||||
function.function.output.type_.clone()
|
||||
} else {
|
||||
return Err(ExpressionError::invalid_member_access(member.name, span));
|
||||
}
|
||||
}
|
||||
None => return Err(ExpressionError::undefined_circuit_function_static(member, span)),
|
||||
};
|
||||
|
||||
// Check type of static circuit function output
|
||||
Type::check_type(&expected_type, &type_, span.clone())?;
|
||||
|
||||
Ok(Expression {
|
||||
type_,
|
||||
value: ExpressionValue::CircuitStaticFunctionAccess(Box::new(circuit_resolved), member, span),
|
||||
})
|
||||
}
|
||||
}
|
||||
//
|
||||
// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
// use leo_static_check::{Attribute, SymbolTable, Type};
|
||||
// use leo_typed::{Expression as UnresolvedExpression, Identifier, Span};
|
||||
//
|
||||
// impl Expression {
|
||||
// /// Resolve the type of a static circuit member
|
||||
// pub(crate) fn circuit_static_access(
|
||||
// table: &mut SymbolTable,
|
||||
// expected_type: Option<Type>,
|
||||
// circuit: Box<UnresolvedExpression>,
|
||||
// member: Identifier,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, ExpressionError> {
|
||||
// // Lookup the circuit in the symbol table.
|
||||
// // We do not know the exact circuit type from this context so `expected_type = None`.
|
||||
// let circuit_resolved = Expression::resolve(table, (None, *circuit))?;
|
||||
// let circuit_name = circuit_resolved.type_().get_type_circuit(span.clone())?;
|
||||
//
|
||||
// // Lookup the circuit type in the symbol table
|
||||
// let circuit_type = table
|
||||
// .get_circuit(&circuit_name.name)
|
||||
// .ok_or(ExpressionError::undefined_circuit(circuit_name.clone()))?;
|
||||
//
|
||||
// // Resolve the circuit member as a circuit function
|
||||
// let matched_function = circuit_type
|
||||
// .functions
|
||||
// .iter()
|
||||
// .find(|function| function.function.identifier.eq(&member));
|
||||
//
|
||||
// let type_ = match matched_function {
|
||||
// Some(function) => {
|
||||
// // Check static method
|
||||
// if function.attributes.contains(&Attribute::Static) {
|
||||
// function.function.output.type_.clone()
|
||||
// } else {
|
||||
// return Err(ExpressionError::invalid_member_access(member.name, span));
|
||||
// }
|
||||
// }
|
||||
// None => return Err(ExpressionError::undefined_circuit_function_static(member, span)),
|
||||
// };
|
||||
//
|
||||
// // Check type of static circuit function output
|
||||
// Type::check_type(&expected_type, &type_, span.clone())?;
|
||||
//
|
||||
// Ok(Expression {
|
||||
// type_,
|
||||
// value: ExpressionValue::CircuitStaticFunctionAccess(Box::new(circuit_resolved), member, span),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
@ -13,38 +13,38 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
use leo_static_check::{SymbolTable, Type};
|
||||
use leo_typed::{Expression as UnresolvedExpression, Span};
|
||||
|
||||
impl Expression {
|
||||
/// Resolves an `if {cond} ? {first} : {second}` expression
|
||||
/// `{cond}` should resolve to a boolean type
|
||||
/// `{first}` and `{second}` should have equal types
|
||||
pub(crate) fn conditional(
|
||||
table: &mut SymbolTable,
|
||||
expected_type: Option<Type>,
|
||||
cond: UnresolvedExpression,
|
||||
first: UnresolvedExpression,
|
||||
second: UnresolvedExpression,
|
||||
span: Span,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
// Resolve the condition to a boolean type
|
||||
let cond_type = Some(Type::Boolean);
|
||||
let cond_resolved = Expression::resolve(table, (cond_type, cond))?;
|
||||
|
||||
// Resolve the first and second expressions to the expected type
|
||||
let (first_resolved, second_resolved) = Expression::binary(table, expected_type, first, second, span.clone())?;
|
||||
|
||||
Ok(Expression {
|
||||
type_: first_resolved.type_.clone(),
|
||||
value: ExpressionValue::IfElse(
|
||||
Box::new(cond_resolved),
|
||||
Box::new(first_resolved),
|
||||
Box::new(second_resolved),
|
||||
span,
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
//
|
||||
// use crate::{Expression, ExpressionError, ExpressionValue, Frame, ResolvedNode};
|
||||
// use leo_static_check::{SymbolTable, Type};
|
||||
// use leo_typed::{Expression as UnresolvedExpression, Span};
|
||||
//
|
||||
// impl Expression {
|
||||
// /// Resolves an `if {cond} ? {first} : {second}` expression
|
||||
// /// `{cond}` should resolve to a boolean type
|
||||
// /// `{first}` and `{second}` should have equal types
|
||||
// pub(crate) fn conditional(
|
||||
// frame: &Frame,
|
||||
// type_: &Type,
|
||||
// cond: UnresolvedExpression,
|
||||
// first: UnresolvedExpression,
|
||||
// second: UnresolvedExpression,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, ExpressionError> {
|
||||
// // Resolve the condition to a boolean type
|
||||
// let boolean_type = Type::Boolean;
|
||||
// let cond_resolved = Expression::new(frame, &boolean_type, cond)?;
|
||||
//
|
||||
// // Resolve the first and second expressions to the expected type
|
||||
// let (first_resolved, second_resolved) = Expression::binary(frame, type_, first, second, &span)?;
|
||||
//
|
||||
// Ok(Expression {
|
||||
// type_: type_.clone(),
|
||||
// value: ExpressionValue::IfElse(
|
||||
// Box::new(cond_resolved),
|
||||
// Box::new(first_resolved),
|
||||
// Box::new(second_resolved),
|
||||
// span,
|
||||
// ),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
@ -92,17 +92,17 @@ impl Expression {
|
||||
UnresolvedExpression::Le(lhs, rhs, span) => Self::le(frame, *lhs, *rhs, span),
|
||||
UnresolvedExpression::Lt(lhs, rhs, span) => Self::lt(frame, *lhs, *rhs, span),
|
||||
|
||||
// // Conditionals
|
||||
// Conditionals
|
||||
// UnresolvedExpression::IfElse(cond, first, second, span) => {
|
||||
// Self::conditional(variable_table, *cond, *first, *second, span)
|
||||
// Self::conditional(variable_table, type_, *cond, *first, *second, span)
|
||||
// }
|
||||
//
|
||||
// // Arrays
|
||||
// UnresolvedExpression::Array(elements, span) => Self::array(variable_table, elements, span),
|
||||
|
||||
// Arrays
|
||||
UnresolvedExpression::Array(elements, span) => Self::array(frame, type_, elements, span),
|
||||
// UnresolvedExpression::ArrayAccess(array, access, span) => {
|
||||
// Self::array_access(variable_table, array, access, span)
|
||||
// Self::array_access(frame, type_, array, access, span)
|
||||
// }
|
||||
//
|
||||
|
||||
// // Tuples
|
||||
// UnresolvedExpression::Tuple(elements, span) => Self::tuple(variable_table, elements, span),
|
||||
// UnresolvedExpression::TupleAccess(tuple, index, span) => {
|
||||
|
@ -13,59 +13,59 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
use leo_static_check::{SymbolTable, Type};
|
||||
use leo_typed::{Expression as UnresolvedExpression, Span};
|
||||
|
||||
impl Expression {
|
||||
/// Resolves an inline function call
|
||||
/// Checks for errors in function name, inputs, and output.
|
||||
pub(crate) fn function_call(
|
||||
table: &mut SymbolTable,
|
||||
expected_type: Option<Type>,
|
||||
function: Box<UnresolvedExpression>,
|
||||
inputs: Vec<UnresolvedExpression>,
|
||||
span: Span,
|
||||
) -> Result<Self, ExpressionError> {
|
||||
// Lookup function in symbol table.
|
||||
// We do not know the exact function type from this context so `expected_type = None`.
|
||||
let function_resolved = Expression::resolve(table, (None, *function))?;
|
||||
let function_name = function_resolved.type_().get_type_function(span.clone())?;
|
||||
|
||||
// Lookup the function type in the symbol table
|
||||
let function_type = table
|
||||
.get_function(&function_name.name)
|
||||
.ok_or(ExpressionError::undefined_function(function_name.clone()))?;
|
||||
|
||||
let type_ = function_type.output.type_.clone();
|
||||
let expected_inputs = function_type.inputs.clone();
|
||||
|
||||
// Check the number of inputs given
|
||||
if inputs.len() != expected_inputs.len() {
|
||||
return Err(ExpressionError::invalid_length_function_inputs(
|
||||
expected_inputs.len(),
|
||||
inputs.len(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
// Check the type for each function input
|
||||
let mut inputs_resolved = vec![];
|
||||
|
||||
for (input, function_input_type) in inputs.into_iter().zip(expected_inputs) {
|
||||
let input_type = function_input_type.type_().clone();
|
||||
let input_resolved = Expression::resolve(table, (Some(input_type), input))?;
|
||||
|
||||
inputs_resolved.push(input_resolved)
|
||||
}
|
||||
|
||||
// Check the function output type
|
||||
Type::check_type(&expected_type, &type_, span.clone())?;
|
||||
|
||||
Ok(Expression {
|
||||
type_,
|
||||
value: ExpressionValue::FunctionCall(Box::new(function_resolved), inputs_resolved, span),
|
||||
})
|
||||
}
|
||||
}
|
||||
//
|
||||
// use crate::{Expression, ExpressionError, ExpressionValue, ResolvedNode};
|
||||
// use leo_static_check::{SymbolTable, Type};
|
||||
// use leo_typed::{Expression as UnresolvedExpression, Span};
|
||||
//
|
||||
// impl Expression {
|
||||
// /// Resolves an inline function call
|
||||
// /// Checks for errors in function name, inputs, and output.
|
||||
// pub(crate) fn function_call(
|
||||
// table: &mut SymbolTable,
|
||||
// expected_type: Option<Type>,
|
||||
// function: Box<UnresolvedExpression>,
|
||||
// inputs: Vec<UnresolvedExpression>,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, ExpressionError> {
|
||||
// // Lookup function in symbol table.
|
||||
// // We do not know the exact function type from this context so `expected_type = None`.
|
||||
// let function_resolved = Expression::resolve(table, (None, *function))?;
|
||||
// let function_name = function_resolved.type_().get_type_function(span.clone())?;
|
||||
//
|
||||
// // Lookup the function type in the symbol table
|
||||
// let function_type = table
|
||||
// .get_function(&function_name.name)
|
||||
// .ok_or(ExpressionError::undefined_function(function_name.clone()))?;
|
||||
//
|
||||
// let type_ = function_type.output.type_.clone();
|
||||
// let expected_inputs = function_type.inputs.clone();
|
||||
//
|
||||
// // Check the number of inputs given
|
||||
// if inputs.len() != expected_inputs.len() {
|
||||
// return Err(ExpressionError::invalid_length_function_inputs(
|
||||
// expected_inputs.len(),
|
||||
// inputs.len(),
|
||||
// span,
|
||||
// ));
|
||||
// }
|
||||
//
|
||||
// // Check the type for each function input
|
||||
// let mut inputs_resolved = vec![];
|
||||
//
|
||||
// for (input, function_input_type) in inputs.into_iter().zip(expected_inputs) {
|
||||
// let input_type = function_input_type.type_().clone();
|
||||
// let input_resolved = Expression::resolve(table, (Some(input_type), input))?;
|
||||
//
|
||||
// inputs_resolved.push(input_resolved)
|
||||
// }
|
||||
//
|
||||
// // Check the function output type
|
||||
// Type::check_type(&expected_type, &type_, span.clone())?;
|
||||
//
|
||||
// Ok(Expression {
|
||||
// type_,
|
||||
// value: ExpressionValue::FunctionCall(Box::new(function_resolved), inputs_resolved, span),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
@ -41,6 +41,7 @@ impl Function {
|
||||
// Create a new `Statement` from every given `UnresolvedStatement`.
|
||||
let statements = function_body
|
||||
.statements
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|unresolved_statement| Statement::new(&function_body, unresolved_statement))
|
||||
.collect::<Result<Vec<Statement>, StatementError>>()?;
|
||||
|
@ -29,74 +29,69 @@ pub struct Assign {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
///
|
||||
/// Resolves an assign statement
|
||||
///
|
||||
pub(crate) fn assign(
|
||||
function_body: &Frame,
|
||||
assignee: Assignee,
|
||||
expression: UnresolvedExpression,
|
||||
span: Span,
|
||||
) -> Result<Self, StatementError> {
|
||||
// Lookup variable in symbol table
|
||||
let key = &assignee.identifier.name;
|
||||
let variable = function_body.variable_table.get(key, &span)?;
|
||||
|
||||
// Throw an error if this variable is not mutable
|
||||
if !variable.is_mutable() {
|
||||
return Err(StatementError::immutable_assign(variable.identifier.name.clone(), span));
|
||||
}
|
||||
|
||||
// Get inner assignee type
|
||||
let type_ = get_inner_assignee_type(
|
||||
variable_table,
|
||||
variable.type_.clone(),
|
||||
assignee.accesses.clone(),
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
// Resolve the expression based on the assignee type
|
||||
let expression_resolved = Expression::new(variable_table, (Some(type_), expression))?;
|
||||
|
||||
Ok(Statement::Assign(Assign {
|
||||
assignee,
|
||||
expression: expression_resolved,
|
||||
span,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Accesses the inner type of an assignee such as an array, tuple, or circuit member.
|
||||
/// Returns an error for invalid accesses.
|
||||
///
|
||||
fn get_inner_assignee_type(
|
||||
table: &SymbolTable,
|
||||
type_: Type,
|
||||
accesses: Vec<AssigneeAccess>,
|
||||
span: Span,
|
||||
) -> Result<Type, StatementError> {
|
||||
match accesses.first() {
|
||||
None => Ok(type_),
|
||||
Some(access) => {
|
||||
// Check that we are correctly accessing the type
|
||||
let next_type = match (&type_, access) {
|
||||
(Type::Array(next_type, _), AssigneeAccess::Array(_)) => *next_type.clone(),
|
||||
(Type::Tuple(types), AssigneeAccess::Tuple(index)) => types[*index].clone(),
|
||||
(Type::Circuit(identifier), AssigneeAccess::Member(member)) => {
|
||||
let circuit_type_option = table.get_circuit(&identifier.name);
|
||||
|
||||
let circuit_type = match circuit_type_option {
|
||||
Some(circuit_type) => circuit_type,
|
||||
None => return Err(StatementError::undefined_circuit(identifier.clone())),
|
||||
};
|
||||
circuit_type.member_type(member)?.clone()
|
||||
}
|
||||
(type_, _) => return Err(StatementError::invalid_assign(type_, span)),
|
||||
};
|
||||
|
||||
return get_inner_assignee_type(table, next_type, accesses[1..].to_vec(), span);
|
||||
}
|
||||
}
|
||||
}
|
||||
// impl Statement {
|
||||
// ///
|
||||
// /// Resolves an assign statement
|
||||
// ///
|
||||
// pub(crate) fn assign(
|
||||
// frame: &Frame,
|
||||
// assignee: Assignee,
|
||||
// expression: UnresolvedExpression,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, StatementError> {
|
||||
// // Lookup variable in symbol table
|
||||
// let key = &assignee.identifier.name;
|
||||
// let variable = frame.variable_table.get(key, &span)?;
|
||||
//
|
||||
// // Throw an error if this variable is not mutable
|
||||
// if !variable.is_mutable() {
|
||||
// return Err(StatementError::immutable_assign(variable.identifier.name.clone(), span));
|
||||
// }
|
||||
//
|
||||
// // Get inner assignee type
|
||||
// let type_ = get_inner_assignee_type(frame, variable.type_.clone(), assignee.accesses.clone(), span.clone())?;
|
||||
//
|
||||
// // Resolve the expression based on the assignee type
|
||||
// let expression_resolved = Expression::new(variable_table, (Some(type_), expression))?;
|
||||
//
|
||||
// Ok(Statement::Assign(Assign {
|
||||
// assignee,
|
||||
// expression: expression_resolved,
|
||||
// span,
|
||||
// }))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// ///
|
||||
// /// Accesses the inner type of an assignee such as an array, tuple, or circuit member.
|
||||
// /// Returns an error for invalid accesses.
|
||||
// ///
|
||||
// fn get_inner_assignee_type(
|
||||
// frame: &Frame,
|
||||
// type_: Type,
|
||||
// accesses: Vec<AssigneeAccess>,
|
||||
// span: Span,
|
||||
// ) -> Result<Type, StatementError> {
|
||||
// match accesses.first() {
|
||||
// None => Ok(type_),
|
||||
// Some(access) => {
|
||||
// // Check that we are correctly accessing the type
|
||||
// let next_type = match (&type_, access) {
|
||||
// (Type::Array(next_type, _), AssigneeAccess::Array(_)) => *next_type.clone(),
|
||||
// (Type::Tuple(types), AssigneeAccess::Tuple(index)) => types[*index].clone(),
|
||||
// (Type::Circuit(identifier), AssigneeAccess::Member(member)) => {
|
||||
// let circuit_type_option = frame.get_circuit(&identifier.name);
|
||||
//
|
||||
// let circuit_type = match circuit_type_option {
|
||||
// Some(circuit_type) => circuit_type,
|
||||
// None => return Err(StatementError::undefined_circuit(identifier.clone())),
|
||||
// };
|
||||
// circuit_type.member_type(member)?.clone()
|
||||
// }
|
||||
// (type_, _) => return Err(StatementError::invalid_assign(type_, span)),
|
||||
// };
|
||||
//
|
||||
// return get_inner_assignee_type(frame, next_type, accesses[1..].to_vec(), span);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
@ -14,12 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, ResolvedNode, Statement, StatementError};
|
||||
use crate::{Expression, Frame, ResolvedNode, Statement, StatementError};
|
||||
use leo_static_check::{FunctionOutputType, SymbolTable, Type};
|
||||
use leo_typed::{
|
||||
ConditionalNestedOrEndStatement as UnresolvedNestedOrEnd,
|
||||
ConditionalStatement as UnresolvedConditional,
|
||||
Span,
|
||||
ConditionalNestedOrEndStatement as UnresolvedNestedOrEnd, ConditionalStatement as UnresolvedConditional, Span,
|
||||
Statement as UnresolvedStatement,
|
||||
};
|
||||
|
||||
@ -41,90 +39,90 @@ pub struct Conditional {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Conditional {
|
||||
///
|
||||
/// Resolves a conditional statement.
|
||||
///
|
||||
pub(crate) fn from_unresolved(
|
||||
table: &mut SymbolTable,
|
||||
return_type: FunctionOutputType,
|
||||
conditional: UnresolvedConditional,
|
||||
span: Span,
|
||||
) -> Result<Self, StatementError> {
|
||||
// Create child symbol table.
|
||||
let mut child_table = SymbolTable::new(Some(Box::new(table.clone())));
|
||||
// impl Conditional {
|
||||
// ///
|
||||
// /// Resolves a conditional statement.
|
||||
// ///
|
||||
// pub(crate) fn from_unresolved(
|
||||
// table: &mut SymbolTable,
|
||||
// return_type: FunctionOutputType,
|
||||
// conditional: UnresolvedConditional,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, StatementError> {
|
||||
// // Create child symbol table.
|
||||
// let mut child_table = SymbolTable::new(Some(Box::new(table.clone())));
|
||||
//
|
||||
// // Resolve the condition to a boolean.
|
||||
// let type_boolean = Some(Type::Boolean);
|
||||
// let condition_resolved = Expression::resolve(&mut child_table, (type_boolean, conditional.condition))?;
|
||||
//
|
||||
// // Resolve all statements.
|
||||
// let statements_resolved = resolve_statements(&mut child_table, return_type.clone(), conditional.statements)?;
|
||||
//
|
||||
// // Check for an `else if` or `else` clause.
|
||||
// let nested_or_end = match conditional.next {
|
||||
// Some(nested_or_end) => nested_or_end,
|
||||
// None => {
|
||||
// return Ok(Conditional {
|
||||
// condition: condition_resolved,
|
||||
// statements: statements_resolved,
|
||||
// next: None,
|
||||
// span,
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// // Evaluate the `else if` or `else` clause.
|
||||
// let next_resolved = match nested_or_end {
|
||||
// UnresolvedNestedOrEnd::Nested(conditional) => {
|
||||
// // Type check the `else if` clause.
|
||||
// let conditional_resolved =
|
||||
// Self::from_unresolved(table, return_type.clone(), *conditional, span.clone())?;
|
||||
//
|
||||
// ConditionalNestedOrEndStatement::Nested(Box::new(conditional_resolved))
|
||||
// }
|
||||
// UnresolvedNestedOrEnd::End(statements) => {
|
||||
// // Create child symbol table.
|
||||
// let mut child_table = SymbolTable::new(Some(Box::new(table.clone())));
|
||||
//
|
||||
// // Type check the `else` clause.
|
||||
// let statements_resolved = resolve_statements(&mut child_table, return_type, statements)?;
|
||||
//
|
||||
// ConditionalNestedOrEndStatement::End(statements_resolved)
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// Ok(Conditional {
|
||||
// condition: condition_resolved,
|
||||
// statements: statements_resolved,
|
||||
// next: Some(next_resolved),
|
||||
// span,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// Resolve the condition to a boolean.
|
||||
let type_boolean = Some(Type::Boolean);
|
||||
let condition_resolved = Expression::resolve(&mut child_table, (type_boolean, conditional.condition))?;
|
||||
// /// Resolve an array of statements.
|
||||
// fn resolve_statements(
|
||||
// table: &mut SymbolTable,
|
||||
// return_type: FunctionOutputType,
|
||||
// statements: Vec<UnresolvedStatement>,
|
||||
// ) -> Result<Vec<Statement>, StatementError> {
|
||||
// Ok(statements
|
||||
// .into_iter()
|
||||
// .map(|statement| Statement::resolve(table, (return_type.clone(), statement)))
|
||||
// .collect::<Result<Vec<_>, _>>()?)
|
||||
// }
|
||||
|
||||
// Resolve all statements.
|
||||
let statements_resolved = resolve_statements(&mut child_table, return_type.clone(), conditional.statements)?;
|
||||
|
||||
// Check for an `else if` or `else` clause.
|
||||
let nested_or_end = match conditional.next {
|
||||
Some(nested_or_end) => nested_or_end,
|
||||
None => {
|
||||
return Ok(Conditional {
|
||||
condition: condition_resolved,
|
||||
statements: statements_resolved,
|
||||
next: None,
|
||||
span,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Evaluate the `else if` or `else` clause.
|
||||
let next_resolved = match nested_or_end {
|
||||
UnresolvedNestedOrEnd::Nested(conditional) => {
|
||||
// Type check the `else if` clause.
|
||||
let conditional_resolved =
|
||||
Self::from_unresolved(table, return_type.clone(), *conditional, span.clone())?;
|
||||
|
||||
ConditionalNestedOrEndStatement::Nested(Box::new(conditional_resolved))
|
||||
}
|
||||
UnresolvedNestedOrEnd::End(statements) => {
|
||||
// Create child symbol table.
|
||||
let mut child_table = SymbolTable::new(Some(Box::new(table.clone())));
|
||||
|
||||
// Type check the `else` clause.
|
||||
let statements_resolved = resolve_statements(&mut child_table, return_type, statements)?;
|
||||
|
||||
ConditionalNestedOrEndStatement::End(statements_resolved)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Conditional {
|
||||
condition: condition_resolved,
|
||||
statements: statements_resolved,
|
||||
next: Some(next_resolved),
|
||||
span,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve an array of statements.
|
||||
fn resolve_statements(
|
||||
table: &mut SymbolTable,
|
||||
return_type: FunctionOutputType,
|
||||
statements: Vec<UnresolvedStatement>,
|
||||
) -> Result<Vec<Statement>, StatementError> {
|
||||
Ok(statements
|
||||
.into_iter()
|
||||
.map(|statement| Statement::resolve(table, (return_type.clone(), statement)))
|
||||
.collect::<Result<Vec<_>, _>>()?)
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
/// Resolves a conditional statement.
|
||||
pub(crate) fn conditional(
|
||||
function_body: &function_body,
|
||||
return_type: FunctionOutputType,
|
||||
conditional: UnresolvedConditional,
|
||||
span: Span,
|
||||
) -> Result<Self, StatementError> {
|
||||
let conditional = Conditional::from_unresolved(function_body, return_type, conditional, span)?;
|
||||
|
||||
Ok(Statement::Conditional(conditional))
|
||||
}
|
||||
}
|
||||
// impl Statement {
|
||||
// /// Resolves a conditional statement.
|
||||
// pub(crate) fn conditional(
|
||||
// function_body: &Frame,
|
||||
// return_type: FunctionOutputType,
|
||||
// conditional: UnresolvedConditional,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, StatementError> {
|
||||
// let conditional = Conditional::from_unresolved(function_body, return_type, conditional, span)?;
|
||||
//
|
||||
// Ok(Statement::Conditional(conditional))
|
||||
// }
|
||||
// }
|
||||
|
@ -15,14 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
check_tuple_type,
|
||||
Expression,
|
||||
ExpressionValue,
|
||||
Frame,
|
||||
ResolvedNode,
|
||||
Statement,
|
||||
StatementError,
|
||||
VariableTable,
|
||||
check_tuple_type, Expression, ExpressionValue, Frame, ResolvedNode, Statement, StatementError, VariableTable,
|
||||
VariableTableError,
|
||||
};
|
||||
use leo_static_check::{Attribute, ParameterType, SymbolTable, Type};
|
||||
@ -106,11 +99,14 @@ impl DefinitionVariables {
|
||||
}
|
||||
|
||||
// Get the type of each variable.
|
||||
let variable_types = variables
|
||||
let variable_types: Vec<Type> = variables
|
||||
.names
|
||||
.iter()
|
||||
.map(|variable_name| function_body.variable_table.get(variable_name.name_string(), span))
|
||||
.collect::<Result<Vec<Type>, VariableTableError>>()?;
|
||||
.collect::<Result<Vec<&Type>, VariableTableError>>()?
|
||||
.into_iter()
|
||||
.map(|type_ref| type_ref.clone())
|
||||
.collect();
|
||||
|
||||
// Create a new vector of `Expression`s from the given vector of `UnresolvedExpression`s.
|
||||
let mut expressions_resolved = vec![];
|
||||
@ -135,11 +131,14 @@ impl DefinitionVariables {
|
||||
span: &Span,
|
||||
) -> Result<Self, StatementError> {
|
||||
// Get the type of each variable.
|
||||
let variable_types = variables
|
||||
let variable_types: Vec<Type> = variables
|
||||
.names
|
||||
.iter()
|
||||
.map(|variable_name| function_body.variable_table.get(variable_name.name_string(), span))
|
||||
.collect::<Result<Vec<Type>, VariableTableError>>()?;
|
||||
.collect::<Result<Vec<&Type>, VariableTableError>>()?
|
||||
.into_iter()
|
||||
.map(|type_ref| type_ref.clone())
|
||||
.collect();
|
||||
|
||||
// Create a new tuple type from the vector of variable types.
|
||||
let tuple_type = Type::Tuple(variable_types);
|
||||
@ -152,39 +151,39 @@ impl DefinitionVariables {
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts a variable definition into the given symbol table
|
||||
fn insert_defined_variable(
|
||||
table: &mut SymbolTable,
|
||||
variable: &VariableName,
|
||||
type_: &Type,
|
||||
span: Span,
|
||||
) -> Result<(), StatementError> {
|
||||
let attributes = if variable.mutable {
|
||||
vec![Attribute::Mutable]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
// Insert variable into symbol table
|
||||
let key = variable.identifier.name.clone();
|
||||
let value = ParameterType {
|
||||
identifier: variable.identifier.clone(),
|
||||
type_: type_.clone(),
|
||||
attributes,
|
||||
};
|
||||
|
||||
// Check that variable name was not defined twice
|
||||
let duplicate = table.insert_name(key, value);
|
||||
|
||||
if duplicate.is_some() {
|
||||
return Err(StatementError::duplicate_variable(
|
||||
variable.identifier.name.clone(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// /// Inserts a variable definition into the given symbol table
|
||||
// fn insert_defined_variable(
|
||||
// table: &mut SymbolTable,
|
||||
// variable: &VariableName,
|
||||
// type_: &Type,
|
||||
// span: Span,
|
||||
// ) -> Result<(), StatementError> {
|
||||
// let attributes = if variable.mutable {
|
||||
// vec![Attribute::Mutable]
|
||||
// } else {
|
||||
// vec![]
|
||||
// };
|
||||
//
|
||||
// // Insert variable into symbol table
|
||||
// let key = variable.identifier.name.clone();
|
||||
// let value = ParameterType {
|
||||
// identifier: variable.identifier.clone(),
|
||||
// type_: type_.clone(),
|
||||
// attributes,
|
||||
// };
|
||||
//
|
||||
// // Check that variable name was not defined twice
|
||||
// let duplicate = table.insert_name(key, value);
|
||||
//
|
||||
// if duplicate.is_some() {
|
||||
// return Err(StatementError::duplicate_variable(
|
||||
// variable.identifier.name.clone(),
|
||||
// span,
|
||||
// ));
|
||||
// }
|
||||
//
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
impl Statement {
|
||||
///
|
||||
|
@ -29,47 +29,47 @@ pub struct Iteration {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
/// Resolve an iteration statement
|
||||
pub(crate) fn iteration(
|
||||
table: &mut SymbolTable,
|
||||
return_type: FunctionOutputType,
|
||||
index: Identifier,
|
||||
start: UnresolvedExpression,
|
||||
stop: UnresolvedExpression,
|
||||
statements: Vec<UnresolvedStatement>,
|
||||
span: Span,
|
||||
) -> Result<Self, StatementError> {
|
||||
// TODO: Create child symbol table and add variables from parent
|
||||
|
||||
// Resolve index numbers to a u32 type
|
||||
let type_number = Type::IntegerType(IntegerType::U32);
|
||||
|
||||
let start_resolved = Expression::resolve(table, (Some(type_number.clone()), start))?;
|
||||
let stop_resolved = Expression::resolve(table, (Some(type_number.clone()), stop))?;
|
||||
|
||||
// Add index to symbol table
|
||||
let key = index.name.clone();
|
||||
let value = ParameterType {
|
||||
identifier: index.clone(),
|
||||
type_: type_number,
|
||||
attributes: vec![],
|
||||
};
|
||||
|
||||
table.insert_name(key, value);
|
||||
|
||||
// Resolve statements
|
||||
let statements_resolved = statements
|
||||
.into_iter()
|
||||
.map(|statement| Statement::resolve(table, (return_type.clone(), statement)))
|
||||
.collect::<Result<Vec<Statement>, _>>()?;
|
||||
|
||||
Ok(Statement::Iteration(Iteration {
|
||||
index,
|
||||
start: start_resolved,
|
||||
stop: stop_resolved,
|
||||
statements: statements_resolved,
|
||||
span,
|
||||
}))
|
||||
}
|
||||
}
|
||||
// impl Statement {
|
||||
// /// Resolve an iteration statement
|
||||
// pub(crate) fn iteration(
|
||||
// table: &mut SymbolTable,
|
||||
// return_type: FunctionOutputType,
|
||||
// index: Identifier,
|
||||
// start: UnresolvedExpression,
|
||||
// stop: UnresolvedExpression,
|
||||
// statements: Vec<UnresolvedStatement>,
|
||||
// span: Span,
|
||||
// ) -> Result<Self, StatementError> {
|
||||
// // TODO: Create child symbol table and add variables from parent
|
||||
//
|
||||
// // Resolve index numbers to a u32 type
|
||||
// let type_number = Type::IntegerType(IntegerType::U32);
|
||||
//
|
||||
// let start_resolved = Expression::resolve(table, (Some(type_number.clone()), start))?;
|
||||
// let stop_resolved = Expression::resolve(table, (Some(type_number.clone()), stop))?;
|
||||
//
|
||||
// // Add index to symbol table
|
||||
// let key = index.name.clone();
|
||||
// let value = ParameterType {
|
||||
// identifier: index.clone(),
|
||||
// type_: type_number,
|
||||
// attributes: vec![],
|
||||
// };
|
||||
//
|
||||
// table.insert_name(key, value);
|
||||
//
|
||||
// // Resolve statements
|
||||
// let statements_resolved = statements
|
||||
// .into_iter()
|
||||
// .map(|statement| Statement::resolve(table, (return_type.clone(), statement)))
|
||||
// .collect::<Result<Vec<Statement>, _>>()?;
|
||||
//
|
||||
// Ok(Statement::Iteration(Iteration {
|
||||
// index,
|
||||
// start: start_resolved,
|
||||
// stop: stop_resolved,
|
||||
// statements: statements_resolved,
|
||||
// span,
|
||||
// }))
|
||||
// }
|
||||
// }
|
||||
|
@ -29,8 +29,11 @@ impl Statement {
|
||||
unresolved_expression: UnresolvedExpression,
|
||||
span: Span,
|
||||
) -> Result<Self, StatementError> {
|
||||
// Get function return type from frame.
|
||||
let return_type = &function_body.function_type.output.type_;
|
||||
|
||||
// Create a new `Expression` from the unresolved return expression
|
||||
let expression = Expression::new(function_body, unresolved_expression)?;
|
||||
let expression = Expression::new(function_body, return_type, unresolved_expression)?;
|
||||
|
||||
Ok(Statement::Return(expression, span))
|
||||
}
|
||||
|
@ -14,15 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
use crate::{
|
||||
Assign,
|
||||
Conditional,
|
||||
Definition,
|
||||
Expression,
|
||||
Frame,
|
||||
Iteration,
|
||||
ResolvedNode,
|
||||
StatementError,
|
||||
VariableTable,
|
||||
Assign, Conditional, Definition, Expression, Frame, Iteration, ResolvedNode, StatementError, VariableTable,
|
||||
};
|
||||
use leo_static_check::{FunctionOutputType, FunctionType, SymbolTable};
|
||||
use leo_typed::{ConsoleFunctionCall, Span, Statement as UnresolvedStatement};
|
||||
@ -54,17 +46,18 @@ impl Statement {
|
||||
UnresolvedStatement::Definition(declare, variables, expressions, span) => {
|
||||
Self::definition(frame, declare, variables, expressions, span)
|
||||
}
|
||||
UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(frame, assignee, expression, span),
|
||||
UnresolvedStatement::Conditional(conditional, span) => {
|
||||
Self::conditional(frame, return_type, conditional, span)
|
||||
}
|
||||
UnresolvedStatement::Iteration(index, start, stop, statements, span) => {
|
||||
Self::iteration(frame, return_type, index, start, stop, statements, span)
|
||||
}
|
||||
UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)),
|
||||
UnresolvedStatement::Expression(expression, span) => {
|
||||
Ok(Statement::Expression(Expression::new(frame, expression)?, span))
|
||||
}
|
||||
// UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(frame, assignee, expression, span),
|
||||
// UnresolvedStatement::Conditional(conditional, span) => {
|
||||
// Self::conditional(frame, return_type, conditional, span)
|
||||
// }
|
||||
// UnresolvedStatement::Iteration(index, start, stop, statements, span) => {
|
||||
// Self::iteration(frame, return_type, index, start, stop, statements, span)
|
||||
// }
|
||||
// UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)),
|
||||
// UnresolvedStatement::Expression(expression, span) => {
|
||||
// Ok(Statement::Expression(Expression::new(frame, expression)?, span))
|
||||
// }
|
||||
_ => unimplemented!("statement not implemented"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,29 +67,30 @@ impl ResolvedNode for Statement {
|
||||
type UnresolvedNode = (FunctionOutputType, UnresolvedStatement);
|
||||
|
||||
/// Type check a statement inside a program AST
|
||||
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
|
||||
let return_type = unresolved.0;
|
||||
let statement = unresolved.1;
|
||||
|
||||
match statement {
|
||||
UnresolvedStatement::Return(expression, span) => {
|
||||
Self::resolve_return(table, return_type.type_, expression, span)
|
||||
}
|
||||
UnresolvedStatement::Definition(declare, variables, expressions, span) => {
|
||||
Self::definition(table, declare, variables, expressions, span)
|
||||
}
|
||||
UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(table, assignee, expression, span),
|
||||
UnresolvedStatement::Conditional(conditional, span) => {
|
||||
Self::conditional(table, return_type, conditional, span)
|
||||
}
|
||||
UnresolvedStatement::Iteration(index, start, stop, statements, span) => {
|
||||
Self::iteration(table, return_type, index, start, stop, statements, span)
|
||||
}
|
||||
UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)),
|
||||
UnresolvedStatement::Expression(expression, span) => Ok(Statement::Expression(
|
||||
Expression::resolve(table, (None, expression))?,
|
||||
span,
|
||||
)),
|
||||
}
|
||||
fn resolve(_table: &mut SymbolTable, _unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
|
||||
// let return_type = unresolved.0;
|
||||
// let statement = unresolved.1;
|
||||
//
|
||||
// match statement {
|
||||
// // UnresolvedStatement::Return(expression, span) => {
|
||||
// // Self::resolve_return(table, return_type.type_, expression, span)
|
||||
// // }
|
||||
// // UnresolvedStatement::Definition(declare, variables, expressions, span) => {
|
||||
// // Self::definition(table, declare, variables, expressions, span)
|
||||
// // }
|
||||
// // UnresolvedStatement::Assign(assignee, expression, span) => Self::assign(table, assignee, expression, span),
|
||||
// // UnresolvedStatement::Conditional(conditional, span) => {
|
||||
// // Self::conditional(table, return_type, conditional, span)
|
||||
// // }
|
||||
// // UnresolvedStatement::Iteration(index, start, stop, statements, span) => {
|
||||
// // Self::iteration(table, return_type, index, start, stop, statements, span)
|
||||
// // }
|
||||
// // UnresolvedStatement::Console(console_function_call) => Ok(Statement::Console(console_function_call)),
|
||||
// // UnresolvedStatement::Expression(expression, span) => Ok(Statement::Expression(
|
||||
// // Expression::resolve(table, (None, expression))?,
|
||||
// // span,
|
||||
// // )),
|
||||
// }
|
||||
unimplemented!("statement resolve deprecated");
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{DynamicCheckError, Function, FunctionError, LeoResolvedAst, VariableTableError};
|
||||
use crate::{DynamicCheckError, FrameError, VariableTableError};
|
||||
use leo_static_check::{FunctionInputType, FunctionType, SymbolTable, Type, TypeVariable};
|
||||
use leo_typed::{
|
||||
Expression,
|
||||
@ -26,7 +26,7 @@ use leo_typed::{
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
/// Performs a dynamic type inference check over a program.
|
||||
pub struct DynamicCheck {
|
||||
@ -87,12 +87,12 @@ impl DynamicCheck {
|
||||
/// Returns a `LeoResolvedAst` if all `TypeAssertion` predicates are true.
|
||||
/// Returns ERROR if a `TypeAssertion` predicate is false or a solution does not exist.
|
||||
///
|
||||
pub fn solve(self) -> Result<LeoResolvedAst, DynamicCheckError> {
|
||||
pub fn solve(self) -> Result<(), DynamicCheckError> {
|
||||
for function_body in self.functions {
|
||||
function_body.solve();
|
||||
function_body.solve()?;
|
||||
}
|
||||
|
||||
Ok(LeoResolvedAst::new())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,8 +142,8 @@ impl Frame {
|
||||
/// Collects a vector of `TypeAssertion` predicates from a vector of statements.
|
||||
///
|
||||
fn parse_statements(&mut self) {
|
||||
for statement in &self.statements {
|
||||
self.parse_statement(statement);
|
||||
for statement in self.statements.clone() {
|
||||
self.parse_statement(&statement);
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,7 +309,7 @@ impl Frame {
|
||||
///
|
||||
/// Returns a new `Function` if all `TypeAssertions` can be solved successfully.
|
||||
///
|
||||
fn solve(self) -> Result<Function, FunctionError> {
|
||||
fn solve(self) -> Result<(), FrameError> {
|
||||
let mut unsolved = self.type_assertions.clone();
|
||||
|
||||
while !unsolved.is_empty() {
|
||||
@ -337,7 +337,9 @@ impl Frame {
|
||||
// }
|
||||
|
||||
// Return a new resolved function struct.
|
||||
Function::new(self)
|
||||
// Function::new(self)
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ExpressionError, FunctionError, ProgramError, StatementError};
|
||||
// use crate::{ExpressionError, FunctionError, ProgramError, StatementError};
|
||||
use crate::FrameError;
|
||||
use leo_typed::Error as FormattedError;
|
||||
|
||||
use std::path::PathBuf;
|
||||
@ -26,16 +27,19 @@ pub enum DynamicCheckError {
|
||||
Error(#[from] FormattedError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ExpressionError(#[from] ExpressionError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FunctionError(#[from] FunctionError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
StatementError(#[from] StatementError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ProgramError(#[from] ProgramError),
|
||||
FrameError(#[from] FrameError),
|
||||
//
|
||||
// #[error("{}", _0)]
|
||||
// ExpressionError(#[from] ExpressionError),
|
||||
//
|
||||
// #[error("{}", _0)]
|
||||
// FunctionError(#[from] FunctionError),
|
||||
//
|
||||
// #[error("{}", _0)]
|
||||
// StatementError(#[from] StatementError),
|
||||
//
|
||||
// #[error("{}", _0)]
|
||||
// ProgramError(#[from] ProgramError),
|
||||
}
|
||||
|
||||
impl DynamicCheckError {
|
||||
@ -43,10 +47,11 @@ impl DynamicCheckError {
|
||||
pub fn set_path(&mut self, path: PathBuf) {
|
||||
match self {
|
||||
DynamicCheckError::Error(error) => error.set_path(path),
|
||||
DynamicCheckError::ExpressionError(error) => error.set_path(path),
|
||||
DynamicCheckError::FunctionError(error) => error.set_path(path),
|
||||
DynamicCheckError::StatementError(error) => error.set_path(path),
|
||||
DynamicCheckError::ProgramError(error) => error.set_path(path),
|
||||
DynamicCheckError::FrameError(error) => error.set_path(path),
|
||||
// DynamicCheckError::ExpressionError(error) => error.set_path(path),
|
||||
// DynamicCheckError::FunctionError(error) => error.set_path(path),
|
||||
// DynamicCheckError::StatementError(error) => error.set_path(path),
|
||||
// DynamicCheckError::ProgramError(error) => error.set_path(path),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ impl ExpressionError {
|
||||
match self {
|
||||
ExpressionError::Error(error) => error.set_path(path),
|
||||
ExpressionError::TypeError(error) => error.set_path(path),
|
||||
ExpressionError::VariableTableError(error) => error.set_path(path),
|
||||
}
|
||||
}
|
||||
|
||||
|
44
dynamic-check/src/errors/frame.rs
Normal file
44
dynamic-check/src/errors/frame.rs
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_typed::{Error as FormattedError, Span};
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Errors encountered when tracking variable names in a program.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FrameError {
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] FormattedError),
|
||||
}
|
||||
|
||||
impl FrameError {
|
||||
///
|
||||
/// Set the filepath for the error stacktrace
|
||||
///
|
||||
pub fn set_path(&mut self, path: PathBuf) {
|
||||
match self {
|
||||
FrameError::Error(error) => error.set_path(path),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Return a new formatted error with a given message and span information
|
||||
///
|
||||
fn new_from_span(message: String, span: Span) -> Self {
|
||||
FrameError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
}
|
@ -14,32 +14,29 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod circuit;
|
||||
pub use self::circuit::*;
|
||||
// pub mod circuit;
|
||||
// pub use self::circuit::*;
|
||||
|
||||
pub mod dynamic_check;
|
||||
pub use self::dynamic_check::*;
|
||||
|
||||
pub mod expression;
|
||||
pub use self::expression::*;
|
||||
pub mod frame;
|
||||
pub use self::frame::*;
|
||||
|
||||
pub mod function;
|
||||
pub use self::function::*;
|
||||
|
||||
pub mod program;
|
||||
pub use self::program::*;
|
||||
|
||||
pub mod resolver;
|
||||
pub use self::resolver::*;
|
||||
|
||||
pub mod statement;
|
||||
pub use self::statement::*;
|
||||
// pub mod expression;
|
||||
// pub use self::expression::*;
|
||||
//
|
||||
// pub mod function;
|
||||
// pub use self::function::*;
|
||||
//
|
||||
// pub mod program;
|
||||
// pub use self::program::*;
|
||||
//
|
||||
// pub mod resolver;
|
||||
// pub use self::resolver::*;
|
||||
//
|
||||
// pub mod statement;
|
||||
// pub use self::statement::*;
|
||||
|
||||
pub mod variable_table;
|
||||
pub use self::variable_table::*;
|
||||
|
||||
// pub mod symbol_table;
|
||||
// pub use self::symbol_table::*;
|
||||
|
||||
// pub mod type_;
|
||||
// pub use self::type_::*;
|
||||
|
@ -17,8 +17,8 @@
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
pub mod ast;
|
||||
pub use self::ast::*;
|
||||
// pub mod ast;
|
||||
// pub use self::ast::*;
|
||||
|
||||
pub mod dynamic_check;
|
||||
pub use self::dynamic_check::*;
|
||||
|
Loading…
Reference in New Issue
Block a user