mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
impl if else conditional statements
This commit is contained in:
parent
efbf4f54e9
commit
f69032c833
@ -1,4 +1,10 @@
|
||||
function main(a: private u32) -> (u32) {
|
||||
b = a + 5;
|
||||
return a
|
||||
function main(a: private bool, b: private bool) -> (u32) {
|
||||
if (a) {
|
||||
res = 1;
|
||||
} else if (b) {
|
||||
res = 2;
|
||||
} else {
|
||||
res = 3;
|
||||
}
|
||||
return res
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use leo_program::{self, ast};
|
||||
use leo_compiler::{self, ast};
|
||||
|
||||
use snarkos_algorithms::snark::{
|
||||
create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
|
||||
@ -45,11 +45,11 @@ impl<F: Field + PrimeField> ConstraintSynthesizer<F> for Benchmark<F> {
|
||||
let syntax_tree = ast::File::from_pest(&mut file).expect("infallible");
|
||||
// println!("{:#?}", syntax_tree);
|
||||
|
||||
let program = leo_program::Program::<'_, F>::from(syntax_tree);
|
||||
let program = leo_compiler::Program::<'_, F>::from(syntax_tree);
|
||||
println!(" compiled: {:#?}", program);
|
||||
|
||||
let program = program.name("simple".into());
|
||||
leo_program::ResolvedProgram::generate_constraints(cs, program);
|
||||
leo_compiler::ResolvedProgram::generate_constraints(cs, program);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ impl<'ast> fmt::Display for Expression<'ast> {
|
||||
}
|
||||
Expression::Ternary(ref expression) => write!(
|
||||
f,
|
||||
"if {} then {} else {} fi",
|
||||
"if {} ? {} : {}",
|
||||
expression.first, expression.second, expression.third
|
||||
),
|
||||
Expression::ArrayInline(ref expression) => {
|
||||
@ -805,6 +805,23 @@ pub struct ReturnStatement<'ast> {
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::conditional_nested_or_end))]
|
||||
pub enum ConditionalNestedOrEnd<'ast> {
|
||||
Nested(Box<ConditionalStatement<'ast>>),
|
||||
End(Vec<Statement<'ast>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_conditional))]
|
||||
pub struct ConditionalStatement<'ast> {
|
||||
pub condition: Expression<'ast>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
pub next: Option<ConditionalNestedOrEnd<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_for))]
|
||||
pub struct ForStatement<'ast> {
|
||||
@ -849,10 +866,11 @@ pub struct AssignStatement<'ast> {
|
||||
#[pest_ast(rule(Rule::statement))]
|
||||
pub enum Statement<'ast> {
|
||||
Return(ReturnStatement<'ast>),
|
||||
Iteration(ForStatement<'ast>),
|
||||
MultipleAssignment(MultipleAssignmentStatement<'ast>),
|
||||
Definition(DefinitionStatement<'ast>),
|
||||
Assign(AssignStatement<'ast>),
|
||||
MultipleAssignment(MultipleAssignmentStatement<'ast>),
|
||||
Conditional(ConditionalStatement<'ast>),
|
||||
Iteration(ForStatement<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ReturnStatement<'ast> {
|
||||
@ -867,6 +885,34 @@ impl<'ast> fmt::Display for ReturnStatement<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ConditionalNestedOrEnd<'ast> {
|
||||
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{}\n", statement)?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ConditionalStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "if ({}) {{\n", self.condition)?;
|
||||
for statement in self.statements.iter() {
|
||||
write!(f, "\t{}\n", statement)?;
|
||||
}
|
||||
self.next
|
||||
.as_ref()
|
||||
.map(|n_or_e| write!(f, "}} {}", n_or_e))
|
||||
.unwrap_or(write!(f, "}}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ForStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
@ -891,13 +937,13 @@ impl<'ast> fmt::Display for MultipleAssignmentStatement<'ast> {
|
||||
|
||||
impl<'ast> fmt::Display for DefinitionStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} {} = {}", self.ty, self.variable, self.expression)
|
||||
write!(f, "{} {} = {};", self.ty, self.variable, self.expression)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for AssignStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} = {}", self.assignee, self.expression)
|
||||
write!(f, "{} = {};", self.assignee, self.expression)
|
||||
}
|
||||
}
|
||||
|
||||
@ -905,10 +951,11 @@ impl<'ast> fmt::Display for Statement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Return(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Iteration(ref statement) => write!(f, "{}", statement),
|
||||
Statement::MultipleAssignment(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Assign(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Definition(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Assign(ref statement) => write!(f, "{}", statement),
|
||||
Statement::MultipleAssignment(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Conditional(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Iteration(ref statement) => write!(f, "{}", statement),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
use from_pest::FromPest;
|
||||
use std::{
|
||||
fs,
|
||||
marker::PhantomData,
|
||||
path::PathBuf,
|
||||
};
|
||||
use std::{fs, marker::PhantomData, path::PathBuf};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Compiler<F: Field + PrimeField> {
|
||||
@ -21,7 +17,10 @@ pub struct Compiler<F: Field + PrimeField> {
|
||||
|
||||
impl<F: Field + PrimeField> Compiler<F> {
|
||||
pub fn init(main_file_path: PathBuf) -> Self {
|
||||
Self { main_file_path, _engine: PhantomData }
|
||||
Self {
|
||||
main_file_path,
|
||||
_engine: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,4 +47,4 @@ impl<F: Field + PrimeField> ConstraintSynthesizer<F> for Compiler<F> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use crate::ast;
|
||||
use crate::constraints::{
|
||||
new_scope, new_scope_from_variable, new_variable_from_variables, ResolvedProgram, ResolvedValue,
|
||||
};
|
||||
use crate::{Expression, Function, Import, Program, Statement, Type};
|
||||
use crate::{Expression, Function, Import, Program, Type};
|
||||
|
||||
use from_pest::FromPest;
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
@ -109,54 +109,15 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
.statements
|
||||
.clone()
|
||||
.into_iter()
|
||||
.for_each(|statement| match statement {
|
||||
Statement::Return(expressions) => {
|
||||
return_values = self.enforce_return_statement(
|
||||
cs,
|
||||
scope.clone(),
|
||||
function_name.clone(),
|
||||
expressions,
|
||||
function.returns.to_owned(),
|
||||
);
|
||||
}
|
||||
Statement::Assign(variable, expression) => {
|
||||
self.enforce_assign_statement(
|
||||
cs,
|
||||
scope.clone(),
|
||||
function_name.clone(),
|
||||
variable,
|
||||
expression,
|
||||
);
|
||||
}
|
||||
Statement::Definition(ty, assignee, expression) => {
|
||||
self.enforce_definition_statement(
|
||||
cs,
|
||||
scope.clone(),
|
||||
function_name.clone(),
|
||||
ty,
|
||||
assignee,
|
||||
expression,
|
||||
);
|
||||
}
|
||||
Statement::MultipleDefinition(assignees, function_call) => {
|
||||
self.enforce_multiple_definition_statement(
|
||||
cs,
|
||||
scope.clone(),
|
||||
function_name.clone(),
|
||||
assignees,
|
||||
function_call,
|
||||
);
|
||||
}
|
||||
Statement::For(index, start, stop, statements) => {
|
||||
self.enforce_for_statement(
|
||||
cs,
|
||||
scope.clone(),
|
||||
function_name.clone(),
|
||||
index,
|
||||
start,
|
||||
stop,
|
||||
statements,
|
||||
);
|
||||
.for_each(|statement| {
|
||||
if let Some(returned) = self.enforce_statement(
|
||||
cs,
|
||||
scope.clone(),
|
||||
function_name.clone(),
|
||||
statement,
|
||||
function.returns.clone(),
|
||||
) {
|
||||
return_values = returned;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,10 +1,15 @@
|
||||
//! Methods to enforce constraints on statements in a resolved aleo program.
|
||||
|
||||
use crate::constraints::{new_scope_from_variable, ResolvedProgram, ResolvedValue};
|
||||
use crate::{Assignee, Expression, Integer, RangeOrExpression, Statement, Type, Variable};
|
||||
use crate::{
|
||||
Assignee, ConditionalNestedOrEnd, ConditionalStatement, Expression, Integer, RangeOrExpression,
|
||||
Statement, Type, Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use snarkos_models::gadgets::{r1cs::ConstraintSystem, utilities::uint32::UInt32};
|
||||
use snarkos_models::gadgets::{
|
||||
r1cs::ConstraintSystem, utilities::boolean::Boolean, utilities::uint32::UInt32,
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
fn resolve_assignee(&mut self, scope: String, assignee: Assignee<F>) -> String {
|
||||
@ -124,7 +129,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_assign_statement(
|
||||
fn enforce_assign_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
@ -142,7 +147,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
self.store_assignment(cs, file_scope, function_scope, assignee, result_value);
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_definition_statement(
|
||||
fn enforce_definition_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
@ -165,7 +170,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_multiple_definition_statement(
|
||||
fn enforce_multiple_definition_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
@ -198,16 +203,16 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_return_statement(
|
||||
fn enforce_return_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
statements: Vec<Expression<F>>,
|
||||
expressions: Vec<Expression<F>>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> ResolvedValue<F> {
|
||||
ResolvedValue::Return(
|
||||
statements
|
||||
expressions
|
||||
.into_iter()
|
||||
.zip(return_types.into_iter())
|
||||
.map(|(expression, ty)| {
|
||||
@ -227,27 +232,125 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
)
|
||||
}
|
||||
|
||||
fn enforce_statement(
|
||||
fn enforce_conditional_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
statement: ConditionalStatement<F>,
|
||||
) -> Option<ResolvedValue<F>> {
|
||||
let mut res = None;
|
||||
|
||||
let condition = match self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
statement.condition.clone(),
|
||||
) {
|
||||
ResolvedValue::Boolean(resolved) => resolved,
|
||||
value => unimplemented!("if else conditional must resolve to boolean, got {}", value),
|
||||
};
|
||||
|
||||
if condition.eq(&Boolean::Constant(true)) {
|
||||
statement
|
||||
.statements
|
||||
.clone()
|
||||
.into_iter()
|
||||
.for_each(|statement| {
|
||||
if let Some(early_return) = self.enforce_statement(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
statement,
|
||||
vec![],
|
||||
) {
|
||||
res = Some(early_return)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if let Some(next) = statement.next {
|
||||
match next {
|
||||
ConditionalNestedOrEnd::Nested(nested) => {
|
||||
res = self.enforce_conditional_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
*nested,
|
||||
)
|
||||
}
|
||||
ConditionalNestedOrEnd::End(statements) => {
|
||||
statements.into_iter().for_each(|statement| {
|
||||
if let Some(early_return) = self.enforce_statement(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
statement,
|
||||
vec![],
|
||||
) {
|
||||
res = Some(early_return)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn enforce_for_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
index: Variable<F>,
|
||||
start: Integer,
|
||||
stop: Integer,
|
||||
statements: Vec<Statement<F>>,
|
||||
) -> Option<ResolvedValue<F>> {
|
||||
let mut res = None;
|
||||
|
||||
for i in start.to_usize()..stop.to_usize() {
|
||||
// Store index in current function scope.
|
||||
// For loop scope is not implemented.
|
||||
let index_name = new_scope_from_variable(function_scope.clone(), &index);
|
||||
self.store(index_name, ResolvedValue::U32(UInt32::constant(i as u32)));
|
||||
|
||||
// Evaluate statements (for loop statements should not have a return type)
|
||||
statements.clone().into_iter().for_each(|statement| {
|
||||
// TODO: handle for loop early termination here
|
||||
res = self.enforce_statement(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
statement,
|
||||
vec![],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
statement: Statement<F>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) {
|
||||
) -> Option<ResolvedValue<F>> {
|
||||
let mut res = None;
|
||||
match statement {
|
||||
Statement::Return(statements) => {
|
||||
Statement::Return(expressions) => {
|
||||
// TODO: add support for early termination
|
||||
let _res = self.enforce_return_statement(
|
||||
res = Some(self.enforce_return_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
statements,
|
||||
expressions,
|
||||
return_types,
|
||||
);
|
||||
}
|
||||
Statement::Assign(variable, expression) => {
|
||||
self.enforce_assign_statement(cs, file_scope, function_scope, variable, expression);
|
||||
));
|
||||
}
|
||||
Statement::Definition(ty, assignee, expression) => {
|
||||
self.enforce_definition_statement(
|
||||
@ -259,7 +362,10 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
expression,
|
||||
);
|
||||
}
|
||||
Statement::MultipleDefinition(assignees, function) => {
|
||||
Statement::Assign(variable, expression) => {
|
||||
self.enforce_assign_statement(cs, file_scope, function_scope, variable, expression);
|
||||
}
|
||||
Statement::MultipleAssign(assignees, function) => {
|
||||
self.enforce_multiple_definition_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
@ -268,8 +374,15 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
function,
|
||||
);
|
||||
}
|
||||
Statement::Conditional(statement) => {
|
||||
if let Some(early_return) =
|
||||
self.enforce_conditional_statement(cs, file_scope, function_scope, statement)
|
||||
{
|
||||
res = Some(early_return)
|
||||
}
|
||||
}
|
||||
Statement::For(index, start, stop, statements) => {
|
||||
self.enforce_for_statement(
|
||||
if let Some(early_return) = self.enforce_for_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
@ -277,37 +390,12 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
start,
|
||||
stop,
|
||||
statements,
|
||||
);
|
||||
) {
|
||||
res = Some(early_return)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_for_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
index: Variable<F>,
|
||||
start: Integer,
|
||||
stop: Integer,
|
||||
statements: Vec<Statement<F>>,
|
||||
) {
|
||||
for i in start.to_usize()..stop.to_usize() {
|
||||
// Store index in current function scope.
|
||||
// For loop scope is not implemented.
|
||||
let index_name = new_scope_from_variable(function_scope.clone(), &index);
|
||||
self.store(index_name, ResolvedValue::U32(UInt32::constant(i as u32)));
|
||||
|
||||
// Evaluate statements (for loop statements should not have a return type)
|
||||
statements.clone().into_iter().for_each(|statement| {
|
||||
self.enforce_statement(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
statement,
|
||||
vec![],
|
||||
)
|
||||
});
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ expression_inline_struct = { variable ~ "{" ~ NEWLINE* ~ inline_struct_member_li
|
||||
|
||||
/// Conditionals
|
||||
|
||||
expression_conditional = { "if" ~ expression ~ "then" ~ expression ~ "else" ~ expression ~ "fi"}
|
||||
expression_conditional = { "if" ~ expression ~ "?" ~ expression ~ ":" ~ expression}
|
||||
|
||||
/// Expressions
|
||||
|
||||
@ -142,15 +142,18 @@ expression = { expression_term ~ (operation_binary ~ expression_term)* }
|
||||
expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
||||
|
||||
/// Statements
|
||||
|
||||
// statement_one_or_more = { (statement ~ NEWLINE*)* }
|
||||
statement_return = { "return" ~ expression_tuple }
|
||||
statement_for = { "for" ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"}
|
||||
statement_multiple_assignment = { optionally_typed_variable_tuple ~ "=" ~ variable ~ "(" ~ expression_tuple ~ ")" }
|
||||
statement_definition = { ty ~ variable ~ "=" ~ expression }
|
||||
statement_assign = { assignee ~ "=" ~ expression }
|
||||
statement_multiple_assignment = { optionally_typed_variable_tuple ~ "=" ~ variable ~ "(" ~ expression_tuple ~ ")" }
|
||||
statement_conditional = {"if" ~ "(" ~ expression ~ ")" ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else" ~ conditional_nested_or_end)?}
|
||||
conditional_nested_or_end = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
statement_for = { "for" ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"}
|
||||
|
||||
statement = {
|
||||
(statement_return
|
||||
| statement_conditional
|
||||
| (statement_for
|
||||
| statement_multiple_assignment
|
||||
| statement_definition
|
||||
|
@ -107,14 +107,28 @@ pub enum Type<F: Field + PrimeField> {
|
||||
Struct(Variable<F>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum ConditionalNestedOrEnd<F: Field + PrimeField> {
|
||||
Nested(Box<ConditionalStatement<F>>),
|
||||
End(Vec<Statement<F>>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConditionalStatement<F: Field + PrimeField> {
|
||||
pub condition: Expression<F>,
|
||||
pub statements: Vec<Statement<F>>,
|
||||
pub next: Option<ConditionalNestedOrEnd<F>>,
|
||||
}
|
||||
|
||||
/// Program statement that defines some action (or expression) to be carried out.
|
||||
#[derive(Clone)]
|
||||
pub enum Statement<F: Field + PrimeField> {
|
||||
// Declaration(Variable),
|
||||
Return(Vec<Expression<F>>),
|
||||
Assign(Assignee<F>, Expression<F>),
|
||||
Definition(Type<F>, Assignee<F>, Expression<F>),
|
||||
MultipleDefinition(Vec<Assignee<F>>, Expression<F>),
|
||||
Assign(Assignee<F>, Expression<F>),
|
||||
MultipleAssign(Vec<Assignee<F>>, Expression<F>),
|
||||
Conditional(ConditionalStatement<F>),
|
||||
For(Variable<F>, Integer, Integer, Vec<Statement<F>>),
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
//! Format display functions for zokrates_program types.
|
||||
|
||||
use crate::{
|
||||
Assignee, Expression, Function, FunctionName, Integer, Parameter, RangeOrExpression,
|
||||
SpreadOrExpression, Statement, Struct, StructField, Type, Variable,
|
||||
Assignee, ConditionalNestedOrEnd, ConditionalStatement, Expression, Function, FunctionName,
|
||||
Integer, Parameter, RangeOrExpression, SpreadOrExpression, Statement, Struct, StructField,
|
||||
Type, Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
@ -138,6 +139,34 @@ impl<F: Field + PrimeField> fmt::Display for Assignee<F> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> fmt::Display for ConditionalNestedOrEnd<F> {
|
||||
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<F: Field + PrimeField> fmt::Display for ConditionalStatement<F> {
|
||||
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<F: Field + PrimeField> fmt::Display for Statement<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
@ -151,13 +180,13 @@ impl<F: Field + PrimeField> fmt::Display for Statement<F> {
|
||||
}
|
||||
write!(f, "\n")
|
||||
}
|
||||
Statement::Assign(ref variable, ref statement) => {
|
||||
write!(f, "{} = {};", variable, statement)
|
||||
}
|
||||
Statement::Definition(ref ty, ref assignee, ref statement) => {
|
||||
write!(f, "{} {} = {};", ty, assignee, statement)
|
||||
}
|
||||
Statement::MultipleDefinition(ref assignees, ref function) => {
|
||||
Statement::Assign(ref variable, ref statement) => {
|
||||
write!(f, "{} = {};", variable, statement)
|
||||
}
|
||||
Statement::MultipleAssign(ref assignees, ref function) => {
|
||||
for (i, id) in assignees.iter().enumerate() {
|
||||
write!(f, "{}", id)?;
|
||||
if i < assignees.len() - 1 {
|
||||
@ -166,6 +195,7 @@ impl<F: Field + PrimeField> fmt::Display for Statement<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 {}..{} do\n", var, start, stop)?;
|
||||
for l in list {
|
||||
@ -190,25 +220,26 @@ impl<F: Field + PrimeField> fmt::Debug for Statement<F> {
|
||||
}
|
||||
write!(f, "\n")
|
||||
}
|
||||
Statement::Assign(ref variable, ref statement) => {
|
||||
write!(f, "{} = {};", variable, statement)
|
||||
}
|
||||
Statement::Definition(ref ty, ref assignee, ref statement) => {
|
||||
write!(f, "{} {} = {};", ty, assignee, statement)
|
||||
}
|
||||
Statement::MultipleDefinition(ref assignees, ref function) => {
|
||||
Statement::Assign(ref variable, ref statement) => {
|
||||
write!(f, "{} = {};", variable, statement)
|
||||
}
|
||||
Statement::MultipleAssign(ref assignees, ref function) => {
|
||||
for (i, id) in assignees.iter().enumerate() {
|
||||
write!(f, "{}", id)?;
|
||||
if i < assignees.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, " = {}();", function)
|
||||
write!(f, " = {};", function)
|
||||
}
|
||||
Statement::Conditional(ref statement) => write!(f, "{}", statement),
|
||||
Statement::For(ref var, ref start, ref stop, ref list) => {
|
||||
write!(f, "for {:?} in {:?}..{:?} do\n", var, start, stop)?;
|
||||
write!(f, "for {} in {}..{} do\n", var, start, stop)?;
|
||||
for l in list {
|
||||
write!(f, "\t\t{:?}\n", l)?;
|
||||
write!(f, "\t\t{}\n", l)?;
|
||||
}
|
||||
write!(f, "\tendfor;")
|
||||
}
|
||||
|
@ -346,6 +346,86 @@ impl<'ast, F: Field + PrimeField> From<ast::ReturnStatement<'ast>> for types::St
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::DefinitionStatement<'ast>) -> Self {
|
||||
types::Statement::Definition(
|
||||
types::Type::from(statement.ty),
|
||||
types::Assignee::from(statement.variable),
|
||||
types::Expression::from(statement.expression),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
||||
types::Statement::Assign(
|
||||
types::Assignee::from(statement.assignee),
|
||||
types::Expression::from(statement.expression),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::MultipleAssignmentStatement<'ast>>
|
||||
for types::Statement<F>
|
||||
{
|
||||
fn from(statement: ast::MultipleAssignmentStatement<'ast>) -> Self {
|
||||
let assignees = statement
|
||||
.assignees
|
||||
.into_iter()
|
||||
.map(|i| types::Assignee::Variable(types::Variable::from(i.id)))
|
||||
.collect();
|
||||
|
||||
types::Statement::MultipleAssign(
|
||||
assignees,
|
||||
types::Expression::FunctionCall(
|
||||
types::Variable::from(statement.function_name),
|
||||
statement
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|e| types::Expression::from(e))
|
||||
.collect(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ConditionalNestedOrEnd<'ast>>
|
||||
for types::ConditionalNestedOrEnd<F>
|
||||
{
|
||||
fn from(statement: ast::ConditionalNestedOrEnd<'ast>) -> Self {
|
||||
match statement {
|
||||
ast::ConditionalNestedOrEnd::Nested(nested) => types::ConditionalNestedOrEnd::Nested(
|
||||
Box::new(types::ConditionalStatement::from(*nested)),
|
||||
),
|
||||
ast::ConditionalNestedOrEnd::End(statements) => types::ConditionalNestedOrEnd::End(
|
||||
statements
|
||||
.into_iter()
|
||||
.map(|statement| types::Statement::from(statement))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ConditionalStatement<'ast>>
|
||||
for types::ConditionalStatement<F>
|
||||
{
|
||||
fn from(statement: ast::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, F: Field + PrimeField> From<ast::ForStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::ForStatement<'ast>) -> Self {
|
||||
let from = match types::Expression::<F>::from(statement.start) {
|
||||
@ -370,57 +450,17 @@ impl<'ast, F: Field + PrimeField> From<ast::ForStatement<'ast>> for types::State
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::MultipleAssignmentStatement<'ast>>
|
||||
for types::Statement<F>
|
||||
{
|
||||
fn from(statement: ast::MultipleAssignmentStatement<'ast>) -> Self {
|
||||
let assignees = statement
|
||||
.assignees
|
||||
.into_iter()
|
||||
.map(|i| types::Assignee::Variable(types::Variable::from(i.id)))
|
||||
.collect();
|
||||
|
||||
types::Statement::MultipleDefinition(
|
||||
assignees,
|
||||
types::Expression::FunctionCall(
|
||||
types::Variable::from(statement.function_name),
|
||||
statement
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|e| types::Expression::from(e))
|
||||
.collect(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
||||
types::Statement::Assign(
|
||||
types::Assignee::from(statement.assignee),
|
||||
types::Expression::from(statement.expression),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::DefinitionStatement<'ast>) -> Self {
|
||||
types::Statement::Definition(
|
||||
types::Type::from(statement.ty),
|
||||
types::Assignee::from(statement.variable),
|
||||
types::Expression::from(statement.expression),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Statement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::Statement<'ast>) -> Self {
|
||||
match statement {
|
||||
ast::Statement::Return(statement) => types::Statement::from(statement),
|
||||
ast::Statement::Iteration(statement) => types::Statement::from(statement),
|
||||
ast::Statement::MultipleAssignment(statement) => types::Statement::from(statement),
|
||||
ast::Statement::Assign(statement) => types::Statement::from(statement),
|
||||
ast::Statement::Definition(statement) => types::Statement::from(statement),
|
||||
ast::Statement::Assign(statement) => types::Statement::from(statement),
|
||||
ast::Statement::MultipleAssignment(statement) => types::Statement::from(statement),
|
||||
ast::Statement::Conditional(statement) => {
|
||||
types::Statement::Conditional(types::ConditionalStatement::from(statement))
|
||||
}
|
||||
ast::Statement::Iteration(statement) => types::Statement::from(statement),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
leo/cli.rs
13
leo/cli.rs
@ -18,10 +18,7 @@ pub trait CLI {
|
||||
fn new<'a, 'b>() -> App<'a, 'b> {
|
||||
let arguments = &Self::ARGUMENTS
|
||||
.iter()
|
||||
.map(|a| Arg::with_name(a.0)
|
||||
.help(a.1)
|
||||
.required(a.2)
|
||||
.index(a.3))
|
||||
.map(|a| Arg::with_name(a.0).help(a.1).required(a.2).index(a.3))
|
||||
.collect::<Vec<Arg<'static, 'static>>>();
|
||||
let flags = &Self::FLAGS
|
||||
.iter()
|
||||
@ -34,7 +31,9 @@ pub trait CLI {
|
||||
.conflicts_with_all(a.1)
|
||||
.possible_values(a.2)
|
||||
.requires_all(a.3),
|
||||
false => Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3),
|
||||
false => Arg::from_usage(a.0)
|
||||
.conflicts_with_all(a.1)
|
||||
.requires_all(a.3),
|
||||
})
|
||||
.collect::<Vec<Arg<'static, 'static>>>();
|
||||
let subcommands = Self::SUBCOMMANDS
|
||||
@ -49,7 +48,9 @@ pub trait CLI {
|
||||
.conflicts_with_all(a.1)
|
||||
.possible_values(a.2)
|
||||
.requires_all(a.3),
|
||||
false => Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3),
|
||||
false => Arg::from_usage(a.0)
|
||||
.conflicts_with_all(a.1)
|
||||
.requires_all(a.3),
|
||||
})
|
||||
.collect::<Vec<Arg<'static, 'static>>>(),
|
||||
)
|
||||
|
@ -21,4 +21,9 @@ pub type OptionType = (
|
||||
&'static [&'static str],
|
||||
);
|
||||
|
||||
pub type SubCommandType = (NameType, AboutType, &'static [OptionType], &'static [AppSettings]);
|
||||
pub type SubCommandType = (
|
||||
NameType,
|
||||
AboutType,
|
||||
&'static [OptionType],
|
||||
&'static [AppSettings],
|
||||
);
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::directories::{OutputsDirectory, source::SOURCE_DIRECTORY_NAME};
|
||||
use crate::errors::{CLIError, BuildError};
|
||||
use crate::directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory};
|
||||
use crate::errors::{BuildError, CLIError};
|
||||
use crate::files::{MainFile, MAIN_FILE_NAME};
|
||||
use crate::manifest::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use leo_compiler::compiler::Compiler;
|
||||
|
||||
use snarkos_curves::bls12_377::Fr;
|
||||
@ -43,7 +43,9 @@ impl CLI for BuildCommand {
|
||||
|
||||
// Verify the main file exists
|
||||
if !MainFile::exists_at(&package_path) {
|
||||
return Err(BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into());
|
||||
return Err(
|
||||
BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into(),
|
||||
);
|
||||
}
|
||||
|
||||
// Create the outputs directory
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::directories::{InputsDirectory, SourceDirectory};
|
||||
use crate::errors::{CLIError, InitError};
|
||||
use crate::files::MainFile;
|
||||
use crate::manifest::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::env::current_dir;
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::directories::{InputsDirectory, SourceDirectory};
|
||||
use crate::errors::{CLIError, NewError};
|
||||
use crate::files::MainFile;
|
||||
use crate::manifest::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::env::current_dir;
|
||||
@ -19,7 +19,12 @@ impl CLI for NewCommand {
|
||||
const ABOUT: AboutType = "Creates a new Leo package";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[
|
||||
// (name, description, required, index)
|
||||
("NAME", "Sets the resulting package name, defaults to the directory name", true, 1u64)
|
||||
(
|
||||
"NAME",
|
||||
"Sets the resulting package name, defaults to the directory name",
|
||||
true,
|
||||
1u64,
|
||||
),
|
||||
];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
@ -29,7 +34,7 @@ impl CLI for NewCommand {
|
||||
fn parse(arguments: &ArgMatches) -> Result<Self::Options, CLIError> {
|
||||
match arguments.value_of("NAME") {
|
||||
Some(name) => Ok(Some(name.to_string())),
|
||||
None => Ok(None)
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,9 +61,8 @@ impl CLI for NewCommand {
|
||||
}
|
||||
|
||||
// Create the package directory
|
||||
fs::create_dir_all(&path).map_err(|error| {
|
||||
NewError::CreatingRootDirectory(path.as_os_str().to_owned(), error)
|
||||
})?;
|
||||
fs::create_dir_all(&path)
|
||||
.map_err(|error| NewError::CreatingRootDirectory(path.as_os_str().to_owned(), error))?;
|
||||
|
||||
// Create the manifest file
|
||||
Manifest::new(&package_name).write_to(&path)?;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::commands::SetupCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
use snarkos_algorithms::snark::{create_random_proof, verify_proof};
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use leo_compiler::compiler::Compiler;
|
||||
|
||||
use snarkos_algorithms::snark::{generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey};
|
||||
use snarkos_algorithms::snark::{
|
||||
generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey,
|
||||
};
|
||||
use snarkos_curves::bls12_377::{Bls12_377, Fr};
|
||||
|
||||
use clap::ArgMatches;
|
||||
@ -15,7 +17,11 @@ pub struct SetupCommand;
|
||||
|
||||
impl CLI for SetupCommand {
|
||||
type Options = ();
|
||||
type Output = (Compiler<Fr>, Parameters<Bls12_377>, PreparedVerifyingKey<Bls12_377>);
|
||||
type Output = (
|
||||
Compiler<Fr>,
|
||||
Parameters<Bls12_377>,
|
||||
PreparedVerifyingKey<Bls12_377>,
|
||||
);
|
||||
|
||||
const NAME: NameType = "setup";
|
||||
const ABOUT: AboutType = "Run a program setup";
|
||||
@ -36,7 +42,8 @@ impl CLI for SetupCommand {
|
||||
let start = Instant::now();
|
||||
|
||||
let rng = &mut thread_rng();
|
||||
let parameters = generate_random_parameters::<Bls12_377, _, _>(circuit.clone(), rng).unwrap();
|
||||
let parameters =
|
||||
generate_random_parameters::<Bls12_377, _, _>(circuit.clone(), rng).unwrap();
|
||||
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶meters.vk);
|
||||
|
||||
let finish = start.elapsed();
|
||||
|
@ -32,9 +32,9 @@ impl InputsDirectory {
|
||||
let file_path = file_entry.path();
|
||||
|
||||
// Verify that the entry is structured as a valid file
|
||||
let file_type = file_entry
|
||||
.file_type()
|
||||
.map_err(|error| InputsDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?;
|
||||
let file_type = file_entry.file_type().map_err(|error| {
|
||||
InputsDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error)
|
||||
})?;
|
||||
if !file_type.is_file() {
|
||||
return Err(InputsDirectoryError::InvalidFileType(
|
||||
file_path.as_os_str().to_owned(),
|
||||
@ -43,9 +43,9 @@ impl InputsDirectory {
|
||||
}
|
||||
|
||||
// Verify that the file has the default file extension
|
||||
let file_extension = file_path
|
||||
.extension()
|
||||
.ok_or_else(|| InputsDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?;
|
||||
let file_extension = file_path.extension().ok_or_else(|| {
|
||||
InputsDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned())
|
||||
})?;
|
||||
if file_extension != INPUTS_FILE_EXTENSION {
|
||||
return Err(InputsDirectoryError::InvalidFileExtension(
|
||||
file_path.as_os_str().to_owned(),
|
||||
|
@ -32,9 +32,9 @@ impl SourceDirectory {
|
||||
let file_path = file_entry.path();
|
||||
|
||||
// Verify that the entry is structured as a valid file
|
||||
let file_type = file_entry
|
||||
.file_type()
|
||||
.map_err(|error| SourceDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?;
|
||||
let file_type = file_entry.file_type().map_err(|error| {
|
||||
SourceDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error)
|
||||
})?;
|
||||
if !file_type.is_file() {
|
||||
return Err(SourceDirectoryError::InvalidFileType(
|
||||
file_path.as_os_str().to_owned(),
|
||||
@ -43,9 +43,9 @@ impl SourceDirectory {
|
||||
}
|
||||
|
||||
// Verify that the file has the default file extension
|
||||
let file_extension = file_path
|
||||
.extension()
|
||||
.ok_or_else(|| SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?;
|
||||
let file_extension = file_path.extension().ok_or_else(|| {
|
||||
SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned())
|
||||
})?;
|
||||
if file_extension != SOURCE_FILE_EXTENSION {
|
||||
return Err(SourceDirectoryError::InvalidFileExtension(
|
||||
file_path.as_os_str().to_owned(),
|
||||
|
@ -2,7 +2,6 @@ use crate::errors::*;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum CLIError {
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
BuildError(BuildError),
|
||||
|
||||
@ -32,7 +31,6 @@ pub enum CLIError {
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
SourceDirectoryError(SourceDirectoryError),
|
||||
|
||||
}
|
||||
|
||||
impl From<BuildError> for CLIError {
|
||||
|
@ -4,13 +4,11 @@ use std::ffi::OsString;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum BuildError {
|
||||
|
||||
#[fail(display = "main file {:?} does not exist", _0)]
|
||||
MainFileDoesNotExist(OsString),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
ManifestError(ManifestError),
|
||||
|
||||
}
|
||||
|
||||
impl From<ManifestError> for BuildError {
|
||||
|
@ -5,7 +5,6 @@ use std::io;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum InitError {
|
||||
|
||||
#[fail(display = "root directory {:?} creating: {}", _0, _1)]
|
||||
CreatingRootDirectory(OsString, io::Error),
|
||||
|
||||
@ -20,7 +19,6 @@ pub enum InitError {
|
||||
|
||||
#[fail(display = "package name is missing - {:?}", _0)]
|
||||
ProjectNameInvalid(OsString),
|
||||
|
||||
}
|
||||
|
||||
impl From<ManifestError> for InitError {
|
||||
|
@ -5,7 +5,6 @@ use std::io;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum NewError {
|
||||
|
||||
#[fail(display = "root directory {:?} creating: {}", _0, _1)]
|
||||
CreatingRootDirectory(OsString, io::Error),
|
||||
|
||||
@ -20,7 +19,6 @@ pub enum NewError {
|
||||
|
||||
#[fail(display = "package name is missing - {:?}", _0)]
|
||||
ProjectNameInvalid(OsString),
|
||||
|
||||
}
|
||||
|
||||
impl From<ManifestError> for NewError {
|
||||
|
@ -4,13 +4,11 @@ use std::ffi::OsString;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum RunError {
|
||||
|
||||
#[fail(display = "main file {:?} does not exist", _0)]
|
||||
MainFileDoesNotExist(OsString),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
ManifestError(ManifestError),
|
||||
|
||||
}
|
||||
|
||||
impl From<ManifestError> for RunError {
|
||||
|
@ -2,7 +2,6 @@ use std::{ffi::OsString, fs::FileType, io};
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum InputsDirectoryError {
|
||||
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
@ -23,5 +22,4 @@ pub enum InputsDirectoryError {
|
||||
|
||||
#[fail(display = "reading: {}", _0)]
|
||||
Reading(io::Error),
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ use std::{ffi::OsString, fs::FileType, io};
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum OutputsDirectoryError {
|
||||
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
@ -26,5 +25,4 @@ pub enum OutputsDirectoryError {
|
||||
|
||||
#[fail(display = "removing: {}", _0)]
|
||||
Removing(io::Error),
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ use std::{ffi::OsString, fs::FileType, io};
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum SourceDirectoryError {
|
||||
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
@ -23,5 +22,4 @@ pub enum SourceDirectoryError {
|
||||
|
||||
#[fail(display = "reading: {}", _0)]
|
||||
Reading(io::Error),
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ use std::io;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum MainFileError {
|
||||
|
||||
#[fail(display = "{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
@ -11,7 +10,6 @@ pub enum MainFileError {
|
||||
|
||||
#[fail(display = "writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for MainFileError {
|
||||
|
@ -2,7 +2,6 @@ use std::io;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum ManifestError {
|
||||
|
||||
#[fail(display = "`{}` creating: {}", _0, _1)]
|
||||
Creating(&'static str, io::Error),
|
||||
|
||||
@ -20,5 +19,4 @@ pub enum ManifestError {
|
||||
|
||||
#[fail(display = "`{}` writing: {}", _0, _1)]
|
||||
Writing(&'static str, io::Error),
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,9 @@ pub struct MainFile {
|
||||
|
||||
impl MainFile {
|
||||
pub fn new(package_name: &str) -> Self {
|
||||
Self { package_name: package_name.to_string() }
|
||||
Self {
|
||||
package_name: package_name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exists_at(path: &PathBuf) -> bool {
|
||||
@ -55,4 +57,4 @@ function main() -> (u32) {{
|
||||
self.package_name
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use leo::{cli::*, commands::*, logger};
|
||||
use leo::errors::CLIError;
|
||||
use leo::{cli::*, commands::*, logger};
|
||||
|
||||
use clap::{App, AppSettings};
|
||||
|
||||
@ -34,11 +34,11 @@ fn main() -> Result<(), CLIError> {
|
||||
("build", Some(arguments)) => {
|
||||
BuildCommand::output(BuildCommand::parse(arguments)?)?;
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
("setup", Some(arguments)) => {
|
||||
SetupCommand::output(SetupCommand::parse(arguments)?)?;
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
("run", Some(arguments)) => RunCommand::output(RunCommand::parse(arguments)?),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -44,8 +44,8 @@ impl Manifest {
|
||||
path.push(PathBuf::from(FILE_NAME_DEFAULT));
|
||||
}
|
||||
|
||||
let mut file =
|
||||
File::create(&path).map_err(|error| ManifestError::Creating(FILE_NAME_DEFAULT, error))?;
|
||||
let mut file = File::create(&path)
|
||||
.map_err(|error| ManifestError::Creating(FILE_NAME_DEFAULT, error))?;
|
||||
file.write_all(self.template().as_bytes())
|
||||
.map_err(|error| ManifestError::Writing(FILE_NAME_DEFAULT, error))
|
||||
}
|
||||
@ -81,6 +81,7 @@ impl TryFrom<&PathBuf> for Manifest {
|
||||
file.read_to_string(&mut buffer)
|
||||
.map_err(|error| ManifestError::Reading(FILE_NAME_DEFAULT, error))?;
|
||||
|
||||
Ok(toml::from_str(&buffer).map_err(|error| ManifestError::Parsing(FILE_NAME_DEFAULT, error))?)
|
||||
Ok(toml::from_str(&buffer)
|
||||
.map_err(|error| ManifestError::Parsing(FILE_NAME_DEFAULT, error))?)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user