diff --git a/Cargo.lock b/Cargo.lock index e8b053ca5a..b51552f695 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -517,6 +517,7 @@ dependencies = [ "from-pest", "hex", "leo-ast", + "leo-types", "log", "pest", "rand", @@ -530,6 +531,16 @@ dependencies = [ "thiserror", ] +[[package]] +name = "leo-types" +version = "0.1.0" +dependencies = [ + "leo-ast", + "snarkos-errors", + "snarkos-models", + "thiserror", +] + [[package]] name = "libc" version = "0.2.67" diff --git a/Cargo.toml b/Cargo.toml index a23e2a05d6..812a129964 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ name = "leo" path = "leo/main.rs" [workspace] -members = [ "ast", "compiler" ] +members = [ "ast", "compiler", "types" ] [dependencies] leo-compiler = { path = "compiler", version = "0.1.0" } diff --git a/ast/src/circuits/circuit_function.rs b/ast/src/circuits/circuit_function.rs index 334d9b4276..a97e06ec59 100644 --- a/ast/src/circuits/circuit_function.rs +++ b/ast/src/circuits/circuit_function.rs @@ -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_ast::FromPest; diff --git a/ast/src/lib.rs b/ast/src/lib.rs index c8b02c38a1..d4907f8d38 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -5,41 +5,18 @@ extern crate pest_derive; #[macro_use] 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 use errors::*; +pub mod access; +pub mod ast; +pub mod circuits; +pub mod common; pub mod expressions; -pub use expressions::*; - pub mod files; -pub use files::*; - pub mod functions; -pub use functions::*; - pub mod imports; -pub use imports::*; - pub mod operations; -pub use operations::*; - pub mod statements; -pub use statements::*; - pub mod values; -pub use values::*; - pub mod types; -pub use types::*; diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index e1228268a8..c022d9342d 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] 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-curves = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", version = "0.8.0" } diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 508cfee1bb..aa3d4b1acf 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -3,9 +3,10 @@ use crate::{ constraints::{generate_constraints, generate_test_constraints, ConstrainedValue}, errors::CompilerError, - GroupType, InputValue, Program, + GroupType, }; use leo_ast::{ast, files::File}; +use leo_types::{InputValue, Program}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/constraints/boolean.rs b/compiler/src/constraints/boolean.rs index 24f885dada..790a8f07b0 100644 --- a/compiler/src/constraints/boolean.rs +++ b/compiler/src/constraints/boolean.rs @@ -3,9 +3,9 @@ use crate::{ constraints::{ConstrainedProgram, ConstrainedValue}, errors::BooleanError, - types::InputValue, GroupType, }; +use leo_types::InputValue; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ diff --git a/compiler/src/constraints/expression.rs b/compiler/src/constraints/expression.rs index 37ec207eb4..0e1f8cffe8 100644 --- a/compiler/src/constraints/expression.rs +++ b/compiler/src/constraints/expression.rs @@ -4,12 +4,10 @@ use crate::{ constraints::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue}, errors::ExpressionError, new_scope, - types::{ - CircuitFieldDefinition, CircuitMember, Expression, Identifier, RangeOrExpression, - SpreadOrExpression, - }, - FieldType, GroupType, Integer, IntegerType, Type, + FieldType, GroupType, }; +use leo_types::{CircuitFieldDefinition,CircuitMember, Expression, RangeOrExpression, + SpreadOrExpression, Identifier, Integer, IntegerType, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/constraints/field.rs b/compiler/src/constraints/field.rs index ea2a682b11..ec39f4fcf8 100644 --- a/compiler/src/constraints/field.rs +++ b/compiler/src/constraints/field.rs @@ -1,8 +1,9 @@ //! Methods to enforce constraints on field elements in a resolved Leo program. 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_models::{ diff --git a/compiler/src/constraints/function.rs b/compiler/src/constraints/function.rs index a7f8c14446..cbc203efca 100644 --- a/compiler/src/constraints/function.rs +++ b/compiler/src/constraints/function.rs @@ -5,9 +5,8 @@ use crate::{ constraints::{new_scope, ConstrainedProgram, ConstrainedValue}, errors::{FunctionError, ImportError}, field_from_input, group_from_input, - types::{Expression, Function, Identifier, InputValue, Program, Type}, - GroupType, Integer, -}; + GroupType}; +use leo_types::{Expression, Function, Identifier, InputValue, Integer, Program, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/constraints/group.rs b/compiler/src/constraints/group.rs index 5ed7dd4c81..cf939f1771 100644 --- a/compiler/src/constraints/group.rs +++ b/compiler/src/constraints/group.rs @@ -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_models::{ diff --git a/compiler/src/constraints/import.rs b/compiler/src/constraints/import.rs index 23146fce90..e116999322 100644 --- a/compiler/src/constraints/import.rs +++ b/compiler/src/constraints/import.rs @@ -2,10 +2,10 @@ use crate::{ constraints::{ConstrainedProgram, ConstrainedValue}, errors::constraints::ImportError, new_scope, - types::Program, - GroupType, Import, + GroupType, }; use leo_ast::{ast, files::File}; +use leo_types::{Import, Program}; use from_pest::FromPest; use snarkos_models::{ diff --git a/compiler/src/constraints/integer/mod.rs b/compiler/src/constraints/integer/mod.rs deleted file mode 100644 index 7fd78ec2fa..0000000000 --- a/compiler/src/constraints/integer/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Module containing methods to enforce constraints on integers in a Leo program - -pub mod integer; -pub use integer::*; diff --git a/compiler/src/constraints/mod.rs b/compiler/src/constraints/mod.rs index 4b90c4e701..dbaf180488 100644 --- a/compiler/src/constraints/mod.rs +++ b/compiler/src/constraints/mod.rs @@ -12,9 +12,6 @@ pub use expression::*; pub mod import; pub use import::*; -pub mod integer; -pub use integer::*; - pub(crate) mod field; pub(crate) use field::*; @@ -32,9 +29,9 @@ pub use statement::*; use crate::{ errors::CompilerError, - types::{InputValue, Program}, GroupType, }; +use leo_types::{InputValue, Program}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/constraints/statement.rs b/compiler/src/constraints/statement.rs index 1850d5bbdb..8f5946008e 100644 --- a/compiler/src/constraints/statement.rs +++ b/compiler/src/constraints/statement.rs @@ -4,12 +4,9 @@ use crate::{ constraints::{ConstrainedProgram, ConstrainedValue}, errors::StatementError, new_scope, - types::{ - Assignee, ConditionalNestedOrEnd, ConditionalStatement, Expression, Identifier, Integer, - RangeOrExpression, Statement, Type, - }, - GroupType, Variable, + GroupType, }; +use leo_types::{Assignee, ConditionalNestedOrEndStatement, ConditionalStatement, Statement, Expression, Identifier, Integer, RangeOrExpression, Type, Variable}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -345,14 +342,14 @@ impl, CS: ConstraintSystem> Constraine } else { match statement.next { Some(next) => match next { - ConditionalNestedOrEnd::Nested(nested) => self.enforce_conditional_statement( + ConditionalNestedOrEndStatement::Nested(nested) => self.enforce_conditional_statement( cs, file_scope, function_scope, *nested, return_types, ), - ConditionalNestedOrEnd::End(statements) => self.iterate_or_early_return( + ConditionalNestedOrEndStatement::End(statements) => self.iterate_or_early_return( cs, file_scope, function_scope, diff --git a/compiler/src/constraints/value.rs b/compiler/src/constraints/value.rs index 0335d191e2..66a102705b 100644 --- a/compiler/src/constraints/value.rs +++ b/compiler/src/constraints/value.rs @@ -2,9 +2,9 @@ use crate::{ errors::ValueError, - types::{Circuit, Function, Identifier, Integer, IntegerType, Type}, FieldType, GroupType, }; +use leo_types::{Circuit, Function, Identifier, Integer, IntegerType, Type}; use snarkos_models::{ curves::{Field, PrimeField}, diff --git a/compiler/src/errors/compiler.rs b/compiler/src/errors/compiler.rs index d444ffbdeb..467e69db8e 100644 --- a/compiler/src/errors/compiler.rs +++ b/compiler/src/errors/compiler.rs @@ -1,5 +1,6 @@ -use crate::errors::{FunctionError, ImportError, IntegerError, }; +use crate::errors::{FunctionError, ImportError}; use leo_ast::{ast::Rule, SyntaxError}; +use leo_types::IntegerError; use pest::error::Error; use std::{io, path::PathBuf}; diff --git a/compiler/src/errors/constraints/expression.rs b/compiler/src/errors/constraints/expression.rs index 692e354015..3df35c8d5e 100644 --- a/compiler/src/errors/constraints/expression.rs +++ b/compiler/src/errors/constraints/expression.rs @@ -1,6 +1,7 @@ use crate::errors::{ - BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError, + BooleanError, FieldError, FunctionError, GroupError, ValueError, }; +use leo_types::IntegerError; use snarkos_errors::gadgets::SynthesisError; use std::num::ParseIntError; diff --git a/compiler/src/errors/constraints/function.rs b/compiler/src/errors/constraints/function.rs index ded87f7eb0..dbc081fdce 100644 --- a/compiler/src/errors/constraints/function.rs +++ b/compiler/src/errors/constraints/function.rs @@ -1,6 +1,7 @@ use crate::errors::{ - BooleanError, ExpressionError, FieldError, GroupError, IntegerError, StatementError, ValueError, + BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError, }; +use leo_types::IntegerError; #[derive(Debug, Error)] pub enum FunctionError { diff --git a/compiler/src/errors/constraints/mod.rs b/compiler/src/errors/constraints/mod.rs index 163fa1c517..315a513422 100644 --- a/compiler/src/errors/constraints/mod.rs +++ b/compiler/src/errors/constraints/mod.rs @@ -12,9 +12,6 @@ pub use expression::*; pub mod import; pub use import::*; -pub mod integer; -pub use integer::*; - pub mod field; pub use field::*; diff --git a/compiler/src/errors/constraints/value.rs b/compiler/src/errors/constraints/value.rs index 20550757f3..ad25aa443a 100644 --- a/compiler/src/errors/constraints/value.rs +++ b/compiler/src/errors/constraints/value.rs @@ -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}; diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 2b1c1d19ad..b6467d5d10 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -15,15 +15,3 @@ pub use self::field::*; pub mod 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::*; diff --git a/compiler/src/types.rs b/compiler/src/types.rs deleted file mode 100644 index c57a16ce79..0000000000 --- a/compiler/src/types.rs +++ /dev/null @@ -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, -} - -/// 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, Option), - 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, Box), - Sub(Box, Box), - Mul(Box, Box), - Div(Box, Box), - Pow(Box, Box), - - // Boolean operations - Not(Box), - Or(Box, Box), - And(Box, Box), - Eq(Box, Box), - Ge(Box, Box), - Gt(Box, Box), - Le(Box, Box), - Lt(Box, Box), - - // Conditionals - IfElse(Box, Box, Box), - - // Arrays - Array(Vec>), - ArrayAccess(Box, Box), // (array name, range) - - // Circuits - Circuit(Identifier, Vec), - CircuitMemberAccess(Box, Identifier), // (declared circuit name, circuit member name) - CircuitStaticFunctionAccess(Box, Identifier), // (defined circuit name, circuit static member name) - - // Functions - FunctionCall(Box, Vec), -} - -/// Definition assignee: v, arr[0..2], Point p.x -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Assignee { - Identifier(Identifier), - Array(Box, RangeOrExpression), - CircuitField(Box, 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, Vec), - Circuit(Identifier), - SelfType, -} - -impl Type { - pub fn outer_dimension(&self, dimensions: &Vec) -> 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) -> 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), - End(Vec), -} - -#[derive(Clone, PartialEq, Eq)] -pub struct ConditionalStatement { - pub condition: Expression, - pub statements: Vec, - pub next: Option, -} - -/// Program statement that defines some action (or expression) to be carried out. -#[derive(Clone, PartialEq, Eq)] -pub enum Statement { - Return(Vec), - Definition(Variable, Expression), - Assign(Assignee, Expression), - MultipleAssign(Vec, Expression), - Conditional(ConditionalStatement), - For(Identifier, Integer, Integer, Vec), - 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, -} - -/// 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), -} - -#[derive(Clone, PartialEq, Eq)] -pub struct Function { - pub function_name: Identifier, - pub inputs: Vec, - pub returns: Vec, - pub statements: Vec, -} - -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, - pub circuits: HashMap, - pub functions: HashMap, - pub tests: HashMap, -} - -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 - } -} diff --git a/compiler/src/types_display.rs b/compiler/src/types_display.rs deleted file mode 100644 index 2ae68b8651..0000000000 --- a/compiler/src/types_display.rs +++ /dev/null @@ -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::>() - .join(","); - let returns = self - .returns - .iter() - .map(|r| format!("{}", r)) - .collect::>() - .join(","); - let statements = self - .statements - .iter() - .map(|s| format!("\t{}\n", s)) - .collect::>() - .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) - } -} diff --git a/compiler/src/types_from.rs b/compiler/src/types_from.rs deleted file mode 100644 index fd6b614be5..0000000000 --- a/compiler/src/types_from.rs +++ /dev/null @@ -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> for types::Identifier { - fn from(identifier: Identifier<'ast>) -> Self { - types::Identifier::new(identifier.value) - } -} - -impl<'ast> From> for types::Expression { - fn from(identifier: Identifier<'ast>) -> Self { - types::Expression::Identifier(types::Identifier::from(identifier)) - } -} - -/// pest ast -> types::Variable - -impl<'ast> From> 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::().expect("unable to parse u8"), - )), - IntegerType::U16Type(_u16) => types::Integer::U16(UInt16::constant( - number.value.parse::().expect("unable to parse u16"), - )), - IntegerType::U32Type(_u32) => types::Integer::U32(UInt32::constant( - number - .value - .parse::() - .expect("unable to parse integers.u32"), - )), - IntegerType::U64Type(_u64) => types::Integer::U64(UInt64::constant( - number.value.parse::().expect("unable to parse u64"), - )), - IntegerType::U128Type(_u128) => types::Integer::U128(UInt128::constant( - number.value.parse::().expect("unable to parse u128"), - )), - } - } - - pub(crate) fn from_implicit(number: String) -> Self { - types::Integer::U128(UInt128::constant( - number.parse::().expect("unable to parse u128"), - )) - } -} - -impl<'ast> From> for types::Expression { - fn from(field: IntegerValue<'ast>) -> Self { - types::Expression::Integer(types::Integer::from(field.number, field._type)) - } -} - -impl<'ast> From> 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> for types::Expression { - fn from(field: FieldValue<'ast>) -> Self { - types::Expression::Field(field.number.value) - } -} - -/// pest ast -> types::Group - -impl<'ast> From> for types::Expression { - fn from(group: GroupValue<'ast>) -> Self { - types::Expression::Group(group.to_string()) - } -} - -/// pest ast -> types::Boolean - -impl<'ast> From> for types::Expression { - fn from(boolean: BooleanValue<'ast>) -> Self { - types::Expression::Boolean(Boolean::Constant( - boolean - .value - .parse::() - .expect("unable to parse boolean"), - )) - } -} - -/// pest ast -> types::NumberImplicit - -impl<'ast> From> for types::Expression { - fn from(number: NumberImplicitValue<'ast>) -> Self { - types::Expression::Implicit(number.number.value) - } -} - -/// pest ast -> types::Expression - -impl<'ast> From> 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> for types::Expression { - fn from(expression: NotExpression<'ast>) -> Self { - types::Expression::Not(Box::new(types::Expression::from(*expression.expression))) - } -} - -impl<'ast> From> 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> 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> 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> 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> 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> 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> 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::>(); - - types::Expression::Circuit(variable, members) - } -} - -impl<'ast> From> 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> 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::() - .expect("Unable to read array size"), - Value::Implicit(number) => number - .number - .value - .parse::() - .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> 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> for types::Assignee { - fn from(variable: Identifier<'ast>) -> Self { - types::Assignee::Identifier(types::Identifier::from(variable)) - } -} - -impl<'ast> From> 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> 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> 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> 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> 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> 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> 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> 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> 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> for types::Statement { - fn from(statement: ExpressionStatement<'ast>) -> Self { - types::Statement::Expression(types::Expression::from(statement.expression)) - } -} - -impl<'ast> From> 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 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 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> 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> for types::Type { - fn from(circuit_type: CircuitType<'ast>) -> Self { - types::Type::Circuit(types::Identifier::from(circuit_type.identifier)) - } -} - -impl<'ast> From> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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::>(); - - 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, - } - } -} diff --git a/compiler/tests/array/mod.rs b/compiler/tests/array/mod.rs index e89d31a90b..dbeda8671b 100644 --- a/compiler/tests/array/mod.rs +++ b/compiler/tests/array/mod.rs @@ -1,8 +1,9 @@ use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler}; use leo_compiler::{ - errors::{CompilerError, FunctionError, IntegerError}, - ConstrainedValue, InputValue, Integer, + errors::{CompilerError, FunctionError}, + ConstrainedValue, }; +use leo_types::{InputValue, Integer, IntegerError}; use snarkos_models::gadgets::utilities::uint::UInt32; diff --git a/compiler/tests/boolean/mod.rs b/compiler/tests/boolean/mod.rs index d782ce69a8..6e79a6633e 100644 --- a/compiler/tests/boolean/mod.rs +++ b/compiler/tests/boolean/mod.rs @@ -1,8 +1,9 @@ use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler}; use leo_compiler::{ errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError}, - ConstrainedValue, InputValue, + ConstrainedValue, }; +use leo_types::InputValue; use snarkos_models::gadgets::utilities::boolean::Boolean; diff --git a/compiler/tests/circuit/inline.leo b/compiler/tests/circuits/inline.leo similarity index 100% rename from compiler/tests/circuit/inline.leo rename to compiler/tests/circuits/inline.leo diff --git a/compiler/tests/circuit/inline_fail.leo b/compiler/tests/circuits/inline_fail.leo similarity index 100% rename from compiler/tests/circuit/inline_fail.leo rename to compiler/tests/circuits/inline_fail.leo diff --git a/compiler/tests/circuit/inline_undefined.leo b/compiler/tests/circuits/inline_undefined.leo similarity index 100% rename from compiler/tests/circuit/inline_undefined.leo rename to compiler/tests/circuits/inline_undefined.leo diff --git a/compiler/tests/circuit/member_field.leo b/compiler/tests/circuits/member_field.leo similarity index 100% rename from compiler/tests/circuit/member_field.leo rename to compiler/tests/circuits/member_field.leo diff --git a/compiler/tests/circuit/member_field_fail.leo b/compiler/tests/circuits/member_field_fail.leo similarity index 100% rename from compiler/tests/circuit/member_field_fail.leo rename to compiler/tests/circuits/member_field_fail.leo diff --git a/compiler/tests/circuit/member_function.leo b/compiler/tests/circuits/member_function.leo similarity index 100% rename from compiler/tests/circuit/member_function.leo rename to compiler/tests/circuits/member_function.leo diff --git a/compiler/tests/circuit/member_function_fail.leo b/compiler/tests/circuits/member_function_fail.leo similarity index 100% rename from compiler/tests/circuit/member_function_fail.leo rename to compiler/tests/circuits/member_function_fail.leo diff --git a/compiler/tests/circuit/member_function_invalid.leo b/compiler/tests/circuits/member_function_invalid.leo similarity index 100% rename from compiler/tests/circuit/member_function_invalid.leo rename to compiler/tests/circuits/member_function_invalid.leo diff --git a/compiler/tests/circuit/member_static_function.leo b/compiler/tests/circuits/member_static_function.leo similarity index 100% rename from compiler/tests/circuit/member_static_function.leo rename to compiler/tests/circuits/member_static_function.leo diff --git a/compiler/tests/circuit/member_static_function_invalid.leo b/compiler/tests/circuits/member_static_function_invalid.leo similarity index 100% rename from compiler/tests/circuit/member_static_function_invalid.leo rename to compiler/tests/circuits/member_static_function_invalid.leo diff --git a/compiler/tests/circuit/member_static_function_undefined.leo b/compiler/tests/circuits/member_static_function_undefined.leo similarity index 100% rename from compiler/tests/circuit/member_static_function_undefined.leo rename to compiler/tests/circuits/member_static_function_undefined.leo diff --git a/compiler/tests/circuit/mod.rs b/compiler/tests/circuits/mod.rs similarity index 95% rename from compiler/tests/circuit/mod.rs rename to compiler/tests/circuits/mod.rs index 4d673e46c0..ec1a4a04b1 100644 --- a/compiler/tests/circuit/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -1,16 +1,17 @@ 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, }; use leo_compiler::{ errors::{CompilerError, ExpressionError, FunctionError, StatementError}, - ConstrainedCircuitMember, ConstrainedValue, Expression, Function, Identifier, Integer, - Statement, Type, + ConstrainedCircuitMember, ConstrainedValue, }; +use leo_types::{Expression, Function, Identifier, Integer, + Statement, Type,}; use snarkos_models::gadgets::utilities::uint::UInt32; -const DIRECTORY_NAME: &str = "tests/circuit/"; +const DIRECTORY_NAME: &str = "tests/circuits/"; // Circ { x: 1u32 } fn output_circuit(program: EdwardsTestCompiler) { diff --git a/compiler/tests/circuit/pedersen_mock.leo b/compiler/tests/circuits/pedersen_mock.leo similarity index 100% rename from compiler/tests/circuit/pedersen_mock.leo rename to compiler/tests/circuits/pedersen_mock.leo diff --git a/compiler/tests/circuit/self.leo b/compiler/tests/circuits/self.leo similarity index 100% rename from compiler/tests/circuit/self.leo rename to compiler/tests/circuits/self.leo diff --git a/compiler/tests/field/mod.rs b/compiler/tests/field/mod.rs index a2e46f1398..45307ddbe1 100644 --- a/compiler/tests/field/mod.rs +++ b/compiler/tests/field/mod.rs @@ -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 leo_compiler::{ errors::{CompilerError, FieldError, FunctionError}, - ConstrainedValue, FieldType, InputValue, + ConstrainedValue, FieldType, }; +use leo_types::InputValue; use snarkos_curves::edwards_bls12::Fq; use snarkos_gadgets::curves::edwards_bls12::FqGadget; diff --git a/compiler/tests/function/mod.rs b/compiler/tests/function/mod.rs index 3bc86b1652..d86c5fc7a4 100644 --- a/compiler/tests/function/mod.rs +++ b/compiler/tests/function/mod.rs @@ -1,5 +1,5 @@ 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, }; use leo_compiler::{ diff --git a/compiler/tests/group/mod.rs b/compiler/tests/group/mod.rs index 02d8effda8..ece881edfa 100644 --- a/compiler/tests/group/mod.rs +++ b/compiler/tests/group/mod.rs @@ -2,7 +2,8 @@ use crate::{ boolean::{output_false, output_true}, 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_gadgets::curves::edwards_bls12::EdwardsBlsGadget; diff --git a/compiler/tests/import/mod.rs b/compiler/tests/import/mod.rs index d81b249909..433538a956 100644 --- a/compiler/tests/import/mod.rs +++ b/compiler/tests/import/mod.rs @@ -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/"; diff --git a/compiler/tests/integer/macros.rs b/compiler/tests/integers/macros.rs similarity index 100% rename from compiler/tests/integer/macros.rs rename to compiler/tests/integers/macros.rs diff --git a/compiler/tests/integer/mod.rs b/compiler/tests/integers/mod.rs similarity index 94% rename from compiler/tests/integer/mod.rs rename to compiler/tests/integers/mod.rs index 24d940a424..fb49b31c94 100644 --- a/compiler/tests/integer/mod.rs +++ b/compiler/tests/integers/mod.rs @@ -2,7 +2,8 @@ pub mod macros; 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 { /// Tests use of the integer in a function input diff --git a/compiler/tests/integer/u128/add.leo b/compiler/tests/integers/u128/add.leo similarity index 100% rename from compiler/tests/integer/u128/add.leo rename to compiler/tests/integers/u128/add.leo diff --git a/compiler/tests/integer/u128/assert_eq.leo b/compiler/tests/integers/u128/assert_eq.leo similarity index 100% rename from compiler/tests/integer/u128/assert_eq.leo rename to compiler/tests/integers/u128/assert_eq.leo diff --git a/compiler/tests/integer/u128/div.leo b/compiler/tests/integers/u128/div.leo similarity index 100% rename from compiler/tests/integer/u128/div.leo rename to compiler/tests/integers/u128/div.leo diff --git a/compiler/tests/integer/u128/eq.leo b/compiler/tests/integers/u128/eq.leo similarity index 100% rename from compiler/tests/integer/u128/eq.leo rename to compiler/tests/integers/u128/eq.leo diff --git a/compiler/tests/integer/u128/ge.leo b/compiler/tests/integers/u128/ge.leo similarity index 100% rename from compiler/tests/integer/u128/ge.leo rename to compiler/tests/integers/u128/ge.leo diff --git a/compiler/tests/integer/u128/gt.leo b/compiler/tests/integers/u128/gt.leo similarity index 100% rename from compiler/tests/integer/u128/gt.leo rename to compiler/tests/integers/u128/gt.leo diff --git a/compiler/tests/integer/u128/input.leo b/compiler/tests/integers/u128/input.leo similarity index 100% rename from compiler/tests/integer/u128/input.leo rename to compiler/tests/integers/u128/input.leo diff --git a/compiler/tests/integer/u128/le.leo b/compiler/tests/integers/u128/le.leo similarity index 100% rename from compiler/tests/integer/u128/le.leo rename to compiler/tests/integers/u128/le.leo diff --git a/compiler/tests/integer/u128/lt.leo b/compiler/tests/integers/u128/lt.leo similarity index 100% rename from compiler/tests/integer/u128/lt.leo rename to compiler/tests/integers/u128/lt.leo diff --git a/compiler/tests/integer/u128/max.leo b/compiler/tests/integers/u128/max.leo similarity index 100% rename from compiler/tests/integer/u128/max.leo rename to compiler/tests/integers/u128/max.leo diff --git a/compiler/tests/integer/u128/min.leo b/compiler/tests/integers/u128/min.leo similarity index 100% rename from compiler/tests/integer/u128/min.leo rename to compiler/tests/integers/u128/min.leo diff --git a/compiler/tests/integer/u128/mod.rs b/compiler/tests/integers/u128/mod.rs similarity index 88% rename from compiler/tests/integer/u128/mod.rs rename to compiler/tests/integers/u128/mod.rs index 6d3e2ee5bf..fe3551dc33 100644 --- a/compiler/tests/integer/u128/mod.rs +++ b/compiler/tests/integers/u128/mod.rs @@ -1,16 +1,17 @@ use crate::{ boolean::{output_expected_boolean, output_false, output_true}, compile_program, get_output, - integer::{fail_integer, fail_synthesis, IntegerTester}, + integers::{fail_integer, fail_synthesis, IntegerTester}, 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_models::gadgets::r1cs::TestConstraintSystem; 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) { let output = get_output(program); diff --git a/compiler/tests/integer/u128/mul.leo b/compiler/tests/integers/u128/mul.leo similarity index 100% rename from compiler/tests/integer/u128/mul.leo rename to compiler/tests/integers/u128/mul.leo diff --git a/compiler/tests/integer/u128/one.leo b/compiler/tests/integers/u128/one.leo similarity index 100% rename from compiler/tests/integer/u128/one.leo rename to compiler/tests/integers/u128/one.leo diff --git a/compiler/tests/integer/u128/pow.leo b/compiler/tests/integers/u128/pow.leo similarity index 100% rename from compiler/tests/integer/u128/pow.leo rename to compiler/tests/integers/u128/pow.leo diff --git a/compiler/tests/integer/u128/sub.leo b/compiler/tests/integers/u128/sub.leo similarity index 100% rename from compiler/tests/integer/u128/sub.leo rename to compiler/tests/integers/u128/sub.leo diff --git a/compiler/tests/integer/u128/ternary.leo b/compiler/tests/integers/u128/ternary.leo similarity index 100% rename from compiler/tests/integer/u128/ternary.leo rename to compiler/tests/integers/u128/ternary.leo diff --git a/compiler/tests/integer/u128/zero.leo b/compiler/tests/integers/u128/zero.leo similarity index 100% rename from compiler/tests/integer/u128/zero.leo rename to compiler/tests/integers/u128/zero.leo diff --git a/compiler/tests/integer/u16/add.leo b/compiler/tests/integers/u16/add.leo similarity index 100% rename from compiler/tests/integer/u16/add.leo rename to compiler/tests/integers/u16/add.leo diff --git a/compiler/tests/integer/u16/assert_eq.leo b/compiler/tests/integers/u16/assert_eq.leo similarity index 100% rename from compiler/tests/integer/u16/assert_eq.leo rename to compiler/tests/integers/u16/assert_eq.leo diff --git a/compiler/tests/integer/u16/div.leo b/compiler/tests/integers/u16/div.leo similarity index 100% rename from compiler/tests/integer/u16/div.leo rename to compiler/tests/integers/u16/div.leo diff --git a/compiler/tests/integer/u16/eq.leo b/compiler/tests/integers/u16/eq.leo similarity index 100% rename from compiler/tests/integer/u16/eq.leo rename to compiler/tests/integers/u16/eq.leo diff --git a/compiler/tests/integer/u16/ge.leo b/compiler/tests/integers/u16/ge.leo similarity index 100% rename from compiler/tests/integer/u16/ge.leo rename to compiler/tests/integers/u16/ge.leo diff --git a/compiler/tests/integer/u16/gt.leo b/compiler/tests/integers/u16/gt.leo similarity index 100% rename from compiler/tests/integer/u16/gt.leo rename to compiler/tests/integers/u16/gt.leo diff --git a/compiler/tests/integer/u16/input.leo b/compiler/tests/integers/u16/input.leo similarity index 100% rename from compiler/tests/integer/u16/input.leo rename to compiler/tests/integers/u16/input.leo diff --git a/compiler/tests/integer/u16/le.leo b/compiler/tests/integers/u16/le.leo similarity index 100% rename from compiler/tests/integer/u16/le.leo rename to compiler/tests/integers/u16/le.leo diff --git a/compiler/tests/integer/u16/lt.leo b/compiler/tests/integers/u16/lt.leo similarity index 100% rename from compiler/tests/integer/u16/lt.leo rename to compiler/tests/integers/u16/lt.leo diff --git a/compiler/tests/integer/u16/max.leo b/compiler/tests/integers/u16/max.leo similarity index 100% rename from compiler/tests/integer/u16/max.leo rename to compiler/tests/integers/u16/max.leo diff --git a/compiler/tests/integer/u16/min.leo b/compiler/tests/integers/u16/min.leo similarity index 100% rename from compiler/tests/integer/u16/min.leo rename to compiler/tests/integers/u16/min.leo diff --git a/compiler/tests/integer/u16/mod.rs b/compiler/tests/integers/u16/mod.rs similarity index 87% rename from compiler/tests/integer/u16/mod.rs rename to compiler/tests/integers/u16/mod.rs index 85a54a9d91..526cb1b138 100644 --- a/compiler/tests/integer/u16/mod.rs +++ b/compiler/tests/integers/u16/mod.rs @@ -1,16 +1,17 @@ use crate::{ boolean::{output_expected_boolean, output_false, output_true}, compile_program, get_output, - integer::{fail_integer, fail_synthesis, IntegerTester}, + integers::{fail_integer, fail_synthesis, IntegerTester}, 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_models::gadgets::r1cs::TestConstraintSystem; 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) { let output = get_output(program); diff --git a/compiler/tests/integer/u16/mul.leo b/compiler/tests/integers/u16/mul.leo similarity index 100% rename from compiler/tests/integer/u16/mul.leo rename to compiler/tests/integers/u16/mul.leo diff --git a/compiler/tests/integer/u16/one.leo b/compiler/tests/integers/u16/one.leo similarity index 100% rename from compiler/tests/integer/u16/one.leo rename to compiler/tests/integers/u16/one.leo diff --git a/compiler/tests/integer/u16/pow.leo b/compiler/tests/integers/u16/pow.leo similarity index 100% rename from compiler/tests/integer/u16/pow.leo rename to compiler/tests/integers/u16/pow.leo diff --git a/compiler/tests/integer/u16/sub.leo b/compiler/tests/integers/u16/sub.leo similarity index 100% rename from compiler/tests/integer/u16/sub.leo rename to compiler/tests/integers/u16/sub.leo diff --git a/compiler/tests/integer/u16/ternary.leo b/compiler/tests/integers/u16/ternary.leo similarity index 100% rename from compiler/tests/integer/u16/ternary.leo rename to compiler/tests/integers/u16/ternary.leo diff --git a/compiler/tests/integer/u16/zero.leo b/compiler/tests/integers/u16/zero.leo similarity index 100% rename from compiler/tests/integer/u16/zero.leo rename to compiler/tests/integers/u16/zero.leo diff --git a/compiler/tests/integer/u32/add.leo b/compiler/tests/integers/u32/add.leo similarity index 100% rename from compiler/tests/integer/u32/add.leo rename to compiler/tests/integers/u32/add.leo diff --git a/compiler/tests/integer/u32/assert_eq.leo b/compiler/tests/integers/u32/assert_eq.leo similarity index 100% rename from compiler/tests/integer/u32/assert_eq.leo rename to compiler/tests/integers/u32/assert_eq.leo diff --git a/compiler/tests/integer/u32/div.leo b/compiler/tests/integers/u32/div.leo similarity index 100% rename from compiler/tests/integer/u32/div.leo rename to compiler/tests/integers/u32/div.leo diff --git a/compiler/tests/integer/u32/eq.leo b/compiler/tests/integers/u32/eq.leo similarity index 100% rename from compiler/tests/integer/u32/eq.leo rename to compiler/tests/integers/u32/eq.leo diff --git a/compiler/tests/integer/u32/ge.leo b/compiler/tests/integers/u32/ge.leo similarity index 100% rename from compiler/tests/integer/u32/ge.leo rename to compiler/tests/integers/u32/ge.leo diff --git a/compiler/tests/integer/u32/gt.leo b/compiler/tests/integers/u32/gt.leo similarity index 100% rename from compiler/tests/integer/u32/gt.leo rename to compiler/tests/integers/u32/gt.leo diff --git a/compiler/tests/integer/u32/input.leo b/compiler/tests/integers/u32/input.leo similarity index 100% rename from compiler/tests/integer/u32/input.leo rename to compiler/tests/integers/u32/input.leo diff --git a/compiler/tests/integer/u32/le.leo b/compiler/tests/integers/u32/le.leo similarity index 100% rename from compiler/tests/integer/u32/le.leo rename to compiler/tests/integers/u32/le.leo diff --git a/compiler/tests/integer/u32/lt.leo b/compiler/tests/integers/u32/lt.leo similarity index 100% rename from compiler/tests/integer/u32/lt.leo rename to compiler/tests/integers/u32/lt.leo diff --git a/compiler/tests/integer/u32/max.leo b/compiler/tests/integers/u32/max.leo similarity index 100% rename from compiler/tests/integer/u32/max.leo rename to compiler/tests/integers/u32/max.leo diff --git a/compiler/tests/integer/u32/min.leo b/compiler/tests/integers/u32/min.leo similarity index 100% rename from compiler/tests/integer/u32/min.leo rename to compiler/tests/integers/u32/min.leo diff --git a/compiler/tests/integer/u32/mod.rs b/compiler/tests/integers/u32/mod.rs similarity index 92% rename from compiler/tests/integer/u32/mod.rs rename to compiler/tests/integers/u32/mod.rs index df5467ef2a..15172621c6 100644 --- a/compiler/tests/integer/u32/mod.rs +++ b/compiler/tests/integers/u32/mod.rs @@ -1,16 +1,17 @@ use crate::{ boolean::{output_expected_boolean, output_false, output_true}, compile_program, get_output, - integer::{fail_integer, fail_synthesis, IntegerTester}, + integers::{fail_integer, fail_synthesis, IntegerTester}, 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_models::gadgets::r1cs::TestConstraintSystem; 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) { let output = get_output(program); diff --git a/compiler/tests/integer/u32/mul.leo b/compiler/tests/integers/u32/mul.leo similarity index 100% rename from compiler/tests/integer/u32/mul.leo rename to compiler/tests/integers/u32/mul.leo diff --git a/compiler/tests/integer/u32/one.leo b/compiler/tests/integers/u32/one.leo similarity index 100% rename from compiler/tests/integer/u32/one.leo rename to compiler/tests/integers/u32/one.leo diff --git a/compiler/tests/integer/u32/pow.leo b/compiler/tests/integers/u32/pow.leo similarity index 100% rename from compiler/tests/integer/u32/pow.leo rename to compiler/tests/integers/u32/pow.leo diff --git a/compiler/tests/integer/u32/sub.leo b/compiler/tests/integers/u32/sub.leo similarity index 100% rename from compiler/tests/integer/u32/sub.leo rename to compiler/tests/integers/u32/sub.leo diff --git a/compiler/tests/integer/u32/ternary.leo b/compiler/tests/integers/u32/ternary.leo similarity index 100% rename from compiler/tests/integer/u32/ternary.leo rename to compiler/tests/integers/u32/ternary.leo diff --git a/compiler/tests/integer/u32/zero.leo b/compiler/tests/integers/u32/zero.leo similarity index 100% rename from compiler/tests/integer/u32/zero.leo rename to compiler/tests/integers/u32/zero.leo diff --git a/compiler/tests/integer/u64/add.leo b/compiler/tests/integers/u64/add.leo similarity index 100% rename from compiler/tests/integer/u64/add.leo rename to compiler/tests/integers/u64/add.leo diff --git a/compiler/tests/integer/u64/assert_eq.leo b/compiler/tests/integers/u64/assert_eq.leo similarity index 100% rename from compiler/tests/integer/u64/assert_eq.leo rename to compiler/tests/integers/u64/assert_eq.leo diff --git a/compiler/tests/integer/u64/div.leo b/compiler/tests/integers/u64/div.leo similarity index 100% rename from compiler/tests/integer/u64/div.leo rename to compiler/tests/integers/u64/div.leo diff --git a/compiler/tests/integer/u64/eq.leo b/compiler/tests/integers/u64/eq.leo similarity index 100% rename from compiler/tests/integer/u64/eq.leo rename to compiler/tests/integers/u64/eq.leo diff --git a/compiler/tests/integer/u64/ge.leo b/compiler/tests/integers/u64/ge.leo similarity index 100% rename from compiler/tests/integer/u64/ge.leo rename to compiler/tests/integers/u64/ge.leo diff --git a/compiler/tests/integer/u64/gt.leo b/compiler/tests/integers/u64/gt.leo similarity index 100% rename from compiler/tests/integer/u64/gt.leo rename to compiler/tests/integers/u64/gt.leo diff --git a/compiler/tests/integer/u64/input.leo b/compiler/tests/integers/u64/input.leo similarity index 100% rename from compiler/tests/integer/u64/input.leo rename to compiler/tests/integers/u64/input.leo diff --git a/compiler/tests/integer/u64/le.leo b/compiler/tests/integers/u64/le.leo similarity index 100% rename from compiler/tests/integer/u64/le.leo rename to compiler/tests/integers/u64/le.leo diff --git a/compiler/tests/integer/u64/lt.leo b/compiler/tests/integers/u64/lt.leo similarity index 100% rename from compiler/tests/integer/u64/lt.leo rename to compiler/tests/integers/u64/lt.leo diff --git a/compiler/tests/integer/u64/max.leo b/compiler/tests/integers/u64/max.leo similarity index 100% rename from compiler/tests/integer/u64/max.leo rename to compiler/tests/integers/u64/max.leo diff --git a/compiler/tests/integer/u64/min.leo b/compiler/tests/integers/u64/min.leo similarity index 100% rename from compiler/tests/integer/u64/min.leo rename to compiler/tests/integers/u64/min.leo diff --git a/compiler/tests/integer/u64/mod.rs b/compiler/tests/integers/u64/mod.rs similarity index 87% rename from compiler/tests/integer/u64/mod.rs rename to compiler/tests/integers/u64/mod.rs index 63562e4005..b092b13f1e 100644 --- a/compiler/tests/integer/u64/mod.rs +++ b/compiler/tests/integers/u64/mod.rs @@ -1,16 +1,17 @@ use crate::{ boolean::{output_expected_boolean, output_false, output_true}, compile_program, get_output, - integer::{fail_integer, fail_synthesis, IntegerTester}, + integers::{fail_integer, fail_synthesis, IntegerTester}, 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_models::gadgets::r1cs::TestConstraintSystem; use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt64}; -const DIRECTORY_NAME: &str = "tests/integer/u64/"; +const DIRECTORY_NAME: &str = "tests/integers/u64/"; fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt64) { let output = get_output(program); diff --git a/compiler/tests/integer/u64/mul.leo b/compiler/tests/integers/u64/mul.leo similarity index 100% rename from compiler/tests/integer/u64/mul.leo rename to compiler/tests/integers/u64/mul.leo diff --git a/compiler/tests/integer/u64/one.leo b/compiler/tests/integers/u64/one.leo similarity index 100% rename from compiler/tests/integer/u64/one.leo rename to compiler/tests/integers/u64/one.leo diff --git a/compiler/tests/integer/u64/pow.leo b/compiler/tests/integers/u64/pow.leo similarity index 100% rename from compiler/tests/integer/u64/pow.leo rename to compiler/tests/integers/u64/pow.leo diff --git a/compiler/tests/integer/u64/sub.leo b/compiler/tests/integers/u64/sub.leo similarity index 100% rename from compiler/tests/integer/u64/sub.leo rename to compiler/tests/integers/u64/sub.leo diff --git a/compiler/tests/integer/u64/ternary.leo b/compiler/tests/integers/u64/ternary.leo similarity index 100% rename from compiler/tests/integer/u64/ternary.leo rename to compiler/tests/integers/u64/ternary.leo diff --git a/compiler/tests/integer/u64/zero.leo b/compiler/tests/integers/u64/zero.leo similarity index 100% rename from compiler/tests/integer/u64/zero.leo rename to compiler/tests/integers/u64/zero.leo diff --git a/compiler/tests/integer/u8/add.leo b/compiler/tests/integers/u8/add.leo similarity index 100% rename from compiler/tests/integer/u8/add.leo rename to compiler/tests/integers/u8/add.leo diff --git a/compiler/tests/integer/u8/assert_eq.leo b/compiler/tests/integers/u8/assert_eq.leo similarity index 100% rename from compiler/tests/integer/u8/assert_eq.leo rename to compiler/tests/integers/u8/assert_eq.leo diff --git a/compiler/tests/integer/u8/div.leo b/compiler/tests/integers/u8/div.leo similarity index 100% rename from compiler/tests/integer/u8/div.leo rename to compiler/tests/integers/u8/div.leo diff --git a/compiler/tests/integer/u8/eq.leo b/compiler/tests/integers/u8/eq.leo similarity index 100% rename from compiler/tests/integer/u8/eq.leo rename to compiler/tests/integers/u8/eq.leo diff --git a/compiler/tests/integer/u8/ge.leo b/compiler/tests/integers/u8/ge.leo similarity index 100% rename from compiler/tests/integer/u8/ge.leo rename to compiler/tests/integers/u8/ge.leo diff --git a/compiler/tests/integer/u8/gt.leo b/compiler/tests/integers/u8/gt.leo similarity index 100% rename from compiler/tests/integer/u8/gt.leo rename to compiler/tests/integers/u8/gt.leo diff --git a/compiler/tests/integer/u8/input.leo b/compiler/tests/integers/u8/input.leo similarity index 100% rename from compiler/tests/integer/u8/input.leo rename to compiler/tests/integers/u8/input.leo diff --git a/compiler/tests/integer/u8/le.leo b/compiler/tests/integers/u8/le.leo similarity index 100% rename from compiler/tests/integer/u8/le.leo rename to compiler/tests/integers/u8/le.leo diff --git a/compiler/tests/integer/u8/lt.leo b/compiler/tests/integers/u8/lt.leo similarity index 100% rename from compiler/tests/integer/u8/lt.leo rename to compiler/tests/integers/u8/lt.leo diff --git a/compiler/tests/integer/u8/max.leo b/compiler/tests/integers/u8/max.leo similarity index 100% rename from compiler/tests/integer/u8/max.leo rename to compiler/tests/integers/u8/max.leo diff --git a/compiler/tests/integer/u8/min.leo b/compiler/tests/integers/u8/min.leo similarity index 100% rename from compiler/tests/integer/u8/min.leo rename to compiler/tests/integers/u8/min.leo diff --git a/compiler/tests/integer/u8/mod.rs b/compiler/tests/integers/u8/mod.rs similarity index 87% rename from compiler/tests/integer/u8/mod.rs rename to compiler/tests/integers/u8/mod.rs index 164c7804cf..864d664cc3 100644 --- a/compiler/tests/integer/u8/mod.rs +++ b/compiler/tests/integers/u8/mod.rs @@ -1,16 +1,17 @@ use crate::{ boolean::{output_expected_boolean, output_false, output_true}, compile_program, get_output, - integer::{fail_integer, fail_synthesis, IntegerTester}, + integers::{fail_integer, fail_synthesis, IntegerTester}, 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_models::gadgets::r1cs::TestConstraintSystem; use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt8}; -const DIRECTORY_NAME: &str = "tests/integer/u8/"; +const DIRECTORY_NAME: &str = "tests/integers/u8/"; fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt8) { let output = get_output(program); diff --git a/compiler/tests/integer/u8/mul.leo b/compiler/tests/integers/u8/mul.leo similarity index 100% rename from compiler/tests/integer/u8/mul.leo rename to compiler/tests/integers/u8/mul.leo diff --git a/compiler/tests/integer/u8/one.leo b/compiler/tests/integers/u8/one.leo similarity index 100% rename from compiler/tests/integer/u8/one.leo rename to compiler/tests/integers/u8/one.leo diff --git a/compiler/tests/integer/u8/pow.leo b/compiler/tests/integers/u8/pow.leo similarity index 100% rename from compiler/tests/integer/u8/pow.leo rename to compiler/tests/integers/u8/pow.leo diff --git a/compiler/tests/integer/u8/sub.leo b/compiler/tests/integers/u8/sub.leo similarity index 100% rename from compiler/tests/integer/u8/sub.leo rename to compiler/tests/integers/u8/sub.leo diff --git a/compiler/tests/integer/u8/ternary.leo b/compiler/tests/integers/u8/ternary.leo similarity index 100% rename from compiler/tests/integer/u8/ternary.leo rename to compiler/tests/integers/u8/ternary.leo diff --git a/compiler/tests/integer/u8/zero.leo b/compiler/tests/integers/u8/zero.leo similarity index 100% rename from compiler/tests/integer/u8/zero.leo rename to compiler/tests/integers/u8/zero.leo diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index 14236d70f7..e92b9d96e1 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -1,13 +1,13 @@ pub mod array; pub mod boolean; -pub mod circuit; +pub mod circuits; pub mod field; pub mod function; pub mod group; pub mod import; -pub mod integer; +pub mod integers; pub mod mutability; -pub mod statement; +pub mod statements; pub mod syntax; use leo_compiler::{ diff --git a/compiler/tests/mutability/mod.rs b/compiler/tests/mutability/mod.rs index a19bd643e2..3c8fa27d81 100644 --- a/compiler/tests/mutability/mod.rs +++ b/compiler/tests/mutability/mod.rs @@ -1,9 +1,9 @@ use crate::{compile_program, EdwardsConstrainedValue, EdwardsTestCompiler}; use leo_compiler::{ errors::{CompilerError, FunctionError, StatementError}, - types::{InputValue, Integer}, ConstrainedValue, }; +use leo_types::{InputValue, Integer}; use snarkos_curves::edwards_bls12::Fq; use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint::UInt32}; diff --git a/compiler/tests/statement/assertion_basic.leo b/compiler/tests/statements/assertion_basic.leo similarity index 100% rename from compiler/tests/statement/assertion_basic.leo rename to compiler/tests/statements/assertion_basic.leo diff --git a/compiler/tests/statement/iteration_basic.leo b/compiler/tests/statements/iteration_basic.leo similarity index 100% rename from compiler/tests/statement/iteration_basic.leo rename to compiler/tests/statements/iteration_basic.leo diff --git a/compiler/tests/statement/mod.rs b/compiler/tests/statements/mod.rs similarity index 92% rename from compiler/tests/statement/mod.rs rename to compiler/tests/statements/mod.rs index 53c5ba040b..a755c9936d 100644 --- a/compiler/tests/statement/mod.rs +++ b/compiler/tests/statements/mod.rs @@ -1,13 +1,13 @@ use crate::{ compile_program, - integer::u32::{output_one, output_zero}, + integers::u32::{output_one, output_zero}, }; -use leo_compiler::InputValue; +use leo_types::InputValue; use snarkos_curves::edwards_bls12::Fq; use snarkos_models::gadgets::r1cs::TestConstraintSystem; -const DIRECTORY_NAME: &str = "tests/statement/"; +const DIRECTORY_NAME: &str = "tests/statements/"; // Ternary if {bool}? {expression} : {expression}; diff --git a/compiler/tests/statement/ternary_basic.leo b/compiler/tests/statements/ternary_basic.leo similarity index 60% rename from compiler/tests/statement/ternary_basic.leo rename to compiler/tests/statements/ternary_basic.leo index 0ca2adcfea..2fd76fa0e8 100644 --- a/compiler/tests/statement/ternary_basic.leo +++ b/compiler/tests/statements/ternary_basic.leo @@ -1,3 +1,3 @@ function main(b: bool) -> u32 { - return if b? 1 : 0 + return if b ? 1 : 0 } \ No newline at end of file diff --git a/types/Cargo.toml b/types/Cargo.toml new file mode 100644 index 0000000000..0b2fc0223e --- /dev/null +++ b/types/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "leo-types" +version = "0.1.0" +authors = ["The Aleo Team "] +edition = "2018" + +[dependencies] +leo-ast = { path = "../ast", version = "0.1.0" } + +snarkos-errors = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", version = "0.8.0" } +snarkos-models = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", version = "0.8.0" } + +thiserror = { version = "1.0" } diff --git a/types/src/circuits/circuit.rs b/types/src/circuits/circuit.rs new file mode 100644 index 0000000000..dad607fecb --- /dev/null +++ b/types/src/circuits/circuit.rs @@ -0,0 +1,49 @@ +use crate::{Identifier, CircuitMember}; +use leo_ast::circuits::Circuit as AstCircuit; + +use std::fmt; + +#[derive(Clone, PartialEq, Eq)] +pub struct Circuit { + pub identifier: Identifier, + pub members: Vec, +} + +impl<'ast> From> for Circuit { + fn from(circuit: AstCircuit<'ast>) -> Self { + let variable = Identifier::from(circuit.identifier); + let members = circuit + .members + .into_iter() + .map(|member| CircuitMember::from(member)) + .collect(); + + Self { + identifier: variable, + members, + } + } +} + +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, "}}") + } +} + +// TODO (Collin): Uncomment when we no longer print out Program +// impl fmt::Display for Circuit { +// 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) + } +} diff --git a/types/src/circuits/circuit_field_definition.rs b/types/src/circuits/circuit_field_definition.rs new file mode 100644 index 0000000000..de5b1b7023 --- /dev/null +++ b/types/src/circuits/circuit_field_definition.rs @@ -0,0 +1,17 @@ +use crate::{Identifier, Expression}; +use leo_ast::circuits::CircuitField; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CircuitFieldDefinition { + pub identifier: Identifier, + pub expression: Expression, +} + +impl<'ast> From> for CircuitFieldDefinition { + fn from(member: CircuitField<'ast>) -> Self { + CircuitFieldDefinition { + identifier: Identifier::from(member.identifier), + expression: Expression::from(member.expression), + } + } +} diff --git a/types/src/circuits/circuit_member.rs b/types/src/circuits/circuit_member.rs new file mode 100644 index 0000000000..c2654bec26 --- /dev/null +++ b/types/src/circuits/circuit_member.rs @@ -0,0 +1,58 @@ +use crate::{Identifier, Function, Type}; +use leo_ast::circuits::{CircuitFieldDefinition as AstCircuitFieldDefinition, CircuitMember as AstCircuitMember, CircuitFunction as AstCircuitFunction}; + +use std::fmt; + +#[derive(Clone, PartialEq, Eq)] +pub enum CircuitMember { + CircuitField(Identifier, Type), + CircuitFunction(bool, Function), +} + + +impl<'ast> From> for CircuitMember { + fn from(circuit_value: AstCircuitFieldDefinition<'ast>) -> Self { + CircuitMember::CircuitField( + Identifier::from(circuit_value.identifier), + Type::from(circuit_value._type), + ) + } +} + +impl<'ast> From> for CircuitMember { + fn from(circuit_function: AstCircuitFunction<'ast>) -> Self { + CircuitMember::CircuitFunction( + circuit_function._static.is_some(), + Function::from(circuit_function.function), + ) + } +} + +impl<'ast> From> for CircuitMember { + fn from(object: AstCircuitMember<'ast>) -> Self { + match object { + AstCircuitMember::CircuitFieldDefinition(circuit_value) => { + CircuitMember::from(circuit_value) + } + AstCircuitMember::CircuitFunction(circuit_function) => { + CircuitMember::from(circuit_function) + } + } + } +} + +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) + } + } + } +} diff --git a/types/src/circuits/mod.rs b/types/src/circuits/mod.rs new file mode 100644 index 0000000000..7531150186 --- /dev/null +++ b/types/src/circuits/mod.rs @@ -0,0 +1,8 @@ +pub mod circuit; +pub use circuit::*; + +pub mod circuit_field_definition; +pub use circuit_field_definition::*; + +pub mod circuit_member; +pub use circuit_member::*; diff --git a/types/src/common/assignee.rs b/types/src/common/assignee.rs new file mode 100644 index 0000000000..53282546d3 --- /dev/null +++ b/types/src/common/assignee.rs @@ -0,0 +1,51 @@ +use crate::{Identifier, RangeOrExpression}; +use leo_ast::{common::{Identifier as AstIdentifier, Assignee as AstAssignee}, access::AssigneeAccess}; + +use std::fmt; + +/// Definition assignee: v, arr[0..2], Point p.x +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Assignee { + Identifier(Identifier), + Array(Box, RangeOrExpression), + CircuitField(Box, Identifier), // (circuit name, circuit field name) +} + +impl<'ast> From> for Assignee { + fn from(variable: AstIdentifier<'ast>) -> Self { + Assignee::Identifier(Identifier::from(variable)) + } +} + +impl<'ast> From> 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 + assignee + .accesses + .into_iter() + .fold(variable, |acc, access| match access { + AssigneeAccess::Array(array) => Assignee::Array( + Box::new(acc), + RangeOrExpression::from(array.expression), + ), + AssigneeAccess::Member(circuit_field) => Assignee::CircuitField( + Box::new(acc), + Identifier::from(circuit_field.identifier), + ), + }) + } +} + +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) + } + } + } +} diff --git a/types/src/common/identifier.rs b/types/src/common/identifier.rs new file mode 100644 index 0000000000..3c424a5b9b --- /dev/null +++ b/types/src/common/identifier.rs @@ -0,0 +1,36 @@ +use leo_ast::common::Identifier as AstIdentifier; + +use std::fmt; + +/// 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" + } +} + +impl<'ast> From> for Identifier { + fn from(identifier: AstIdentifier<'ast>) -> Self { + Identifier::new(identifier.value) + } +} + +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) + } +} diff --git a/types/src/common/mod.rs b/types/src/common/mod.rs new file mode 100644 index 0000000000..a338bc954f --- /dev/null +++ b/types/src/common/mod.rs @@ -0,0 +1,14 @@ +pub mod assignee; +pub use assignee::*; + +pub mod identifier; +pub use identifier::*; + +pub mod range_or_expression; +pub use range_or_expression::*; + +pub mod spread_or_expression; +pub use spread_or_expression::*; + +pub mod variable; +pub use variable::*; diff --git a/types/src/common/range_or_expression.rs b/types/src/common/range_or_expression.rs new file mode 100644 index 0000000000..b6569470c8 --- /dev/null +++ b/types/src/common/range_or_expression.rs @@ -0,0 +1,61 @@ +use crate::{Integer, Expression}; +use leo_ast::common::RangeOrExpression as AstRangeOrExpression; + +use std::fmt; + +/// Range or expression enum +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum RangeOrExpression { + Range(Option, Option), + Expression(Expression), +} + +impl<'ast> From> for RangeOrExpression { + fn from(range_or_expression: AstRangeOrExpression<'ast>) -> Self { + match range_or_expression { + AstRangeOrExpression::Range(range) => { + let from = range + .from + .map(|from| match Expression::from(from.0) { + Expression::Integer(number) => number, + Expression::Implicit(string) => { + Integer::from_implicit(string) + } + expression => { + unimplemented!("Range bounds should be integers, found {}", expression) + } + }); + let to = range.to.map(|to| match Expression::from(to.0) { + Expression::Integer(number) => number, + Expression::Implicit(string) => Integer::from_implicit(string), + expression => { + unimplemented!("Range bounds should be integers, found {}", expression) + } + }); + + RangeOrExpression::Range(from, to) + } + AstRangeOrExpression::Expression(expression) => { + RangeOrExpression::Expression(Expression::from(expression)) + } + } + } +} + +impl 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), + } + } +} diff --git a/types/src/common/spread_or_expression.rs b/types/src/common/spread_or_expression.rs new file mode 100644 index 0000000000..8b7c2f1942 --- /dev/null +++ b/types/src/common/spread_or_expression.rs @@ -0,0 +1,33 @@ +use crate::Expression; +use leo_ast::common::SpreadOrExpression as AstSpreadOrExpression; + +use std::fmt; + +/// Spread or expression +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum SpreadOrExpression { + Spread(Expression), + Expression(Expression), +} + +impl<'ast> From> for SpreadOrExpression { + fn from(s_or_e: AstSpreadOrExpression<'ast>) -> Self { + match s_or_e { + AstSpreadOrExpression::Spread(spread) => { + SpreadOrExpression::Spread(Expression::from(spread.expression)) + } + AstSpreadOrExpression::Expression(expression) => { + SpreadOrExpression::Expression(Expression::from(expression)) + } + } + } +} + +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), + } + } +} diff --git a/types/src/common/variable.rs b/types/src/common/variable.rs new file mode 100644 index 0000000000..eb38c1e03f --- /dev/null +++ b/types/src/common/variable.rs @@ -0,0 +1,38 @@ +use crate::{Identifier, Type}; +use leo_ast::common::Variable as AstVariable; + +use std::fmt; + +/// 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, +} + +impl<'ast> From> for Variable { + fn from(variable: AstVariable<'ast>) -> Self { + Variable { + identifier: Identifier::from(variable.identifier), + mutable: variable.mutable.is_some(), + _type: variable._type.map(|_type| Type::from(_type)), + } + } +} + +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, "") + } +} diff --git a/compiler/src/errors/constraints/integer.rs b/types/src/errors/integer.rs similarity index 100% rename from compiler/src/errors/constraints/integer.rs rename to types/src/errors/integer.rs diff --git a/types/src/errors/mod.rs b/types/src/errors/mod.rs new file mode 100644 index 0000000000..b817aa2387 --- /dev/null +++ b/types/src/errors/mod.rs @@ -0,0 +1,2 @@ +pub mod integer; +pub use integer::*; diff --git a/types/src/expression.rs b/types/src/expression.rs new file mode 100644 index 0000000000..6e621f74db --- /dev/null +++ b/types/src/expression.rs @@ -0,0 +1,432 @@ +use crate::{CircuitFieldDefinition, Identifier, Integer, SpreadOrExpression, RangeOrExpression}; +use leo_ast::{ + access::{Access, AssigneeAccess}, + common::{ + Assignee, + Identifier as AstIdentifier, + }, + expressions::{ + Expression as AstExpression, + CircuitInlineExpression, + PostfixExpression, + ArrayInitializerExpression, + ArrayInlineExpression, + TernaryExpression, + BinaryExpression, + NotExpression + }, + operations::{ + BinaryOperation, + }, + values::{ + Value, + FieldValue, + BooleanValue, + GroupValue, + NumberImplicitValue, + IntegerValue + } +}; + +use snarkos_models::gadgets::utilities::{ + boolean::Boolean, +}; + +use std::fmt; + +/// 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, Box), + Sub(Box, Box), + Mul(Box, Box), + Div(Box, Box), + Pow(Box, Box), + + // Boolean operations + Not(Box), + Or(Box, Box), + And(Box, Box), + Eq(Box, Box), + Ge(Box, Box), + Gt(Box, Box), + Le(Box, Box), + Lt(Box, Box), + + // Conditionals + IfElse(Box, Box, Box), + + // Arrays + Array(Vec>), + ArrayAccess(Box, Box), // (array name, range) + + // Circuits + Circuit(Identifier, Vec), + CircuitMemberAccess(Box, Identifier), // (declared circuit name, circuit member name) + CircuitStaticFunctionAccess(Box, Identifier), // (defined circuit name, circuit static member name) + + // Functions + FunctionCall(Box, Vec), +} + +impl<'ast> Expression { + pub(crate) fn get_count(count: Value<'ast>) -> usize { + match count { + Value::Integer(integer) => integer + .number + .value + .parse::() + .expect("Unable to read array size"), + Value::Implicit(number) => number + .number + .value + .parse::() + .expect("Unable to read array size"), + size => unimplemented!("Array size should be an integer {}", size), + } + } +} + +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<'ast> From> for Expression { + fn from(expression: CircuitInlineExpression<'ast>) -> Self { + let variable = Identifier::from(expression.identifier); + let members = expression + .members + .into_iter() + .map(|member| CircuitFieldDefinition::from(member)) + .collect::>(); + + Expression::Circuit(variable, members) + } +} + +impl<'ast> From> for Expression { + fn from(expression: PostfixExpression<'ast>) -> Self { + let variable = + Expression::Identifier(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) => Expression::ArrayAccess( + Box::new(acc), + Box::new(RangeOrExpression::from(array.expression)), + ), + + // Handle function calls + Access::Call(function) => Expression::FunctionCall( + Box::new(acc), + function + .expressions + .into_iter() + .map(|expression| Expression::from(expression)) + .collect(), + ), + + // Handle circuit member accesses + Access::Object(circuit_object) => Expression::CircuitMemberAccess( + Box::new(acc), + Identifier::from(circuit_object.identifier), + ), + Access::StaticObject(circuit_object) => { + Expression::CircuitStaticFunctionAccess( + Box::new(acc), + Identifier::from(circuit_object.identifier), + ) + } + }) + } +} + +impl<'ast> From> for Expression { + fn from(expression: AstExpression<'ast>) -> Self { + match expression { + AstExpression::Value(value) => Expression::from(value), + AstExpression::Identifier(variable) => Expression::from(variable), + AstExpression::Not(expression) => Expression::from(expression), + AstExpression::Binary(expression) => Expression::from(expression), + AstExpression::Ternary(expression) => Expression::from(expression), + AstExpression::ArrayInline(expression) => Expression::from(expression), + AstExpression::ArrayInitializer(expression) => Expression::from(expression), + AstExpression::CircuitInline(expression) => Expression::from(expression), + AstExpression::Postfix(expression) => Expression::from(expression), + } + } +} + +// Assignee -> Expression for operator assign statements +impl<'ast> From> for Expression { + fn from(assignee: Assignee<'ast>) -> Self { + let variable = Expression::Identifier(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) => { + Expression::CircuitMemberAccess( + Box::new(acc), + Identifier::from(circuit_member.identifier), + ) + } + AssigneeAccess::Array(array) => Expression::ArrayAccess( + Box::new(acc), + Box::new(RangeOrExpression::from(array.expression)), + ), + }) + } +} + + +impl<'ast> From> for Expression { + fn from(expression: BinaryExpression<'ast>) -> Self { + match expression.operation { + // Boolean operations + BinaryOperation::Or => Expression::Or( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::And => Expression::And( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Eq => Expression::Eq( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Ne => { + Expression::Not(Box::new(Expression::from(expression))) + } + BinaryOperation::Ge => Expression::Ge( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Gt => Expression::Gt( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Le => Expression::Le( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Lt => Expression::Lt( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + // Number operations + BinaryOperation::Add => Expression::Add( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Sub => Expression::Sub( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Mul => Expression::Mul( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Div => Expression::Div( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + BinaryOperation::Pow => Expression::Pow( + Box::new(Expression::from(*expression.left)), + Box::new(Expression::from(*expression.right)), + ), + } + } +} + +impl<'ast> From> for Expression { + fn from(expression: TernaryExpression<'ast>) -> Self { + Expression::IfElse( + Box::new(Expression::from(*expression.first)), + Box::new(Expression::from(*expression.second)), + Box::new(Expression::from(*expression.third)), + ) + } +} + +impl<'ast> From> for Expression { + fn from(array: ArrayInlineExpression<'ast>) -> Self { + Expression::Array( + array + .expressions + .into_iter() + .map(|s_or_e| Box::new(SpreadOrExpression::from(s_or_e))) + .collect(), + ) + } +} + +impl<'ast> From> for Expression { + fn from(array: ArrayInitializerExpression<'ast>) -> Self { + let count = Expression::get_count(array.count); + let expression = Box::new(SpreadOrExpression::from(*array.expression)); + + Expression::Array(vec![expression; count]) + } +} + + +impl<'ast> From> for Expression { + fn from(value: Value<'ast>) -> Self { + match value { + Value::Integer(num) => Expression::from(num), + Value::Field(field) => Expression::from(field), + Value::Group(group) => Expression::from(group), + Value::Boolean(bool) => Expression::from(bool), + Value::Implicit(value) => Expression::from(value), + } + } +} + +impl<'ast> From> for Expression { + fn from(expression: NotExpression<'ast>) -> Self { + Expression::Not(Box::new(Expression::from(*expression.expression))) + } +} + + +impl<'ast> From> for Expression { + fn from(field: FieldValue<'ast>) -> Self { + Expression::Field(field.number.value) + } +} + +impl<'ast> From> for Expression { + fn from(group: GroupValue<'ast>) -> Self { + Expression::Group(group.to_string()) + } +} + +impl<'ast> From> for Expression { + fn from(boolean: BooleanValue<'ast>) -> Self { + Expression::Boolean(Boolean::Constant( + boolean + .value + .parse::() + .expect("unable to parse boolean"), + )) + } +} + +impl<'ast> From> for Expression { + fn from(number: NumberImplicitValue<'ast>) -> Self { + Expression::Implicit(number.number.value) + } +} + + +impl<'ast> From> for Expression { + fn from(field: IntegerValue<'ast>) -> Self { + Expression::Integer(Integer::from(field.number, field._type)) + } +} + +impl<'ast> From> for Expression { + fn from(identifier: AstIdentifier<'ast>) -> Self { + Expression::Identifier(Identifier::from(identifier)) + } +} diff --git a/types/src/functions/function.rs b/types/src/functions/function.rs new file mode 100644 index 0000000000..9a4d458358 --- /dev/null +++ b/types/src/functions/function.rs @@ -0,0 +1,87 @@ +use crate::{Identifier, FunctionInput, Statement, Type}; +use leo_ast::functions::Function as AstFunction; + +use std::fmt; + +#[derive(Clone, PartialEq, Eq)] +pub struct Function { + pub function_name: Identifier, + pub inputs: Vec, + pub returns: Vec, + pub statements: Vec, +} + +impl<'ast> From> for Function { + fn from(function_definition: AstFunction<'ast>) -> Self { + let function_name = Identifier::from(function_definition.function_name); + let parameters = function_definition + .parameters + .into_iter() + .map(|parameter| FunctionInput::from(parameter)) + .collect(); + let returns = function_definition + .returns + .into_iter() + .map(|return_type| Type::from(return_type)) + .collect(); + let statements = function_definition + .statements + .into_iter() + .map(|statement| Statement::from(statement)) + .collect(); + + Function { + function_name, + inputs: parameters, + returns, + statements, + } + } +} + +impl Function { + pub fn get_name(&self) -> String { + self.function_name.name.clone() + } + + 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::>() + .join(","); + let returns = self + .returns + .iter() + .map(|r| format!("{}", r)) + .collect::>() + .join(","); + let statements = self + .statements + .iter() + .map(|s| format!("\t{}\n", s)) + .collect::>() + .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) + } +} diff --git a/types/src/functions/function_input.rs b/types/src/functions/function_input.rs new file mode 100644 index 0000000000..3ce3b66035 --- /dev/null +++ b/types/src/functions/function_input.rs @@ -0,0 +1,42 @@ +use crate::{Identifier, Type}; +use leo_ast::{common::{Visibility, Private}, functions::FunctionInput as AstFunctionInput}; + +use std::fmt; + +#[derive(Clone, PartialEq, Eq)] +pub struct FunctionInput { + pub identifier: Identifier, + pub mutable: bool, + pub private: bool, + pub _type: Type, +} + +impl<'ast> From> for FunctionInput { + fn from(parameter: AstFunctionInput<'ast>) -> Self { + FunctionInput { + identifier: 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: Type::from(parameter._type), + } + } +} + +impl fmt::Display for FunctionInput { + 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) + } +} diff --git a/types/src/functions/mod.rs b/types/src/functions/mod.rs new file mode 100644 index 0000000000..fadb2897b1 --- /dev/null +++ b/types/src/functions/mod.rs @@ -0,0 +1,8 @@ +pub mod function; +pub use function::*; + +pub mod function_input; +pub use function_input::*; + +pub mod test_function; +pub use test_function::*; diff --git a/types/src/functions/test_function.rs b/types/src/functions/test_function.rs new file mode 100644 index 0000000000..c4a318a75f --- /dev/null +++ b/types/src/functions/test_function.rs @@ -0,0 +1,11 @@ +use crate::Function; +use leo_ast::functions::TestFunction as AstTestFunction; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TestFunction(pub Function); + +impl<'ast> From> for TestFunction { + fn from(test: AstTestFunction) -> Self { + TestFunction(Function::from(test.function)) + } +} diff --git a/compiler/src/imports.rs b/types/src/imports/import.rs similarity index 70% rename from compiler/src/imports.rs rename to types/src/imports/import.rs index 383606315f..1caa243fcf 100644 --- a/compiler/src/imports.rs +++ b/types/src/imports/import.rs @@ -1,21 +1,29 @@ -//! The Import type for a Leo program. +//! The import type for a Leo program. -use crate::Identifier; +use crate::ImportSymbol; +use leo_ast::imports::Import as AstImport; use std::fmt; -#[derive(Clone)] -pub struct ImportSymbol { - pub symbol: Identifier, - pub alias: Option, -} - #[derive(Clone)] pub struct Import { pub path_string: String, pub symbols: Vec, } +impl<'ast> From> 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(), + } + } +} + impl Import { pub fn new(source: String, symbols: Vec) -> Import { Import { @@ -50,23 +58,13 @@ impl Import { } } -impl fmt::Display for ImportSymbol { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.alias.is_some() { - write!(f, "\t{} as {}", self.symbol, self.alias.as_ref().unwrap()) - } else { - write!(f, "\t{}", self.symbol) - } - } -} - -impl<'ast> fmt::Display for Import { +impl fmt::Display for Import { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } } -impl<'ast> fmt::Debug for Import { +impl fmt::Debug for Import { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } diff --git a/types/src/imports/import_symbol.rs b/types/src/imports/import_symbol.rs new file mode 100644 index 0000000000..17e6257296 --- /dev/null +++ b/types/src/imports/import_symbol.rs @@ -0,0 +1,29 @@ +use crate::Identifier; +use leo_ast::imports::ImportSymbol as AstImportSymbol; + +use std::fmt; + +#[derive(Clone)] +pub struct ImportSymbol { + pub symbol: Identifier, + pub alias: Option, +} + +impl<'ast> From> for ImportSymbol { + fn from(symbol: AstImportSymbol<'ast>) -> Self { + ImportSymbol { + symbol: Identifier::from(symbol.value), + alias: symbol.alias.map(|alias| Identifier::from(alias)), + } + } +} + +impl fmt::Display for ImportSymbol { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.alias.is_some() { + write!(f, "\t{} as {}", self.symbol, self.alias.as_ref().unwrap()) + } else { + write!(f, "\t{}", self.symbol) + } + } +} diff --git a/types/src/imports/mod.rs b/types/src/imports/mod.rs new file mode 100644 index 0000000000..78250a4179 --- /dev/null +++ b/types/src/imports/mod.rs @@ -0,0 +1,5 @@ +pub mod import; +pub use import::*; + +pub mod import_symbol; +pub use import_symbol::*; diff --git a/types/src/input_value.rs b/types/src/input_value.rs new file mode 100644 index 0000000000..3e7cf72732 --- /dev/null +++ b/types/src/input_value.rs @@ -0,0 +1,31 @@ +use std::fmt; + +#[derive(Clone, PartialEq, Eq)] +pub enum InputValue { + Integer(u128), + Field(String), + Group(String), + Boolean(bool), + Array(Vec), +} + +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, "]") + } + } + } +} diff --git a/compiler/src/constraints/integer/integer.rs b/types/src/integer.rs similarity index 90% rename from compiler/src/constraints/integer/integer.rs rename to types/src/integer.rs index 838709aeb3..afab66e87a 100644 --- a/compiler/src/constraints/integer/integer.rs +++ b/types/src/integer.rs @@ -1,10 +1,7 @@ -//! Methods to enforce constraints on integers in a resolved Leo program. +//! Conversion of integer declarations to constraints in Leo. -use crate::{ - errors::IntegerError, - types::{InputValue, Integer}, - IntegerType, -}; +use crate::{errors::IntegerError, IntegerType, InputValue}; +use leo_ast::{types::IntegerType as AstIntegerType, values::NumberValue}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ @@ -21,6 +18,49 @@ use snarkos_models::{ }, }; +use std::fmt; + +/// 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), +} + +impl<'ast> Integer { + pub fn from(number: NumberValue<'ast>, _type: AstIntegerType) -> Self { + match _type { + AstIntegerType::U8Type(_u8) => Integer::U8(UInt8::constant( + number.value.parse::().expect("unable to parse u8"), + )), + AstIntegerType::U16Type(_u16) => Integer::U16(UInt16::constant( + number.value.parse::().expect("unable to parse u16"), + )), + AstIntegerType::U32Type(_u32) => Integer::U32(UInt32::constant( + number + .value + .parse::() + .expect("unable to parse integers.u32"), + )), + AstIntegerType::U64Type(_u64) => Integer::U64(UInt64::constant( + number.value.parse::().expect("unable to parse u64"), + )), + AstIntegerType::U128Type(_u128) => Integer::U128(UInt128::constant( + number.value.parse::().expect("unable to parse u128"), + )), + } + } + + pub fn from_implicit(number: String) -> Self { + Integer::U128(UInt128::constant( + number.parse::().expect("unable to parse u128"), + )) + } +} + impl Integer { pub fn to_usize(&self) -> usize { match self { @@ -32,7 +72,7 @@ impl Integer { } } - pub(crate) fn get_type(&self) -> IntegerType { + pub fn get_type(&self) -> IntegerType { match self { Integer::U8(_u8) => IntegerType::U8, Integer::U16(_u16) => IntegerType::U16, @@ -42,7 +82,7 @@ impl Integer { } } - pub(crate) fn from_input>( + pub fn from_input>( cs: &mut CS, integer_type: IntegerType, name: String, @@ -125,7 +165,7 @@ impl Integer { }) } - pub(crate) fn add>( + pub fn add>( self, cs: &mut CS, other: Self, @@ -202,7 +242,7 @@ impl Integer { }) } - pub(crate) fn sub>( + pub fn sub>( self, cs: &mut CS, other: Self, @@ -279,7 +319,7 @@ impl Integer { }) } - pub(crate) fn mul>( + pub fn mul>( self, cs: &mut CS, other: Self, @@ -356,7 +396,7 @@ impl Integer { }) } - pub(crate) fn div>( + pub fn div>( self, cs: &mut CS, other: Self, @@ -433,7 +473,7 @@ impl Integer { }) } - pub(crate) fn pow>( + pub fn pow>( self, cs: &mut CS, other: Self, @@ -579,3 +619,9 @@ impl CondSelectGadget for Integer { unimplemented!("Cannot calculate cost.") } } + +impl fmt::Display for Integer { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}{}", self.to_usize(), self.get_type()) + } +} diff --git a/types/src/lib.rs b/types/src/lib.rs new file mode 100644 index 0000000000..431c25c8d2 --- /dev/null +++ b/types/src/lib.rs @@ -0,0 +1,35 @@ +#[macro_use] +extern crate thiserror; + +pub mod circuits; +pub use circuits::*; + +pub mod common; +pub use common::*; + +pub mod errors; +pub use errors::*; + +pub mod expression; +pub use expression::*; + +pub mod functions; +pub use functions::*; + +pub mod imports; +pub use imports::*; + +pub mod input_value; +pub use input_value::*; + +pub mod integer; +pub use integer::*; + +pub mod program; +pub use program::*; + +pub mod statements; +pub use statements::*; + +pub mod types; +pub use types::*; diff --git a/types/src/program.rs b/types/src/program.rs new file mode 100644 index 0000000000..ac4904d995 --- /dev/null +++ b/types/src/program.rs @@ -0,0 +1,91 @@ +//! A typed Leo program consists of import, circuit, and function definitions. +//! Each defined type consists of typed statements and expressions. + +use crate::{Circuit, Identifier, Import, Function, TestFunction}; +use leo_ast::{ + files::File, +}; + +use std::collections::HashMap; + +/// 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, + pub circuits: HashMap, + pub functions: HashMap, + pub tests: HashMap, +} + +impl<'ast> Program { + //! Logic to convert from an abstract syntax tree (ast) representation to a Leo 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::>(); + + 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( + Identifier::from(circuit.identifier.clone()), + Circuit::from(circuit), + ); + }); + file.functions.into_iter().for_each(|function_def| { + functions.insert( + Identifier::from(function_def.function_name.clone()), + Function::from(function_def), + ); + }); + file.tests.into_iter().for_each(|test_def| { + tests.insert( + Identifier::from(test_def.function.function_name.clone()), + TestFunction::from(test_def), + ); + }); + + if let Some(main_function) = functions.get(&Identifier::new("main".into())) { + num_parameters = main_function.inputs.len(); + } + + Self { + name: Identifier::new(name), + num_parameters, + imports, + circuits, + functions, + tests, + } + } +} + +impl 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 + } +} diff --git a/types/src/statements/conditional_nested_or_end_statement.rs b/types/src/statements/conditional_nested_or_end_statement.rs new file mode 100644 index 0000000000..60f3c88de8 --- /dev/null +++ b/types/src/statements/conditional_nested_or_end_statement.rs @@ -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), + End(Vec), +} + +impl<'ast> From> 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}}") + } + } + } +} diff --git a/types/src/statements/conditional_statement.rs b/types/src/statements/conditional_statement.rs new file mode 100644 index 0000000000..efd7df1fad --- /dev/null +++ b/types/src/statements/conditional_statement.rs @@ -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, + pub next: Option, +} + +impl<'ast> From> 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}}"), + } + } +} diff --git a/types/src/statements/mod.rs b/types/src/statements/mod.rs new file mode 100644 index 0000000000..8860efeb3f --- /dev/null +++ b/types/src/statements/mod.rs @@ -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::*; diff --git a/types/src/statements/statement.rs b/types/src/statements/statement.rs new file mode 100644 index 0000000000..f96f0c3dc0 --- /dev/null +++ b/types/src/statements/statement.rs @@ -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), + Definition(Variable, Expression), + Assign(Assignee, Expression), + MultipleAssign(Vec, Expression), + Conditional(ConditionalStatement), + For(Identifier, Integer, Integer, Vec), + AssertEq(Expression, Expression), + Expression(Expression), +} + +impl<'ast> From> for Statement { + fn from(statement: ReturnStatement<'ast>) -> Self { + Statement::Return( + statement + .expressions + .into_iter() + .map(|expression| Expression::from(expression)) + .collect(), + ) + } +} + +impl<'ast> From> for Statement { + fn from(statement: DefinitionStatement<'ast>) -> Self { + Statement::Definition( + Variable::from(statement.variable), + Expression::from(statement.expression), + ) + } +} + +impl<'ast> From> 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> 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> 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> 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> for Statement { + fn from(statement: ExpressionStatement<'ast>) -> Self { + Statement::Expression(Expression::from(statement.expression)) + } +} + +impl<'ast> From> 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), + } + } +} diff --git a/types/src/types/integer_type.rs b/types/src/types/integer_type.rs new file mode 100644 index 0000000000..ea1f4c95a8 --- /dev/null +++ b/types/src/types/integer_type.rs @@ -0,0 +1,37 @@ +use leo_ast::types::IntegerType as AstIntegerType; + +use std::fmt; + +/// Explicit integer type +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum IntegerType { + U8, + U16, + U32, + U64, + U128, +} + +impl From for IntegerType { + fn from(integer_type: AstIntegerType) -> Self { + match integer_type { + AstIntegerType::U8Type(_type) => IntegerType::U8, + AstIntegerType::U16Type(_type) => IntegerType::U16, + AstIntegerType::U32Type(_type) => IntegerType::U32, + AstIntegerType::U64Type(_type) => IntegerType::U64, + AstIntegerType::U128Type(_type) => IntegerType::U128, + } + } +} + +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"), + } + } +} diff --git a/types/src/types/mod.rs b/types/src/types/mod.rs new file mode 100644 index 0000000000..44962bfb67 --- /dev/null +++ b/types/src/types/mod.rs @@ -0,0 +1,5 @@ +pub mod integer_type; +pub use integer_type::*; + +pub mod type_; +pub use type_::*; diff --git a/types/src/types/type_.rs b/types/src/types/type_.rs new file mode 100644 index 0000000000..de0500e1c3 --- /dev/null +++ b/types/src/types/type_.rs @@ -0,0 +1,109 @@ +use crate::{Expression, IntegerType, Identifier}; +use leo_ast::types::{DataType, ArrayType, CircuitType, Type as AstType}; + +use std::fmt; + +/// 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, Vec), + Circuit(Identifier), + SelfType, +} + +/// pest ast -> Explicit Type for defining circuit members and function params + +impl From for Type { + fn from(basic_type: DataType) -> Self { + match basic_type { + DataType::Integer(_type) => { + Type::IntegerType(IntegerType::from(_type)) + } + DataType::Field(_type) => Type::Field, + DataType::Group(_type) => Type::Group, + DataType::Boolean(_type) => Type::Boolean, + } + } +} + +impl<'ast> From> for Type { + fn from(array_type: ArrayType<'ast>) -> Self { + let element_type = Box::new(Type::from(array_type._type)); + let dimensions = array_type + .dimensions + .into_iter() + .map(|row| Expression::get_count(row)) + .collect(); + + Type::Array(element_type, dimensions) + } +} + +impl<'ast> From> for Type { + fn from(circuit_type: CircuitType<'ast>) -> Self { + Type::Circuit(Identifier::from(circuit_type.identifier)) + } +} + +impl<'ast> From> for Type { + fn from(_type: AstType<'ast>) -> Self { + match _type { + AstType::Basic(_type) => Type::from(_type), + AstType::Array(_type) => Type::from(_type), + AstType::Circuit(_type) => Type::from(_type), + AstType::SelfType(_type) => Type::SelfType, + } + } +} + +impl Type { + pub fn outer_dimension(&self, dimensions: &Vec) -> 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) -> 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 + } +} + +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, "") + } + } + } +}