Merge branch 'master' of https://github.com/Kyroy/VerifiableStatementCompiler
Conflicts: lib/wraplibsnark.cpp
This commit is contained in:
commit
9a466c9cb7
9 changed files with 179 additions and 94 deletions
7
examples/for.code
Normal file
7
examples/for.code
Normal file
|
@ -0,0 +1,7 @@
|
|||
def forex(a):
|
||||
x = 7
|
||||
for i in 0..10 do
|
||||
// x = x + a
|
||||
x = x + a
|
||||
endfor
|
||||
return x
|
|
@ -34,12 +34,14 @@ using namespace libsnark;
|
|||
// conversion byte[32] <-> libsnark bigint.
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> libsnarkBigintFromBytes(const uint8_t* _x)
|
||||
{
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> x;
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> x;
|
||||
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
for (unsigned j = 0; j < 8; j++)
|
||||
x.data[3 - i] |= uint64_t(_x[i * 8 + j]) << (8 * (7-j));
|
||||
return x;
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
for (unsigned j = 0; j < 8; j++) {
|
||||
x.data[3 - i] |= uint64_t(_x[i * 8 + j]) << (8 * (7-j));
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,57 +87,55 @@ std::string outputPointG2Affine(libsnark::alt_bn128_G2 _p)
|
|||
//takes input and puts it into constraint system
|
||||
r1cs_ppzksnark_constraint_system<alt_bn128_pp> createConstraintSystem(const uint8_t* A, const uint8_t* B, const uint8_t* C, const uint8_t* witness, int constraints, int variables)
|
||||
{
|
||||
r1cs_constraint_system<Fr<alt_bn128_pp> > cs;
|
||||
cs.primary_input_size = variables - 1;
|
||||
cs.auxiliary_input_size = 0;
|
||||
r1cs_constraint_system<Fr<alt_bn128_pp> > cs;
|
||||
cs.primary_input_size = variables - 1;
|
||||
cs.auxiliary_input_size = 0;
|
||||
|
||||
cout << "num variables: " << variables <<endl;
|
||||
cout << "num constraints: " << constraints <<endl;
|
||||
cout << "num variables: " << variables <<endl;
|
||||
cout << "num constraints: " << constraints <<endl;
|
||||
|
||||
for (int row = 0; row < constraints; row++) {
|
||||
for (int row = 0; row < constraints; row++) {
|
||||
linear_combination<Fr<alt_bn128_pp> > lin_comb_A, lin_comb_B, lin_comb_C;
|
||||
|
||||
linear_combination<Fr<alt_bn128_pp> > lin_comb_A, lin_comb_B, lin_comb_C;
|
||||
for (int idx=0; idx<variables; idx++) {
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(A+row*variables*32 + idx*32);
|
||||
// cout << "C entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "A(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_A.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
for (int idx=0; idx<variables; idx++) {
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(B+row*variables*32 + idx*32);
|
||||
// cout << "B entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "B(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_B.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
for (int idx=0; idx<variables; idx++) {
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(C+row*variables*32 + idx*32);
|
||||
// cout << "C entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "C(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_C.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
cs.add_constraint(r1cs_constraint<Fr<alt_bn128_pp> >(lin_comb_A, lin_comb_B, lin_comb_C));
|
||||
}
|
||||
for (int idx=0; idx<variables; idx++) {
|
||||
cout << "witness entry " << idx << ": " << libsnarkBigintFromBytes(witness + idx*32) << endl;
|
||||
}
|
||||
|
||||
for (int idx=0; idx<variables; idx++) {
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(A+row*variables*32 + idx*32);
|
||||
// cout << "C entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "A(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_A.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
for (int idx=0; idx<variables; idx++) {
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(B+row*variables*32 + idx*32);
|
||||
// cout << "B entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "B(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_B.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
for (int idx=0; idx<variables; idx++) {
|
||||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(C+row*variables*32 + idx*32);
|
||||
// cout << "C entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "C(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_C.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
cs.add_constraint(r1cs_constraint<Fr<alt_bn128_pp> >(lin_comb_A, lin_comb_B, lin_comb_C));
|
||||
}
|
||||
for (int idx=0; idx<variables; idx++) {
|
||||
cout << "witness entry " << idx << ": " << libsnarkBigintFromBytes(witness + idx*32) << endl;
|
||||
}
|
||||
|
||||
return cs;
|
||||
return cs;
|
||||
}
|
||||
|
||||
// keypair generateKeypair(constraints)
|
||||
r1cs_ppzksnark_keypair<alt_bn128_pp> generateKeypair(const r1cs_ppzksnark_constraint_system<alt_bn128_pp> &cs){
|
||||
// from r1cs_ppzksnark.hpp
|
||||
return r1cs_ppzksnark_generator<alt_bn128_pp>(cs);
|
||||
// from r1cs_ppzksnark.hpp
|
||||
return r1cs_ppzksnark_generator<alt_bn128_pp>(cs);
|
||||
}
|
||||
|
||||
|
||||
// compliant with solidty, from c++ client libsnark integration
|
||||
void exportVerificationKey(r1cs_ppzksnark_keypair<alt_bn128_pp> keypair){
|
||||
unsigned icLength = keypair.vk.encoded_IC_query.rest.indices.size() + 1;
|
||||
|
@ -162,43 +162,44 @@ void exportVerificationKey(r1cs_ppzksnark_keypair<alt_bn128_pp> keypair){
|
|||
|
||||
bool _run_libsnark(const uint8_t* A, const uint8_t* B, const uint8_t* C, const uint8_t* witness, int constraints, int variables)
|
||||
{
|
||||
// Setup:
|
||||
// create constraint system
|
||||
r1cs_constraint_system<Fr<alt_bn128_pp> > cs;
|
||||
cs = createConstraintSystem(A,B,C,witness,constraints,variables);
|
||||
// Setup:
|
||||
// create constraint system
|
||||
r1cs_constraint_system<Fr<alt_bn128_pp> > cs;
|
||||
cs = createConstraintSystem(A,B,C,witness,constraints,variables);
|
||||
|
||||
// assign variables
|
||||
r1cs_variable_assignment<Fr<alt_bn128_pp> > full_variable_assignment;
|
||||
for (int i = 1; i < variables; i++) {
|
||||
full_variable_assignment.push_back(witness[i]);
|
||||
}
|
||||
// assign variables
|
||||
r1cs_variable_assignment<Fr<alt_bn128_pp> > full_variable_assignment;
|
||||
for (int i = 1; i < variables; i++) {
|
||||
full_variable_assignment.push_back(witness[i]);
|
||||
}
|
||||
|
||||
//split up variables into primary and auxiliary inputs
|
||||
// TODO: Check whether this is consistent with inputs from VerifiableStatementCompiler
|
||||
r1cs_primary_input<Fr<alt_bn128_pp> > primary_input(full_variable_assignment.begin(), full_variable_assignment.begin() + variables - 1);
|
||||
r1cs_primary_input<Fr<alt_bn128_pp> > auxiliary_input(full_variable_assignment.begin() + variables - 1, full_variable_assignment.end());
|
||||
//split up variables into primary and auxiliary inputs
|
||||
// TODO: Check whether this is consistent with inputs from VerifiableStatementCompiler
|
||||
r1cs_primary_input<Fr<alt_bn128_pp> > primary_input(full_variable_assignment.begin(), full_variable_assignment.begin() + variables - 1);
|
||||
r1cs_primary_input<Fr<alt_bn128_pp> > auxiliary_input(full_variable_assignment.begin() + variables - 1, full_variable_assignment.end());
|
||||
|
||||
// sanity checks
|
||||
assert(cs.num_variables() == full_variable_assignment.size());
|
||||
assert(cs.num_variables() >= variables - 1);
|
||||
assert(cs.num_inputs() == variables - 1);
|
||||
assert(cs.num_constraints() == constraints);
|
||||
assert(cs.is_satisfied(primary_input, auxiliary_input));
|
||||
// sanity checks
|
||||
assert(cs.num_variables() == full_variable_assignment.size());
|
||||
assert(cs.num_variables() >= variables - 1);
|
||||
assert(cs.num_inputs() == variables - 1);
|
||||
assert(cs.num_constraints() == constraints);
|
||||
assert(cs.is_satisfied(primary_input, auxiliary_input));
|
||||
|
||||
//initialize curve parameters
|
||||
alt_bn128_pp::init_public_params();
|
||||
//initialize curve parameters
|
||||
alt_bn128_pp::init_public_params();
|
||||
|
||||
// create keypair
|
||||
r1cs_ppzksnark_keypair<alt_bn128_pp> keypair = r1cs_ppzksnark_generator<alt_bn128_pp>(cs);
|
||||
// create keypair
|
||||
r1cs_ppzksnark_keypair<alt_bn128_pp> keypair = r1cs_ppzksnark_generator<alt_bn128_pp>(cs);
|
||||
|
||||
// Print VerificationKey in Solidity compatible format
|
||||
exportVerificationKey(keypair);
|
||||
// Print VerificationKey in Solidity compatible format
|
||||
exportVerificationKey(keypair);
|
||||
|
||||
// Proof Generation
|
||||
r1cs_ppzksnark_proof<alt_bn128_pp> proof = r1cs_ppzksnark_prover<alt_bn128_pp>(keypair.pk, primary_input, auxiliary_input);
|
||||
|
||||
// Verification
|
||||
bool result = r1cs_ppzksnark_verifier_strong_IC<alt_bn128_pp>(keypair.vk, primary_input, proof);
|
||||
// Proof Generation
|
||||
r1cs_ppzksnark_proof<alt_bn128_pp> proof = r1cs_ppzksnark_prover<alt_bn128_pp>(keypair.pk, primary_input, auxiliary_input);
|
||||
|
||||
return result;
|
||||
// Verification
|
||||
bool result = r1cs_ppzksnark_verifier_strong_IC<alt_bn128_pp>(keypair.vk, primary_input, proof);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ extern "C" {
|
|||
|
||||
// entrypoint, wraps the whole process, probably should be removed later
|
||||
bool _run_libsnark(const uint8_t* A,
|
||||
const uint8_t* B,
|
||||
const uint8_t* C,
|
||||
const uint8_t* witness,
|
||||
int constraints,
|
||||
int variables);
|
||||
const uint8_t* B,
|
||||
const uint8_t* C,
|
||||
const uint8_t* witness,
|
||||
int constraints,
|
||||
int variables);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
16
src/absy.rs
16
src/absy.rs
|
@ -38,6 +38,7 @@ impl<T: Field> Prog<T> {
|
|||
let s = expr.solve(&mut witness);
|
||||
witness.insert(id.to_string(), s);
|
||||
},
|
||||
Statement::For(..) => unimplemented!(),
|
||||
Statement::Condition(ref lhs, ref rhs) => assert_eq!(lhs.solve(&mut witness), rhs.solve(&mut witness)),
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +62,7 @@ pub enum Statement<T: Field> {
|
|||
Return(Expression<T>),
|
||||
Definition(String, Expression<T>),
|
||||
Condition(Expression<T>, Expression<T>),
|
||||
For(String, T, T, Vec<Statement<T>>),
|
||||
Compiler(String, Expression<T>),
|
||||
}
|
||||
|
||||
|
@ -70,6 +72,13 @@ impl<T: Field> fmt::Display for Statement<T> {
|
|||
Statement::Return(ref expr) => write!(f, "return {}", expr),
|
||||
Statement::Definition(ref lhs, ref rhs) => write!(f, "{} = {}", lhs, rhs),
|
||||
Statement::Condition(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
|
||||
Statement::For(ref var, ref start, ref stop, ref list) => {
|
||||
try!(write!(f, "for {} in {}..{} do\n", var, start, stop));
|
||||
for l in list {
|
||||
try!(write!(f, "\t\t{}\n", l));
|
||||
}
|
||||
write!(f, "\tendfor")
|
||||
},
|
||||
Statement::Compiler(ref lhs, ref rhs) => write!(f, "# {} = {}", lhs, rhs),
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +90,13 @@ impl<T: Field> fmt::Debug for Statement<T> {
|
|||
Statement::Return(ref expr) => write!(f, "Return({:?})", expr),
|
||||
Statement::Definition(ref lhs, ref rhs) => write!(f, "Definition({:?}, {:?})", lhs, rhs),
|
||||
Statement::Condition(ref lhs, ref rhs) => write!(f, "Condition({:?}, {:?})", lhs, rhs),
|
||||
Statement::For(ref var, ref start, ref stop, ref list) => {
|
||||
try!(write!(f, "for {:?} in {:?}..{:?} do\n", var, start, stop));
|
||||
for l in list {
|
||||
try!(write!(f, "\t\t{:?}\n", l));
|
||||
}
|
||||
write!(f, "\tendfor")
|
||||
},
|
||||
Statement::Compiler(ref lhs, ref rhs) => write!(f, "Compiler({:?}, {:?})", lhs, rhs),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,6 @@ pub trait Field : From<i32> + From<u32> + From<usize> + for<'a> From<&'a str>
|
|||
+ Div<Self, Output=Self> + for<'a> Div<&'a Self, Output=Self>
|
||||
+ Pow<usize, Output=Self> + Pow<Self, Output=Self> + for<'a> Pow<&'a Self, Output=Self>
|
||||
{
|
||||
/// Returns a byte slice of this `Field`'s contents in decimal `String` representation.
|
||||
fn into_dec_bytes(&self) -> Vec<u8>;
|
||||
/// Returns this `Field`'s contents as little-endian byte vector
|
||||
fn into_byte_vector(&self) -> Vec<u8>;
|
||||
/// Returns the multiplicative inverse, i.e.: self * self.inverse_mul() = Self::one()
|
||||
|
@ -48,10 +46,6 @@ pub struct FieldPrime {
|
|||
}
|
||||
|
||||
impl Field for FieldPrime {
|
||||
fn into_dec_bytes(&self) -> Vec<u8> {
|
||||
self.value.to_str_radix(10).to_string().into_bytes()
|
||||
}
|
||||
|
||||
fn into_byte_vector(&self) -> Vec<u8> {
|
||||
////for debugging
|
||||
//println!("uint dec: {}\n",self.value.to_biguint().unwrap().to_str_radix(10));
|
||||
|
|
|
@ -355,6 +355,7 @@ impl Flattener {
|
|||
};
|
||||
statements_flattened.push(Statement::Condition(lhs, rhs));
|
||||
},
|
||||
Statement::For(..) => unimplemented!(),
|
||||
s @ Statement::Compiler(..) => statements_flattened.push(s),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,6 @@ use self::libc::c_int;
|
|||
use self::libc::uint8_t;
|
||||
use field::Field;
|
||||
|
||||
#[cfg(test)]
|
||||
use field::FieldPrime;
|
||||
use num::bigint::{BigUint};
|
||||
|
||||
#[link(name = "snark")]
|
||||
#[link(name = "supercop")]
|
||||
#[link(name = "gmp")]
|
||||
|
@ -74,6 +70,8 @@ fn vec_as_u8_32_array(vec: &Vec<u8>) -> [u8;32]{
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use field::FieldPrime;
|
||||
use num::bigint::{BigUint};
|
||||
|
||||
#[cfg(test)]
|
||||
mod libsnark_integration {
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
//
|
||||
|
||||
use std::fmt;
|
||||
use std::io::BufReader;
|
||||
use std::io::{BufReader, Lines};
|
||||
use std::io::prelude::*;
|
||||
use std::fs::File;
|
||||
use field::Field;
|
||||
|
@ -106,6 +106,7 @@ enum Token<T: Field> {
|
|||
Open, Close, Comma, Colon, Hash,
|
||||
Eq, Return,
|
||||
If, Then, Else, Fi,
|
||||
For, In, Dotdot, Do, Endfor,
|
||||
Lt, Le, Eqeq, Ge, Gt,
|
||||
Add, Sub, Mult, Div, Pow,
|
||||
Ide(String),
|
||||
|
@ -128,6 +129,11 @@ impl<T: Field> fmt::Display for Token<T> {
|
|||
Token::Then => write!(f, "then"),
|
||||
Token::Else => write!(f, "else"),
|
||||
Token::Fi => write!(f, "fi"),
|
||||
Token::For => write!(f, "for"),
|
||||
Token::In => write!(f, "in"),
|
||||
Token::Dotdot => write!(f, ".."),
|
||||
Token::Do => write!(f, "do"),
|
||||
Token::Endfor => write!(f, "endfor"),
|
||||
Token::Lt => write!(f, "<"),
|
||||
Token::Le => write!(f, "<="),
|
||||
Token::Eqeq => write!(f, "=="),
|
||||
|
@ -228,6 +234,11 @@ fn next_token<T: Field>(input: &String, pos: &Position) -> (Token<T>, String, Po
|
|||
Some(_) if input[offset..].starts_with("then ") => (Token::Then, input[offset + 5..].to_string(), Position { line: pos.line, col: pos.col + offset + 5 }),
|
||||
Some(_) if input[offset..].starts_with("else ") => (Token::Else, input[offset + 5..].to_string(), Position { line: pos.line, col: pos.col + offset + 5 }),
|
||||
Some(_) if input[offset..].starts_with("fi ") || input[offset..].to_string() == "fi" => (Token::Fi, input[offset + 2..].to_string(), Position { line: pos.line, col: pos.col + offset + 2 }),
|
||||
Some(_) if input[offset..].starts_with("for ") => (Token::For, input[offset + 4..].to_string(), Position { line: pos.line, col: pos.col + offset + 4 }),
|
||||
Some(_) if input[offset..].starts_with("in ") => (Token::In, input[offset + 3..].to_string(), Position { line: pos.line, col: pos.col + offset + 3 }),
|
||||
Some(_) if input[offset..].starts_with("..") => (Token::Dotdot, input[offset + 2..].to_string(), Position { line: pos.line, col: pos.col + offset + 2 }),
|
||||
Some(_) if input[offset..].starts_with("do ") || input[offset..].to_string() == "do" => (Token::Do, input[offset + 2..].to_string(), Position { line: pos.line, col: pos.col + offset + 2 }),
|
||||
Some(_) if input[offset..].starts_with("endfor ") || input[offset..].to_string() == "endfor" => (Token::For, input[offset + 6..].to_string(), Position { line: pos.line, col: pos.col + offset + 6 }),
|
||||
Some(x) => match x {
|
||||
'0'...'9' => parse_num(&input[offset..].to_string(), &Position { line: pos.line, col: pos.col + offset }),
|
||||
'a'...'z' | 'A'...'Z' => parse_ide(&input[offset..].to_string(), &Position { line: pos.line, col: pos.col + offset }),
|
||||
|
@ -435,7 +446,7 @@ fn parse_statement1<T: Field>(ide: String, input: String, pos: Position) -> Resu
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_statement<T: Field>(input: &String, pos: &Position) -> Result<(Statement<T>, String, Position), Error<T>> {
|
||||
fn parse_statement<T: Field>(lines: &mut Lines<BufReader<File>>, input: &String, pos: &Position) -> Result<(Statement<T>, String, Position), Error<T>> {
|
||||
match next_token::<T>(input, pos) {
|
||||
(Token::Ide(x1), s1, p1) => parse_statement1(x1, s1, p1),
|
||||
(Token::If, ..) |
|
||||
|
@ -456,6 +467,62 @@ fn parse_statement<T: Field>(input: &String, pos: &Position) -> Result<(Statemen
|
|||
},
|
||||
Err(err) => Err(err),
|
||||
},
|
||||
(Token::For, s1, p1) => match parse_ide(&s1, &p1) {
|
||||
(Token::Ide(x2), s2, p2) => match next_token(&s2, &p2) {
|
||||
(Token::In, s3, p3) => match next_token(&s3, &p3) {
|
||||
(Token::Num(x4), s4, p4) => match next_token(&s4, &p4) {
|
||||
(Token::Dotdot, s5, p5) => match next_token(&s5, &p5) {
|
||||
(Token::Num(x6), s6, p6) => match next_token(&s6, &p6) {
|
||||
(Token::Do, s7, p7) => {
|
||||
match next_token(&s7, &p7) {
|
||||
(Token::Unknown(ref t8), ref s8, _) if t8 == "" => {
|
||||
assert_eq!(s8, "");
|
||||
},
|
||||
(t8, _, p8) => return Err(Error { expected: vec![Token::Unknown("".to_string())], got: t8 , pos: p8 }),
|
||||
}
|
||||
let mut current_line = p7.line;
|
||||
let mut statements = Vec::new();
|
||||
loop {
|
||||
current_line += 1;
|
||||
match lines.next() {
|
||||
Some(Ok(ref x)) if x.trim().starts_with("//") || x.trim() == "" => {}, // skip
|
||||
Some(Ok(ref x)) if x.trim().starts_with("endfor") => {
|
||||
let offset = skip_whitespaces(x);
|
||||
let s8 = x[offset + 6..].to_string();
|
||||
let p8 = Position{ line: current_line, col: offset + 7 };
|
||||
match next_token(&s8, &p8) {
|
||||
(Token::Unknown(ref t9), ref s9, _) if t9 == "" => {
|
||||
assert_eq!(s9, "");
|
||||
return Ok((Statement::For(x2, x4, x6, statements), s8, p8))
|
||||
},
|
||||
(t9, _, p9) => return Err(Error { expected: vec![Token::Unknown("1432567iuhgvfc".to_string())], got: t9 , pos: p9 }),
|
||||
}
|
||||
},
|
||||
Some(Ok(ref x)) if !x.trim().starts_with("return") => match parse_statement(lines, x, &Position { line: current_line, col: 1 }) {
|
||||
Ok((statement, ..)) => statements.push(statement),
|
||||
Err(err) => return Err(err),
|
||||
},
|
||||
Some(Err(err)) => panic!("Error while reading Definitions: {}", err),
|
||||
Some(Ok(ref x)) => {
|
||||
let (t, ..) = next_token(x, &Position{ line: current_line, col: 1 });
|
||||
return Err(Error { expected: vec![Token::ErrIde, Token::ErrNum, Token::If, Token::Open, Token::Hash, Token::For, Token::Endfor], got: t , pos: Position{ line: current_line, col: 1 } })
|
||||
},
|
||||
None => return Err(Error { expected: vec![Token::ErrIde, Token::ErrNum, Token::If, Token::Open, Token::Hash, Token::For], got: Token::Unknown("".to_string()) , pos: Position{ line: current_line, col: 1 } }),
|
||||
}
|
||||
};
|
||||
},
|
||||
(t7, _, p7) => Err(Error { expected: vec![Token::Do], got: t7 , pos: p7 }),
|
||||
},
|
||||
(t6, _, p6) => Err(Error { expected: vec![Token::ErrNum], got: t6 , pos: p6 }),
|
||||
},
|
||||
(t5, _, p5) => Err(Error { expected: vec![Token::Dotdot], got: t5 , pos: p5 }),
|
||||
},
|
||||
(t4, _, p4) => Err(Error { expected: vec![Token::ErrNum], got: t4 , pos: p4 }),
|
||||
},
|
||||
(t3, _, p3) => Err(Error { expected: vec![Token::In], got: t3 , pos: p3 }),
|
||||
},
|
||||
(t2, _, p2) => Err(Error { expected: vec![Token::ErrIde], got: t2 , pos: p2 }),
|
||||
},
|
||||
(Token::Hash, s1, p1) => match parse_ide(&s1, &p1) {
|
||||
(Token::Ide(x2), s2, p2) => match next_token(&s2, &p2) {
|
||||
(Token::Eq, s3, p3) => match parse_expr(&s3, &p3) {
|
||||
|
@ -547,7 +614,7 @@ pub fn parse_program<T: Field>(file: File) -> Result<Prog<T>, Error<T>> {
|
|||
loop {
|
||||
match lines.next() {
|
||||
Some(Ok(ref x)) if x.trim().starts_with("//") || x.trim() == "" => {}, // skip
|
||||
Some(Ok(ref x)) => match parse_statement(x, &Position { line: current_line, col: 1 }) {
|
||||
Some(Ok(ref x)) => match parse_statement(&mut lines, x, &Position { line: current_line, col: 1 }) {
|
||||
Ok((statement @ Statement::Return(_), ..)) => {
|
||||
if !got_return {
|
||||
got_return = true;
|
||||
|
|
|
@ -258,6 +258,7 @@ pub fn r1cs_program<T: Field>(prog: &Prog<T>) -> (Vec<String>, Vec<Vec<(usize, T
|
|||
Statement::Return(ref expr) => r1cs_expression(Identifier("~out".to_string()), expr.clone(), &mut variables, &mut a_row, &mut b_row, &mut c_row),
|
||||
Statement::Definition(ref id, ref expr) => r1cs_expression(Identifier(id.to_string()), expr.clone(), &mut variables, &mut a_row, &mut b_row, &mut c_row),
|
||||
Statement::Condition(ref expr1, ref expr2) => r1cs_expression(expr1.clone(), expr2.clone(), &mut variables, &mut a_row, &mut b_row, &mut c_row),
|
||||
Statement::For(..) => unimplemented!(),
|
||||
Statement::Compiler(..) => continue,
|
||||
}
|
||||
a.push(a_row);
|
||||
|
|
Loading…
Reference in a new issue