mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
constraints for loops
This commit is contained in:
parent
0a8cda3d7f
commit
455c0b631a
@ -1,9 +1,6 @@
|
|||||||
struct Foo {
|
|
||||||
bool x
|
|
||||||
}
|
|
||||||
def main() -> (field):
|
def main() -> (field):
|
||||||
field[3] a = [1, 2, 3] // initialize the array
|
a = 1
|
||||||
field[4] b = [42; 4]
|
for i in 0..4 do
|
||||||
c = a[1..3] // helloo???
|
a = a + 1
|
||||||
bool[3] d = [true, false, true]
|
endfor
|
||||||
return a[0]
|
return a
|
@ -639,21 +639,50 @@ impl ResolvedProgram {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn enforce_statement<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
fn enforce_statement<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
// &mut self,
|
&mut self,
|
||||||
// cs: &mut CS,
|
cs: &mut CS,
|
||||||
// statement: Statement,
|
statement: Statement,
|
||||||
// ) {
|
) {
|
||||||
// match statement {
|
match statement {
|
||||||
// Statement::Definition(variable, expression) => {
|
Statement::Definition(variable, expression) => {
|
||||||
// self.enforce_definition_statement(cs, variable, expression);
|
self.enforce_definition_statement(cs, variable, expression);
|
||||||
// }
|
}
|
||||||
// Statement::Return(statements) => {
|
Statement::For(index, start, stop, statements) => {
|
||||||
// let res = self.enforce_return_statement(cs, statements);
|
self.enforce_for_statement(cs, index, start, stop, statements);
|
||||||
//
|
}
|
||||||
// }
|
Statement::Return(statements) => {
|
||||||
// };
|
// TODO: add support for early termination
|
||||||
// }
|
let _res = self.enforce_return_statement(cs, statements);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enforce_for_statement<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
|
index: Variable,
|
||||||
|
start: FieldExpression,
|
||||||
|
stop: FieldExpression,
|
||||||
|
statements: Vec<Statement>,
|
||||||
|
) {
|
||||||
|
let start_index = self.enforce_index(cs, start);
|
||||||
|
let stop_index = self.enforce_index(cs, stop);
|
||||||
|
|
||||||
|
for i in start_index..stop_index {
|
||||||
|
// Store index
|
||||||
|
self.resolved_variables.insert(
|
||||||
|
index.clone(),
|
||||||
|
ResolvedValue::FieldElement(UInt32::constant(i as u32)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Evaluate statements
|
||||||
|
statements
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|statement| self.enforce_statement(cs, statement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn enforce_function<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
fn enforce_function<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -715,7 +744,10 @@ impl ResolvedProgram {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.for_each(|statement| match statement {
|
.for_each(|statement| match statement {
|
||||||
Statement::Definition(variable, expression) => {
|
Statement::Definition(variable, expression) => {
|
||||||
self.enforce_definition_statement(cs, variable, expression)
|
self.enforce_definition_statement(cs, variable, expression);
|
||||||
|
}
|
||||||
|
Statement::For(index, start, stop, statements) => {
|
||||||
|
self.enforce_for_statement(cs, index, start, stop, statements);
|
||||||
}
|
}
|
||||||
Statement::Return(expressions) => {
|
Statement::Return(expressions) => {
|
||||||
return_values = self.enforce_return_statement(cs, expressions)
|
return_values = self.enforce_return_statement(cs, expressions)
|
||||||
|
@ -103,6 +103,7 @@ pub enum Expression {
|
|||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
// Declaration(Variable),
|
// Declaration(Variable),
|
||||||
Definition(Variable, Expression),
|
Definition(Variable, Expression),
|
||||||
|
For(Variable, FieldExpression, FieldExpression, Vec<Statement>),
|
||||||
Return(Vec<Expression>),
|
Return(Vec<Expression>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,12 +121,6 @@ pub struct StructMember {
|
|||||||
pub expression: Expression,
|
pub expression: Expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Clone, Debug)]
|
|
||||||
// pub struct StructExpression {
|
|
||||||
// pub variable: Variable,
|
|
||||||
// pub members: Vec<StructMember>
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct StructField {
|
pub struct StructField {
|
||||||
pub variable: Variable,
|
pub variable: Variable,
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
use crate::aleo_program::{
|
use crate::aleo_program::{
|
||||||
BooleanExpression, BooleanSpread, BooleanSpreadOrExpression, Expression, FieldExpression,
|
BooleanExpression, BooleanSpread, BooleanSpreadOrExpression, Expression, FieldExpression,
|
||||||
FieldRangeOrExpression, FieldSpread, FieldSpreadOrExpression, Function, FunctionName, Parameter, Statement,
|
FieldRangeOrExpression, FieldSpread, FieldSpreadOrExpression, Function, FunctionName,
|
||||||
Struct, StructField, Type, Variable,
|
Parameter, Statement, Struct, StructField, Type, Variable,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -166,15 +166,22 @@ impl<'ast> fmt::Display for Expression {
|
|||||||
impl fmt::Display for Statement {
|
impl fmt::Display for Statement {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
Statement::Definition(ref variable, ref statement) => {
|
||||||
|
write!(f, "{} = {}", variable, statement)
|
||||||
|
}
|
||||||
|
Statement::For(ref var, ref start, ref stop, ref list) => {
|
||||||
|
write!(f, "for {} in {}..{} do\n", var, start, stop)?;
|
||||||
|
for l in list {
|
||||||
|
write!(f, "\t\t{}\n", l)?;
|
||||||
|
}
|
||||||
|
write!(f, "\tendfor")
|
||||||
|
}
|
||||||
Statement::Return(ref statements) => {
|
Statement::Return(ref statements) => {
|
||||||
statements.iter().for_each(|statement| {
|
statements.iter().for_each(|statement| {
|
||||||
write!(f, "return {}", statement).unwrap();
|
write!(f, "return {}", statement).unwrap();
|
||||||
});
|
});
|
||||||
write!(f, "\n")
|
write!(f, "\n")
|
||||||
}
|
}
|
||||||
Statement::Definition(ref variable, ref statement) => {
|
|
||||||
write!(f, "{} = {}", variable, statement)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,15 +189,22 @@ impl fmt::Display for Statement {
|
|||||||
impl fmt::Debug for Statement {
|
impl fmt::Debug for Statement {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
Statement::Definition(ref variable, ref statement) => {
|
||||||
|
write!(f, "{} = {}", variable, statement)
|
||||||
|
}
|
||||||
|
Statement::For(ref var, ref start, ref stop, ref list) => {
|
||||||
|
write!(f, "for {:?} in {:?}..{:?} do\n", var, start, stop)?;
|
||||||
|
for l in list {
|
||||||
|
write!(f, "\t\t{:?}\n", l)?;
|
||||||
|
}
|
||||||
|
write!(f, "\tendfor")
|
||||||
|
}
|
||||||
Statement::Return(ref statements) => {
|
Statement::Return(ref statements) => {
|
||||||
statements.iter().for_each(|statement| {
|
statements.iter().for_each(|statement| {
|
||||||
write!(f, "return {}", statement).unwrap();
|
write!(f, "return {}", statement).unwrap();
|
||||||
});
|
});
|
||||||
write!(f, "\n")
|
write!(f, "\n")
|
||||||
}
|
}
|
||||||
Statement::Definition(ref variable, ref statement) => {
|
|
||||||
write!(f, "{} = {}", variable, statement)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,10 +561,18 @@ impl<'ast> From<ast::ReturnStatement<'ast>> for types::Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<ast::IterationStatement<'ast>> for types::Statement {
|
impl<'ast> From<ast::ForStatement<'ast>> for types::Statement {
|
||||||
fn from(statement: ast::IterationStatement<'ast>) -> Self {
|
fn from(statement: ast::ForStatement<'ast>) -> Self {
|
||||||
println!("{:#?}", statement);
|
types::Statement::For(
|
||||||
unimplemented!()
|
types::Variable::from(statement.index),
|
||||||
|
types::FieldExpression::from(statement.start),
|
||||||
|
types::FieldExpression::from(statement.stop),
|
||||||
|
statement
|
||||||
|
.statements
|
||||||
|
.into_iter()
|
||||||
|
.map(|statement| types::Statement::from(statement))
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,7 +712,8 @@ impl<'ast> From<ast::Function<'ast>> for types::Function {
|
|||||||
|
|
||||||
impl<'ast> From<ast::File<'ast>> for types::Program {
|
impl<'ast> From<ast::File<'ast>> for types::Program {
|
||||||
fn from(file: ast::File<'ast>) -> Self {
|
fn from(file: ast::File<'ast>) -> Self {
|
||||||
// 1. compile ast -> aleo program representation
|
// Compiled ast -> aleo program representation
|
||||||
|
|
||||||
let mut structs = HashMap::new();
|
let mut structs = HashMap::new();
|
||||||
let mut functions = HashMap::new();
|
let mut functions = HashMap::new();
|
||||||
|
|
||||||
@ -721,17 +730,10 @@ impl<'ast> From<ast::File<'ast>> for types::Program {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// let statements: Vec<types::Statement> = file
|
|
||||||
// .statements
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|statement| types::Statement::from(statement))
|
|
||||||
// .collect();
|
|
||||||
|
|
||||||
types::Program {
|
types::Program {
|
||||||
id: "main".into(),
|
id: "main".into(),
|
||||||
structs,
|
structs,
|
||||||
functions,
|
functions,
|
||||||
// statements,
|
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
returns: vec![],
|
returns: vec![],
|
||||||
}
|
}
|
||||||
|
17
src/ast.rs
17
src/ast.rs
@ -701,12 +701,11 @@ pub struct DefinitionStatement<'ast> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||||
#[pest_ast(rule(Rule::statement_iteration))]
|
#[pest_ast(rule(Rule::statement_for))]
|
||||||
pub struct IterationStatement<'ast> {
|
pub struct ForStatement<'ast> {
|
||||||
pub ty: Type<'ast>,
|
|
||||||
pub index: Variable<'ast>,
|
pub index: Variable<'ast>,
|
||||||
pub from: Expression<'ast>,
|
pub start: Expression<'ast>,
|
||||||
pub to: Expression<'ast>,
|
pub stop: Expression<'ast>,
|
||||||
pub statements: Vec<Statement<'ast>>,
|
pub statements: Vec<Statement<'ast>>,
|
||||||
#[pest_ast(outer())]
|
#[pest_ast(outer())]
|
||||||
pub span: Span<'ast>,
|
pub span: Span<'ast>,
|
||||||
@ -725,7 +724,7 @@ pub struct ReturnStatement<'ast> {
|
|||||||
pub enum Statement<'ast> {
|
pub enum Statement<'ast> {
|
||||||
Assign(AssignStatement<'ast>),
|
Assign(AssignStatement<'ast>),
|
||||||
Definition(DefinitionStatement<'ast>),
|
Definition(DefinitionStatement<'ast>),
|
||||||
Iteration(IterationStatement<'ast>),
|
Iteration(ForStatement<'ast>),
|
||||||
Return(ReturnStatement<'ast>),
|
Return(ReturnStatement<'ast>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,12 +740,12 @@ impl<'ast> fmt::Display for DefinitionStatement<'ast> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> fmt::Display for IterationStatement<'ast> {
|
impl<'ast> fmt::Display for ForStatement<'ast> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"for {} {} in {}..{} do {:#?} endfor",
|
"for {} in {}..{} do {:#?} endfor",
|
||||||
self.ty, self.index, self.from, self.to, self.statements
|
self.index, self.start, self.stop, self.statements
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,11 +135,11 @@ expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
|||||||
statement_assign = { variable ~ "=" ~ expression }
|
statement_assign = { variable ~ "=" ~ expression }
|
||||||
statement_definition = { ty ~ variable ~ "=" ~ expression }
|
statement_definition = { ty ~ variable ~ "=" ~ expression }
|
||||||
statement_return = { "return" ~ expression_tuple }
|
statement_return = { "return" ~ expression_tuple }
|
||||||
statement_iteration = { "for" ~ ty ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"}
|
statement_for = { "for" ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"}
|
||||||
|
|
||||||
statement = {
|
statement = {
|
||||||
(statement_return
|
(statement_return
|
||||||
| (statement_iteration
|
| (statement_for
|
||||||
| statement_definition
|
| statement_definition
|
||||||
| statement_assign
|
| statement_assign
|
||||||
) ~ NEWLINE
|
) ~ NEWLINE
|
||||||
|
Loading…
Reference in New Issue
Block a user