Migrate statements

This commit is contained in:
howardwu 2020-06-07 20:24:27 -07:00
parent bc1c37faa0
commit 3a554af9fe
15 changed files with 332 additions and 321 deletions

View File

@ -4,12 +4,9 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::StatementError,
new_scope,
types::{
ConditionalNestedOrEndStatement, ConditionalStatement, Statement,
},
GroupType,
};
use leo_types::{Assignee, Expression, Identifier, Integer, RangeOrExpression, Type, Variable};
use leo_types::{Assignee, ConditionalNestedOrEndStatement, ConditionalStatement, Statement, Expression, Identifier, Integer, RangeOrExpression, Type, Variable};
use snarkos_models::{
curves::{Field, PrimeField},

View File

@ -2,37 +2,10 @@
//! Each defined type consists of typed statements and expressions.
use crate::Import;
use leo_types::{Assignee, Expression, Identifier, Integer, Type, Variable};
use leo_types::{Identifier, Statement, Type};
use std::collections::HashMap;
#[derive(Clone, PartialEq, Eq)]
pub enum ConditionalNestedOrEndStatement {
Nested(Box<ConditionalStatement>),
End(Vec<Statement>),
}
#[derive(Clone, PartialEq, Eq)]
pub struct ConditionalStatement {
pub condition: Expression,
pub statements: Vec<Statement>,
pub next: Option<ConditionalNestedOrEndStatement>,
}
/// Program statement that defines some action (or expression) to be carried out.
#[derive(Clone, PartialEq, Eq)]
pub enum Statement {
Return(Vec<Expression>),
Definition(Variable, Expression),
Assign(Assignee, Expression),
MultipleAssign(Vec<Variable>, Expression),
Conditional(ConditionalStatement),
For(Identifier, Integer, Integer, Vec<Statement>),
AssertEq(Expression, Expression),
Expression(Expression),
}
/// Circuits
#[derive(Clone, PartialEq, Eq)]

View File

@ -1,86 +1,12 @@
//! Format display functions for Leo types.
use crate::{
Circuit, CircuitMember, ConditionalNestedOrEndStatement, ConditionalStatement,
Function, InputModel, Statement,
Circuit, CircuitMember,
Function, InputModel,
};
use std::fmt;
impl fmt::Display for ConditionalNestedOrEndStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested),
ConditionalNestedOrEndStatement::End(ref statements) => {
write!(f, "else {{\n")?;
for statement in statements.iter() {
write!(f, "\t\t{}\n", statement)?;
}
write!(f, "\t}}")
}
}
}
}
impl fmt::Display for ConditionalStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "if ({}) {{\n", self.condition)?;
for statement in self.statements.iter() {
write!(f, "\t\t{}\n", statement)?;
}
match self.next.clone() {
Some(n_or_e) => write!(f, "\t}} {}", n_or_e),
None => write!(f, "\t}}"),
}
}
}
impl fmt::Display for Statement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Return(ref statements) => {
write!(f, "return (")?;
for (i, value) in statements.iter().enumerate() {
write!(f, "{}", value)?;
if i < statements.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ")\n")
}
Statement::Definition(ref variable, ref expression) => {
write!(f, "let {} = {};", variable, expression)
}
Statement::Assign(ref variable, ref statement) => {
write!(f, "{} = {};", variable, statement)
}
Statement::MultipleAssign(ref assignees, ref function) => {
write!(f, "let (")?;
for (i, id) in assignees.iter().enumerate() {
write!(f, "{}", id)?;
if i < assignees.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ") = {};", function)
}
Statement::Conditional(ref statement) => write!(f, "{}", statement),
Statement::For(ref var, ref start, ref stop, ref list) => {
write!(f, "for {} in {}..{} {{\n", var, start, stop)?;
for l in list {
write!(f, "\t\t{}\n", l)?;
}
write!(f, "\t}}")
}
Statement::AssertEq(ref left, ref right) => {
write!(f, "assert_eq({}, {});", left, right)
}
Statement::Expression(ref expression) => write!(f, "{};", expression),
}
}
}
impl fmt::Display for CircuitMember {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {

View File

@ -22,220 +22,11 @@ use leo_ast::{
Import as AstImport,
ImportSymbol as AstImportSymbol,
},
operations::{
AssignOperation,
},
statements::{
AssertStatement,
AssignStatement,
ConditionalStatement,
ConditionalNestedOrEndStatement,
DefinitionStatement,
ExpressionStatement,
ForStatement,
MultipleAssignmentStatement,
ReturnStatement,
Statement,
},
};
use leo_types::{Assignee, Expression, Identifier, Integer, Type, Variable};
use leo_types::{Identifier, Statement, Type};
use std::collections::HashMap;
/// pest ast -> types::Statement
impl<'ast> From<ReturnStatement<'ast>> for types::Statement {
fn from(statement: ReturnStatement<'ast>) -> Self {
types::Statement::Return(
statement
.expressions
.into_iter()
.map(|expression| Expression::from(expression))
.collect(),
)
}
}
impl<'ast> From<DefinitionStatement<'ast>> for types::Statement {
fn from(statement: DefinitionStatement<'ast>) -> Self {
types::Statement::Definition(
Variable::from(statement.variable),
Expression::from(statement.expression),
)
}
}
impl<'ast> From<AssignStatement<'ast>> for types::Statement {
fn from(statement: AssignStatement<'ast>) -> Self {
match statement.assign {
AssignOperation::Assign(ref _assign) => types::Statement::Assign(
Assignee::from(statement.assignee),
Expression::from(statement.expression),
),
operation_assign => {
// convert assignee into postfix expression
let converted = Expression::from(statement.assignee.clone());
match operation_assign {
AssignOperation::AddAssign(ref _assign) => types::Statement::Assign(
Assignee::from(statement.assignee),
Expression::Add(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::SubAssign(ref _assign) => types::Statement::Assign(
Assignee::from(statement.assignee),
Expression::Sub(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::MulAssign(ref _assign) => types::Statement::Assign(
Assignee::from(statement.assignee),
Expression::Mul(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::DivAssign(ref _assign) => types::Statement::Assign(
Assignee::from(statement.assignee),
Expression::Div(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::PowAssign(ref _assign) => types::Statement::Assign(
Assignee::from(statement.assignee),
Expression::Pow(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::Assign(ref _assign) => {
unimplemented!("cannot assign twice to assign statement")
}
}
}
}
}
}
impl<'ast> From<MultipleAssignmentStatement<'ast>> for types::Statement {
fn from(statement: MultipleAssignmentStatement<'ast>) -> Self {
let variables = statement
.variables
.into_iter()
.map(|typed_variable| Variable::from(typed_variable))
.collect();
types::Statement::MultipleAssign(
variables,
Expression::FunctionCall(
Box::new(Expression::from(statement.function_name)),
statement
.arguments
.into_iter()
.map(|e| Expression::from(e))
.collect(),
),
)
}
}
impl<'ast> From<ConditionalNestedOrEndStatement<'ast>> for types::ConditionalNestedOrEndStatement {
fn from(statement: ConditionalNestedOrEndStatement<'ast>) -> Self {
match statement {
ConditionalNestedOrEndStatement::Nested(nested) => types::ConditionalNestedOrEndStatement::Nested(
Box::new(types::ConditionalStatement::from(*nested)),
),
ConditionalNestedOrEndStatement::End(statements) => types::ConditionalNestedOrEndStatement::End(
statements
.into_iter()
.map(|statement| types::Statement::from(statement))
.collect(),
),
}
}
}
impl<'ast> From<ConditionalStatement<'ast>> for types::ConditionalStatement {
fn from(statement: ConditionalStatement<'ast>) -> Self {
types::ConditionalStatement {
condition: Expression::from(statement.condition),
statements: statement
.statements
.into_iter()
.map(|statement| types::Statement::from(statement))
.collect(),
next: statement
.next
.map(|n_or_e| Some(types::ConditionalNestedOrEndStatement::from(n_or_e)))
.unwrap_or(None),
}
}
}
impl<'ast> From<ForStatement<'ast>> for types::Statement {
fn from(statement: ForStatement<'ast>) -> Self {
let from = match Expression::from(statement.start) {
Expression::Integer(number) => number,
Expression::Implicit(string) => Integer::from_implicit(string),
expression => unimplemented!("Range bounds should be integers, found {}", expression),
};
let to = match Expression::from(statement.stop) {
Expression::Integer(number) => number,
Expression::Implicit(string) => Integer::from_implicit(string),
expression => unimplemented!("Range bounds should be integers, found {}", expression),
};
types::Statement::For(
Identifier::from(statement.index),
from,
to,
statement
.statements
.into_iter()
.map(|statement| types::Statement::from(statement))
.collect(),
)
}
}
impl<'ast> From<AssertStatement<'ast>> for types::Statement {
fn from(statement: AssertStatement<'ast>) -> Self {
match statement {
AssertStatement::AssertEq(assert_eq) => types::Statement::AssertEq(
Expression::from(assert_eq.left),
Expression::from(assert_eq.right),
),
}
}
}
impl<'ast> From<ExpressionStatement<'ast>> for types::Statement {
fn from(statement: ExpressionStatement<'ast>) -> Self {
types::Statement::Expression(Expression::from(statement.expression))
}
}
impl<'ast> From<Statement<'ast>> for types::Statement {
fn from(statement: Statement<'ast>) -> Self {
match statement {
Statement::Return(statement) => types::Statement::from(statement),
Statement::Definition(statement) => types::Statement::from(statement),
Statement::Assign(statement) => types::Statement::from(statement),
Statement::MultipleAssignment(statement) => types::Statement::from(statement),
Statement::Conditional(statement) => {
types::Statement::Conditional(types::ConditionalStatement::from(statement))
}
Statement::Iteration(statement) => types::Statement::from(statement),
Statement::Assert(statement) => types::Statement::from(statement),
Statement::Expression(statement) => types::Statement::from(statement),
}
}
}
/// pest ast -> types::Circuit
impl<'ast> From<AstCircuitFieldDefinition<'ast>> for types::CircuitMember {
@ -319,7 +110,7 @@ impl<'ast> From<Function<'ast>> for types::Function {
let statements = function_definition
.statements
.into_iter()
.map(|statement| types::Statement::from(statement))
.map(|statement| Statement::from(statement))
.collect();
types::Function {

View File

@ -7,7 +7,7 @@ pub mod group;
pub mod import;
pub mod integer;
pub mod mutability;
pub mod statement;
pub mod statements;
pub mod syntax;
use leo_compiler::{

View File

@ -21,7 +21,7 @@ impl<'ast> From<AstAssignee<'ast>> for Assignee {
fn from(assignee: AstAssignee<'ast>) -> Self {
let variable = Assignee::from(assignee.identifier);
// we start with the id, and we fold the array of accesses by wrapping the current value
// We start with the id, and we fold the array of accesses by wrapping the current value
assignee
.accesses
.into_iter()

View File

@ -19,5 +19,8 @@ pub use input_value::*;
pub mod integer;
pub use integer::*;
pub mod statements;
pub use statements::*;
pub mod types;
pub use types::*;

View File

@ -0,0 +1,41 @@
use crate::{ConditionalStatement, Statement};
use leo_ast::statements::ConditionalNestedOrEndStatement as AstConditionalNestedOrEndStatement;
use std::fmt;
#[derive(Clone, PartialEq, Eq)]
pub enum ConditionalNestedOrEndStatement {
Nested(Box<ConditionalStatement>),
End(Vec<Statement>),
}
impl<'ast> From<AstConditionalNestedOrEndStatement<'ast>> for ConditionalNestedOrEndStatement {
fn from(statement: AstConditionalNestedOrEndStatement<'ast>) -> Self {
match statement {
AstConditionalNestedOrEndStatement::Nested(nested) => ConditionalNestedOrEndStatement::Nested(
Box::new(ConditionalStatement::from(*nested)),
),
AstConditionalNestedOrEndStatement::End(statements) => ConditionalNestedOrEndStatement::End(
statements
.into_iter()
.map(|statement| Statement::from(statement))
.collect(),
),
}
}
}
impl fmt::Display for ConditionalNestedOrEndStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested),
ConditionalNestedOrEndStatement::End(ref statements) => {
write!(f, "else {{\n")?;
for statement in statements.iter() {
write!(f, "\t\t{}\n", statement)?;
}
write!(f, "\t}}")
}
}
}
}

View File

@ -0,0 +1,41 @@
use crate::{Expression, Statement, ConditionalNestedOrEndStatement};
use leo_ast::statements::ConditionalStatement as AstConditionalStatement;
use std::fmt;
#[derive(Clone, PartialEq, Eq)]
pub struct ConditionalStatement {
pub condition: Expression,
pub statements: Vec<Statement>,
pub next: Option<ConditionalNestedOrEndStatement>,
}
impl<'ast> From<AstConditionalStatement<'ast>> for ConditionalStatement {
fn from(statement: AstConditionalStatement<'ast>) -> Self {
ConditionalStatement {
condition: Expression::from(statement.condition),
statements: statement
.statements
.into_iter()
.map(|statement| Statement::from(statement))
.collect(),
next: statement
.next
.map(|n_or_e| Some(ConditionalNestedOrEndStatement::from(n_or_e)))
.unwrap_or(None),
}
}
}
impl fmt::Display for ConditionalStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "if ({}) {{\n", self.condition)?;
for statement in self.statements.iter() {
write!(f, "\t\t{}\n", statement)?;
}
match self.next.clone() {
Some(n_or_e) => write!(f, "\t}} {}", n_or_e),
None => write!(f, "\t}}"),
}
}
}

View File

@ -0,0 +1,8 @@
pub mod conditional_nested_or_end_statement;
pub use conditional_nested_or_end_statement::*;
pub mod conditional_statement;
pub use conditional_statement::*;
pub mod statement;
pub use statement::*;

View File

@ -0,0 +1,231 @@
use crate::{Assignee, Expression, Identifier, Integer, Variable, ConditionalStatement};
use leo_ast::{operations::AssignOperation, statements::{
ReturnStatement,
AssignStatement,
Statement as AstStatement,
AssertStatement,
ExpressionStatement,
DefinitionStatement,
ForStatement,
MultipleAssignmentStatement
}};
use std::fmt;
/// Program statement that defines some action (or expression) to be carried out.
#[derive(Clone, PartialEq, Eq)]
pub enum Statement {
Return(Vec<Expression>),
Definition(Variable, Expression),
Assign(Assignee, Expression),
MultipleAssign(Vec<Variable>, Expression),
Conditional(ConditionalStatement),
For(Identifier, Integer, Integer, Vec<Statement>),
AssertEq(Expression, Expression),
Expression(Expression),
}
impl<'ast> From<ReturnStatement<'ast>> for Statement {
fn from(statement: ReturnStatement<'ast>) -> Self {
Statement::Return(
statement
.expressions
.into_iter()
.map(|expression| Expression::from(expression))
.collect(),
)
}
}
impl<'ast> From<DefinitionStatement<'ast>> for Statement {
fn from(statement: DefinitionStatement<'ast>) -> Self {
Statement::Definition(
Variable::from(statement.variable),
Expression::from(statement.expression),
)
}
}
impl<'ast> From<AssignStatement<'ast>> for Statement {
fn from(statement: AssignStatement<'ast>) -> Self {
match statement.assign {
AssignOperation::Assign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::from(statement.expression),
),
operation_assign => {
// convert assignee into postfix expression
let converted = Expression::from(statement.assignee.clone());
match operation_assign {
AssignOperation::AddAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Add(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::SubAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Sub(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::MulAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Mul(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::DivAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Div(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::PowAssign(ref _assign) => Statement::Assign(
Assignee::from(statement.assignee),
Expression::Pow(
Box::new(converted),
Box::new(Expression::from(statement.expression)),
),
),
AssignOperation::Assign(ref _assign) => {
unimplemented!("cannot assign twice to assign statement")
}
}
}
}
}
}
impl<'ast> From<MultipleAssignmentStatement<'ast>> for Statement {
fn from(statement: MultipleAssignmentStatement<'ast>) -> Self {
let variables = statement
.variables
.into_iter()
.map(|typed_variable| Variable::from(typed_variable))
.collect();
Statement::MultipleAssign(
variables,
Expression::FunctionCall(
Box::new(Expression::from(statement.function_name)),
statement
.arguments
.into_iter()
.map(|e| Expression::from(e))
.collect(),
),
)
}
}
impl<'ast> From<ForStatement<'ast>> for Statement {
fn from(statement: ForStatement<'ast>) -> Self {
let from = match Expression::from(statement.start) {
Expression::Integer(number) => number,
Expression::Implicit(string) => Integer::from_implicit(string),
expression => unimplemented!("Range bounds should be integers, found {}", expression),
};
let to = match Expression::from(statement.stop) {
Expression::Integer(number) => number,
Expression::Implicit(string) => Integer::from_implicit(string),
expression => unimplemented!("Range bounds should be integers, found {}", expression),
};
Statement::For(
Identifier::from(statement.index),
from,
to,
statement
.statements
.into_iter()
.map(|statement| Statement::from(statement))
.collect(),
)
}
}
impl<'ast> From<AssertStatement<'ast>> for Statement {
fn from(statement: AssertStatement<'ast>) -> Self {
match statement {
AssertStatement::AssertEq(assert_eq) => Statement::AssertEq(
Expression::from(assert_eq.left),
Expression::from(assert_eq.right),
),
}
}
}
impl<'ast> From<ExpressionStatement<'ast>> for Statement {
fn from(statement: ExpressionStatement<'ast>) -> Self {
Statement::Expression(Expression::from(statement.expression))
}
}
impl<'ast> From<AstStatement<'ast>> for Statement {
fn from(statement: AstStatement<'ast>) -> Self {
match statement {
AstStatement::Return(statement) => Statement::from(statement),
AstStatement::Definition(statement) => Statement::from(statement),
AstStatement::Assign(statement) => Statement::from(statement),
AstStatement::MultipleAssignment(statement) => Statement::from(statement),
AstStatement::Conditional(statement) => {
Statement::Conditional(ConditionalStatement::from(statement))
}
AstStatement::Iteration(statement) => Statement::from(statement),
AstStatement::Assert(statement) => Statement::from(statement),
AstStatement::Expression(statement) => Statement::from(statement),
}
}
}
impl fmt::Display for Statement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Return(ref statements) => {
write!(f, "return (")?;
for (i, value) in statements.iter().enumerate() {
write!(f, "{}", value)?;
if i < statements.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ")\n")
}
Statement::Definition(ref variable, ref expression) => {
write!(f, "let {} = {};", variable, expression)
}
Statement::Assign(ref variable, ref statement) => {
write!(f, "{} = {};", variable, statement)
}
Statement::MultipleAssign(ref assignees, ref function) => {
write!(f, "let (")?;
for (i, id) in assignees.iter().enumerate() {
write!(f, "{}", id)?;
if i < assignees.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ") = {};", function)
}
Statement::Conditional(ref statement) => write!(f, "{}", statement),
Statement::For(ref var, ref start, ref stop, ref list) => {
write!(f, "for {} in {}..{} {{\n", var, start, stop)?;
for l in list {
write!(f, "\t\t{}\n", l)?;
}
write!(f, "\t}}")
}
Statement::AssertEq(ref left, ref right) => {
write!(f, "assert_eq({}, {});", left, right)
}
Statement::Expression(ref expression) => write!(f, "{};", expression),
}
}
}