Skip to content

Commit

Permalink
Input/output files
Browse files Browse the repository at this point in the history
  • Loading branch information
cloone8 committed Mar 20, 2024
1 parent 5bae08e commit a1093e4
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 25 deletions.
8 changes: 4 additions & 4 deletions cpr_bf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ impl<T: BrainfuckCell, A: BrainfuckAllocator, R: Read, W: Write> Display for VMB
}
}

impl<T: BrainfuckCell + 'static, A: BrainfuckAllocator + 'static, R: Read, W: Write>
impl<T: BrainfuckCell + 'static, A: BrainfuckAllocator + 'static, R: Read + 'static, W: Write + 'static>
VMBuilder<T, A, R, W>
{
/// Changes the type of the memory cells to `U`
Expand Down Expand Up @@ -287,10 +287,10 @@ impl<T: BrainfuckCell + 'static, A: BrainfuckAllocator + 'static, R: Read, W: Wr
pub fn build(self) -> Box<dyn BrainfuckVM> {
log::info!("Building Brainfuck VM with configuration: {}", self);

Box::new(VirtualMachine::<T, A, Stdin, Stdout>::new(
Box::new(VirtualMachine::<T, A, R, W>::new(
self.initial_size,
stdin(),
stdout(),
self.reader,
self.writer,
))
}
}
Expand Down
14 changes: 14 additions & 0 deletions cpr_bfvm/src/cli_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,36 @@ use clap::{Parser, ValueEnum};
#[derive(Parser, Debug)]
#[command(author, about, version)]
pub(crate) struct CLIArgs {
/// The file to run
#[arg()]
pub filename: PathBuf,

/// The file from which running programs take their input. Defaults to stdin if empty
#[arg(short, long)]
pub input: Option<PathBuf>,

/// The file to which running programs write their output. Defaults to stdout if empty
#[arg(short, long)]
pub output: Option<PathBuf>,

/// The size of each individual memory cell
#[arg(value_enum, short, long, default_value_t = CellSize::U8)]
pub cellsize: CellSize,

/// The amount of preallocated memory cells. If a static allocator is used, this is also the total amount of available memory
#[arg(short, long, default_value_t = 16)]
pub preallocated: usize,

/// The memory allocator to use
#[arg(value_enum, short, long, default_value_t = Allocator::Dynamic)]
pub allocator: Allocator,

/// The verbosity of the logger
#[cfg(not(debug_assertions))]
#[arg(value_enum, short, long, default_value_t = LogLevel::Warn)]
pub verbosity: LogLevel,

/// The verbosity of the logger
#[cfg(debug_assertions)]
#[arg(value_enum, short, long, default_value_t = LogLevel::Info)]
pub verbosity: LogLevel,
Expand Down
69 changes: 48 additions & 21 deletions cpr_bfvm/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod cli_args;

use std::fs::File;
use std::process::ExitCode;

use clap::Parser;
Expand All @@ -9,7 +10,7 @@ use cpr_bf::VMBuilder;

macro_rules! assign_allocator_and_build {
($args:expr, $builder:expr) => {
match $args {
match $args.allocator {
cli_args::Allocator::Dynamic => $builder.with_allocator::<DynamicAllocator>().build(),
cli_args::Allocator::StaticChecked => $builder
.with_allocator::<BoundsCheckingStaticAllocator>()
Expand All @@ -21,32 +22,58 @@ macro_rules! assign_allocator_and_build {
};
}

macro_rules! assign_cellsize_and_build {
($args:expr, $builder:expr) => {
match $args.cellsize {
cli_args::CellSize::U8 => assign_allocator_and_build!($args, $builder.with_cell_type::<u8>()),
cli_args::CellSize::U16 => assign_allocator_and_build!($args, $builder.with_cell_type::<u16>()),
cli_args::CellSize::U32 => assign_allocator_and_build!($args, $builder.with_cell_type::<u32>()),
cli_args::CellSize::U64 => assign_allocator_and_build!($args, $builder.with_cell_type::<u64>()),
cli_args::CellSize::U128 => assign_allocator_and_build!($args, $builder.with_cell_type::<u128>()),
}
}
}

macro_rules! assign_input_and_build {
($args:expr, $builder:expr) => {
match $args.input {
Some(input) => {
assign_cellsize_and_build!($args, $builder.with_reader(File::open(input).expect("Could not open input file")))
}
None => assign_cellsize_and_build!($args, $builder)
}
};
}

macro_rules! assign_output_and_build {
($args:expr, $builder:expr) => {
match $args.output {
Some(output) => {
let output_file = File::options().create(true).truncate(true).write(true).open(output).expect("Could not open output file");
assign_input_and_build!($args, $builder.with_writer(output_file))
}
None => assign_input_and_build!($args, $builder)
}
};
}

macro_rules! process_args_and_build_vm {
($args:expr) => {
{
let vm_builder = VMBuilder::new().with_preallocated_cells($args.preallocated);
assign_output_and_build!($args, vm_builder)
}
};
}

fn main() -> ExitCode {
let args = CLIArgs::parse();

simple_logger::init_with_level(args.verbosity.clone().into()).unwrap();

log::info!("Assigning VM options and building");

let vm_builder = VMBuilder::new().with_preallocated_cells(args.preallocated);

let mut vm = match args.cellsize {
cli_args::CellSize::U8 => {
assign_allocator_and_build!(args.allocator, vm_builder.with_cell_type::<u8>())
}
cli_args::CellSize::U16 => {
assign_allocator_and_build!(args.allocator, vm_builder.with_cell_type::<u16>())
}
cli_args::CellSize::U32 => {
assign_allocator_and_build!(args.allocator, vm_builder.with_cell_type::<u32>())
}
cli_args::CellSize::U64 => {
assign_allocator_and_build!(args.allocator, vm_builder.with_cell_type::<u64>())
}
cli_args::CellSize::U128 => {
assign_allocator_and_build!(args.allocator, vm_builder.with_cell_type::<u128>())
}
};
let mut vm = process_args_and_build_vm!(args);

log::info!("Running program");
if let Err(e) = vm.run_from_path(&args.filename) {
Expand Down

0 comments on commit a1093e4

Please sign in to comment.