From 3ec1a8efdaba91673a8e20c3e9a18033cfe0505e Mon Sep 17 00:00:00 2001 From: Steve Biedermann Date: Thu, 12 Dec 2024 15:57:00 +0100 Subject: [PATCH] better cli --- src/main.rs | 175 ++++++++++++++++++++++++++++++-------------------- src/native.rs | 4 +- 2 files changed, 107 insertions(+), 72 deletions(-) diff --git a/src/main.rs b/src/main.rs index fdacc9c..058d536 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ -use std::path::PathBuf; +use std::{io::BufWriter, path::PathBuf}; -use byteorder::ReadBytesExt; -use clap::Parser; +use byteorder::{ReadBytesExt, WriteBytesExt}; +use clap::{Parser, Subcommand}; use common::{CpuTrait, RunMode}; use native::{Bytecode, NativeCpu}; use std::io::BufReader; @@ -10,86 +10,121 @@ mod native; #[derive(Parser)] struct Args { - memory: Option, - #[arg(short, long)] + #[arg(short, long, global = true)] verbose: bool, + #[command(subcommand)] + action: Action, } -fn main() -> anyhow::Result<()> { - let Args { memory, verbose } = Args::parse(); +#[derive(Subcommand)] +enum Action { + Run { path: PathBuf }, + RunDemo, + WriteDemo { path: PathBuf }, +} - let memory = memory - .and_then(|p| { - std::fs::File::open(p) - .and_then(|file| { +const DEMO: &[u32] = { + use Bytecode::*; + &[ + /* 0 */ PushValue as u32, + /* 1 */ 42, + /* 2 */ LoadValue as u32, + /* 3 */ 0, + /* 4 */ 10, + /* 5 */ PushReg as u32, + /* 6 */ 0, + /* 7 */ Call as u32, + /* 8 */ 17, + /* 9 */ Pop as u32, + /* 10 */ 3, + /* 11 */ Store as u32, + /* 12 */ 40, + /* 13 */ 3, + /* 14 */ Inspect as u32, + /* 15 */ 40, + /* 16 */ Halt as u32, + /* 17 */ Pop as u32, + /* 18 */ 5, + /* 19 */ Pop as u32, + /* 20 */ 0, + /* 21 */ Pop as u32, + /* 22 */ 1, + /* 23 */ Add as u32, + /* 24 */ 0, + /* 25 */ 1, + /* 26 */ PushReg as u32, + /* 27 */ 5, + /* 28 */ RetReg as u32, + /* 29 */ 0, + ] +}; + +fn main() -> anyhow::Result<()> { + let Args { action, verbose } = Args::parse(); + + match action { + Action::RunDemo => { + let mut cpu = NativeCpu::new(1024 * 1024, 6); + cpu.set_verbose(verbose); + + cpu.load_memory(0, DEMO); + + let stats = cpu.execute(RunMode::Run)?; + + println!(); + println!(" ========== STATS ==========="); + println!(); + + if verbose { + println!( + "Total cycles: {}, Memory Access score: {}", + stats.cycles, stats.memory_access_score + ); + } + + println!("Total Score: {}", stats.cycles + stats.memory_access_score); + } + Action::WriteDemo { path } => { + let file = std::fs::File::create(path)?; + let mut writer = BufWriter::new(file); + for &v in DEMO { + writer.write_u32::(v)?; + } + } + + Action::Run { path } => { + let memory = std::fs::File::open(path) + .map(|file| { let mut reader = BufReader::new(file); let mut values = Vec::new(); - let result = reader.read_u32_into::(&mut values); - result.map(|_| values) + while let Ok(v) = reader.read_u32::() { + values.push(v); + } + values }) - .ok() - }) - .unwrap_or_else(|| { - use Bytecode::*; - vec![ - /* 0 */ Jmp as u32, - /* 1 */ 15, - /* 2 */ Pop as u32, - /* 3 */ 5, - /* 4 */ Pop as u32, - /* 5 */ 0, - /* 6 */ Pop as u32, - /* 7 */ 1, - /* 8 */ Add as u32, - /* 9 */ 0, - /* 10 */ 1, - /* 11 */ PushReg as u32, - /* 12 */ 5, - /* 13 */ RetReg as u32, - /* 14 */ 0, - /* 15 */ Nop as u32, - /* 16 */ Nop as u32, - /* 17 */ Nop as u32, - /* 18 */ Nop as u32, - /* 19 */ PushValue as u32, - /* 20 */ 42, - /* 21 */ LoadValue as u32, - /* 22 */ 0, - /* 23 */ 10, - /* 24 */ PushReg as u32, - /* 25 */ 0, - /* 26 */ Call as u32, - /* 27 */ 2, - /* 28 */ Pop as u32, - /* 29 */ 3, - /* 30 */ Store as u32, - /* 31 */ 40, - /* 32 */ 3, - /* 33 */ Inspect as u32, - /* 34 */ 40, - /* 35 */ Halt as u32, - ] - }); + .unwrap(); - let mut cpu = NativeCpu::new(1024 * 1024, 6); - cpu.set_verbose(verbose); + let mut cpu = NativeCpu::new(1024 * 1024, 6); + cpu.set_verbose(verbose); - cpu.load_memory(0, &memory); + cpu.load_memory(0, &memory); - let stats = cpu.execute(RunMode::Run)?; + let stats = cpu.execute(RunMode::Run)?; - println!(); - println!(" ========== STATS ==========="); - println!(); + println!(); + println!(" ========== STATS ==========="); + println!(); - if verbose { - println!( - "Total cycles: {}, Memory Access score: {}", - stats.cycles, stats.memory_access_score - ); + if verbose { + println!( + "Total cycles: {}, Memory Access score: {}", + stats.cycles, stats.memory_access_score + ); + } + + println!("Total Score: {}", stats.cycles + stats.memory_access_score); + } } - println!("Total Score: {}", stats.cycles + stats.memory_access_score); - Ok(()) } diff --git a/src/native.rs b/src/native.rs index 086f20d..fde2039 100644 --- a/src/native.rs +++ b/src/native.rs @@ -214,12 +214,12 @@ impl NativeCpu { let reg = self.read_memory(self.instruction_pointer)?; self.instruction_pointer += 1; - let val = self.registers[reg as usize]; - if self.verbose { println!("PUSH R{}", reg); } + let val = self.registers[reg as usize]; + self.push_stack(val)?; self.cycles += 2;