mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-01 18:56:38 +03:00
enforce explicit types in defnitions and arrays
This commit is contained in:
parent
9e163428a9
commit
59cf617a08
@ -1,10 +1,8 @@
|
|||||||
function test() -> (u32, u32) {
|
function main() -> (u32[3]) {
|
||||||
return 4, 4
|
a = [1, 2]
|
||||||
}
|
c = 3
|
||||||
|
u32[3] b = [...a, c]
|
||||||
function main() -> (u32, u32) {
|
|
||||||
a, b = test()
|
return b
|
||||||
|
|
||||||
return a, b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! Methods to enforce constraints a resolved aleo program.
|
//! Methods to enforce constraints and construct a resolved aleo program.
|
||||||
|
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
use crate::constraints::{new_scope_from_variable, ResolvedProgram, ResolvedValue};
|
use crate::constraints::{new_scope_from_variable, ResolvedProgram, ResolvedValue};
|
||||||
@ -98,13 +98,26 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
function.returns.to_owned(),
|
function.returns.to_owned(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Statement::MultipleDefinition(assignees, function_call) => self
|
Statement::Assign(variable, expression) => {
|
||||||
.enforce_multiple_definition_statement(
|
self.enforce_assign_statement(cs, function.get_name(), variable, expression);
|
||||||
|
}
|
||||||
|
Statement::Definition(ty, assignee, expression) => {
|
||||||
|
self.enforce_definition_statement(
|
||||||
|
cs,
|
||||||
|
function.get_name(),
|
||||||
|
ty,
|
||||||
|
assignee,
|
||||||
|
expression,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Statement::MultipleDefinition(assignees, function_call) => {
|
||||||
|
self.enforce_multiple_definition_statement(
|
||||||
cs,
|
cs,
|
||||||
function.get_name(),
|
function.get_name(),
|
||||||
assignees,
|
assignees,
|
||||||
function_call,
|
function_call,
|
||||||
),
|
);
|
||||||
|
}
|
||||||
Statement::For(index, start, stop, statements) => {
|
Statement::For(index, start, stop, statements) => {
|
||||||
self.enforce_for_statement(
|
self.enforce_for_statement(
|
||||||
cs,
|
cs,
|
||||||
@ -115,14 +128,6 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
statements,
|
statements,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Statement::Definition(variable, expression) => {
|
|
||||||
self.enforce_definition_statement(
|
|
||||||
cs,
|
|
||||||
function.get_name(),
|
|
||||||
variable,
|
|
||||||
expression,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return_values
|
return_values
|
||||||
@ -140,9 +145,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
.for_each(|(i, parameter)| {
|
.for_each(|(i, parameter)| {
|
||||||
// append each variable to arguments vector
|
// append each variable to arguments vector
|
||||||
arguments.push(Expression::Variable(match parameter.ty {
|
arguments.push(Expression::Variable(match parameter.ty {
|
||||||
Type::U32 => {
|
Type::U32 => self.u32_from_parameter(cs, function.get_name(), i + 1, parameter),
|
||||||
self.integer_from_parameter(cs, function.get_name(), i + 1, parameter)
|
|
||||||
}
|
|
||||||
Type::FieldElement => {
|
Type::FieldElement => {
|
||||||
self.field_element_from_parameter(cs, function.get_name(), i + 1, parameter)
|
self.field_element_from_parameter(cs, function.get_name(), i + 1, parameter)
|
||||||
}
|
}
|
||||||
@ -150,12 +153,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
self.bool_from_parameter(cs, function.get_name(), i + 1, parameter)
|
self.bool_from_parameter(cs, function.get_name(), i + 1, parameter)
|
||||||
}
|
}
|
||||||
Type::Array(ref ty, _length) => match *ty.clone() {
|
Type::Array(ref ty, _length) => match *ty.clone() {
|
||||||
Type::U32 => self.integer_array_from_parameter(
|
Type::U32 => {
|
||||||
cs,
|
self.u32_array_from_parameter(cs, function.get_name(), i + 1, parameter)
|
||||||
function.get_name(),
|
}
|
||||||
i + 1,
|
|
||||||
parameter,
|
|
||||||
),
|
|
||||||
Type::FieldElement => self.field_element_array_from_parameter(
|
Type::FieldElement => self.field_element_array_from_parameter(
|
||||||
cs,
|
cs,
|
||||||
function.get_name(),
|
function.get_name(),
|
||||||
|
@ -10,7 +10,7 @@ use snarkos_models::gadgets::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||||
pub(crate) fn integer_from_parameter(
|
pub(crate) fn u32_from_parameter(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
scope: String,
|
scope: String,
|
||||||
@ -46,7 +46,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
parameter_variable
|
parameter_variable
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn integer_array_from_parameter(
|
pub(crate) fn u32_array_from_parameter(
|
||||||
&mut self,
|
&mut self,
|
||||||
_cs: &mut CS,
|
_cs: &mut CS,
|
||||||
_scope: String,
|
_scope: String,
|
||||||
|
@ -27,7 +27,15 @@ impl<F: Field + PrimeField> ResolvedValue<F> {
|
|||||||
(ResolvedValue::U32(ref _a), Type::U32) => true,
|
(ResolvedValue::U32(ref _a), Type::U32) => true,
|
||||||
(ResolvedValue::FieldElement(ref _a), Type::FieldElement) => true,
|
(ResolvedValue::FieldElement(ref _a), Type::FieldElement) => true,
|
||||||
(ResolvedValue::Boolean(ref _a), Type::Boolean) => true,
|
(ResolvedValue::Boolean(ref _a), Type::Boolean) => true,
|
||||||
(ResolvedValue::Array(ref arr), Type::Array(ref _ty, ref len)) => arr.len() == *len, // todo: add array types
|
(ResolvedValue::Array(ref arr), Type::Array(ref ty, ref len)) => {
|
||||||
|
// check array lengths are equal
|
||||||
|
let mut res = arr.len() == *len;
|
||||||
|
// check each value in array matches
|
||||||
|
for value in arr {
|
||||||
|
res &= value.match_type(ty)
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
(
|
(
|
||||||
ResolvedValue::StructExpression(ref actual_name, ref _members),
|
ResolvedValue::StructExpression(ref actual_name, ref _members),
|
||||||
Type::Struct(ref expected_name),
|
Type::Struct(ref expected_name),
|
||||||
|
@ -17,7 +17,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enforce_definition(
|
fn store_assignment(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
scope: String,
|
scope: String,
|
||||||
@ -117,7 +117,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enforce_definition_statement(
|
pub(crate) fn enforce_assign_statement(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
scope: String,
|
scope: String,
|
||||||
@ -126,7 +126,24 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
) {
|
) {
|
||||||
let result_value = &mut self.enforce_expression(cs, scope.clone(), expression);
|
let result_value = &mut self.enforce_expression(cs, scope.clone(), expression);
|
||||||
|
|
||||||
self.enforce_definition(cs, scope, assignee, result_value);
|
self.store_assignment(cs, scope, assignee, result_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn enforce_definition_statement(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
scope: String,
|
||||||
|
ty: Type<F>,
|
||||||
|
assignee: Assignee<F>,
|
||||||
|
expression: Expression<F>,
|
||||||
|
) {
|
||||||
|
let result_value = &mut self.enforce_expression(cs, scope.clone(), expression);
|
||||||
|
|
||||||
|
if result_value.match_type(&ty) {
|
||||||
|
self.store_assignment(cs, scope, assignee, result_value);
|
||||||
|
} else {
|
||||||
|
unimplemented!("incompatible types {} = {}", assignee, result_value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enforce_multiple_definition_statement(
|
pub(crate) fn enforce_multiple_definition_statement(
|
||||||
@ -149,7 +166,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(return_values.into_iter())
|
.zip(return_values.into_iter())
|
||||||
.for_each(|(assignee, mut return_value)| {
|
.for_each(|(assignee, mut return_value)| {
|
||||||
self.enforce_definition(cs, scope.clone(), assignee, &mut return_value);
|
self.store_assignment(cs, scope.clone(), assignee, &mut return_value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,14 +205,17 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
|||||||
// TODO: add support for early termination
|
// TODO: add support for early termination
|
||||||
let _res = self.enforce_return_statement(cs, scope, statements, return_types);
|
let _res = self.enforce_return_statement(cs, scope, statements, return_types);
|
||||||
}
|
}
|
||||||
Statement::For(index, start, stop, statements) => {
|
Statement::Assign(variable, expression) => {
|
||||||
self.enforce_for_statement(cs, scope, index, start, stop, statements);
|
self.enforce_assign_statement(cs, scope, variable, expression);
|
||||||
|
}
|
||||||
|
Statement::Definition(ty, assignee, expression) => {
|
||||||
|
self.enforce_definition_statement(cs, scope, ty, assignee, expression);
|
||||||
}
|
}
|
||||||
Statement::MultipleDefinition(assignees, function) => {
|
Statement::MultipleDefinition(assignees, function) => {
|
||||||
self.enforce_multiple_definition_statement(cs, scope, assignees, function);
|
self.enforce_multiple_definition_statement(cs, scope, assignees, function);
|
||||||
}
|
}
|
||||||
Statement::Definition(variable, expression) => {
|
Statement::For(index, start, stop, statements) => {
|
||||||
self.enforce_definition_statement(cs, scope, variable, expression);
|
self.enforce_for_statement(cs, scope, index, start, stop, statements);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -97,17 +97,7 @@ pub enum Assignee<F: Field + PrimeField> {
|
|||||||
StructMember(Box<Assignee<F>>, Variable<F>),
|
StructMember(Box<Assignee<F>>, Variable<F>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Program statement that defines some action (or expression) to be carried out.
|
/// Explicit type used for defining a variable or expression type
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum Statement<F: Field + PrimeField> {
|
|
||||||
// Declaration(Variable),
|
|
||||||
Return(Vec<Expression<F>>),
|
|
||||||
Definition(Assignee<F>, Expression<F>),
|
|
||||||
For(Variable<F>, Integer, Integer, Vec<Statement<F>>),
|
|
||||||
MultipleDefinition(Vec<Assignee<F>>, Expression<F>),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Explicit type used for defining struct members and function parameters
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Type<F: Field + PrimeField> {
|
pub enum Type<F: Field + PrimeField> {
|
||||||
U32,
|
U32,
|
||||||
@ -117,6 +107,17 @@ pub enum Type<F: Field + PrimeField> {
|
|||||||
Struct(Variable<F>),
|
Struct(Variable<F>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Program statement that defines some action (or expression) to be carried out.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum Statement<F: Field + PrimeField> {
|
||||||
|
// Declaration(Variable),
|
||||||
|
Return(Vec<Expression<F>>),
|
||||||
|
Assign(Assignee<F>, Expression<F>),
|
||||||
|
Definition(Type<F>, Assignee<F>, Expression<F>),
|
||||||
|
MultipleDefinition(Vec<Assignee<F>>, Expression<F>),
|
||||||
|
For(Variable<F>, Integer, Integer, Vec<Statement<F>>),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct StructMember<F: Field + PrimeField> {
|
pub struct StructMember<F: Field + PrimeField> {
|
||||||
pub variable: Variable<F>,
|
pub variable: Variable<F>,
|
||||||
|
@ -151,6 +151,12 @@ impl<F: Field + PrimeField> fmt::Display for Statement<F> {
|
|||||||
}
|
}
|
||||||
write!(f, "\n")
|
write!(f, "\n")
|
||||||
}
|
}
|
||||||
|
Statement::Assign(ref variable, ref statement) => {
|
||||||
|
write!(f, "{} = {}", variable, statement)
|
||||||
|
}
|
||||||
|
Statement::Definition(ref ty, ref assignee, ref statement) => {
|
||||||
|
write!(f, "{} {} = {}", ty, assignee, statement)
|
||||||
|
}
|
||||||
Statement::MultipleDefinition(ref assignees, ref function) => {
|
Statement::MultipleDefinition(ref assignees, ref function) => {
|
||||||
for (i, id) in assignees.iter().enumerate() {
|
for (i, id) in assignees.iter().enumerate() {
|
||||||
write!(f, "{}", id)?;
|
write!(f, "{}", id)?;
|
||||||
@ -167,9 +173,6 @@ impl<F: Field + PrimeField> fmt::Display for Statement<F> {
|
|||||||
}
|
}
|
||||||
write!(f, "\tendfor")
|
write!(f, "\tendfor")
|
||||||
}
|
}
|
||||||
Statement::Definition(ref variable, ref statement) => {
|
|
||||||
write!(f, "{} = {}", variable, statement)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,6 +190,12 @@ impl<F: Field + PrimeField> fmt::Debug for Statement<F> {
|
|||||||
}
|
}
|
||||||
write!(f, "\n")
|
write!(f, "\n")
|
||||||
}
|
}
|
||||||
|
Statement::Assign(ref variable, ref statement) => {
|
||||||
|
write!(f, "{} = {}", variable, statement)
|
||||||
|
}
|
||||||
|
Statement::Definition(ref ty, ref assignee, ref statement) => {
|
||||||
|
write!(f, "{} {} = {}", ty, assignee, statement)
|
||||||
|
}
|
||||||
Statement::MultipleDefinition(ref assignees, ref function) => {
|
Statement::MultipleDefinition(ref assignees, ref function) => {
|
||||||
for (i, id) in assignees.iter().enumerate() {
|
for (i, id) in assignees.iter().enumerate() {
|
||||||
write!(f, "{}", id)?;
|
write!(f, "{}", id)?;
|
||||||
@ -203,9 +212,6 @@ impl<F: Field + PrimeField> fmt::Debug for Statement<F> {
|
|||||||
}
|
}
|
||||||
write!(f, "\tendfor")
|
write!(f, "\tendfor")
|
||||||
}
|
}
|
||||||
Statement::Definition(ref variable, ref statement) => {
|
|
||||||
write!(f, "{} = {}", variable, statement)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +192,50 @@ impl<'ast, F: Field + PrimeField> From<ast::TernaryExpression<'ast>> for types::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'ast, F: Field + PrimeField> From<ast::ArrayInlineExpression<'ast>> for types::Expression<F> {
|
||||||
|
fn from(array: ast::ArrayInlineExpression<'ast>) -> Self {
|
||||||
|
types::Expression::Array(
|
||||||
|
array
|
||||||
|
.expressions
|
||||||
|
.into_iter()
|
||||||
|
.map(|s_or_e| Box::new(types::SpreadOrExpression::from(s_or_e)))
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast, F: Field + PrimeField> From<ast::ArrayInitializerExpression<'ast>>
|
||||||
|
for types::Expression<F>
|
||||||
|
{
|
||||||
|
fn from(array: ast::ArrayInitializerExpression<'ast>) -> Self {
|
||||||
|
let count = types::Expression::<F>::get_count(array.count);
|
||||||
|
let expression = Box::new(types::SpreadOrExpression::from(*array.expression));
|
||||||
|
|
||||||
|
types::Expression::Array(vec![expression; count])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast, F: Field + PrimeField> From<ast::InlineStructMember<'ast>> for types::StructMember<F> {
|
||||||
|
fn from(member: ast::InlineStructMember<'ast>) -> Self {
|
||||||
|
types::StructMember {
|
||||||
|
variable: types::Variable::from(member.variable),
|
||||||
|
expression: types::Expression::from(member.expression),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast, F: Field + PrimeField> From<ast::StructInlineExpression<'ast>> for types::Expression<F> {
|
||||||
|
fn from(expression: ast::StructInlineExpression<'ast>) -> Self {
|
||||||
|
let variable = types::Variable::from(expression.variable);
|
||||||
|
let members = expression
|
||||||
|
.members
|
||||||
|
.into_iter()
|
||||||
|
.map(|member| types::StructMember::from(member))
|
||||||
|
.collect::<Vec<types::StructMember<F>>>();
|
||||||
|
|
||||||
|
types::Expression::Struct(variable, members)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'ast, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::Expression<F> {
|
impl<'ast, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::Expression<F> {
|
||||||
fn from(expression: ast::PostfixExpression<'ast>) -> Self {
|
fn from(expression: ast::PostfixExpression<'ast>) -> Self {
|
||||||
let variable = types::Expression::Variable(types::Variable::from(expression.variable));
|
let variable = types::Expression::Variable(types::Variable::from(expression.variable));
|
||||||
@ -229,28 +273,6 @@ impl<'ast, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast, F: Field + PrimeField> From<ast::ArrayInlineExpression<'ast>> for types::Expression<F> {
|
|
||||||
fn from(array: ast::ArrayInlineExpression<'ast>) -> Self {
|
|
||||||
types::Expression::Array(
|
|
||||||
array
|
|
||||||
.expressions
|
|
||||||
.into_iter()
|
|
||||||
.map(|s_or_e| Box::new(types::SpreadOrExpression::from(s_or_e)))
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'ast, F: Field + PrimeField> From<ast::ArrayInitializerExpression<'ast>>
|
|
||||||
for types::Expression<F>
|
|
||||||
{
|
|
||||||
fn from(array: ast::ArrayInitializerExpression<'ast>) -> Self {
|
|
||||||
let count = types::Expression::<F>::get_count(array.count);
|
|
||||||
let expression = Box::new(types::SpreadOrExpression::from(*array.expression));
|
|
||||||
|
|
||||||
types::Expression::Array(vec![expression; count])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Expression<F> {
|
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Expression<F> {
|
||||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||||
match expression {
|
match expression {
|
||||||
@ -261,18 +283,13 @@ impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Express
|
|||||||
ast::Expression::Ternary(expression) => types::Expression::from(expression),
|
ast::Expression::Ternary(expression) => types::Expression::from(expression),
|
||||||
ast::Expression::ArrayInline(expression) => types::Expression::from(expression),
|
ast::Expression::ArrayInline(expression) => types::Expression::from(expression),
|
||||||
ast::Expression::ArrayInitializer(expression) => types::Expression::from(expression),
|
ast::Expression::ArrayInitializer(expression) => types::Expression::from(expression),
|
||||||
ast::Expression::StructInline(_expression) => {
|
ast::Expression::StructInline(expression) => types::Expression::from(expression),
|
||||||
unimplemented!("unknown type for inline struct expression")
|
|
||||||
}
|
|
||||||
ast::Expression::Postfix(expression) => types::Expression::from(expression),
|
ast::Expression::Postfix(expression) => types::Expression::from(expression),
|
||||||
// _ => unimplemented!(),
|
// _ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pest ast -> typed types::Expression
|
|
||||||
/// For defined types (ex: u32[4]) we manually construct the expression instead of implementing the From trait.
|
|
||||||
/// This saves us from having to resolve things at a later point in time.
|
|
||||||
impl<'ast, F: Field + PrimeField> types::Expression<F> {
|
impl<'ast, F: Field + PrimeField> types::Expression<F> {
|
||||||
fn get_count(count: ast::Value<'ast>) -> usize {
|
fn get_count(count: ast::Value<'ast>) -> usize {
|
||||||
match count {
|
match count {
|
||||||
@ -284,34 +301,6 @@ impl<'ast, F: Field + PrimeField> types::Expression<F> {
|
|||||||
size => unimplemented!("Array size should be an integer {}", size),
|
size => unimplemented!("Array size should be an integer {}", size),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_struct(ty: ast::StructType<'ast>, expression: ast::Expression<'ast>) -> Self {
|
|
||||||
let declaration_struct = ty.variable.value;
|
|
||||||
match expression {
|
|
||||||
ast::Expression::StructInline(inline_struct) => {
|
|
||||||
if inline_struct.variable.value != declaration_struct {
|
|
||||||
unimplemented!("Declared struct type must match inline struct type")
|
|
||||||
}
|
|
||||||
let variable = types::Variable::from(inline_struct.variable);
|
|
||||||
let members = inline_struct
|
|
||||||
.members
|
|
||||||
.into_iter()
|
|
||||||
.map(|member| types::StructMember::from(member))
|
|
||||||
.collect::<Vec<types::StructMember<F>>>();
|
|
||||||
|
|
||||||
types::Expression::Struct(variable, members)
|
|
||||||
}
|
|
||||||
_ => unimplemented!("Struct declaration must be followed by inline struct"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_type(ty: ast::Type<'ast>, expression: ast::Expression<'ast>) -> Self {
|
|
||||||
match ty {
|
|
||||||
ast::Type::Basic(_ty) => Self::from(expression),
|
|
||||||
ast::Type::Array(_ty) => Self::from(expression),
|
|
||||||
ast::Type::Struct(ty) => Self::from_struct(ty, expression),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pest ast -> types::Assignee
|
/// pest ast -> types::Assignee
|
||||||
@ -407,7 +396,7 @@ impl<'ast, F: Field + PrimeField> From<ast::MultipleAssignmentStatement<'ast>>
|
|||||||
|
|
||||||
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
|
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
|
||||||
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
||||||
types::Statement::Definition(
|
types::Statement::Assign(
|
||||||
types::Assignee::from(statement.assignee),
|
types::Assignee::from(statement.assignee),
|
||||||
types::Expression::from(statement.expression),
|
types::Expression::from(statement.expression),
|
||||||
)
|
)
|
||||||
@ -417,8 +406,9 @@ impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::St
|
|||||||
impl<'ast, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types::Statement<F> {
|
impl<'ast, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types::Statement<F> {
|
||||||
fn from(statement: ast::DefinitionStatement<'ast>) -> Self {
|
fn from(statement: ast::DefinitionStatement<'ast>) -> Self {
|
||||||
types::Statement::Definition(
|
types::Statement::Definition(
|
||||||
|
types::Type::from(statement.ty),
|
||||||
types::Assignee::from(statement.variable),
|
types::Assignee::from(statement.variable),
|
||||||
types::Expression::from_type(statement.ty, statement.expression),
|
types::Expression::from(statement.expression),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -474,15 +464,6 @@ impl<'ast, F: Field + PrimeField> From<ast::Type<'ast>> for types::Type<F> {
|
|||||||
|
|
||||||
/// pest ast -> types::Struct
|
/// pest ast -> types::Struct
|
||||||
|
|
||||||
impl<'ast, F: Field + PrimeField> From<ast::InlineStructMember<'ast>> for types::StructMember<F> {
|
|
||||||
fn from(member: ast::InlineStructMember<'ast>) -> Self {
|
|
||||||
types::StructMember {
|
|
||||||
variable: types::Variable::from(member.variable),
|
|
||||||
expression: types::Expression::from(member.expression),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast, F: Field + PrimeField> From<ast::StructField<'ast>> for types::StructField<F> {
|
impl<'ast, F: Field + PrimeField> From<ast::StructField<'ast>> for types::StructField<F> {
|
||||||
fn from(struct_field: ast::StructField<'ast>) -> Self {
|
fn from(struct_field: ast::StructField<'ast>) -> Self {
|
||||||
types::StructField {
|
types::StructField {
|
||||||
|
Loading…
Reference in New Issue
Block a user