Skip to content

Commit 0f1ad3a

Browse files
authored
Using clap for command line arguments. (#31)
* Using clap for command line arguments. * Cleanup.
1 parent 00504ad commit 0f1ad3a

File tree

4 files changed

+103
-46
lines changed

4 files changed

+103
-46
lines changed

Cargo.lock

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ openvm-stark-backend = { workspace = true }
2020
wasmparser = { workspace = true }
2121
womir = { workspace = true }
2222
serde_json = { workspace = true }
23+
clap = { version = "4.5.43", features = ["derive"] }

integration/src/main.rs

Lines changed: 89 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
use clap::{Parser, Subcommand};
12
use derive_more::From;
23
use eyre::Result;
34
use openvm_sdk::{Sdk, StdIn};
45
use openvm_stark_backend::p3_field::PrimeField32;
56
use serde::{Deserialize, Serialize};
6-
use std::env::args;
77
use std::path::Path;
88

99
use openvm_circuit::arch::{
@@ -20,6 +20,8 @@ mod womir_translation;
2020

2121
use openvm_womir_circuit::{self, WomirI, WomirIExecutor, WomirIPeriphery};
2222

23+
use crate::womir_translation::OpenVMSettings;
24+
2325
#[derive(Serialize, Deserialize, Clone)]
2426
pub struct SpecializedConfig {
2527
pub sdk_config: SdkVmConfig,
@@ -89,41 +91,85 @@ impl VmConfig<F> for SpecializedConfig {
8991
}
9092
}
9193

92-
fn main() -> Result<(), Box<dyn std::error::Error>> {
93-
// Create VM configuration
94-
let vm_config = SdkVmConfig::builder()
95-
.system(Default::default())
96-
.rv32i(Default::default())
97-
.rv32m(Default::default())
98-
.io(Default::default())
99-
.build();
100-
let vm_config = SpecializedConfig::new(vm_config);
101-
let sdk = Sdk::new();
102-
103-
// Create and execute program
104-
let mut args = args();
105-
if args.len() < 3 {
106-
eprintln!(
107-
"Usage: {} <wasm_path> <entry_point> [<32_bit_args>...]",
108-
args.next().unwrap()
109-
);
110-
return Ok(());
111-
}
112-
let wasm_path = args.nth(1).unwrap();
113-
let entry_point = args.next().unwrap();
114-
let exe = womir_translation::program_from_wasm::<F>(&wasm_path, &entry_point);
94+
#[derive(Parser)]
95+
struct CliArgs {
96+
#[command(subcommand)]
97+
command: Commands,
98+
}
11599

116-
let inputs = args
117-
.flat_map(|arg| {
118-
let val = arg.parse::<u32>().unwrap();
119-
val.to_le_bytes().into_iter()
120-
})
121-
.collect::<Vec<_>>();
100+
#[derive(Subcommand)]
101+
enum Commands {
102+
/// Just prints the program WOM listing
103+
PrintWom {
104+
/// Path to the WASM program
105+
program: String,
106+
},
107+
/// Runs a function from the program with arguments
108+
Run {
109+
/// Path to the WASM program
110+
program: String,
111+
/// Function name
112+
function: String,
113+
/// Arguments to pass to the function
114+
args: Vec<String>,
115+
},
116+
}
122117

123-
let stdin = StdIn::from_bytes(&inputs);
118+
impl Commands {
119+
fn get_program_path(&self) -> &str {
120+
match self {
121+
Commands::PrintWom { program } => program,
122+
Commands::Run { program, .. } => program,
123+
}
124+
}
125+
}
124126

125-
let output = sdk.execute(exe.clone(), vm_config.clone(), stdin.clone())?;
126-
println!("output: {output:?}");
127+
fn main() -> Result<(), Box<dyn std::error::Error>> {
128+
// Parse command line arguments
129+
let cli_args = CliArgs::parse();
130+
let wasm_path = cli_args.command.get_program_path();
131+
132+
// Load the program
133+
let wasm_bytes = std::fs::read(wasm_path).expect("Failed to read WASM file");
134+
let ir_program = womir::loader::load_wasm(OpenVMSettings::<F>::new(), &wasm_bytes).unwrap();
135+
136+
match cli_args.command {
137+
Commands::PrintWom { .. } => {
138+
for func in &ir_program.functions {
139+
println!("Function {}:", func.func_idx);
140+
for directive in &func.directives {
141+
println!(" {directive:?}");
142+
}
143+
}
144+
}
145+
Commands::Run { function, args, .. } => {
146+
// Create VM configuration
147+
let vm_config = SdkVmConfig::builder()
148+
.system(Default::default())
149+
.rv32i(Default::default())
150+
.rv32m(Default::default())
151+
.io(Default::default())
152+
.build();
153+
let vm_config = SpecializedConfig::new(vm_config);
154+
let sdk = Sdk::new();
155+
156+
// Create and execute program
157+
let exe = womir_translation::program_from_womir::<F>(ir_program, &function);
158+
159+
let inputs = args
160+
.into_iter()
161+
.flat_map(|arg| {
162+
let val = arg.parse::<u32>().unwrap();
163+
val.to_le_bytes().into_iter()
164+
})
165+
.collect::<Vec<_>>();
166+
167+
let stdin = StdIn::from_bytes(&inputs);
168+
169+
let output = sdk.execute(exe.clone(), vm_config.clone(), stdin.clone())?;
170+
println!("output: {output:?}");
171+
}
172+
}
127173

128174
Ok(())
129175
}
@@ -1282,7 +1328,10 @@ mod tests {
12821328

12831329
#[cfg(test)]
12841330
mod wast_tests {
1331+
use crate::womir_translation::program_from_womir;
1332+
12851333
use super::*;
1334+
use openvm_instructions::exe::VmExe;
12861335
use openvm_sdk::{Sdk, StdIn};
12871336
use openvm_stark_sdk::config::setup_tracing_with_log_level;
12881337
use serde::Deserialize;
@@ -1444,6 +1493,12 @@ mod wast_tests {
14441493
}
14451494
}
14461495

1496+
fn program_from_wasm<F: PrimeField32>(wasm_path: &str, entry_point: &str) -> VmExe<F> {
1497+
let wasm_bytes = std::fs::read(wasm_path).expect("Failed to read WASM file");
1498+
let ir_program = womir::loader::load_wasm(OpenVMSettings::new(), &wasm_bytes).unwrap();
1499+
program_from_womir(ir_program, entry_point)
1500+
}
1501+
14471502
fn run_single_wast_test(
14481503
module_path: &str,
14491504
function: &str,
@@ -1463,7 +1518,7 @@ mod wast_tests {
14631518
let sdk = Sdk::new();
14641519

14651520
// Load and execute the module
1466-
let exe = womir_translation::program_from_wasm::<F>(module_path, function);
1521+
let exe = program_from_wasm::<F>(module_path, function);
14671522

14681523
// Prepare input
14691524
let mut stdin = StdIn::default();

integration/src/womir_translation.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ use womir::{
1515
},
1616
};
1717

18-
pub fn program_from_wasm<F: PrimeField32>(wasm_path: &str, entry_point: &str) -> VmExe<F> {
19-
let wasm_bytes = std::fs::read(wasm_path).expect("Failed to read WASM file");
20-
let ir_program = womir::loader::load_wasm(OpenVMSettings::new(), &wasm_bytes).unwrap();
21-
18+
pub fn program_from_womir<F: PrimeField32>(
19+
ir_program: womir::loader::Program<OpenVMSettings<F>>,
20+
entry_point: &str,
21+
) -> VmExe<F> {
2222
let functions = ir_program
2323
.functions
2424
.into_iter()
@@ -162,7 +162,7 @@ where
162162
// and it is needed because we can only resolve the labels to PCs during linking.
163163
#[derive(Clone, Debug)]
164164
#[allow(dead_code)]
165-
enum Directive<F> {
165+
pub enum Directive<F> {
166166
Nop,
167167
Label {
168168
id: String,
@@ -201,7 +201,7 @@ enum Directive<F> {
201201
Instruction(Instruction<F>),
202202
}
203203

204-
struct OpenVMSettings<F> {
204+
pub struct OpenVMSettings<F> {
205205
_phantom: std::marker::PhantomData<F>,
206206
}
207207

0 commit comments

Comments
 (0)