mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-22 17:51:39 +03:00
Merge pull request #49 from AleoHQ/feature/types
Introduces types module for internal program representation
This commit is contained in:
commit
d34121ae50
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -517,6 +517,7 @@ dependencies = [
|
|||||||
"from-pest",
|
"from-pest",
|
||||||
"hex",
|
"hex",
|
||||||
"leo-ast",
|
"leo-ast",
|
||||||
|
"leo-types",
|
||||||
"log",
|
"log",
|
||||||
"pest",
|
"pest",
|
||||||
"rand",
|
"rand",
|
||||||
@ -530,6 +531,16 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leo-types"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"leo-ast",
|
||||||
|
"snarkos-errors",
|
||||||
|
"snarkos-models",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.67"
|
version = "0.2.67"
|
||||||
|
@ -13,7 +13,7 @@ name = "leo"
|
|||||||
path = "leo/main.rs"
|
path = "leo/main.rs"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [ "ast", "compiler" ]
|
members = [ "ast", "compiler", "types" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
leo-compiler = { path = "compiler", version = "0.1.0" }
|
leo-compiler = { path = "compiler", version = "0.1.0" }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{ast::Rule, common::Static, function::Function};
|
use crate::{ast::Rule, common::Static, functions::Function};
|
||||||
|
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
use pest_ast::FromPest;
|
use pest_ast::FromPest;
|
||||||
|
@ -5,41 +5,18 @@ extern crate pest_derive;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate thiserror;
|
extern crate thiserror;
|
||||||
|
|
||||||
pub mod access;
|
|
||||||
pub use access::*;
|
|
||||||
|
|
||||||
pub mod ast;
|
|
||||||
pub use ast::*;
|
|
||||||
|
|
||||||
pub mod circuits;
|
|
||||||
pub use circuits::*;
|
|
||||||
|
|
||||||
pub mod common;
|
|
||||||
pub use common::*;
|
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub use errors::*;
|
pub use errors::*;
|
||||||
|
|
||||||
|
pub mod access;
|
||||||
|
pub mod ast;
|
||||||
|
pub mod circuits;
|
||||||
|
pub mod common;
|
||||||
pub mod expressions;
|
pub mod expressions;
|
||||||
pub use expressions::*;
|
|
||||||
|
|
||||||
pub mod files;
|
pub mod files;
|
||||||
pub use files::*;
|
|
||||||
|
|
||||||
pub mod functions;
|
pub mod functions;
|
||||||
pub use functions::*;
|
|
||||||
|
|
||||||
pub mod imports;
|
pub mod imports;
|
||||||
pub use imports::*;
|
|
||||||
|
|
||||||
pub mod operations;
|
pub mod operations;
|
||||||
pub use operations::*;
|
|
||||||
|
|
||||||
pub mod statements;
|
pub mod statements;
|
||||||
pub use statements::*;
|
|
||||||
|
|
||||||
pub mod values;
|
pub mod values;
|
||||||
pub use values::*;
|
|
||||||
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
pub use types::*;
|
|
||||||
|
@ -6,6 +6,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
leo-ast = { path = "../ast", version = "0.1.0" }
|
leo-ast = { path = "../ast", version = "0.1.0" }
|
||||||
|
leo-types = { path = "../types", version = "0.1.0" }
|
||||||
|
|
||||||
snarkos-algorithms = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", version = "0.8.0" }
|
snarkos-algorithms = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", version = "0.8.0" }
|
||||||
snarkos-curves = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", version = "0.8.0" }
|
snarkos-curves = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", version = "0.8.0" }
|
||||||
|
@ -3,9 +3,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
constraints::{generate_constraints, generate_test_constraints, ConstrainedValue},
|
constraints::{generate_constraints, generate_test_constraints, ConstrainedValue},
|
||||||
errors::CompilerError,
|
errors::CompilerError,
|
||||||
GroupType, InputValue, Program,
|
GroupType,
|
||||||
};
|
};
|
||||||
use leo_ast::{ast, files::File};
|
use leo_ast::{ast, files::File};
|
||||||
|
use leo_types::{InputValue, Program};
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||||
errors::BooleanError,
|
errors::BooleanError,
|
||||||
types::InputValue,
|
|
||||||
GroupType,
|
GroupType,
|
||||||
};
|
};
|
||||||
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
|
@ -4,12 +4,10 @@ use crate::{
|
|||||||
constraints::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue},
|
constraints::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue},
|
||||||
errors::ExpressionError,
|
errors::ExpressionError,
|
||||||
new_scope,
|
new_scope,
|
||||||
types::{
|
FieldType, GroupType,
|
||||||
CircuitFieldDefinition, CircuitMember, Expression, Identifier, RangeOrExpression,
|
|
||||||
SpreadOrExpression,
|
|
||||||
},
|
|
||||||
FieldType, GroupType, Integer, IntegerType, Type,
|
|
||||||
};
|
};
|
||||||
|
use leo_types::{CircuitFieldDefinition,CircuitMember, Expression, RangeOrExpression,
|
||||||
|
SpreadOrExpression, Identifier, Integer, IntegerType, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
//! Methods to enforce constraints on field elements in a resolved Leo program.
|
//! Methods to enforce constraints on field elements in a resolved Leo program.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
constraints::ConstrainedValue, errors::FieldError, types::InputValue, FieldType, GroupType,
|
constraints::ConstrainedValue, errors::FieldError, FieldType, GroupType,
|
||||||
};
|
};
|
||||||
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
|
@ -5,9 +5,8 @@ use crate::{
|
|||||||
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
|
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
|
||||||
errors::{FunctionError, ImportError},
|
errors::{FunctionError, ImportError},
|
||||||
field_from_input, group_from_input,
|
field_from_input, group_from_input,
|
||||||
types::{Expression, Function, Identifier, InputValue, Program, Type},
|
GroupType};
|
||||||
GroupType, Integer,
|
use leo_types::{Expression, Function, Identifier, InputValue, Integer, Program, Type};
|
||||||
};
|
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::{errors::GroupError, ConstrainedValue, GroupType, InputValue};
|
use crate::{errors::GroupError, ConstrainedValue, GroupType};
|
||||||
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
|
@ -2,10 +2,10 @@ use crate::{
|
|||||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||||
errors::constraints::ImportError,
|
errors::constraints::ImportError,
|
||||||
new_scope,
|
new_scope,
|
||||||
types::Program,
|
GroupType,
|
||||||
GroupType, Import,
|
|
||||||
};
|
};
|
||||||
use leo_ast::{ast, files::File};
|
use leo_ast::{ast, files::File};
|
||||||
|
use leo_types::{Import, Program};
|
||||||
|
|
||||||
use from_pest::FromPest;
|
use from_pest::FromPest;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
//! Module containing methods to enforce constraints on integers in a Leo program
|
|
||||||
|
|
||||||
pub mod integer;
|
|
||||||
pub use integer::*;
|
|
@ -12,9 +12,6 @@ pub use expression::*;
|
|||||||
pub mod import;
|
pub mod import;
|
||||||
pub use import::*;
|
pub use import::*;
|
||||||
|
|
||||||
pub mod integer;
|
|
||||||
pub use integer::*;
|
|
||||||
|
|
||||||
pub(crate) mod field;
|
pub(crate) mod field;
|
||||||
pub(crate) use field::*;
|
pub(crate) use field::*;
|
||||||
|
|
||||||
@ -32,9 +29,9 @@ pub use statement::*;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::CompilerError,
|
errors::CompilerError,
|
||||||
types::{InputValue, Program},
|
|
||||||
GroupType,
|
GroupType,
|
||||||
};
|
};
|
||||||
|
use leo_types::{InputValue, Program};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
|
@ -4,12 +4,9 @@ use crate::{
|
|||||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||||
errors::StatementError,
|
errors::StatementError,
|
||||||
new_scope,
|
new_scope,
|
||||||
types::{
|
GroupType,
|
||||||
Assignee, ConditionalNestedOrEnd, ConditionalStatement, Expression, Identifier, Integer,
|
|
||||||
RangeOrExpression, Statement, Type,
|
|
||||||
},
|
|
||||||
GroupType, Variable,
|
|
||||||
};
|
};
|
||||||
|
use leo_types::{Assignee, ConditionalNestedOrEndStatement, ConditionalStatement, Statement, Expression, Identifier, Integer, RangeOrExpression, Type, Variable};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
@ -345,14 +342,14 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
|||||||
} else {
|
} else {
|
||||||
match statement.next {
|
match statement.next {
|
||||||
Some(next) => match next {
|
Some(next) => match next {
|
||||||
ConditionalNestedOrEnd::Nested(nested) => self.enforce_conditional_statement(
|
ConditionalNestedOrEndStatement::Nested(nested) => self.enforce_conditional_statement(
|
||||||
cs,
|
cs,
|
||||||
file_scope,
|
file_scope,
|
||||||
function_scope,
|
function_scope,
|
||||||
*nested,
|
*nested,
|
||||||
return_types,
|
return_types,
|
||||||
),
|
),
|
||||||
ConditionalNestedOrEnd::End(statements) => self.iterate_or_early_return(
|
ConditionalNestedOrEndStatement::End(statements) => self.iterate_or_early_return(
|
||||||
cs,
|
cs,
|
||||||
file_scope,
|
file_scope,
|
||||||
function_scope,
|
function_scope,
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::ValueError,
|
errors::ValueError,
|
||||||
types::{Circuit, Function, Identifier, Integer, IntegerType, Type},
|
|
||||||
FieldType, GroupType,
|
FieldType, GroupType,
|
||||||
};
|
};
|
||||||
|
use leo_types::{Circuit, Function, Identifier, Integer, IntegerType, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::errors::{FunctionError, ImportError, IntegerError, };
|
use crate::errors::{FunctionError, ImportError};
|
||||||
use leo_ast::{ast::Rule, SyntaxError};
|
use leo_ast::{ast::Rule, SyntaxError};
|
||||||
|
use leo_types::IntegerError;
|
||||||
|
|
||||||
use pest::error::Error;
|
use pest::error::Error;
|
||||||
use std::{io, path::PathBuf};
|
use std::{io, path::PathBuf};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError,
|
BooleanError, FieldError, FunctionError, GroupError, ValueError,
|
||||||
};
|
};
|
||||||
|
use leo_types::IntegerError;
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
BooleanError, ExpressionError, FieldError, GroupError, IntegerError, StatementError, ValueError,
|
BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError,
|
||||||
};
|
};
|
||||||
|
use leo_types::IntegerError;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum FunctionError {
|
pub enum FunctionError {
|
||||||
|
@ -12,9 +12,6 @@ pub use expression::*;
|
|||||||
pub mod import;
|
pub mod import;
|
||||||
pub use import::*;
|
pub use import::*;
|
||||||
|
|
||||||
pub mod integer;
|
|
||||||
pub use integer::*;
|
|
||||||
|
|
||||||
pub mod field;
|
pub mod field;
|
||||||
pub use field::*;
|
pub use field::*;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::errors::{FieldError, GroupError, IntegerError};
|
use crate::errors::{FieldError, GroupError};
|
||||||
|
use leo_types::IntegerError;
|
||||||
|
|
||||||
use std::{num::ParseIntError, str::ParseBoolError};
|
use std::{num::ParseIntError, str::ParseBoolError};
|
||||||
|
|
||||||
|
@ -15,15 +15,3 @@ pub use self::field::*;
|
|||||||
|
|
||||||
pub mod group;
|
pub mod group;
|
||||||
pub use self::group::*;
|
pub use self::group::*;
|
||||||
|
|
||||||
pub mod imports;
|
|
||||||
pub use self::imports::*;
|
|
||||||
|
|
||||||
pub mod types;
|
|
||||||
pub use self::types::*;
|
|
||||||
|
|
||||||
pub mod types_display;
|
|
||||||
pub use self::types_display::*;
|
|
||||||
|
|
||||||
pub mod types_from;
|
|
||||||
pub use self::types_from::*;
|
|
||||||
|
@ -1,279 +0,0 @@
|
|||||||
//! A typed Leo program consists of import, circuit, and function definitions.
|
|
||||||
//! Each defined type consists of typed statements and expressions.
|
|
||||||
|
|
||||||
use crate::Import;
|
|
||||||
|
|
||||||
use snarkos_models::gadgets::utilities::{
|
|
||||||
boolean::Boolean,
|
|
||||||
uint::{UInt128, UInt16, UInt32, UInt64, UInt8},
|
|
||||||
};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
/// An identifier in the constrained program.
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct Identifier {
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Identifier {
|
|
||||||
pub fn new(name: String) -> Self {
|
|
||||||
Self { name }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_self(&self) -> bool {
|
|
||||||
self.name == "Self"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A variable that is assigned to a value in the constrained program
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
pub struct Variable {
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub mutable: bool,
|
|
||||||
pub _type: Option<Type>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An integer type enum wrapping the integer value. Used only in expressions.
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
|
|
||||||
pub enum Integer {
|
|
||||||
U8(UInt8),
|
|
||||||
U16(UInt16),
|
|
||||||
U32(UInt32),
|
|
||||||
U64(UInt64),
|
|
||||||
U128(UInt128),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Range or expression enum
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum RangeOrExpression {
|
|
||||||
Range(Option<Integer>, Option<Integer>),
|
|
||||||
Expression(Expression),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Spread or expression
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum SpreadOrExpression {
|
|
||||||
Spread(Expression),
|
|
||||||
Expression(Expression),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Expression that evaluates to a value
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum Expression {
|
|
||||||
// Identifier
|
|
||||||
Identifier(Identifier),
|
|
||||||
|
|
||||||
// Values
|
|
||||||
Integer(Integer),
|
|
||||||
Field(String),
|
|
||||||
Group(String),
|
|
||||||
Boolean(Boolean),
|
|
||||||
Implicit(String),
|
|
||||||
|
|
||||||
// Number operations
|
|
||||||
Add(Box<Expression>, Box<Expression>),
|
|
||||||
Sub(Box<Expression>, Box<Expression>),
|
|
||||||
Mul(Box<Expression>, Box<Expression>),
|
|
||||||
Div(Box<Expression>, Box<Expression>),
|
|
||||||
Pow(Box<Expression>, Box<Expression>),
|
|
||||||
|
|
||||||
// Boolean operations
|
|
||||||
Not(Box<Expression>),
|
|
||||||
Or(Box<Expression>, Box<Expression>),
|
|
||||||
And(Box<Expression>, Box<Expression>),
|
|
||||||
Eq(Box<Expression>, Box<Expression>),
|
|
||||||
Ge(Box<Expression>, Box<Expression>),
|
|
||||||
Gt(Box<Expression>, Box<Expression>),
|
|
||||||
Le(Box<Expression>, Box<Expression>),
|
|
||||||
Lt(Box<Expression>, Box<Expression>),
|
|
||||||
|
|
||||||
// Conditionals
|
|
||||||
IfElse(Box<Expression>, Box<Expression>, Box<Expression>),
|
|
||||||
|
|
||||||
// Arrays
|
|
||||||
Array(Vec<Box<SpreadOrExpression>>),
|
|
||||||
ArrayAccess(Box<Expression>, Box<RangeOrExpression>), // (array name, range)
|
|
||||||
|
|
||||||
// Circuits
|
|
||||||
Circuit(Identifier, Vec<CircuitFieldDefinition>),
|
|
||||||
CircuitMemberAccess(Box<Expression>, Identifier), // (declared circuit name, circuit member name)
|
|
||||||
CircuitStaticFunctionAccess(Box<Expression>, Identifier), // (defined circuit name, circuit static member name)
|
|
||||||
|
|
||||||
// Functions
|
|
||||||
FunctionCall(Box<Expression>, Vec<Expression>),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Definition assignee: v, arr[0..2], Point p.x
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum Assignee {
|
|
||||||
Identifier(Identifier),
|
|
||||||
Array(Box<Assignee>, RangeOrExpression),
|
|
||||||
CircuitField(Box<Assignee>, Identifier), // (circuit name, circuit field name)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Explicit integer type
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub enum IntegerType {
|
|
||||||
U8,
|
|
||||||
U16,
|
|
||||||
U32,
|
|
||||||
U64,
|
|
||||||
U128,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Explicit type used for defining a variable or expression type
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub enum Type {
|
|
||||||
IntegerType(IntegerType),
|
|
||||||
Field,
|
|
||||||
Group,
|
|
||||||
Boolean,
|
|
||||||
Array(Box<Type>, Vec<usize>),
|
|
||||||
Circuit(Identifier),
|
|
||||||
SelfType,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Type {
|
|
||||||
pub fn outer_dimension(&self, dimensions: &Vec<usize>) -> Self {
|
|
||||||
let _type = self.clone();
|
|
||||||
|
|
||||||
if dimensions.len() > 1 {
|
|
||||||
let mut next = vec![];
|
|
||||||
next.extend_from_slice(&dimensions[1..]);
|
|
||||||
|
|
||||||
return Type::Array(Box::new(_type), next);
|
|
||||||
}
|
|
||||||
|
|
||||||
_type
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inner_dimension(&self, dimensions: &Vec<usize>) -> Self {
|
|
||||||
let _type = self.clone();
|
|
||||||
|
|
||||||
if dimensions.len() > 1 {
|
|
||||||
let mut next = vec![];
|
|
||||||
next.extend_from_slice(&dimensions[..dimensions.len() - 1]);
|
|
||||||
|
|
||||||
return Type::Array(Box::new(_type), next);
|
|
||||||
}
|
|
||||||
|
|
||||||
_type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
pub enum ConditionalNestedOrEnd {
|
|
||||||
Nested(Box<ConditionalStatement>),
|
|
||||||
End(Vec<Statement>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
pub struct ConditionalStatement {
|
|
||||||
pub condition: Expression,
|
|
||||||
pub statements: Vec<Statement>,
|
|
||||||
pub next: Option<ConditionalNestedOrEnd>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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, Debug, PartialEq, Eq)]
|
|
||||||
pub struct CircuitFieldDefinition {
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub expression: Expression,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
pub enum CircuitMember {
|
|
||||||
CircuitField(Identifier, Type),
|
|
||||||
CircuitFunction(bool, Function),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
pub struct Circuit {
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub members: Vec<CircuitMember>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Function parameters
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
pub struct InputModel {
|
|
||||||
pub identifier: Identifier,
|
|
||||||
pub mutable: bool,
|
|
||||||
pub private: bool,
|
|
||||||
pub _type: Type,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
pub enum InputValue {
|
|
||||||
Integer(u128),
|
|
||||||
Field(String),
|
|
||||||
Group(String),
|
|
||||||
Boolean(bool),
|
|
||||||
Array(Vec<InputValue>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
|
||||||
pub struct Function {
|
|
||||||
pub function_name: Identifier,
|
|
||||||
pub inputs: Vec<InputModel>,
|
|
||||||
pub returns: Vec<Type>,
|
|
||||||
pub statements: Vec<Statement>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Function {
|
|
||||||
pub fn get_name(&self) -> String {
|
|
||||||
self.function_name.name.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tests
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub struct Test(pub Function);
|
|
||||||
|
|
||||||
/// A simple program with statement expressions, program arguments and program returns.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Program {
|
|
||||||
pub name: Identifier,
|
|
||||||
pub num_parameters: usize,
|
|
||||||
pub imports: Vec<Import>,
|
|
||||||
pub circuits: HashMap<Identifier, Circuit>,
|
|
||||||
pub functions: HashMap<Identifier, Function>,
|
|
||||||
pub tests: HashMap<Identifier, Test>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> Program {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
name: Identifier::new("".into()),
|
|
||||||
num_parameters: 0,
|
|
||||||
imports: vec![],
|
|
||||||
circuits: HashMap::new(),
|
|
||||||
functions: HashMap::new(),
|
|
||||||
tests: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_name(&self) -> String {
|
|
||||||
self.name.name.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name(mut self, name: String) -> Self {
|
|
||||||
self.name = Identifier::new(name);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,385 +0,0 @@
|
|||||||
//! Format display functions for Leo types.
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
Assignee, Circuit, CircuitMember, ConditionalNestedOrEnd, ConditionalStatement, Expression,
|
|
||||||
Function, Identifier, InputModel, InputValue, Integer, IntegerType, RangeOrExpression,
|
|
||||||
SpreadOrExpression, Statement, Type, Variable,
|
|
||||||
};
|
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
impl fmt::Display for Identifier {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{}", self.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl fmt::Debug for Identifier {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{}", self.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Variable {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
if self.mutable {
|
|
||||||
write!(f, "mut ")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
write!(f, "{}", self.identifier)?;
|
|
||||||
|
|
||||||
if self._type.is_some() {
|
|
||||||
write!(f, ": {}", self._type.as_ref().unwrap())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
write!(f, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Integer {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{}{}", self.to_usize(), self.get_type())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> fmt::Display for RangeOrExpression {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
RangeOrExpression::Range(ref from, ref to) => write!(
|
|
||||||
f,
|
|
||||||
"{}..{}",
|
|
||||||
from.as_ref()
|
|
||||||
.map(|e| format!("{}", e))
|
|
||||||
.unwrap_or("".to_string()),
|
|
||||||
to.as_ref()
|
|
||||||
.map(|e| format!("{}", e))
|
|
||||||
.unwrap_or("".to_string())
|
|
||||||
),
|
|
||||||
RangeOrExpression::Expression(ref e) => write!(f, "{}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for SpreadOrExpression {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
SpreadOrExpression::Spread(ref spread) => write!(f, "...{}", spread),
|
|
||||||
SpreadOrExpression::Expression(ref expression) => write!(f, "{}", expression),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> fmt::Display for Expression {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
// Variables
|
|
||||||
Expression::Identifier(ref variable) => write!(f, "{}", variable),
|
|
||||||
|
|
||||||
// Values
|
|
||||||
Expression::Integer(ref integer) => write!(f, "{}", integer),
|
|
||||||
Expression::Field(ref field) => write!(f, "{}", field),
|
|
||||||
Expression::Group(ref group) => write!(f, "{}", group),
|
|
||||||
Expression::Boolean(ref bool) => write!(f, "{}", bool.get_value().unwrap()),
|
|
||||||
Expression::Implicit(ref value) => write!(f, "{}", value),
|
|
||||||
|
|
||||||
// Number operations
|
|
||||||
Expression::Add(ref left, ref right) => write!(f, "{} + {}", left, right),
|
|
||||||
Expression::Sub(ref left, ref right) => write!(f, "{} - {}", left, right),
|
|
||||||
Expression::Mul(ref left, ref right) => write!(f, "{} * {}", left, right),
|
|
||||||
Expression::Div(ref left, ref right) => write!(f, "{} / {}", left, right),
|
|
||||||
Expression::Pow(ref left, ref right) => write!(f, "{} ** {}", left, right),
|
|
||||||
|
|
||||||
// Boolean operations
|
|
||||||
Expression::Not(ref expression) => write!(f, "!{}", expression),
|
|
||||||
Expression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs),
|
|
||||||
Expression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs),
|
|
||||||
Expression::Eq(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
|
|
||||||
Expression::Ge(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs),
|
|
||||||
Expression::Gt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs),
|
|
||||||
Expression::Le(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs),
|
|
||||||
Expression::Lt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs),
|
|
||||||
|
|
||||||
// Conditionals
|
|
||||||
Expression::IfElse(ref first, ref second, ref third) => {
|
|
||||||
write!(f, "if {} then {} else {} fi", first, second, third)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Arrays
|
|
||||||
Expression::Array(ref array) => {
|
|
||||||
write!(f, "[")?;
|
|
||||||
for (i, e) in array.iter().enumerate() {
|
|
||||||
write!(f, "{}", e)?;
|
|
||||||
if i < array.len() - 1 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(f, "]")
|
|
||||||
}
|
|
||||||
Expression::ArrayAccess(ref array, ref index) => write!(f, "{}[{}]", array, index),
|
|
||||||
|
|
||||||
// Circuits
|
|
||||||
Expression::Circuit(ref var, ref members) => {
|
|
||||||
write!(f, "{} {{", var)?;
|
|
||||||
for (i, member) in members.iter().enumerate() {
|
|
||||||
write!(f, "{}: {}", member.identifier, member.expression)?;
|
|
||||||
if i < members.len() - 1 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(f, "}}")
|
|
||||||
}
|
|
||||||
Expression::CircuitMemberAccess(ref circuit_name, ref member) => {
|
|
||||||
write!(f, "{}.{}", circuit_name, member)
|
|
||||||
}
|
|
||||||
Expression::CircuitStaticFunctionAccess(ref circuit_name, ref member) => {
|
|
||||||
write!(f, "{}::{}", circuit_name, member)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function calls
|
|
||||||
Expression::FunctionCall(ref function, ref arguments) => {
|
|
||||||
write!(f, "{}(", function,)?;
|
|
||||||
for (i, param) in arguments.iter().enumerate() {
|
|
||||||
write!(f, "{}", param)?;
|
|
||||||
if i < arguments.len() - 1 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(f, ")")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Assignee {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
Assignee::Identifier(ref variable) => write!(f, "{}", variable),
|
|
||||||
Assignee::Array(ref array, ref index) => write!(f, "{}[{}]", array, index),
|
|
||||||
Assignee::CircuitField(ref circuit_variable, ref member) => {
|
|
||||||
write!(f, "{}.{}", circuit_variable, member)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for ConditionalNestedOrEnd {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
ConditionalNestedOrEnd::Nested(ref nested) => write!(f, "else {}", nested),
|
|
||||||
ConditionalNestedOrEnd::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 IntegerType {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
IntegerType::U8 => write!(f, "u8"),
|
|
||||||
IntegerType::U16 => write!(f, "u16"),
|
|
||||||
IntegerType::U32 => write!(f, "u32"),
|
|
||||||
IntegerType::U64 => write!(f, "u64"),
|
|
||||||
IntegerType::U128 => write!(f, "u128"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Type {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type),
|
|
||||||
Type::Field => write!(f, "field"),
|
|
||||||
Type::Group => write!(f, "group"),
|
|
||||||
Type::Boolean => write!(f, "bool"),
|
|
||||||
Type::Circuit(ref variable) => write!(f, "{}", variable),
|
|
||||||
Type::SelfType => write!(f, "Self"),
|
|
||||||
Type::Array(ref array, ref dimensions) => {
|
|
||||||
write!(f, "{}", *array)?;
|
|
||||||
for row in dimensions {
|
|
||||||
write!(f, "[{}]", row)?;
|
|
||||||
}
|
|
||||||
write!(f, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for CircuitMember {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
CircuitMember::CircuitField(ref identifier, ref _type) => {
|
|
||||||
write!(f, "{}: {}", identifier, _type)
|
|
||||||
}
|
|
||||||
CircuitMember::CircuitFunction(ref _static, ref function) => {
|
|
||||||
if *_static {
|
|
||||||
write!(f, "static ")?;
|
|
||||||
}
|
|
||||||
write!(f, "{}", function)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Circuit {
|
|
||||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "circuit {} {{ \n", self.identifier)?;
|
|
||||||
for field in self.members.iter() {
|
|
||||||
write!(f, " {}\n", field)?;
|
|
||||||
}
|
|
||||||
write!(f, "}}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// impl fmt::Display for Circuit {// uncomment when we no longer print out Program
|
|
||||||
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
// self.format(f)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
impl fmt::Debug for Circuit {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self.format(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for InputModel {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
// mut var: private bool
|
|
||||||
if self.mutable {
|
|
||||||
write!(f, "mut ")?;
|
|
||||||
}
|
|
||||||
write!(f, "{}: ", self.identifier)?;
|
|
||||||
if self.private {
|
|
||||||
write!(f, "private ")?;
|
|
||||||
} else {
|
|
||||||
write!(f, "public ")?;
|
|
||||||
}
|
|
||||||
write!(f, "{}", self._type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for InputValue {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
InputValue::Integer(ref integer) => write!(f, "{}", integer),
|
|
||||||
InputValue::Field(ref field) => write!(f, "{}", field),
|
|
||||||
InputValue::Group(ref group) => write!(f, "{}", group),
|
|
||||||
InputValue::Boolean(ref bool) => write!(f, "{}", bool),
|
|
||||||
InputValue::Array(ref array) => {
|
|
||||||
write!(f, "[")?;
|
|
||||||
for (i, e) in array.iter().enumerate() {
|
|
||||||
write!(f, "{}", e)?;
|
|
||||||
if i < array.len() - 1 {
|
|
||||||
write!(f, ", ")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(f, "]")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Function {
|
|
||||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "function {}", self.function_name)?;
|
|
||||||
let parameters = self
|
|
||||||
.inputs
|
|
||||||
.iter()
|
|
||||||
.map(|x| format!("{}", x))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(",");
|
|
||||||
let returns = self
|
|
||||||
.returns
|
|
||||||
.iter()
|
|
||||||
.map(|r| format!("{}", r))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(",");
|
|
||||||
let statements = self
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|s| format!("\t{}\n", s))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("");
|
|
||||||
if self.returns.len() == 0 {
|
|
||||||
write!(f, "({}) {{\n{}}}", parameters, statements,)
|
|
||||||
} else if self.returns.len() == 1 {
|
|
||||||
write!(f, "({}) -> {} {{\n{}}}", parameters, returns, statements,)
|
|
||||||
} else {
|
|
||||||
write!(f, "({}) -> ({}) {{\n{}}}", parameters, returns, statements,)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Function {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self.format(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for Function {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self.format(f)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,920 +0,0 @@
|
|||||||
//! Logic to convert from an abstract syntax tree (ast) representation to a Leo program.
|
|
||||||
|
|
||||||
use crate::{types, Import, ImportSymbol};
|
|
||||||
use leo_ast::{
|
|
||||||
File,
|
|
||||||
access::{
|
|
||||||
Access,
|
|
||||||
AssigneeAccess,
|
|
||||||
},
|
|
||||||
circuits::{
|
|
||||||
Circuit,
|
|
||||||
CircuitField,
|
|
||||||
CircuitFieldDefinition,
|
|
||||||
CircuitFunction,
|
|
||||||
CircuitMember
|
|
||||||
},
|
|
||||||
common::{
|
|
||||||
Assignee,
|
|
||||||
Identifier,
|
|
||||||
RangeOrExpression as AstRangeOrExpression,
|
|
||||||
SpreadOrExpression as AstSpreadOrExpression,
|
|
||||||
Variable as AstVariable,
|
|
||||||
Visibility,
|
|
||||||
Private,
|
|
||||||
},
|
|
||||||
expressions::{
|
|
||||||
ArrayInitializerExpression,
|
|
||||||
ArrayInlineExpression,
|
|
||||||
BinaryExpression,
|
|
||||||
CircuitInlineExpression,
|
|
||||||
Expression,
|
|
||||||
NotExpression,
|
|
||||||
PostfixExpression,
|
|
||||||
TernaryExpression
|
|
||||||
},
|
|
||||||
functions::{
|
|
||||||
Function,
|
|
||||||
FunctionInput,
|
|
||||||
TestFunction
|
|
||||||
},
|
|
||||||
imports::{
|
|
||||||
Import as AstImport,
|
|
||||||
ImportSymbol as AstImportSymbol,
|
|
||||||
},
|
|
||||||
operations::{
|
|
||||||
AssignOperation,
|
|
||||||
BinaryOperation,
|
|
||||||
},
|
|
||||||
statements::{
|
|
||||||
AssertStatement,
|
|
||||||
AssignStatement,
|
|
||||||
ConditionalStatement,
|
|
||||||
ConditionalNestedOrEndStatement,
|
|
||||||
DefinitionStatement,
|
|
||||||
ExpressionStatement,
|
|
||||||
ForStatement,
|
|
||||||
MultipleAssignmentStatement,
|
|
||||||
ReturnStatement,
|
|
||||||
Statement,
|
|
||||||
},
|
|
||||||
types::{
|
|
||||||
ArrayType,
|
|
||||||
CircuitType,
|
|
||||||
DataType,
|
|
||||||
IntegerType,
|
|
||||||
Type as AstType
|
|
||||||
},
|
|
||||||
values::{
|
|
||||||
BooleanValue,
|
|
||||||
FieldValue,
|
|
||||||
GroupValue,
|
|
||||||
IntegerValue,
|
|
||||||
NumberValue,
|
|
||||||
NumberImplicitValue,
|
|
||||||
Value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
use snarkos_models::gadgets::utilities::{
|
|
||||||
boolean::Boolean,
|
|
||||||
uint::{UInt128, UInt16, UInt32, UInt64, UInt8},
|
|
||||||
};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
/// pest ast -> types::Identifier
|
|
||||||
|
|
||||||
impl<'ast> From<Identifier<'ast>> for types::Identifier {
|
|
||||||
fn from(identifier: Identifier<'ast>) -> Self {
|
|
||||||
types::Identifier::new(identifier.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<Identifier<'ast>> for types::Expression {
|
|
||||||
fn from(identifier: Identifier<'ast>) -> Self {
|
|
||||||
types::Expression::Identifier(types::Identifier::from(identifier))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Variable
|
|
||||||
|
|
||||||
impl<'ast> From<AstVariable<'ast>> for types::Variable {
|
|
||||||
fn from(variable: AstVariable<'ast>) -> Self {
|
|
||||||
types::Variable {
|
|
||||||
identifier: types::Identifier::from(variable.identifier),
|
|
||||||
mutable: variable.mutable.is_some(),
|
|
||||||
_type: variable._type.map(|_type| types::Type::from(_type)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast - types::Integer
|
|
||||||
|
|
||||||
impl<'ast> types::Integer {
|
|
||||||
pub(crate) fn from(number: NumberValue<'ast>, _type: IntegerType) -> Self {
|
|
||||||
match _type {
|
|
||||||
IntegerType::U8Type(_u8) => types::Integer::U8(UInt8::constant(
|
|
||||||
number.value.parse::<u8>().expect("unable to parse u8"),
|
|
||||||
)),
|
|
||||||
IntegerType::U16Type(_u16) => types::Integer::U16(UInt16::constant(
|
|
||||||
number.value.parse::<u16>().expect("unable to parse u16"),
|
|
||||||
)),
|
|
||||||
IntegerType::U32Type(_u32) => types::Integer::U32(UInt32::constant(
|
|
||||||
number
|
|
||||||
.value
|
|
||||||
.parse::<u32>()
|
|
||||||
.expect("unable to parse integers.u32"),
|
|
||||||
)),
|
|
||||||
IntegerType::U64Type(_u64) => types::Integer::U64(UInt64::constant(
|
|
||||||
number.value.parse::<u64>().expect("unable to parse u64"),
|
|
||||||
)),
|
|
||||||
IntegerType::U128Type(_u128) => types::Integer::U128(UInt128::constant(
|
|
||||||
number.value.parse::<u128>().expect("unable to parse u128"),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn from_implicit(number: String) -> Self {
|
|
||||||
types::Integer::U128(UInt128::constant(
|
|
||||||
number.parse::<u128>().expect("unable to parse u128"),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<IntegerValue<'ast>> for types::Expression {
|
|
||||||
fn from(field: IntegerValue<'ast>) -> Self {
|
|
||||||
types::Expression::Integer(types::Integer::from(field.number, field._type))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<AstRangeOrExpression<'ast>> for types::RangeOrExpression {
|
|
||||||
fn from(range_or_expression: AstRangeOrExpression<'ast>) -> Self {
|
|
||||||
match range_or_expression {
|
|
||||||
AstRangeOrExpression::Range(range) => {
|
|
||||||
let from = range
|
|
||||||
.from
|
|
||||||
.map(|from| match types::Expression::from(from.0) {
|
|
||||||
types::Expression::Integer(number) => number,
|
|
||||||
types::Expression::Implicit(string) => {
|
|
||||||
types::Integer::from_implicit(string)
|
|
||||||
}
|
|
||||||
expression => {
|
|
||||||
unimplemented!("Range bounds should be integers, found {}", expression)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let to = range.to.map(|to| match types::Expression::from(to.0) {
|
|
||||||
types::Expression::Integer(number) => number,
|
|
||||||
types::Expression::Implicit(string) => types::Integer::from_implicit(string),
|
|
||||||
expression => {
|
|
||||||
unimplemented!("Range bounds should be integers, found {}", expression)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
types::RangeOrExpression::Range(from, to)
|
|
||||||
}
|
|
||||||
AstRangeOrExpression::Expression(expression) => {
|
|
||||||
types::RangeOrExpression::Expression(types::Expression::from(expression))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Field
|
|
||||||
|
|
||||||
impl<'ast> From<FieldValue<'ast>> for types::Expression {
|
|
||||||
fn from(field: FieldValue<'ast>) -> Self {
|
|
||||||
types::Expression::Field(field.number.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Group
|
|
||||||
|
|
||||||
impl<'ast> From<GroupValue<'ast>> for types::Expression {
|
|
||||||
fn from(group: GroupValue<'ast>) -> Self {
|
|
||||||
types::Expression::Group(group.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Boolean
|
|
||||||
|
|
||||||
impl<'ast> From<BooleanValue<'ast>> for types::Expression {
|
|
||||||
fn from(boolean: BooleanValue<'ast>) -> Self {
|
|
||||||
types::Expression::Boolean(Boolean::Constant(
|
|
||||||
boolean
|
|
||||||
.value
|
|
||||||
.parse::<bool>()
|
|
||||||
.expect("unable to parse boolean"),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::NumberImplicit
|
|
||||||
|
|
||||||
impl<'ast> From<NumberImplicitValue<'ast>> for types::Expression {
|
|
||||||
fn from(number: NumberImplicitValue<'ast>) -> Self {
|
|
||||||
types::Expression::Implicit(number.number.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Expression
|
|
||||||
|
|
||||||
impl<'ast> From<Value<'ast>> for types::Expression {
|
|
||||||
fn from(value: Value<'ast>) -> Self {
|
|
||||||
match value {
|
|
||||||
Value::Integer(num) => types::Expression::from(num),
|
|
||||||
Value::Field(field) => types::Expression::from(field),
|
|
||||||
Value::Group(group) => types::Expression::from(group),
|
|
||||||
Value::Boolean(bool) => types::Expression::from(bool),
|
|
||||||
Value::Implicit(value) => types::Expression::from(value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<NotExpression<'ast>> for types::Expression {
|
|
||||||
fn from(expression: NotExpression<'ast>) -> Self {
|
|
||||||
types::Expression::Not(Box::new(types::Expression::from(*expression.expression)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<AstSpreadOrExpression<'ast>> for types::SpreadOrExpression {
|
|
||||||
fn from(s_or_e: AstSpreadOrExpression<'ast>) -> Self {
|
|
||||||
match s_or_e {
|
|
||||||
AstSpreadOrExpression::Spread(spread) => {
|
|
||||||
types::SpreadOrExpression::Spread(types::Expression::from(spread.expression))
|
|
||||||
}
|
|
||||||
AstSpreadOrExpression::Expression(expression) => {
|
|
||||||
types::SpreadOrExpression::Expression(types::Expression::from(expression))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<BinaryExpression<'ast>> for types::Expression {
|
|
||||||
fn from(expression: BinaryExpression<'ast>) -> Self {
|
|
||||||
match expression.operation {
|
|
||||||
// Boolean operations
|
|
||||||
BinaryOperation::Or => types::Expression::Or(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::And => types::Expression::And(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Eq => types::Expression::Eq(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Ne => {
|
|
||||||
types::Expression::Not(Box::new(types::Expression::from(expression)))
|
|
||||||
}
|
|
||||||
BinaryOperation::Ge => types::Expression::Ge(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Gt => types::Expression::Gt(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Le => types::Expression::Le(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Lt => types::Expression::Lt(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
// Number operations
|
|
||||||
BinaryOperation::Add => types::Expression::Add(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Sub => types::Expression::Sub(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Mul => types::Expression::Mul(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Div => types::Expression::Div(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
BinaryOperation::Pow => types::Expression::Pow(
|
|
||||||
Box::new(types::Expression::from(*expression.left)),
|
|
||||||
Box::new(types::Expression::from(*expression.right)),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<TernaryExpression<'ast>> for types::Expression {
|
|
||||||
fn from(expression: TernaryExpression<'ast>) -> Self {
|
|
||||||
types::Expression::IfElse(
|
|
||||||
Box::new(types::Expression::from(*expression.first)),
|
|
||||||
Box::new(types::Expression::from(*expression.second)),
|
|
||||||
Box::new(types::Expression::from(*expression.third)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<ArrayInlineExpression<'ast>> for types::Expression {
|
|
||||||
fn from(array: 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> From<ArrayInitializerExpression<'ast>> for types::Expression {
|
|
||||||
fn from(array: ArrayInitializerExpression<'ast>) -> Self {
|
|
||||||
let count = types::Expression::get_count(array.count);
|
|
||||||
let expression = Box::new(types::SpreadOrExpression::from(*array.expression));
|
|
||||||
|
|
||||||
types::Expression::Array(vec![expression; count])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<CircuitField<'ast>> for types::CircuitFieldDefinition {
|
|
||||||
fn from(member: CircuitField<'ast>) -> Self {
|
|
||||||
types::CircuitFieldDefinition {
|
|
||||||
identifier: types::Identifier::from(member.identifier),
|
|
||||||
expression: types::Expression::from(member.expression),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<CircuitInlineExpression<'ast>> for types::Expression {
|
|
||||||
fn from(expression: CircuitInlineExpression<'ast>) -> Self {
|
|
||||||
let variable = types::Identifier::from(expression.identifier);
|
|
||||||
let members = expression
|
|
||||||
.members
|
|
||||||
.into_iter()
|
|
||||||
.map(|member| types::CircuitFieldDefinition::from(member))
|
|
||||||
.collect::<Vec<types::CircuitFieldDefinition>>();
|
|
||||||
|
|
||||||
types::Expression::Circuit(variable, members)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<PostfixExpression<'ast>> for types::Expression {
|
|
||||||
fn from(expression: PostfixExpression<'ast>) -> Self {
|
|
||||||
let variable =
|
|
||||||
types::Expression::Identifier(types::Identifier::from(expression.identifier));
|
|
||||||
|
|
||||||
// ast::PostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but Access call expressions
|
|
||||||
// are recursive, so it is `Select(Call(a, 34), 42)`. We apply this transformation here
|
|
||||||
|
|
||||||
// we start with the id, and we fold the array of accesses by wrapping the current value
|
|
||||||
expression
|
|
||||||
.accesses
|
|
||||||
.into_iter()
|
|
||||||
.fold(variable, |acc, access| match access {
|
|
||||||
// Handle array accesses
|
|
||||||
Access::Array(array) => types::Expression::ArrayAccess(
|
|
||||||
Box::new(acc),
|
|
||||||
Box::new(types::RangeOrExpression::from(array.expression)),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Handle function calls
|
|
||||||
Access::Call(function) => types::Expression::FunctionCall(
|
|
||||||
Box::new(acc),
|
|
||||||
function
|
|
||||||
.expressions
|
|
||||||
.into_iter()
|
|
||||||
.map(|expression| types::Expression::from(expression))
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Handle circuit member accesses
|
|
||||||
Access::Object(circuit_object) => types::Expression::CircuitMemberAccess(
|
|
||||||
Box::new(acc),
|
|
||||||
types::Identifier::from(circuit_object.identifier),
|
|
||||||
),
|
|
||||||
Access::StaticObject(circuit_object) => {
|
|
||||||
types::Expression::CircuitStaticFunctionAccess(
|
|
||||||
Box::new(acc),
|
|
||||||
types::Identifier::from(circuit_object.identifier),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<Expression<'ast>> for types::Expression {
|
|
||||||
fn from(expression: Expression<'ast>) -> Self {
|
|
||||||
match expression {
|
|
||||||
Expression::Value(value) => types::Expression::from(value),
|
|
||||||
Expression::Identifier(variable) => types::Expression::from(variable),
|
|
||||||
Expression::Not(expression) => types::Expression::from(expression),
|
|
||||||
Expression::Binary(expression) => types::Expression::from(expression),
|
|
||||||
Expression::Ternary(expression) => types::Expression::from(expression),
|
|
||||||
Expression::ArrayInline(expression) => types::Expression::from(expression),
|
|
||||||
Expression::ArrayInitializer(expression) => types::Expression::from(expression),
|
|
||||||
Expression::CircuitInline(expression) => types::Expression::from(expression),
|
|
||||||
Expression::Postfix(expression) => types::Expression::from(expression),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> types::Expression {
|
|
||||||
fn get_count(count: Value<'ast>) -> usize {
|
|
||||||
match count {
|
|
||||||
Value::Integer(integer) => integer
|
|
||||||
.number
|
|
||||||
.value
|
|
||||||
.parse::<usize>()
|
|
||||||
.expect("Unable to read array size"),
|
|
||||||
Value::Implicit(number) => number
|
|
||||||
.number
|
|
||||||
.value
|
|
||||||
.parse::<usize>()
|
|
||||||
.expect("Unable to read array size"),
|
|
||||||
size => unimplemented!("Array size should be an integer {}", size),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assignee -> types::Expression for operator assign statements
|
|
||||||
impl<'ast> From<Assignee<'ast>> for types::Expression {
|
|
||||||
fn from(assignee: Assignee<'ast>) -> Self {
|
|
||||||
let variable = types::Expression::Identifier(types::Identifier::from(assignee.identifier));
|
|
||||||
|
|
||||||
// we start with the id, and we fold the array of accesses by wrapping the current value
|
|
||||||
assignee
|
|
||||||
.accesses
|
|
||||||
.into_iter()
|
|
||||||
.fold(variable, |acc, access| match access {
|
|
||||||
AssigneeAccess::Member(circuit_member) => {
|
|
||||||
types::Expression::CircuitMemberAccess(
|
|
||||||
Box::new(acc),
|
|
||||||
types::Identifier::from(circuit_member.identifier),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
AssigneeAccess::Array(array) => types::Expression::ArrayAccess(
|
|
||||||
Box::new(acc),
|
|
||||||
Box::new(types::RangeOrExpression::from(array.expression)),
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Assignee
|
|
||||||
|
|
||||||
impl<'ast> From<Identifier<'ast>> for types::Assignee {
|
|
||||||
fn from(variable: Identifier<'ast>) -> Self {
|
|
||||||
types::Assignee::Identifier(types::Identifier::from(variable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<Assignee<'ast>> for types::Assignee {
|
|
||||||
fn from(assignee: Assignee<'ast>) -> Self {
|
|
||||||
let variable = types::Assignee::from(assignee.identifier);
|
|
||||||
|
|
||||||
// we start with the id, and we fold the array of accesses by wrapping the current value
|
|
||||||
assignee
|
|
||||||
.accesses
|
|
||||||
.into_iter()
|
|
||||||
.fold(variable, |acc, access| match access {
|
|
||||||
AssigneeAccess::Array(array) => types::Assignee::Array(
|
|
||||||
Box::new(acc),
|
|
||||||
types::RangeOrExpression::from(array.expression),
|
|
||||||
),
|
|
||||||
AssigneeAccess::Member(circuit_field) => types::Assignee::CircuitField(
|
|
||||||
Box::new(acc),
|
|
||||||
types::Identifier::from(circuit_field.identifier),
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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| types::Expression::from(expression))
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<DefinitionStatement<'ast>> for types::Statement {
|
|
||||||
fn from(statement: DefinitionStatement<'ast>) -> Self {
|
|
||||||
types::Statement::Definition(
|
|
||||||
types::Variable::from(statement.variable),
|
|
||||||
types::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(
|
|
||||||
types::Assignee::from(statement.assignee),
|
|
||||||
types::Expression::from(statement.expression),
|
|
||||||
),
|
|
||||||
operation_assign => {
|
|
||||||
// convert assignee into postfix expression
|
|
||||||
let converted = types::Expression::from(statement.assignee.clone());
|
|
||||||
|
|
||||||
match operation_assign {
|
|
||||||
AssignOperation::AddAssign(ref _assign) => types::Statement::Assign(
|
|
||||||
types::Assignee::from(statement.assignee),
|
|
||||||
types::Expression::Add(
|
|
||||||
Box::new(converted),
|
|
||||||
Box::new(types::Expression::from(statement.expression)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
AssignOperation::SubAssign(ref _assign) => types::Statement::Assign(
|
|
||||||
types::Assignee::from(statement.assignee),
|
|
||||||
types::Expression::Sub(
|
|
||||||
Box::new(converted),
|
|
||||||
Box::new(types::Expression::from(statement.expression)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
AssignOperation::MulAssign(ref _assign) => types::Statement::Assign(
|
|
||||||
types::Assignee::from(statement.assignee),
|
|
||||||
types::Expression::Mul(
|
|
||||||
Box::new(converted),
|
|
||||||
Box::new(types::Expression::from(statement.expression)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
AssignOperation::DivAssign(ref _assign) => types::Statement::Assign(
|
|
||||||
types::Assignee::from(statement.assignee),
|
|
||||||
types::Expression::Div(
|
|
||||||
Box::new(converted),
|
|
||||||
Box::new(types::Expression::from(statement.expression)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
AssignOperation::PowAssign(ref _assign) => types::Statement::Assign(
|
|
||||||
types::Assignee::from(statement.assignee),
|
|
||||||
types::Expression::Pow(
|
|
||||||
Box::new(converted),
|
|
||||||
Box::new(types::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| types::Variable::from(typed_variable))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
types::Statement::MultipleAssign(
|
|
||||||
variables,
|
|
||||||
types::Expression::FunctionCall(
|
|
||||||
Box::new(types::Expression::from(statement.function_name)),
|
|
||||||
statement
|
|
||||||
.arguments
|
|
||||||
.into_iter()
|
|
||||||
.map(|e| types::Expression::from(e))
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<ConditionalNestedOrEndStatement<'ast>> for types::ConditionalNestedOrEnd {
|
|
||||||
fn from(statement: ConditionalNestedOrEndStatement<'ast>) -> Self {
|
|
||||||
match statement {
|
|
||||||
ConditionalNestedOrEndStatement::Nested(nested) => types::ConditionalNestedOrEnd::Nested(
|
|
||||||
Box::new(types::ConditionalStatement::from(*nested)),
|
|
||||||
),
|
|
||||||
ConditionalNestedOrEndStatement::End(statements) => types::ConditionalNestedOrEnd::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: types::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::ConditionalNestedOrEnd::from(n_or_e)))
|
|
||||||
.unwrap_or(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<ForStatement<'ast>> for types::Statement {
|
|
||||||
fn from(statement: ForStatement<'ast>) -> Self {
|
|
||||||
let from = match types::Expression::from(statement.start) {
|
|
||||||
types::Expression::Integer(number) => number,
|
|
||||||
types::Expression::Implicit(string) => types::Integer::from_implicit(string),
|
|
||||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
|
||||||
};
|
|
||||||
let to = match types::Expression::from(statement.stop) {
|
|
||||||
types::Expression::Integer(number) => number,
|
|
||||||
types::Expression::Implicit(string) => types::Integer::from_implicit(string),
|
|
||||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
|
||||||
};
|
|
||||||
|
|
||||||
types::Statement::For(
|
|
||||||
types::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(
|
|
||||||
types::Expression::from(assert_eq.left),
|
|
||||||
types::Expression::from(assert_eq.right),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<ExpressionStatement<'ast>> for types::Statement {
|
|
||||||
fn from(statement: ExpressionStatement<'ast>) -> Self {
|
|
||||||
types::Statement::Expression(types::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 -> Explicit types::Type for defining circuit members and function params
|
|
||||||
|
|
||||||
impl From<IntegerType> for types::IntegerType {
|
|
||||||
fn from(integer_type: IntegerType) -> Self {
|
|
||||||
match integer_type {
|
|
||||||
IntegerType::U8Type(_type) => types::IntegerType::U8,
|
|
||||||
IntegerType::U16Type(_type) => types::IntegerType::U16,
|
|
||||||
IntegerType::U32Type(_type) => types::IntegerType::U32,
|
|
||||||
IntegerType::U64Type(_type) => types::IntegerType::U64,
|
|
||||||
IntegerType::U128Type(_type) => types::IntegerType::U128,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<DataType> for types::Type {
|
|
||||||
fn from(basic_type: DataType) -> Self {
|
|
||||||
match basic_type {
|
|
||||||
DataType::Integer(_type) => {
|
|
||||||
types::Type::IntegerType(types::IntegerType::from(_type))
|
|
||||||
}
|
|
||||||
DataType::Field(_type) => types::Type::Field,
|
|
||||||
DataType::Group(_type) => types::Type::Group,
|
|
||||||
DataType::Boolean(_type) => types::Type::Boolean,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<ArrayType<'ast>> for types::Type {
|
|
||||||
fn from(array_type: ArrayType<'ast>) -> Self {
|
|
||||||
let element_type = Box::new(types::Type::from(array_type._type));
|
|
||||||
let dimensions = array_type
|
|
||||||
.dimensions
|
|
||||||
.into_iter()
|
|
||||||
.map(|row| types::Expression::get_count(row))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
types::Type::Array(element_type, dimensions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<CircuitType<'ast>> for types::Type {
|
|
||||||
fn from(circuit_type: CircuitType<'ast>) -> Self {
|
|
||||||
types::Type::Circuit(types::Identifier::from(circuit_type.identifier))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<AstType<'ast>> for types::Type {
|
|
||||||
fn from(_type: AstType<'ast>) -> Self {
|
|
||||||
match _type {
|
|
||||||
AstType::Basic(_type) => types::Type::from(_type),
|
|
||||||
AstType::Array(_type) => types::Type::from(_type),
|
|
||||||
AstType::Circuit(_type) => types::Type::from(_type),
|
|
||||||
AstType::SelfType(_type) => types::Type::SelfType,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Circuit
|
|
||||||
|
|
||||||
impl<'ast> From<CircuitFieldDefinition<'ast>> for types::CircuitMember {
|
|
||||||
fn from(circuit_value: CircuitFieldDefinition<'ast>) -> Self {
|
|
||||||
types::CircuitMember::CircuitField(
|
|
||||||
types::Identifier::from(circuit_value.identifier),
|
|
||||||
types::Type::from(circuit_value._type),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<CircuitFunction<'ast>> for types::CircuitMember {
|
|
||||||
fn from(circuit_function: CircuitFunction<'ast>) -> Self {
|
|
||||||
types::CircuitMember::CircuitFunction(
|
|
||||||
circuit_function._static.is_some(),
|
|
||||||
types::Function::from(circuit_function.function),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<CircuitMember<'ast>> for types::CircuitMember {
|
|
||||||
fn from(object: CircuitMember<'ast>) -> Self {
|
|
||||||
match object {
|
|
||||||
CircuitMember::CircuitFieldDefinition(circuit_value) => {
|
|
||||||
types::CircuitMember::from(circuit_value)
|
|
||||||
}
|
|
||||||
CircuitMember::CircuitFunction(circuit_function) => {
|
|
||||||
types::CircuitMember::from(circuit_function)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<Circuit<'ast>> for types::Circuit {
|
|
||||||
fn from(circuit: Circuit<'ast>) -> Self {
|
|
||||||
let variable = types::Identifier::from(circuit.identifier);
|
|
||||||
let members = circuit
|
|
||||||
.members
|
|
||||||
.into_iter()
|
|
||||||
.map(|member| types::CircuitMember::from(member))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
types::Circuit {
|
|
||||||
identifier: variable,
|
|
||||||
members,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> function types::Parameters
|
|
||||||
|
|
||||||
impl<'ast> From<FunctionInput<'ast>> for types::InputModel {
|
|
||||||
fn from(parameter: FunctionInput<'ast>) -> Self {
|
|
||||||
types::InputModel {
|
|
||||||
identifier: types::Identifier::from(parameter.identifier),
|
|
||||||
mutable: parameter.mutable.is_some(),
|
|
||||||
// private by default
|
|
||||||
private: parameter.visibility.map_or(true, |visibility| {
|
|
||||||
visibility.eq(&Visibility::Private(Private {}))
|
|
||||||
}),
|
|
||||||
_type: types::Type::from(parameter._type),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Function
|
|
||||||
|
|
||||||
impl<'ast> From<Function<'ast>> for types::Function {
|
|
||||||
fn from(function_definition: Function<'ast>) -> Self {
|
|
||||||
let function_name = types::Identifier::from(function_definition.function_name);
|
|
||||||
let parameters = function_definition
|
|
||||||
.parameters
|
|
||||||
.into_iter()
|
|
||||||
.map(|parameter| types::InputModel::from(parameter))
|
|
||||||
.collect();
|
|
||||||
let returns = function_definition
|
|
||||||
.returns
|
|
||||||
.into_iter()
|
|
||||||
.map(|return_type| types::Type::from(return_type))
|
|
||||||
.collect();
|
|
||||||
let statements = function_definition
|
|
||||||
.statements
|
|
||||||
.into_iter()
|
|
||||||
.map(|statement| types::Statement::from(statement))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
types::Function {
|
|
||||||
function_name,
|
|
||||||
inputs: parameters,
|
|
||||||
returns,
|
|
||||||
statements,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> Import
|
|
||||||
|
|
||||||
impl<'ast> From<AstImportSymbol<'ast>> for ImportSymbol {
|
|
||||||
fn from(symbol: AstImportSymbol<'ast>) -> Self {
|
|
||||||
ImportSymbol {
|
|
||||||
symbol: types::Identifier::from(symbol.value),
|
|
||||||
alias: symbol.alias.map(|alias| types::Identifier::from(alias)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<AstImport<'ast>> for Import {
|
|
||||||
fn from(import: AstImport<'ast>) -> Self {
|
|
||||||
Import {
|
|
||||||
path_string: import.source.value,
|
|
||||||
symbols: import
|
|
||||||
.symbols
|
|
||||||
.into_iter()
|
|
||||||
.map(|symbol| ImportSymbol::from(symbol))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> Test
|
|
||||||
impl<'ast> From<TestFunction<'ast>> for types::Test {
|
|
||||||
fn from(test: TestFunction) -> Self {
|
|
||||||
types::Test(types::Function::from(test.function))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pest ast -> types::Program
|
|
||||||
|
|
||||||
impl<'ast> types::Program {
|
|
||||||
pub fn from(file: File<'ast>, name: String) -> Self {
|
|
||||||
// Compiled ast -> aleo program representation
|
|
||||||
let imports = file
|
|
||||||
.imports
|
|
||||||
.into_iter()
|
|
||||||
.map(|import| Import::from(import))
|
|
||||||
.collect::<Vec<Import>>();
|
|
||||||
|
|
||||||
let mut circuits = HashMap::new();
|
|
||||||
let mut functions = HashMap::new();
|
|
||||||
let mut tests = HashMap::new();
|
|
||||||
let mut num_parameters = 0usize;
|
|
||||||
|
|
||||||
file.circuits.into_iter().for_each(|circuit| {
|
|
||||||
circuits.insert(
|
|
||||||
types::Identifier::from(circuit.identifier.clone()),
|
|
||||||
types::Circuit::from(circuit),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
file.functions.into_iter().for_each(|function_def| {
|
|
||||||
functions.insert(
|
|
||||||
types::Identifier::from(function_def.function_name.clone()),
|
|
||||||
types::Function::from(function_def),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
file.tests.into_iter().for_each(|test_def| {
|
|
||||||
tests.insert(
|
|
||||||
types::Identifier::from(test_def.function.function_name.clone()),
|
|
||||||
types::Test::from(test_def),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(main_function) = functions.get(&types::Identifier::new("main".into())) {
|
|
||||||
num_parameters = main_function.inputs.len();
|
|
||||||
}
|
|
||||||
|
|
||||||
types::Program {
|
|
||||||
name: types::Identifier::new(name),
|
|
||||||
num_parameters,
|
|
||||||
imports,
|
|
||||||
circuits,
|
|
||||||
functions,
|
|
||||||
tests,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,9 @@
|
|||||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||||
use leo_compiler::{
|
use leo_compiler::{
|
||||||
errors::{CompilerError, FunctionError, IntegerError},
|
errors::{CompilerError, FunctionError},
|
||||||
ConstrainedValue, InputValue, Integer,
|
ConstrainedValue,
|
||||||
};
|
};
|
||||||
|
use leo_types::{InputValue, Integer, IntegerError};
|
||||||
|
|
||||||
use snarkos_models::gadgets::utilities::uint::UInt32;
|
use snarkos_models::gadgets::utilities::uint::UInt32;
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||||
use leo_compiler::{
|
use leo_compiler::{
|
||||||
errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError},
|
errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError},
|
||||||
ConstrainedValue, InputValue,
|
ConstrainedValue,
|
||||||
};
|
};
|
||||||
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||||
|
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
compile_program, get_error, get_output, integer::u32::output_one, EdwardsConstrainedValue,
|
compile_program, get_error, get_output, integers::u32::output_one, EdwardsConstrainedValue,
|
||||||
EdwardsTestCompiler,
|
EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::{
|
use leo_compiler::{
|
||||||
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
|
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
|
||||||
ConstrainedCircuitMember, ConstrainedValue, Expression, Function, Identifier, Integer,
|
ConstrainedCircuitMember, ConstrainedValue,
|
||||||
Statement, Type,
|
|
||||||
};
|
};
|
||||||
|
use leo_types::{Expression, Function, Identifier, Integer,
|
||||||
|
Statement, Type,};
|
||||||
|
|
||||||
use snarkos_models::gadgets::utilities::uint::UInt32;
|
use snarkos_models::gadgets::utilities::uint::UInt32;
|
||||||
|
|
||||||
const DIRECTORY_NAME: &str = "tests/circuit/";
|
const DIRECTORY_NAME: &str = "tests/circuits/";
|
||||||
|
|
||||||
// Circ { x: 1u32 }
|
// Circ { x: 1u32 }
|
||||||
fn output_circuit(program: EdwardsTestCompiler) {
|
fn output_circuit(program: EdwardsTestCompiler) {
|
@ -2,8 +2,9 @@ use crate::boolean::{output_expected_boolean, output_false, output_true};
|
|||||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||||
use leo_compiler::{
|
use leo_compiler::{
|
||||||
errors::{CompilerError, FieldError, FunctionError},
|
errors::{CompilerError, FieldError, FunctionError},
|
||||||
ConstrainedValue, FieldType, InputValue,
|
ConstrainedValue, FieldType,
|
||||||
};
|
};
|
||||||
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_gadgets::curves::edwards_bls12::FqGadget;
|
use snarkos_gadgets::curves::edwards_bls12::FqGadget;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
compile_program, get_error, get_output, integer::u32::output_one, EdwardsConstrainedValue,
|
compile_program, get_error, get_output, integers::u32::output_one, EdwardsConstrainedValue,
|
||||||
EdwardsTestCompiler,
|
EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::{
|
use leo_compiler::{
|
||||||
|
@ -2,7 +2,8 @@ use crate::{
|
|||||||
boolean::{output_false, output_true},
|
boolean::{output_false, output_true},
|
||||||
compile_program, fail_enforce, get_output, EdwardsConstrainedValue, EdwardsTestCompiler,
|
compile_program, fail_enforce, get_output, EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::{group::edwards_bls12::EdwardsGroupType, ConstrainedValue, InputValue};
|
use leo_compiler::{group::edwards_bls12::EdwardsGroupType, ConstrainedValue};
|
||||||
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::{EdwardsAffine, Fq};
|
use snarkos_curves::edwards_bls12::{EdwardsAffine, Fq};
|
||||||
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{compile_program, integer::u32::output_one};
|
use crate::{compile_program, integers::u32::output_one};
|
||||||
|
|
||||||
const DIRECTORY_NAME: &str = "tests/import/";
|
const DIRECTORY_NAME: &str = "tests/import/";
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
pub mod macros;
|
pub mod macros;
|
||||||
|
|
||||||
use crate::{get_error, EdwardsTestCompiler};
|
use crate::{get_error, EdwardsTestCompiler};
|
||||||
use leo_compiler::errors::{CompilerError, FunctionError, IntegerError};
|
use leo_compiler::errors::{CompilerError, FunctionError};
|
||||||
|
use leo_types::IntegerError;
|
||||||
|
|
||||||
pub trait IntegerTester {
|
pub trait IntegerTester {
|
||||||
/// Tests use of the integer in a function input
|
/// Tests use of the integer in a function input
|
@ -1,16 +1,17 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
boolean::{output_expected_boolean, output_false, output_true},
|
boolean::{output_expected_boolean, output_false, output_true},
|
||||||
compile_program, get_output,
|
compile_program, get_output,
|
||||||
integer::{fail_integer, fail_synthesis, IntegerTester},
|
integers::{fail_integer, fail_synthesis, IntegerTester},
|
||||||
EdwardsConstrainedValue, EdwardsTestCompiler,
|
EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::{types::Integer, ConstrainedValue, InputValue};
|
use leo_compiler::ConstrainedValue;
|
||||||
|
use leo_types::{Integer, InputValue};
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt128};
|
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt128};
|
||||||
|
|
||||||
const DIRECTORY_NAME: &str = "tests/integer/u128/";
|
const DIRECTORY_NAME: &str = "tests/integers/u128/";
|
||||||
|
|
||||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt128) {
|
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt128) {
|
||||||
let output = get_output(program);
|
let output = get_output(program);
|
@ -1,16 +1,17 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
boolean::{output_expected_boolean, output_false, output_true},
|
boolean::{output_expected_boolean, output_false, output_true},
|
||||||
compile_program, get_output,
|
compile_program, get_output,
|
||||||
integer::{fail_integer, fail_synthesis, IntegerTester},
|
integers::{fail_integer, fail_synthesis, IntegerTester},
|
||||||
EdwardsConstrainedValue, EdwardsTestCompiler,
|
EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::{types::Integer, ConstrainedValue, InputValue};
|
use leo_compiler::ConstrainedValue;
|
||||||
|
use leo_types::{Integer, InputValue};
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt16};
|
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt16};
|
||||||
|
|
||||||
const DIRECTORY_NAME: &str = "tests/integer/u16/";
|
const DIRECTORY_NAME: &str = "tests/integers/u16/";
|
||||||
|
|
||||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt16) {
|
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt16) {
|
||||||
let output = get_output(program);
|
let output = get_output(program);
|
@ -1,16 +1,17 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
boolean::{output_expected_boolean, output_false, output_true},
|
boolean::{output_expected_boolean, output_false, output_true},
|
||||||
compile_program, get_output,
|
compile_program, get_output,
|
||||||
integer::{fail_integer, fail_synthesis, IntegerTester},
|
integers::{fail_integer, fail_synthesis, IntegerTester},
|
||||||
EdwardsConstrainedValue, EdwardsTestCompiler,
|
EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::{types::Integer, ConstrainedValue, InputValue};
|
use leo_compiler::ConstrainedValue;
|
||||||
|
use leo_types::{Integer, InputValue};
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt32};
|
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt32};
|
||||||
|
|
||||||
const DIRECTORY_NAME: &str = "tests/integer/u32/";
|
const DIRECTORY_NAME: &str = "tests/integers/u32/";
|
||||||
|
|
||||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt32) {
|
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt32) {
|
||||||
let output = get_output(program);
|
let output = get_output(program);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user