mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 03:04:13 +03:00
commit
ad8223a8a4
21
README.md
21
README.md
@ -29,6 +29,27 @@ graph LR
|
||||
2. Circuit definitions
|
||||
3. Function definitions
|
||||
|
||||
## Defining Variables
|
||||
Leo supports `let` and `const` keywords for variable definition.
|
||||
|
||||
```let a = true;``` defines an **allocated** program variable `a` with boolean value `true`.
|
||||
|
||||
```const a = true;``` defines a **constant** program variable `a` with boolean value `true`.
|
||||
|
||||
**Allocated** variables define private variables in the constraint system. Their value is constrained in the circuit on initialization.
|
||||
|
||||
**Constant** variables do not define a variable in the constraint system. Their value is constrained in the circuit on computation with an **allocated** variable.
|
||||
**Constant** variables can be mutable. They do not have the same functionality as `const` variables in other languages.
|
||||
```rust
|
||||
function addOne() -> {
|
||||
let a = 0u8; // allocated, value enforced on this line
|
||||
const b = 1u8; // constant, value not enforced yet
|
||||
|
||||
return a + b // allocated, computed value is enforced to be the sum of both values
|
||||
}
|
||||
```
|
||||
Computations are expressed in terms of arithmetic circuits, in particular rank-1 quadratic constraint systems. Thus computing on an allocated variable always results in another allocated variable.
|
||||
|
||||
## Mutability
|
||||
* All defined variables in Leo are immutable by default.
|
||||
* Variables can be made mutable with the `mut` keyword.
|
||||
|
18
ast/src/common/declare.rs
Normal file
18
ast/src/common/declare.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::declare))]
|
||||
pub enum Declare {
|
||||
Const(Const),
|
||||
Let(Let),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::const_))]
|
||||
pub struct Const {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::let_))]
|
||||
pub struct Let {}
|
@ -1,6 +1,9 @@
|
||||
pub mod assignee;
|
||||
pub use assignee::*;
|
||||
|
||||
pub mod declare;
|
||||
pub use declare::*;
|
||||
|
||||
pub mod eoi;
|
||||
pub use eoi::*;
|
||||
|
||||
|
@ -8,7 +8,11 @@ file = { SOI ~ NEWLINE* ~ import* ~ NEWLINE* ~ circuit_definition* ~ NEWLINE* ~
|
||||
|
||||
// Declared in common/identifier.rs
|
||||
identifier = @{ ((!protected_name ~ ASCII_ALPHA) | (protected_name ~ (ASCII_ALPHANUMERIC | "_"))) ~ (ASCII_ALPHANUMERIC | "_")* }
|
||||
protected_name = { "let" | "for"| "if" | "else" | "as" | "return" }
|
||||
protected_name = {
|
||||
"for"| "if" | "else" | "as" | "return"
|
||||
| declare | mutable | static_ | value_boolean
|
||||
| type_array | type_data
|
||||
}
|
||||
|
||||
// Declared in common/line_end.rs
|
||||
LINE_END = { ";" ~ NEWLINE* }
|
||||
@ -36,6 +40,11 @@ static_ = { "static" }
|
||||
// Declared in common/variable.rs
|
||||
variable = { mutable? ~ identifier ~ (":" ~ type_)? }
|
||||
|
||||
// Declared in common/declare.rs
|
||||
declare = { let_ | const_ }
|
||||
const_ = { "const" }
|
||||
let_ = { "let" }
|
||||
|
||||
/// Operations
|
||||
|
||||
// Declared in operations/not_operation.rs
|
||||
@ -249,7 +258,7 @@ statement_conditional = {"if" ~ (expression | "(" ~ expression ~ ")") ~ "{" ~ NE
|
||||
conditional_nested_or_end_statement = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
|
||||
// Declared in statements/definition_statement.rs
|
||||
statement_definition = { "let" ~ variable ~ "=" ~ expression ~ LINE_END}
|
||||
statement_definition = { declare ~ variable ~ "=" ~ expression ~ LINE_END}
|
||||
|
||||
// Declared in statements/expression_statement.rs
|
||||
statement_expression = { expression ~ LINE_END }
|
||||
@ -258,7 +267,7 @@ statement_expression = { expression ~ LINE_END }
|
||||
statement_for = { "for" ~ identifier ~ "in" ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
|
||||
// Declared in statements/multiple_assignment_statement.rs
|
||||
statement_multiple_assignment = { "let" ~ "(" ~ variable_tuple ~ ")" ~ "=" ~ identifier ~ "(" ~ expression_tuple ~ ")" ~ LINE_END}
|
||||
statement_multiple_assignment = { declare ~ "(" ~ variable_tuple ~ ")" ~ "=" ~ identifier ~ "(" ~ expression_tuple ~ ")" ~ LINE_END}
|
||||
variable_tuple = _{ variable ~ ("," ~ variable)* }
|
||||
|
||||
// Declared in statements/return_statement.rs
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{LineEnd, Variable},
|
||||
common::{Declare, LineEnd, Variable},
|
||||
expressions::Expression,
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@ use std::fmt;
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_definition))]
|
||||
pub struct DefinitionStatement<'ast> {
|
||||
pub declare: Declare,
|
||||
pub variable: Variable<'ast>,
|
||||
pub expression: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{Identifier, LineEnd, Variable},
|
||||
common::{Declare, Identifier, LineEnd, Variable},
|
||||
expressions::Expression,
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@ use std::fmt;
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_multiple_assignment))]
|
||||
pub struct MultipleAssignmentStatement<'ast> {
|
||||
pub declare: Declare,
|
||||
pub variables: Vec<Variable<'ast>>,
|
||||
pub function_name: Identifier<'ast>,
|
||||
pub arguments: Vec<Expression<'ast>>,
|
||||
|
@ -10,6 +10,7 @@ use leo_types::{
|
||||
Assignee,
|
||||
ConditionalNestedOrEndStatement,
|
||||
ConditionalStatement,
|
||||
Declare,
|
||||
Expression,
|
||||
Identifier,
|
||||
Integer,
|
||||
@ -221,6 +222,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
declare: Declare,
|
||||
variable: Variable,
|
||||
expression: Expression,
|
||||
) -> Result<(), StatementError> {
|
||||
@ -228,7 +230,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
if let Some(ref _type) = variable._type {
|
||||
expected_types.push(_type.clone());
|
||||
}
|
||||
let value = self.enforce_expression(
|
||||
let mut value = self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
@ -236,6 +238,10 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
expression,
|
||||
)?;
|
||||
|
||||
if let Declare::Let = declare {
|
||||
value.allocate_value(cs)?;
|
||||
}
|
||||
|
||||
self.store_definition(function_scope, variable, value)
|
||||
}
|
||||
|
||||
@ -484,8 +490,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Statement::Return(expressions) => {
|
||||
res = Some(self.enforce_return_statement(cs, file_scope, function_scope, expressions, return_types)?);
|
||||
}
|
||||
Statement::Definition(variable, expression) => {
|
||||
self.enforce_definition_statement(cs, file_scope, function_scope, variable, expression)?;
|
||||
Statement::Definition(declare, variable, expression) => {
|
||||
self.enforce_definition_statement(cs, file_scope, function_scope, declare, variable, expression)?;
|
||||
}
|
||||
Statement::Assign(variable, expression) => {
|
||||
self.enforce_assign_statement(cs, file_scope, function_scope, indicator, variable, expression)?;
|
||||
|
@ -9,6 +9,7 @@ use snarkos_models::{
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{
|
||||
alloc::AllocGadget,
|
||||
boolean::Boolean,
|
||||
eq::ConditionalEqGadget,
|
||||
select::CondSelectGadget,
|
||||
@ -105,6 +106,74 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
*self = *inner.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn allocate_value<CS: ConstraintSystem<F>>(&mut self, mut cs: CS) -> Result<(), ValueError> {
|
||||
match self {
|
||||
// allocated values
|
||||
ConstrainedValue::Boolean(boolean) => {
|
||||
let option = boolean.get_value();
|
||||
|
||||
*boolean = Boolean::alloc(cs, || option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
}
|
||||
ConstrainedValue::Integer(integer) => {
|
||||
let integer_type = integer.get_type();
|
||||
let option = integer.get_value();
|
||||
let name = format!("clone {}", integer);
|
||||
|
||||
*integer = Integer::allocate_type(&mut cs, integer_type, name, option)?;
|
||||
}
|
||||
ConstrainedValue::Field(field) => {
|
||||
let option = field.get_value().map(|v| format!("{}", v));
|
||||
|
||||
*field = FieldType::alloc(cs, || option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
}
|
||||
ConstrainedValue::Group(group) => {
|
||||
let string = format!("{}", group); // may need to implement u256 -> decimal formatting
|
||||
|
||||
*group = G::alloc(cs, || Ok(string))?;
|
||||
}
|
||||
// value wrappers
|
||||
ConstrainedValue::Array(array) => {
|
||||
array
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.map(|(i, value)| value.allocate_value(cs.ns(|| format!("allocate array member {}", i))))
|
||||
.collect::<Result<(), ValueError>>()?;
|
||||
}
|
||||
ConstrainedValue::CircuitExpression(_id, members) => {
|
||||
members
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.map(|(i, member)| {
|
||||
member
|
||||
.1
|
||||
.allocate_value(cs.ns(|| format!("allocate circuit member {}", i)))
|
||||
})
|
||||
.collect::<Result<(), ValueError>>()?;
|
||||
}
|
||||
ConstrainedValue::Return(array) => {
|
||||
array
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.map(|(i, value)| value.allocate_value(cs.ns(|| format!("allocate return member {}", i))))
|
||||
.collect::<Result<(), ValueError>>()?;
|
||||
}
|
||||
ConstrainedValue::Mutable(value) => {
|
||||
value.allocate_value(cs)?;
|
||||
}
|
||||
ConstrainedValue::Static(value) => {
|
||||
value.allocate_value(cs)?;
|
||||
}
|
||||
// empty wrappers
|
||||
ConstrainedValue::CircuitDefinition(_) => {}
|
||||
ConstrainedValue::Function(_, _) => {}
|
||||
ConstrainedValue::Unresolved(_) => {
|
||||
return Err(ValueError::SynthesisError(SynthesisError::AssignmentMissing));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F, G> {
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::errors::{FieldError, GroupError};
|
||||
use leo_types::IntegerError;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use std::{num::ParseIntError, str::ParseBoolError};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -19,4 +20,7 @@ pub enum ValueError {
|
||||
|
||||
#[error("{}", _0)]
|
||||
ParseIntError(#[from] ParseIntError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Multidimensional array syntax in leo
|
||||
function main() -> u32[3][2] {
|
||||
let m = [[0u32, 0u32, 0u32], [0u32, 0u32, 0u32]]; // inline
|
||||
const m = [[0u32, 0u32, 0u32], [0u32, 0u32, 0u32]]; // inline
|
||||
|
||||
let m: u32[3][2] = [[0; 3]; 2]; // initializer
|
||||
const m: u32[3][2] = [[0; 3]; 2]; // initializer
|
||||
|
||||
return m
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
// !(true && (false || true))
|
||||
function main() -> bool {
|
||||
let a = true;
|
||||
let b = false || a;
|
||||
let c = !(true && b);
|
||||
const a = true;
|
||||
const b = false || a;
|
||||
const c = !(true && b);
|
||||
|
||||
return c
|
||||
}
|
@ -3,6 +3,6 @@ function foo() -> field {
|
||||
}
|
||||
|
||||
function main() -> field {
|
||||
let myGlobal = 42field;
|
||||
const myGlobal = 42field;
|
||||
return foo()
|
||||
}
|
@ -12,7 +12,7 @@ function bad_mutate(mut x: u32) {
|
||||
}
|
||||
|
||||
function main() -> u32 {
|
||||
let a = 1;
|
||||
let a = 1u32;
|
||||
bad_mutate(a);
|
||||
|
||||
return a // <- returns 1
|
||||
|
@ -1,6 +1,6 @@
|
||||
function main() -> group {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
const point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return point_1 + point_2
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
function main() {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
const point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
assert_eq!(point_1, point_2);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
function main() {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_2 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
|
||||
assert_eq!(point_1, point_2);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
function main() -> bool {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
const point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return point_1 == point_2
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
function main() -> bool {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_2 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
|
||||
return point_1 == point_2
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
function main() -> group {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
const point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return point_1 - point_2
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
function main (b: bool) -> group {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
const point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
const point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return if b ? point_1 : point_2
|
||||
}
|
27
types/src/common/declare.rs
Normal file
27
types/src/common/declare.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use leo_ast::common::Declare as AstDeclare;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Declare {
|
||||
Const,
|
||||
Let,
|
||||
}
|
||||
|
||||
impl<'ast> From<AstDeclare> for Declare {
|
||||
fn from(declare: AstDeclare) -> Self {
|
||||
match declare {
|
||||
AstDeclare::Const(_) => Declare::Const,
|
||||
AstDeclare::Let(_) => Declare::Let,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Declare {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Declare::Const => write!(f, "const"),
|
||||
Declare::Let => write!(f, "let"),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
pub mod assignee;
|
||||
pub use assignee::*;
|
||||
|
||||
pub mod declare;
|
||||
pub use declare::*;
|
||||
|
||||
pub mod identifier;
|
||||
pub use identifier::*;
|
||||
|
||||
|
@ -58,16 +58,20 @@ impl<'ast> Integer {
|
||||
}
|
||||
|
||||
impl Integer {
|
||||
pub fn to_usize(&self) -> usize {
|
||||
pub fn get_value(&self) -> Option<u128> {
|
||||
match self {
|
||||
Integer::U8(u8) => u8.value.unwrap() as usize,
|
||||
Integer::U16(u16) => u16.value.unwrap() as usize,
|
||||
Integer::U32(u32) => u32.value.unwrap() as usize,
|
||||
Integer::U64(u64) => u64.value.unwrap() as usize,
|
||||
Integer::U128(u128) => u128.value.unwrap() as usize,
|
||||
Integer::U8(u8) => u8.value.map(|v| v as u128),
|
||||
Integer::U16(u16) => u16.value.map(|v| v as u128),
|
||||
Integer::U32(u32) => u32.value.map(|v| v as u128),
|
||||
Integer::U64(u64) => u64.value.map(|v| v as u128),
|
||||
Integer::U128(u128) => u128.value.map(|v| v as u128),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_usize(&self) -> usize {
|
||||
self.get_value().unwrap() as usize
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> IntegerType {
|
||||
match self {
|
||||
Integer::U8(_u8) => IntegerType::U8,
|
||||
@ -78,6 +82,47 @@ impl Integer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocate_type<F: Field, CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
integer_type: IntegerType,
|
||||
name: String,
|
||||
option: Option<u128>,
|
||||
) -> Result<Self, IntegerError> {
|
||||
Ok(match integer_type {
|
||||
IntegerType::U8 => {
|
||||
let u8_option = option.map(|integer| integer as u8);
|
||||
let u8_result = UInt8::alloc(cs.ns(|| name), || u8_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U8(u8_result)
|
||||
}
|
||||
IntegerType::U16 => {
|
||||
let u16_option = option.map(|integer| integer as u16);
|
||||
let u16_result = UInt16::alloc(cs.ns(|| name), || u16_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U16(u16_result)
|
||||
}
|
||||
IntegerType::U32 => {
|
||||
let u32_option = option.map(|integer| integer as u32);
|
||||
let u32_result = UInt32::alloc(cs.ns(|| name), || u32_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U32(u32_result)
|
||||
}
|
||||
IntegerType::U64 => {
|
||||
let u64_option = option.map(|integer| integer as u64);
|
||||
let u64_result = UInt64::alloc(cs.ns(|| name), || u64_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U64(u64_result)
|
||||
}
|
||||
IntegerType::U128 => {
|
||||
let u128_option = option.map(|integer| integer as u128);
|
||||
let u128_result =
|
||||
UInt128::alloc(cs.ns(|| name), || u128_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U128(u128_result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_input<F: Field, CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
integer_type: IntegerType,
|
||||
@ -85,7 +130,7 @@ impl Integer {
|
||||
integer_value: Option<InputValue>,
|
||||
) -> Result<Self, IntegerError> {
|
||||
// Check that the input value is the correct type
|
||||
let integer_option = match integer_value {
|
||||
let option = match integer_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Integer(_type_, integer) = input {
|
||||
Some(integer)
|
||||
@ -96,39 +141,7 @@ impl Integer {
|
||||
None => None,
|
||||
};
|
||||
|
||||
Ok(match integer_type {
|
||||
IntegerType::U8 => {
|
||||
let u8_option = integer_option.map(|integer| integer as u8);
|
||||
let u8_result = UInt8::alloc(cs.ns(|| name), || u8_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U8(u8_result)
|
||||
}
|
||||
IntegerType::U16 => {
|
||||
let u16_option = integer_option.map(|integer| integer as u16);
|
||||
let u16_result = UInt16::alloc(cs.ns(|| name), || u16_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U16(u16_result)
|
||||
}
|
||||
IntegerType::U32 => {
|
||||
let u32_option = integer_option.map(|integer| integer as u32);
|
||||
let u32_result = UInt32::alloc(cs.ns(|| name), || u32_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U32(u32_result)
|
||||
}
|
||||
IntegerType::U64 => {
|
||||
let u64_option = integer_option.map(|integer| integer as u64);
|
||||
let u64_result = UInt64::alloc(cs.ns(|| name), || u64_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U64(u64_result)
|
||||
}
|
||||
IntegerType::U128 => {
|
||||
let u128_option = integer_option.map(|integer| integer as u128);
|
||||
let u128_result =
|
||||
UInt128::alloc(cs.ns(|| name), || u128_option.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Integer::U128(u128_result)
|
||||
}
|
||||
})
|
||||
Self::allocate_type(cs, integer_type, name, option)
|
||||
}
|
||||
|
||||
pub fn add<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{Assignee, ConditionalStatement, Expression, Identifier, Integer, Variable};
|
||||
use crate::{Assignee, ConditionalStatement, Declare, Expression, Identifier, Integer, Variable};
|
||||
use leo_ast::{
|
||||
operations::AssignOperation,
|
||||
statements::{
|
||||
@ -19,7 +19,7 @@ use std::fmt;
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum Statement {
|
||||
Return(Vec<Expression>),
|
||||
Definition(Variable, Expression),
|
||||
Definition(Declare, Variable, Expression),
|
||||
Assign(Assignee, Expression),
|
||||
MultipleAssign(Vec<Variable>, Expression),
|
||||
Conditional(ConditionalStatement),
|
||||
@ -43,6 +43,7 @@ impl<'ast> From<ReturnStatement<'ast>> for Statement {
|
||||
impl<'ast> From<DefinitionStatement<'ast>> for Statement {
|
||||
fn from(statement: DefinitionStatement<'ast>) -> Self {
|
||||
Statement::Definition(
|
||||
Declare::from(statement.declare),
|
||||
Variable::from(statement.variable),
|
||||
Expression::from(statement.expression),
|
||||
)
|
||||
@ -176,7 +177,9 @@ impl fmt::Display for Statement {
|
||||
}
|
||||
write!(f, ")\n")
|
||||
}
|
||||
Statement::Definition(ref variable, ref expression) => write!(f, "let {} = {};", variable, expression),
|
||||
Statement::Definition(ref declare, ref variable, ref expression) => {
|
||||
write!(f, "{} {} = {};", declare, variable, expression)
|
||||
}
|
||||
Statement::Assign(ref variable, ref statement) => write!(f, "{} = {};", variable, statement),
|
||||
Statement::MultipleAssign(ref assignees, ref function) => {
|
||||
write!(f, "let (")?;
|
||||
|
Loading…
Reference in New Issue
Block a user