Commandline access to asm compiler.

This commit is contained in:
chriseth
2023-03-02 12:15:54 +01:00
parent 2dd049d196
commit 37b7a3bbf0
4 changed files with 138 additions and 34 deletions

View File

@@ -5,12 +5,13 @@ edition = "2021"
build = "build.rs"
[dependencies]
codespan-reporting = "0.11.1"
json = "0.12.4"
lalrpop-util = {version = "0.19.8", features = ["lexer"]}
clap = { version = "^4.1", features = ["derive"] }
codespan-reporting = "^0.11"
itertools = "^0.10"
json = "^0.12"
lalrpop-util = {version = "^0.19", features = ["lexer"]}
mktemp = "0.5.0"
num-bigint = "0.4.3"
regex = "1"
num-bigint = "^0.4"
[build-dependencies]
lalrpop = "0.19.8"
lalrpop = "^0.19"

View File

@@ -1,27 +1,84 @@
use std::{env, fs, path::Path};
use clap::{Parser, Subcommand};
use powdr::compiler::no_callback;
use powdr::number::AbstractNumberType;
use std::{fs, path::Path};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// 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)]
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 main() {
if env::args().nth(1).unwrap() == "--asm" {
let file_name = env::args().nth(2).unwrap();
let contents = fs::read_to_string(Path::new(&file_name)).unwrap();
match powdr::asm_compiler::compile(Some(&file_name), &contents) {
Ok(pil) => println!("{pil}"),
Err(err) => err.output_to_stderr(),
match Cli::parse().command {
Commands::Asm {
file,
inputs,
output_directory,
force,
} => {
let inputs = inputs
.split(',')
.map(|x| x.parse().unwrap())
.collect::<Vec<AbstractNumberType>>();
powdr::compiler::compile_asm(&file, inputs, Path::new(&output_directory), force);
}
} else if env::args().nth(1).unwrap() == "--reformat" {
let file_name = env::args().nth(2).unwrap();
let contents = fs::read_to_string(Path::new(&file_name)).unwrap();
match powdr::parser::parse(Some(&file_name), &contents) {
Ok(ast) => println!("{ast}"),
Err(err) => err.output_to_stderr(),
Commands::Reformat { file } => {
let contents = fs::read_to_string(&file).unwrap();
match powdr::parser::parse(Some(&file), &contents) {
Ok(ast) => println!("{ast}"),
Err(err) => err.output_to_stderr(),
}
}
Commands::Compile {
file,
output_directory,
} => {
powdr::compiler::compile_pil(
Path::new(&file),
Path::new(&output_directory),
no_callback(),
);
}
} else {
powdr::compiler::compile_pil(
Path::new(&env::args().nth(1).unwrap()),
&env::current_dir().unwrap(),
no_callback(),
);
}
}

View File

@@ -2,11 +2,12 @@ use std::fs;
use std::io::{BufWriter, Write};
use std::path::Path;
use itertools::Itertools;
use num_bigint::Sign;
use crate::number::{abstract_to_degree, AbstractNumberType, DegreeType};
use crate::parser::ast::PILFile;
use crate::{analyzer, commit_evaluator, constant_evaluator, json_exporter};
use crate::{analyzer, asm_compiler, commit_evaluator, constant_evaluator, json_exporter};
pub fn no_callback() -> Option<fn(&str) -> Option<AbstractNumberType>> {
None
@@ -45,6 +46,52 @@ pub fn compile_pil_ast(
)
}
/// Compiles a .asm file, outputs the PIL on stdout and tries to generate
/// fixed and witness columns.
pub fn compile_asm(
file_name: &str,
inputs: Vec<AbstractNumberType>,
output_dir: &Path,
force_overwrite: bool,
) {
let contents = fs::read_to_string(file_name).unwrap();
let pil = asm_compiler::compile(Some(file_name), &contents).unwrap();
let pil_file_name = output_dir.join(format!(
"{}.pil",
Path::new(file_name).file_stem().unwrap().to_str().unwrap()
));
if pil_file_name.exists() && !force_overwrite {
eprint!(
"Target file {} already exists. Not overwriting.",
pil_file_name.to_str().unwrap()
);
return;
}
fs::write(pil_file_name.clone(), format!("{pil}")).unwrap();
let query_callback = |query: &str| -> Option<AbstractNumberType> {
let items = query.split(',').map(|s| s.trim()).collect::<Vec<_>>();
let mut it = items.iter();
let _current_step = it.next().unwrap();
let current_pc = it.next().unwrap();
assert!(it.clone().len() % 3 == 0);
for (pc_check, input, index) in it.tuples() {
if pc_check == current_pc {
assert_eq!(*input, "\"input\"");
let index: usize = index.parse().unwrap();
return inputs.get(index).cloned();
}
}
None
};
compile_pil_ast(
&pil,
pil_file_name.to_str().unwrap(),
output_dir,
Some(query_callback),
);
}
fn compile(
analyzed: &analyzer::Analyzed,
file_name: &str,

View File

@@ -1,5 +1,6 @@
use std::{fs, path::Path, process::Command};
use itertools::Itertools;
use powdr::compiler;
use powdr::number::AbstractNumberType;
@@ -31,14 +32,12 @@ fn verify_asm(file_name: &str, inputs: Vec<AbstractNumberType>) {
let mut it = items.iter();
let _current_step = it.next().unwrap();
let current_pc = it.next().unwrap();
while let Some(pc_check) = it.next() {
assert!(it.clone().len() % 3 == 0);
for (pc_check, input, index) in it.tuples() {
if pc_check == current_pc {
assert_eq!(*it.next().unwrap(), "\"input\"");
let index: usize = it.next().map(|s| s.parse().unwrap()).unwrap();
return Some(inputs[index].clone());
} else {
it.next();
it.next();
assert_eq!(*input, "\"input\"");
let index: usize = index.parse().unwrap();
return inputs.get(index).cloned();
}
}
None