From 82271913a7b0425e9fb2dfe2ff8641bb4661bb46 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 19 May 2023 23:31:54 +0200 Subject: [PATCH] Combine CLI for pil and asm compilation. --- compiler/src/lib.rs | 64 +++++++++++++++++++++++------------ powdr_cli/src/main.rs | 79 ++++++++++++++++--------------------------- 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 6bc53b520..f8aeee218 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -18,6 +18,25 @@ pub fn no_callback() -> Option Option> { None } +/// Compiles a .pil or .asm file and runs witness generation. +/// If the file ends in .asm, converts it to .pil first. +pub fn compile_pil_or_asm( + file_name: &str, + inputs: Vec, + output_dir: &Path, + force_overwrite: bool, +) { + if file_name.ends_with(".asm") { + compile_asm(file_name, inputs, output_dir, force_overwrite) + } else { + compile_pil( + Path::new(file_name), + output_dir, + Some(inputs_to_query_callback(inputs)), + ); + } +} + /// Compiles a .pil file to its json form and also tries to generate /// constants and committed polynomials. /// @returns true if all committed/witness and constant/fixed polynomials @@ -90,31 +109,11 @@ pub fn compile_asm_string( } fs::write(pil_file_name.clone(), format!("{pil}")).unwrap(); - let query_callback = |query: &str| -> Option { - let items = query.split(',').map(|s| s.trim()).collect::>(); - match items[0] { - "\"input\"" => { - assert_eq!(items.len(), 2); - let index = items[1].parse::().unwrap(); - let value = inputs.get(index).cloned(); - if let Some(value) = value { - log::trace!("Input query: Index {index} -> {value}"); - } - value - } - "\"print_char\"" => { - assert_eq!(items.len(), 2); - print!("{}", items[1].parse::().unwrap() as char); - Some(0.into()) - } - _ => None, - } - }; compile_pil_ast( &pil, pil_file_name.file_name().unwrap(), output_dir, - Some(query_callback), + Some(inputs_to_query_callback(inputs)), ); } @@ -174,3 +173,26 @@ fn write_polys_file( } } } + +fn inputs_to_query_callback(inputs: Vec) -> impl Fn(&str) -> Option { + move |query: &str| -> Option { + let items = query.split(',').map(|s| s.trim()).collect::>(); + match items[0] { + "\"input\"" => { + assert_eq!(items.len(), 2); + let index = items[1].parse::().unwrap(); + let value = inputs.get(index).cloned(); + if let Some(value) = value { + log::trace!("Input query: Index {index} -> {value}"); + } + value + } + "\"print_char\"" => { + assert_eq!(items.len(), 2); + print!("{}", items[1].parse::().unwrap() as char); + Some(0.into()) + } + _ => None, + } + } +} diff --git a/powdr_cli/src/main.rs b/powdr_cli/src/main.rs index b70091ba5..68968708c 100644 --- a/powdr_cli/src/main.rs +++ b/powdr_cli/src/main.rs @@ -1,7 +1,6 @@ //! The powdr CLI tool use clap::{Parser, Subcommand}; -use compiler::no_callback; use env_logger::{Builder, Target}; use log::LevelFilter; use number::{FieldElement, GoldilocksField}; @@ -16,6 +15,29 @@ struct Cli { #[derive(Subcommand)] enum Commands { + /// Runs compilation and witness generation for .pil and .asm files. + /// First converts .asm files to .pil, if needed. + /// Then converts the .pil file to json and generates fixed and witness column data files. + Pil { + /// Input file + file: String, + + /// Output directory for the PIL file, json file and fixed and witness column data. + #[arg(short, long)] + #[arg(default_value_t = String::from("."))] + output_directory: String, + + /// Comma-separated list of free inputs (numbers). Assumes queries to have the form + /// ("input", ). + #[arg(short, long)] + #[arg(default_value_t = String::new())] + inputs: String, + + /// Force overwriting of PIL output file. + #[arg(short, long)] + #[arg(default_value_t = false)] + force: bool, + }, /// Compiles (no-std) rust code to riscv assembly, then to powdr assembly /// and finally to PIL and generates fixed and witness columns. /// Needs `rustup target add riscv32imc-unknown-none-elf`. @@ -61,42 +83,11 @@ enum Commands { force: bool, }, - /// Compiles assembly to PIL and generates fixed and witness columns. - Asm { - /// Input file - file: String, - - /// Comma-separated list of free inputs (numbers). - #[arg(short, long)] - #[arg(default_value_t = String::new())] - inputs: String, - - /// Output directory for PIL file, json file and fixed and witness column data. - #[arg(short, long)] - #[arg(default_value_t = String::from("."))] - output_directory: String, - - /// Force overwriting of PIL output file. - #[arg(short, long)] - #[arg(default_value_t = false)] - force: bool, - }, - /// Parses and prints the PIL file on stdout. Reformat { /// Input file file: String, }, - - /// Compiles the PIL file to json and generates fixed and witness columns. - Compile { - /// Input file - file: String, - /// Output directory for json file and fixed and witness column data. - #[arg(short, long)] - #[arg(default_value_t = String::from("."))] - output_directory: String, - }, } fn split_inputs(inputs: &str) -> Vec { @@ -146,19 +137,6 @@ fn main() { force, ); } - Commands::Asm { - file, - inputs, - output_directory, - force, - } => { - compiler::compile_asm::( - &file, - split_inputs(&inputs), - Path::new(&output_directory), - force, - ); - } Commands::Reformat { file } => { let contents = fs::read_to_string(&file).unwrap(); match parser::parse::(Some(&file), &contents) { @@ -166,14 +144,17 @@ fn main() { Err(err) => err.output_to_stderr(), } } - Commands::Compile { + Commands::Pil { file, output_directory, + inputs, + force, } => { - compiler::compile_pil::( - Path::new(&file), + compiler::compile_pil_or_asm::( + &file, + split_inputs(&inputs), Path::new(&output_directory), - no_callback(), + force, ); } }