mirror of
https://github.com/AleoHQ/leo.git
synced 2024-09-11 15:05:33 +03:00
Migrate statements
This commit is contained in:
parent
bc1c37faa0
commit
3a554af9fe
@ -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},
|
||||
|
@ -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)]
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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::{
|
||||
|
@ -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()
|
||||
|
@ -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::*;
|
||||
|
41
types/src/statements/conditional_nested_or_end_statement.rs
Normal file
41
types/src/statements/conditional_nested_or_end_statement.rs
Normal 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}}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
types/src/statements/conditional_statement.rs
Normal file
41
types/src/statements/conditional_statement.rs
Normal 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}}"),
|
||||
}
|
||||
}
|
||||
}
|
8
types/src/statements/mod.rs
Normal file
8
types/src/statements/mod.rs
Normal 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::*;
|
231
types/src/statements/statement.rs
Normal file
231
types/src/statements/statement.rs
Normal 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),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user