add check command
This commit is contained in:
parent
3efcab6afc
commit
a28f2080d5
2 changed files with 101 additions and 11 deletions
|
@ -16,7 +16,7 @@ use std::io::{stdin, BufReader, BufWriter, Read, Write};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::string::String;
|
||||
use zokrates_abi::Encode;
|
||||
use zokrates_core::compile::{compile, CompilationArtifacts, CompileError};
|
||||
use zokrates_core::compile::{check, compile, CompilationArtifacts, CompileError};
|
||||
use zokrates_core::ir::{self, ProgEnum};
|
||||
use zokrates_core::proof_system::*;
|
||||
use zokrates_core::typed_absy::abi::Abi;
|
||||
|
@ -342,6 +342,46 @@ fn cli_compile<T: Field>(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn cli_check<T: Field>(sub_matches: &ArgMatches) -> Result<(), String> {
|
||||
println!("Checking {}\n", sub_matches.value_of("input").unwrap());
|
||||
let path = PathBuf::from(sub_matches.value_of("input").unwrap());
|
||||
|
||||
let file = File::open(path.clone())
|
||||
.map_err(|why| format!("Couldn't open input file {}: {}", path.display(), why))?;
|
||||
|
||||
let mut reader = BufReader::new(file);
|
||||
let mut source = String::new();
|
||||
reader.read_to_string(&mut source).unwrap();
|
||||
|
||||
let fmt_error = |e: &CompileError| {
|
||||
format!(
|
||||
"{}:{}",
|
||||
e.file()
|
||||
.canonicalize()
|
||||
.unwrap()
|
||||
.strip_prefix(std::env::current_dir().unwrap())
|
||||
.unwrap()
|
||||
.display(),
|
||||
e.value()
|
||||
)
|
||||
};
|
||||
|
||||
let resolver = FileSystemResolver::new();
|
||||
let _ = check::<T, _>(source, path, Some(&resolver)).map_err(|e| {
|
||||
format!(
|
||||
"Check failed:\n\n{}",
|
||||
e.0.iter()
|
||||
.map(|e| fmt_error(e))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\n")
|
||||
)
|
||||
})?;
|
||||
|
||||
println!("Program checked, no errors found.");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cli_verify<T: Field, P: ProofSystem<T>>(sub_matches: &ArgMatches) -> Result<(), String> {
|
||||
let vk_path = Path::new(sub_matches.value_of("verification-key-path").unwrap());
|
||||
let vk = std::fs::read_to_string(vk_path)
|
||||
|
@ -420,6 +460,25 @@ fn cli() -> Result<(), String> {
|
|||
.required(false)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("check")
|
||||
.about("Checks a program for errors")
|
||||
.arg(Arg::with_name("input")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.help("Path of the source code")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
).arg(Arg::with_name("curve")
|
||||
.short("c")
|
||||
.long("curve")
|
||||
.help("Curve to be used in the compilation")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
.possible_values(CURVES)
|
||||
.default_value(&default_curve)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("setup")
|
||||
.about("Performs a trusted setup for a given constraint system")
|
||||
.arg(Arg::with_name("input")
|
||||
|
@ -667,6 +726,15 @@ fn cli() -> Result<(), String> {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
("check", Some(sub_matches)) => {
|
||||
let curve = sub_matches.value_of("curve").unwrap();
|
||||
|
||||
match curve {
|
||||
constants::BN128 => cli_check::<Bn128Field>(sub_matches)?,
|
||||
constants::BLS12_381 => cli_check::<Bls12Field>(sub_matches)?,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
("compute-witness", Some(sub_matches)) => {
|
||||
println!("Computing witness...");
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::fmt;
|
|||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use typed_absy::abi::Abi;
|
||||
use typed_absy::TypedProgram;
|
||||
use typed_arena::Arena;
|
||||
use zokrates_common::Resolver;
|
||||
use zokrates_field::Field;
|
||||
|
@ -149,19 +150,10 @@ pub fn compile<T: Field, E: Into<imports::Error>>(
|
|||
) -> Result<CompilationArtifacts<T>, CompileErrors> {
|
||||
let arena = Arena::new();
|
||||
|
||||
let source = arena.alloc(source);
|
||||
let compiled = compile_program(source, location.clone(), resolver, &arena)?;
|
||||
|
||||
// check semantics
|
||||
let typed_ast = Checker::check(compiled).map_err(|errors| {
|
||||
CompileErrors(errors.into_iter().map(|e| CompileError::from(e)).collect())
|
||||
})?;
|
||||
let typed_ast = check_with_arena(source, location, resolver, &arena)?;
|
||||
|
||||
let abi = typed_ast.abi();
|
||||
|
||||
// analyse (unroll and constant propagation)
|
||||
let typed_ast = typed_ast.analyse();
|
||||
|
||||
// flatten input program
|
||||
let program_flattened = Flattener::flatten(typed_ast);
|
||||
|
||||
|
@ -183,6 +175,36 @@ pub fn compile<T: Field, E: Into<imports::Error>>(
|
|||
})
|
||||
}
|
||||
|
||||
pub fn check<'ast, T: Field, E: Into<imports::Error>>(
|
||||
source: String,
|
||||
location: FilePath,
|
||||
resolver: Option<&dyn Resolver<E>>,
|
||||
) -> Result<(), CompileErrors> {
|
||||
let arena = Arena::new();
|
||||
|
||||
check_with_arena::<T, _>(source, location, resolver, &arena).map(|_| ())
|
||||
}
|
||||
|
||||
fn check_with_arena<'ast, T: Field, E: Into<imports::Error>>(
|
||||
source: String,
|
||||
location: FilePath,
|
||||
resolver: Option<&dyn Resolver<E>>,
|
||||
arena: &'ast Arena<String>,
|
||||
) -> Result<TypedProgram<'ast, T>, CompileErrors> {
|
||||
let source = arena.alloc(source);
|
||||
let compiled = compile_program(source, location.clone(), resolver, &arena)?;
|
||||
|
||||
// check semantics
|
||||
let typed_ast = Checker::check(compiled).map_err(|errors| {
|
||||
CompileErrors(errors.into_iter().map(|e| CompileError::from(e)).collect())
|
||||
})?;
|
||||
|
||||
// analyse (unroll and constant propagation)
|
||||
let typed_ast = typed_ast.analyse();
|
||||
|
||||
Ok(typed_ast)
|
||||
}
|
||||
|
||||
pub fn compile_program<'ast, T: Field, E: Into<imports::Error>>(
|
||||
source: &'ast str,
|
||||
location: FilePath,
|
||||
|
|
Loading…
Reference in a new issue