diff --git a/simple.program b/simple.program index ee7041432a..54358ba0ec 100644 --- a/simple.program +++ b/simple.program @@ -1 +1 @@ -return a + b \ No newline at end of file +return a == 1 \ No newline at end of file diff --git a/src/aleo_program/mod.rs b/src/aleo_program/mod.rs new file mode 100644 index 0000000000..b498569a76 --- /dev/null +++ b/src/aleo_program/mod.rs @@ -0,0 +1,17 @@ +//! Module containing structs and types that make up a zokrates_program. +//! +//! @file zokrates_program.rs +//! @author Collin Chin +//! @date 2020 + +pub mod types; +pub use self::types::*; + +pub mod setup; +pub use self::setup::*; + +pub mod types_display; +pub use self::types_display::*; + +pub mod types_from; +pub use self::types_from::*; diff --git a/src/aleo_program/setup.rs b/src/aleo_program/setup.rs new file mode 100644 index 0000000000..99899effe1 --- /dev/null +++ b/src/aleo_program/setup.rs @@ -0,0 +1,15 @@ +// use crate::{ +// aleo_program::program::{ +// Program, +// }, +// }; + +// impl Program { +// pub fn setup(&self) { +// self.statements +// .iter() +// .for_each(|statement| { +// +// }) +// } +// } diff --git a/src/aleo_program/types.rs b/src/aleo_program/types.rs new file mode 100644 index 0000000000..0037788a05 --- /dev/null +++ b/src/aleo_program/types.rs @@ -0,0 +1,162 @@ +//! A zokrates_program consists of nodes that keep track of position and wrap zokrates_program types. +//! +//! @file types.rs +//! @author Collin Chin +//! @date 2020 + +// id == 0 for field values +// id < 0 for boolean values +/// A variable in a constraint system. +#[derive(Debug, Clone)] +pub struct Variable(pub String); +// +// /// Linear combination of variables in a program. (a + b + c) +// #[derive(Debug, Clone)] +// pub struct LinearCombination (pub Vec); +// +// impl LinearCombination { +// pub fn one() -> Self { +// LinearCombination(vec![Variable{ id: 0, value: "1".into() }]) +// } +// +// pub fn value(&self) -> String { +// self.0[0].value.clone() +// } +// } +// +// /// Quadratic combination of variables in a program (a * b) +// #[derive(Debug, Clone)] +// pub struct QuadraticCombination (pub LinearCombination, pub LinearCombination); + +/// Expression that evaluates to a field value +#[derive(Debug, Clone)] +pub enum FieldExpression { + Variable(Variable), + Number(u32), + Add(Box, Box), + Sub(Box, Box), + Mul(Box, Box), + Div(Box, Box), + Pow(Box, Box), + IfElse( + Box, + Box, + Box, + ), +} + +/// Expression that evaluates to a boolean value +#[derive(Debug, Clone)] +pub enum BooleanExpression { + Variable(Variable), + Value(bool), + // Boolean operators + Not(Box), + Or(Box, Box), + And(Box, Box), + BoolEq(Box, Box), + // Field operators + FieldEq(Box, Box), + Geq(Box, Box), + Gt(Box, Box), + Leq(Box, Box), + Lt(Box, Box), +} + +/// Expression that evaluates to a value +#[derive(Debug, Clone)] +pub enum Expression { + Boolean(BooleanExpression), + FieldElement(FieldExpression), + Variable(Variable), +} + +/// Program statement that defines some action (or expression) to be carried out. +#[derive(Clone)] +pub enum Statement { + /// A statement that could be directly translated to a R1CS constraint a * b = c to be enforced + // Constraint(QuadraticCombination, LinearCombination), + Declaration(Variable), + Definition(Variable, Expression), + Return(Vec), +} + +/// A simple program with statement expressions, program arguments and program returns. +#[derive(Debug, Clone)] +pub struct Program { + pub id: String, + pub statements: Vec, + pub arguments: Vec, + pub returns: Vec, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_variable() { + let variable = Variable("1".into()); + + println!("{:#?}", variable); + } + + // #[test] + // fn test_linear_combination() { + // let variable_0 = Variable { id: 0, value: "1".into() }; + // let variable_1 = Variable { id: 0, value: "1".into() }; + // let linear_combination = LinearCombination(vec![variable_0, variable_1]); + // + // println!("{:#?}", linear_combination); + // } + + // #[test] + // fn test_statement_linear() { + // let linear_combination = LinearCombination(vec![Variable { id: 0 }, Variable { id: 1 }]); + // let statement_linear = Statement::Linear(linear_combination); + // + // println!("{:#?}", statement_linear); + // } + // + // #[test] + // fn test_statement_quadratic() { + // let linear_combination_0 = LinearCombination(vec![Variable { id: 0 }]); + // let linear_combination_1 = LinearCombination(vec![Variable { id: 1 }]); + // let statement_quadratic = Statement::Quadratic(linear_combination_0, linear_combination_1); + // + // println!("{:#?}", statement_quadratic); + // } + // + // #[test] + // fn test_program() { + // let variable_0 = Variable{ id: 0}; + // let linear_combination = LinearCombination(vec![variable_0.clone()]); + // let statement_linear = Statement::Linear(linear_combination.clone()); + // let statement_quadratic = Statement::Quadratic(linear_combination.clone(), linear_combination); + // let program = Program{ + // id: "main".into(), + // statements: vec![statement_linear, statement_quadratic], + // arguments: vec![variable_0.clone()], + // returns: vec![variable_0.clone()] + // }; + // + // println!("{:#?}", program); + // } + #[test] + fn test_basic_prog() { + // return 1 == 1 + let prog = Program { + id: "main".into(), + statements: vec![Statement::Return(vec![Expression::Boolean( + BooleanExpression::FieldEq( + Box::new(FieldExpression::Number(1)), + Box::new(FieldExpression::Number(1)), + ), + )])], + arguments: vec![], + returns: vec![], + }; + + println!("{:#?}", prog); + } +} diff --git a/src/aleo_program/types_display.rs b/src/aleo_program/types_display.rs new file mode 100644 index 0000000000..588d095b3d --- /dev/null +++ b/src/aleo_program/types_display.rs @@ -0,0 +1,111 @@ +//! Format display functions for zokrates_program types. +//! +//! @file zokrates_program.rs +//! @author Collin Chin +//! @date 2020 + +use crate::aleo_program::{BooleanExpression, Expression, FieldExpression, Statement, Variable}; + +use std::fmt; + +impl fmt::Display for Variable { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl<'ast> fmt::Display for FieldExpression { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + FieldExpression::Variable(ref variable) => write!(f, "{}", variable), + FieldExpression::Number(ref number) => write!(f, "{}", number), + FieldExpression::Add(ref lhs, ref rhs) => write!(f, "{} + {}", lhs, rhs), + FieldExpression::Sub(ref lhs, ref rhs) => write!(f, "{} - {}", lhs, rhs), + FieldExpression::Mul(ref lhs, ref rhs) => write!(f, "{} * {}", lhs, rhs), + FieldExpression::Div(ref lhs, ref rhs) => write!(f, "{} / {}", lhs, rhs), + FieldExpression::Pow(ref lhs, ref rhs) => write!(f, "{} ** {}", lhs, rhs), + FieldExpression::IfElse(ref _a, ref _b, ref _c) => unimplemented!(), + } + } +} + +impl<'ast> fmt::Display for BooleanExpression { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + BooleanExpression::Variable(ref variable) => write!(f, "{}", variable), + BooleanExpression::Value(ref value) => write!(f, "{}", value), + BooleanExpression::Not(ref expression) => write!(f, "!{}", expression), + BooleanExpression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs), + BooleanExpression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs), + BooleanExpression::BoolEq(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs), + BooleanExpression::FieldEq(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs), + // BooleanExpression::Neq(ref lhs, ref rhs) => write!(f, "{} != {}", lhs, rhs), + BooleanExpression::Geq(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs), + BooleanExpression::Gt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs), + BooleanExpression::Leq(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs), + BooleanExpression::Lt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs), + } + } +} + +impl<'ast> fmt::Display for Expression { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Expression::Boolean(ref boolean_expression) => write!(f, "{}", boolean_expression), + Expression::FieldElement(ref field_expression) => write!(f, "{}", field_expression), + Expression::Variable(ref variable) => write!(f, "{}", variable), + } + } +} +impl fmt::Display for Statement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Statement::Return(ref statements) => { + statements.iter().for_each(|statement| { + write!(f, "return {}", statement).unwrap(); + }); + write!(f, "") + } + _ => unimplemented!(), // Statement::Constraint(ref quadratic, ref linear) => { + // let a = (quadratic.0).0[0].value.clone(); + // let b = (quadratic.1).0[0].value.clone(); + // let c = linear.0[0].value.clone(); + // + // write!(f, "constraint {} * {} = {}", a, b, c) + // } + } + } +} +impl fmt::Debug for Statement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Statement::Return(ref statements) => { + statements.iter().for_each(|statement| { + write!(f, "return {}", statement).unwrap(); + }); + write!(f, "") + } + _ => unimplemented!(), // Statement::Constraint(ref quadratic, ref linear) => { + // let a = (quadratic.0).0[0].value.clone(); + // let b = (quadratic.1).0[0].value.clone(); + // let c = linear.0[0].value.clone(); + // + // write!(f, "constraint {} * {} = {}", a, b, c) + // } + } + } +} + +// impl fmt::Debug for Statement { +// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +// match *self { +// Statement::Constraint(ref quadratic, ref linear) => { +// let a = (quadratic.0).0[0].value.clone(); +// let b = (quadratic.1).0[0].value.clone(); +// let c = linear.0[0].value.clone(); +// +// write!(f, "constraint {} * {} = {}", a, b, c) +// } +// } +// } +// } diff --git a/src/aleo_program/types_from.rs b/src/aleo_program/types_from.rs new file mode 100644 index 0000000000..83dd16f9ca --- /dev/null +++ b/src/aleo_program/types_from.rs @@ -0,0 +1,325 @@ +//! Logic to convert from an abstract syntax tree (ast) representation to a typed zokrates_program. +//! We implement "unwrap" functions instead of the From trait to handle nested statements (flattening). +//! +//! @file zokrates_program.rs +//! @author Collin Chin +//! @date 2020 + +use crate::aleo_program::{BooleanExpression, Expression, FieldExpression}; +use crate::{aleo_program::types, ast}; + +// use crate::{ +// ast, +// aleo_program::{program, types, NodeValue}, +// }; +// +// impl<'ast> From> for types::ExpressionNode<'ast> { +// fn from(boolean: ast::Boolean<'ast>) -> Self { +// types::Expression::Boolean( +// boolean +// .value +// .parse::() +// .expect("unable to parse boolean"), +// ) +// .span(boolean.span) +// } +// } +// +// impl<'ast> From> for types::ExpressionNode<'ast> { +// fn from(field: ast::Field<'ast>) -> Self { +// types::Expression::Field(field.span.as_str()).span(field.span) +// } +// } +// +// impl<'ast> From> for types::ExpressionNode<'ast> { +// fn from(value: ast::Value<'ast>) -> Self { +// match value { +// ast::Value::Boolean(boolean) => types::ExpressionNode::from(boolean), +// ast::Value::Field(field) => types::ExpressionNode::from(field), +// } +// } +// } +// +// impl<'ast> From> for types::VariableNode<'ast> { +// fn from(variable: ast::Variable<'ast>) -> Self { +// types::Variable { +// id: variable.span.as_str(), +// } +// .span(variable.span) +// } +// } +// +// impl<'ast> From> for types::ExpressionNode<'ast> { +// fn from(variable: ast::Variable<'ast>) -> Self { +// types::Expression::Variable(types::VariableNode::from(variable.clone())).span(variable.span) +// } +// } +// +// impl<'ast> From> for types::ExpressionNode<'ast> { +// fn from(expression: ast::NotExpression<'ast>) -> Self { +// types::Expression::Not(Box::new(types::ExpressionNode::from( +// *expression.expression, +// ))) +// .span(expression.span) +// } +// } + +impl<'ast> From> for types::FieldExpression { + fn from(field: ast::Field<'ast>) -> Self { + let number = field.value.parse::().expect("unable to unwrap field"); + FieldExpression::Number(number) + } +} + +impl<'ast> From> for types::BooleanExpression { + fn from(boolean: ast::Boolean<'ast>) -> Self { + let boolean = boolean + .value + .parse::() + .expect("unable to unwrap boolean"); + BooleanExpression::Value(boolean) + } +} + +impl<'ast> From> for types::Expression { + fn from(value: ast::Value<'ast>) -> Self { + match value { + ast::Value::Boolean(value) => Expression::Boolean(BooleanExpression::from(value)), + ast::Value::Field(value) => Expression::FieldElement(FieldExpression::from(value)), + } + } +} + +impl<'ast> From> for types::FieldExpression { + fn from(variable: ast::Variable<'ast>) -> Self { + FieldExpression::Variable(types::Variable(variable.value)) + } +} + +impl<'ast> From> for types::BooleanExpression { + fn from(variable: ast::Variable<'ast>) -> Self { + BooleanExpression::Variable(types::Variable(variable.value)) + } +} + +impl<'ast> From> for types::Expression { + fn from(variable: ast::Variable<'ast>) -> Self { + types::Expression::Variable(types::Variable(variable.value)) + } +} + +impl<'ast> types::BooleanExpression { + /// Find out which types we are comparing and output the corresponding expression. + fn from_eq(expression: ast::BinaryExpression<'ast>) -> Self { + let left = types::Expression::from(*expression.left); + let right = types::Expression::from(*expression.right); + + // When matching a variable, look at the opposite side to see what we are comparing to and assume that variable type + match (left, right) { + // Boolean equality + (Expression::Boolean(lhs), Expression::Boolean(rhs)) => { + BooleanExpression::BoolEq(Box::new(lhs), Box::new(rhs)) + } + (Expression::Boolean(lhs), Expression::Variable(rhs)) => { + BooleanExpression::BoolEq(Box::new(lhs), Box::new(BooleanExpression::Variable(rhs))) + } + (Expression::Variable(lhs), Expression::Boolean(rhs)) => { + BooleanExpression::BoolEq(Box::new(BooleanExpression::Variable(lhs)), Box::new(rhs)) + } + // Field equality + (Expression::FieldElement(lhs), Expression::FieldElement(rhs)) => { + BooleanExpression::FieldEq(Box::new(lhs), Box::new(rhs)) + } + (Expression::FieldElement(lhs), Expression::Variable(rhs)) => { + BooleanExpression::FieldEq(Box::new(lhs), Box::new(FieldExpression::Variable(rhs))) + } + (Expression::Variable(lhs), Expression::FieldElement(rhs)) => { + BooleanExpression::FieldEq(Box::new(FieldExpression::Variable(lhs)), Box::new(rhs)) + } + + (_, _) => unimplemented!(), + } + } +} + +impl<'ast> From> for types::Expression { + fn from(expression: ast::BinaryExpression<'ast>) -> Self { + match expression.operation { + // Boolean operations + ast::BinaryOperator::Or => unimplemented!(), + ast::BinaryOperator::And => unimplemented!(), + ast::BinaryOperator::Eq => { + types::Expression::Boolean(BooleanExpression::from_eq(expression)) + } + ast::BinaryOperator::Neq => unimplemented!(), + ast::BinaryOperator::Geq => unimplemented!(), + ast::BinaryOperator::Gt => unimplemented!(), + ast::BinaryOperator::Leq => unimplemented!(), + ast::BinaryOperator::Lt => unimplemented!(), + // Field operations + ast::BinaryOperator::Add => unimplemented!(), + ast::BinaryOperator::Sub => unimplemented!(), + ast::BinaryOperator::Mul => unimplemented!(), + ast::BinaryOperator::Div => unimplemented!(), + ast::BinaryOperator::Pow => unimplemented!(), + } + } +} + +impl<'ast> From> for types::Expression { + fn from(expression: ast::Expression<'ast>) -> Self { + match expression { + ast::Expression::Value(value) => types::Expression::from(value), + ast::Expression::Variable(variable) => types::Expression::from(variable), + ast::Expression::Not(_expression) => unimplemented!(), + ast::Expression::Binary(expression) => types::Expression::from(expression), + } + } +} + +// impl<'ast> From> for types::StatementNode<'ast> { +// fn from(statement: ast::AssignStatement<'ast>) -> Self { +// types::Statement::Definition( +// types::VariableNode::from(statement.variable), +// types::ExpressionNode::from(statement.expression), +// ) +// .span(statement.span) +// } +// } +// +impl<'ast> From> for types::Statement { + fn from(statement: ast::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: ast::Statement<'ast>) -> Self { + match statement { + ast::Statement::Assign(_statement) => unimplemented!(), + ast::Statement::Return(statement) => types::Statement::from(statement), + } + } +} + +impl<'ast> From> for types::Program { + fn from(file: ast::File<'ast>) -> Self { + let statements = file + .statement + .into_iter() + .map(|statement| types::Statement::from(statement)) + .collect(); + + types::Program { + id: "main".into(), + statements, + arguments: vec![], + returns: vec![], + } + } +} + +// #[cfg(test)] +// mod tests { +// use super::*; +// +// #[test] +// fn test_file() { +// +// } +// } + +// impl<'ast> From> for types::LinearCombination { +// fn from(variable: ast::Variable<'ast>) -> Self { +// LinearCombination(vec![Variable { id: 1, value: variable.value }]) +// } +// } +// +// impl<'ast> From> for types::LinearCombination { +// fn from(boolean: ast::Boolean<'ast>) -> Self { +// LinearCombination(vec![Variable { id: -1, value: boolean.value }]) +// } +// } +// +// impl<'ast> From> for types::LinearCombination { +// fn from(field: ast::Field<'ast>) -> Self { +// LinearCombination(vec![Variable { id: 0, value: field.value }]) +// } +// } +// impl<'ast> From> for types::LinearCombination { +// fn from(value: ast::Value<'ast>) -> Self { +// match value { +// ast::Value::Boolean(boolean) => types::LinearCombination::from(boolean), +// ast::Value::Field(field) => types::LinearCombination::from(field), +// } +// } +// } +// +// impl<'ast> From> for types::LinearCombination { +// fn from(expression: ast::Expression<'ast>) -> Self { +// match expression { +// ast::Expression::Value(value) => types::LinearCombination::from(value), +// ast::Expression::Variable(variable) => types::LinearCombination::from(variable), +// ast::Expression::Not(_) => unimplemented!(), +// ast::Expression::Binary(_) => unimplemented!(), +// } +// } +// } +// +// impl<'ast> types::Expression { +// fn unwrap_expression(expression: ast::Expression<'ast>) -> Vec { +// match expression { +// ast::Expression::Value(value) => unimplemented!(), +// ast::Expression::Variable(variable) => unimplemented!(), +// ast::Expression::Not(expression) => unimplemented!(), +// ast::Expression::Binary(expression) => Self::unwrap_binary(expression), +// } +// } +// +// fn unwrap_binary(expression: ast::BinaryExpression<'ast>) -> Vec { +// match expression.operation { +// ast::BinaryOperator::Eq => , +// _ => unimplemented!() +// } +// } +// +// fn unwrap_eq(expression: ast::BinaryExpression<'ast>) -> Vec { +// +// } +// } +// +// impl<'ast> types::Statement { +// fn unwrap_statement(statement: ast::Statement<'ast>) -> Self { +// match statement { +// ast::Statement::Assign(statement) => unimplemented!(), +// ast::Statement::Return(statement) => Self::unwrap_return(statement), +// } +// } +// +// fn unwrap_return(statement: ast::ReturnStatement<'ast>) -> Self { +// let mut expressions: Vec = vec![]; +// +// statement +// .expressions +// .into_iter() +// .map(|expression| { +// expressions.extend_from_slice(&types::Expression::unwrap_expression(expression)) +// }); +// +// types::Statement::Return(expressions) +// } +// } +// +// impl<'ast> From> for types::Statement { +// fn from(statement: ast::Statement<'ast>) -> Self { +// match statement { +// ast::Statement::Assign(statement) => unimplemented!() +// } +// } +// } diff --git a/src/ast.rs b/src/ast.rs index 3ed1236d5b..6a6801b703 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,3 +1,9 @@ +//! Abstract syntax tree (ast) representation from language.pest. +//! +//! @file zokrates_program.rs +//! @author Howard Wu +//! @date 2020 + use from_pest::{ConversionError, FromPest, Void}; use pest::{ error::Error, diff --git a/src/lib.rs b/src/lib.rs index a56330eed4..a7ab88dfa2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,4 +11,6 @@ extern crate lazy_static; pub mod ast; -pub mod program; +pub mod aleo_program; + +pub mod zokrates_program; diff --git a/src/main.rs b/src/main.rs index ed84f3945b..ed065c628a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,17 +2,16 @@ use language::*; use from_pest::FromPest; use std::fs; +// use std::env; fn main() { // use snarkos_gadgets::curves::edwards_bls12::FqGadget; - // use snarkos_models::gadgets::{ - // r1cs::{ConstraintSystem, TestConstraintSystem, Fr}, - // utilities::{ - // alloc::{AllocGadget}, - // boolean::Boolean, - // uint32::UInt32, - // } - // }; + use snarkos_models::gadgets::{ + r1cs::{ConstraintSystem, Fr, TestConstraintSystem}, + utilities::{ + alloc::AllocGadget, boolean::Boolean, eq::ConditionalEqGadget, uint32::UInt32, + }, + }; // Read in file as string let unparsed_file = fs::read_to_string("simple.program").expect("cannot read file"); @@ -22,10 +21,88 @@ fn main() { // Build the abstract syntax tree let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); + // println!("{:#?}", syntax_tree); - let program = program::Program::from(syntax_tree); + let program = aleo_program::Program::from(syntax_tree); + println!(" compiled: {:#?}", program); - println!("{:?}", program); + let mut cs = TestConstraintSystem::::new(); + let argument = std::env::args() + .nth(1) + .unwrap_or("1".into()) + .parse::() + .unwrap(); + + println!(" argument passed to command line a = {:?}", argument); + + program + .statements + .into_iter() + .for_each(|statement| match statement { + aleo_program::Statement::Return(statements) => { + statements + .into_iter() + .for_each(|expression| match expression { + aleo_program::Expression::Boolean(operation) => match operation { + aleo_program::BooleanExpression::FieldEq(lhs, rhs) => match *lhs { + aleo_program::FieldExpression::Variable(variable) => { + let left_variable = + UInt32::alloc(cs.ns(|| variable.0), Some(argument)) + .unwrap(); + match *rhs { + aleo_program::FieldExpression::Number(number) => { + let right_number = UInt32::constant(number); + + let bool = Boolean::alloc( + cs.ns(|| format!("boolean")), + || Ok(true), + ) + .unwrap(); + left_variable + .conditional_enforce_equal( + cs.ns(|| format!("enforce equal")), + &right_number, + &bool, + ) + .unwrap(); + } + _ => unimplemented!(), + } + } + _ => unimplemented!(), + }, + _ => unimplemented!(), + }, + _ => unimplemented!(), + }); + } + _ => unimplemented!(), + }); + + // program + // .statements + // .into_iter() + // .for_each(|statement| { + // match statement { + // aleo_program::Statement::Constraint(quadratic, linear) => { + // let a_var = (quadratic.0).0[0].clone(); + // assert!(a_var.id > 0); + // + // let c_var = linear.0[0].clone(); + // let c_value = c_var.value.parse::().unwrap(); + // + // let a_bit = UInt32::alloc(cs.ns(|| "a_bit"), Some(argument)).unwrap(); + // let c_bit = UInt32::constant(c_value); + // let bool = Boolean::alloc(cs.ns(|| format!("boolean")), || Ok(true)).unwrap(); + // + // a_bit.conditional_enforce_equal(cs.ns(|| format!("enforce equal")), &c_bit, &bool).unwrap(); + // } + // } + // }); + + // let program = zokrates_program::Program::from(syntax_tree); + + // println!("{:#?}", program); // // Use this code when proving // let left_u32 = left_string.parse::().unwrap(); @@ -41,16 +118,19 @@ fn main() { // // left_constraint.conditional_enforce_equal(cs.ns(|| format!("enforce left == right")), &right_constraint, &bool).unwrap(); - // // Constraint testing + // Constraint testing // let bool = Boolean::alloc(cs.ns(|| format!("boolean")), || Ok(true)).unwrap(); // let a_bit = UInt32::alloc(cs.ns(|| "a_bit"), Some(4u32)).unwrap(); - // let b_bit = UInt32::constant(5u32); + // let b_bit = UInt32::constant(4u32); // // a_bit.conditional_enforce_equal(cs.ns(|| format!("enforce equal")), &b_bit, &bool).unwrap(); - // println!("satisfied: {:?}", cs.is_satisfied()); + println!("\n satisfied: {:?}", cs.is_satisfied()); - // println!("\n\n number of constraints for input: {}", cs.num_constraints()); + println!( + "\n number of constraints for input: {}", + cs.num_constraints() + ); // for token in file.into_inner() { // match token.as_rule() { diff --git a/src/program/mod.rs b/src/zokrates_program/mod.rs similarity index 53% rename from src/program/mod.rs rename to src/zokrates_program/mod.rs index 976d3ad63b..c184ed827e 100644 --- a/src/program/mod.rs +++ b/src/zokrates_program/mod.rs @@ -1,3 +1,9 @@ +//! Module containing structs and types that make up a zokrates_program. +//! +//! @file zokrates_program.rs +//! @author Collin Chin +//! @date 2020 + pub mod program; pub use self::program::*; diff --git a/src/program/program.rs b/src/zokrates_program/program.rs similarity index 85% rename from src/program/program.rs rename to src/zokrates_program/program.rs index 085b9a07b9..a49f013bae 100644 --- a/src/program/program.rs +++ b/src/zokrates_program/program.rs @@ -1,11 +1,15 @@ -use crate::program::{Expression, ExpressionList, Statement, StatementNode, Variable}; +//! A zokrates_program consists of nodes that keep track of position and wrap zokrates_program types. +//! +//! @file zokrates_program.rs +//! @author Collin Chin +//! @date 2020 + +use crate::zokrates_program::{Expression, ExpressionList, Statement, StatementNode, Variable}; use pest::Span; use std::fmt; use std::fmt::Formatter; -// AST -> Program - /// Position in input file #[derive(Clone, Copy)] pub struct Position { @@ -25,7 +29,7 @@ impl fmt::Debug for Position { } } -/// Building blocks for a program +/// Building blocks for a zokrates_program #[derive(Debug, Clone)] pub struct Node { start: Position, diff --git a/src/program/types.rs b/src/zokrates_program/types.rs similarity index 90% rename from src/program/types.rs rename to src/zokrates_program/types.rs index a24893d6ba..5e3047604b 100644 --- a/src/program/types.rs +++ b/src/zokrates_program/types.rs @@ -1,6 +1,11 @@ -use crate::program::Node; +//! A zokrates_program type constrains data that an expression might take. +//! +//! @file zokrates_program.rs +//! @author Collin Chin +//! @date 2020 + +use crate::zokrates_program::Node; -// Program Nodes - Wrappers for different types in a program. pub type ExpressionNode<'ast> = Node>; pub type ExpressionListNode<'ast> = Node>; pub type StatementNode<'ast> = Node>; diff --git a/src/program/types_display.rs b/src/zokrates_program/types_display.rs similarity index 91% rename from src/program/types_display.rs rename to src/zokrates_program/types_display.rs index a2c0e7bbc8..35c6891352 100644 --- a/src/program/types_display.rs +++ b/src/zokrates_program/types_display.rs @@ -1,4 +1,10 @@ -use crate::program::{Expression, ExpressionList, Statement, Variable}; +//! Format display functions for zokrates_program types. +//! +//! @file zokrates_program.rs +//! @author Collin Chin +//! @date 2020 + +use crate::zokrates_program::{Expression, ExpressionList, Statement, Variable}; use std::fmt; diff --git a/src/program/types_from.rs b/src/zokrates_program/types_from.rs similarity index 96% rename from src/program/types_from.rs rename to src/zokrates_program/types_from.rs index 7a556b64e9..f9ad4dddec 100644 --- a/src/program/types_from.rs +++ b/src/zokrates_program/types_from.rs @@ -1,6 +1,12 @@ +//! Logic to convert from an abstract syntax tree (ast) representation to a typed zokrates_program. +//! +//! @file zokrates_program.rs +//! @author Collin Chin +//! @date 2020 + use crate::{ ast, - program::{program, types, NodeValue}, + zokrates_program::{program, types, NodeValue}, }; impl<'ast> From> for types::ExpressionNode<'ast> { @@ -169,10 +175,5 @@ impl<'ast> From> for program::Program<'ast> { .map(|statement| types::StatementNode::from(statement.clone())) .collect(), } - // for statement in file.statement { - // // println!("statement {:?}", statement); - // let node = program::StatementNode::from(statement); - // println!("node {:?}", node); - // } } }