program a==1 compiles and generates constraints

This commit is contained in:
collin 2020-03-27 19:00:19 -07:00
parent c798635e29
commit 4a83a0e879
14 changed files with 769 additions and 29 deletions

View File

@ -1 +1 @@
return a + b
return a == 1

17
src/aleo_program/mod.rs Normal file
View File

@ -0,0 +1,17 @@
//! Module containing structs and types that make up a zokrates_program.
//!
//! @file zokrates_program.rs
//! @author Collin Chin <collin@aleo.org>
//! @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::*;

15
src/aleo_program/setup.rs Normal file
View File

@ -0,0 +1,15 @@
// use crate::{
// aleo_program::program::{
// Program,
// },
// };
// impl Program {
// pub fn setup(&self) {
// self.statements
// .iter()
// .for_each(|statement| {
//
// })
// }
// }

162
src/aleo_program/types.rs Normal file
View File

@ -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 <collin@aleo.org>
//! @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<Variable>);
//
// 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<FieldExpression>, Box<FieldExpression>),
Sub(Box<FieldExpression>, Box<FieldExpression>),
Mul(Box<FieldExpression>, Box<FieldExpression>),
Div(Box<FieldExpression>, Box<FieldExpression>),
Pow(Box<FieldExpression>, Box<FieldExpression>),
IfElse(
Box<BooleanExpression>,
Box<FieldExpression>,
Box<FieldExpression>,
),
}
/// Expression that evaluates to a boolean value
#[derive(Debug, Clone)]
pub enum BooleanExpression {
Variable(Variable),
Value(bool),
// Boolean operators
Not(Box<BooleanExpression>),
Or(Box<BooleanExpression>, Box<BooleanExpression>),
And(Box<BooleanExpression>, Box<BooleanExpression>),
BoolEq(Box<BooleanExpression>, Box<BooleanExpression>),
// Field operators
FieldEq(Box<FieldExpression>, Box<FieldExpression>),
Geq(Box<FieldExpression>, Box<FieldExpression>),
Gt(Box<FieldExpression>, Box<FieldExpression>),
Leq(Box<FieldExpression>, Box<FieldExpression>),
Lt(Box<FieldExpression>, Box<FieldExpression>),
}
/// 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<Expression>),
}
/// A simple program with statement expressions, program arguments and program returns.
#[derive(Debug, Clone)]
pub struct Program {
pub id: String,
pub statements: Vec<Statement>,
pub arguments: Vec<Variable>,
pub returns: Vec<Variable>,
}
#[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);
}
}

View File

@ -0,0 +1,111 @@
//! Format display functions for zokrates_program types.
//!
//! @file zokrates_program.rs
//! @author Collin Chin <collin@aleo.org>
//! @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)
// }
// }
// }
// }

View File

@ -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 <collin@aleo.org>
//! @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<ast::Boolean<'ast>> for types::ExpressionNode<'ast> {
// fn from(boolean: ast::Boolean<'ast>) -> Self {
// types::Expression::Boolean(
// boolean
// .value
// .parse::<bool>()
// .expect("unable to parse boolean"),
// )
// .span(boolean.span)
// }
// }
//
// impl<'ast> From<ast::Field<'ast>> for types::ExpressionNode<'ast> {
// fn from(field: ast::Field<'ast>) -> Self {
// types::Expression::Field(field.span.as_str()).span(field.span)
// }
// }
//
// impl<'ast> From<ast::Value<'ast>> 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<ast::Variable<'ast>> for types::VariableNode<'ast> {
// fn from(variable: ast::Variable<'ast>) -> Self {
// types::Variable {
// id: variable.span.as_str(),
// }
// .span(variable.span)
// }
// }
//
// impl<'ast> From<ast::Variable<'ast>> 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<ast::NotExpression<'ast>> 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<ast::Field<'ast>> for types::FieldExpression {
fn from(field: ast::Field<'ast>) -> Self {
let number = field.value.parse::<u32>().expect("unable to unwrap field");
FieldExpression::Number(number)
}
}
impl<'ast> From<ast::Boolean<'ast>> for types::BooleanExpression {
fn from(boolean: ast::Boolean<'ast>) -> Self {
let boolean = boolean
.value
.parse::<bool>()
.expect("unable to unwrap boolean");
BooleanExpression::Value(boolean)
}
}
impl<'ast> From<ast::Value<'ast>> 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<ast::Variable<'ast>> for types::FieldExpression {
fn from(variable: ast::Variable<'ast>) -> Self {
FieldExpression::Variable(types::Variable(variable.value))
}
}
impl<'ast> From<ast::Variable<'ast>> for types::BooleanExpression {
fn from(variable: ast::Variable<'ast>) -> Self {
BooleanExpression::Variable(types::Variable(variable.value))
}
}
impl<'ast> From<ast::Variable<'ast>> 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<ast::BinaryExpression<'ast>> 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<ast::Expression<'ast>> 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<ast::AssignStatement<'ast>> 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<ast::ReturnStatement<'ast>> 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<ast::Statement<'ast>> 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<ast::File<'ast>> 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<ast::Variable<'ast>> for types::LinearCombination {
// fn from(variable: ast::Variable<'ast>) -> Self {
// LinearCombination(vec![Variable { id: 1, value: variable.value }])
// }
// }
//
// impl<'ast> From<ast::Boolean<'ast>> for types::LinearCombination {
// fn from(boolean: ast::Boolean<'ast>) -> Self {
// LinearCombination(vec![Variable { id: -1, value: boolean.value }])
// }
// }
//
// impl<'ast> From<ast::Field<'ast>> for types::LinearCombination {
// fn from(field: ast::Field<'ast>) -> Self {
// LinearCombination(vec![Variable { id: 0, value: field.value }])
// }
// }
// impl<'ast> From<ast::Value<'ast>> 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<ast::Expression<'ast>> 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<Self> {
// 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<Self> {
// match expression.operation {
// ast::BinaryOperator::Eq => ,
// _ => unimplemented!()
// }
// }
//
// fn unwrap_eq(expression: ast::BinaryExpression<'ast>) -> Vec<Self> {
//
// }
// }
//
// 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<types::Expression> = vec![];
//
// statement
// .expressions
// .into_iter()
// .map(|expression| {
// expressions.extend_from_slice(&types::Expression::unwrap_expression(expression))
// });
//
// types::Statement::Return(expressions)
// }
// }
//
// impl<'ast> From<ast::Statement<'ast>> for types::Statement {
// fn from(statement: ast::Statement<'ast>) -> Self {
// match statement {
// ast::Statement::Assign(statement) => unimplemented!()
// }
// }
// }

View File

@ -1,3 +1,9 @@
//! Abstract syntax tree (ast) representation from language.pest.
//!
//! @file zokrates_program.rs
//! @author Howard Wu <howard@aleo.org>
//! @date 2020
use from_pest::{ConversionError, FromPest, Void};
use pest::{
error::Error,

View File

@ -11,4 +11,6 @@ extern crate lazy_static;
pub mod ast;
pub mod program;
pub mod aleo_program;
pub mod zokrates_program;

View File

@ -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::<Fr>::new();
let argument = std::env::args()
.nth(1)
.unwrap_or("1".into())
.parse::<u32>()
.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::<u32>().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::<u32>().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() {

View File

@ -1,3 +1,9 @@
//! Module containing structs and types that make up a zokrates_program.
//!
//! @file zokrates_program.rs
//! @author Collin Chin <collin@aleo.org>
//! @date 2020
pub mod program;
pub use self::program::*;

View File

@ -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 <collin@aleo.org>
//! @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<T: fmt::Display> {
start: Position,

View File

@ -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 <collin@aleo.org>
//! @date 2020
use crate::zokrates_program::Node;
// Program Nodes - Wrappers for different types in a program.
pub type ExpressionNode<'ast> = Node<Expression<'ast>>;
pub type ExpressionListNode<'ast> = Node<ExpressionList<'ast>>;
pub type StatementNode<'ast> = Node<Statement<'ast>>;

View File

@ -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 <collin@aleo.org>
//! @date 2020
use crate::zokrates_program::{Expression, ExpressionList, Statement, Variable};
use std::fmt;

View File

@ -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 <collin@aleo.org>
//! @date 2020
use crate::{
ast,
program::{program, types, NodeValue},
zokrates_program::{program, types, NodeValue},
};
impl<'ast> From<ast::Boolean<'ast>> for types::ExpressionNode<'ast> {
@ -169,10 +175,5 @@ impl<'ast> From<ast::File<'ast>> 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);
// }
}
}