summary refs log tree commit diff
path: root/src/main.rs
blob: f5c4740baf373a79c8ba82d4f67b95777067dadf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#![allow(incomplete_features)]
#![feature(async_fn_in_trait)]
#![feature(custom_inner_attributes)]
#![feature(lint_reasons)]
#![feature(never_type)]
#![feature(once_cell)]
#![deny(clippy::complexity)]
#![deny(clippy::nursery)]
#![deny(clippy::pedantic)]
#![deny(clippy::perf)]
#![deny(clippy::suspicious)]
#![deny(clippy::alloc_instead_of_core)]
#![deny(clippy::as_underscore)]
#![deny(clippy::clone_on_ref_ptr)]
#![deny(clippy::create_dir)]
#![warn(clippy::dbg_macro)]
#![deny(clippy::default_numeric_fallback)]
#![deny(clippy::default_union_representation)]
#![deny(clippy::deref_by_slicing)]
#![deny(clippy::empty_structs_with_brackets)]
#![deny(clippy::exit)]
#![deny(clippy::filetype_is_file)]
#![deny(clippy::fn_to_numeric_cast)]
#![deny(clippy::format_push_string)]
#![deny(clippy::get_unwrap)]
#![deny(clippy::if_then_some_else_none)]
#![allow(
	clippy::implicit_return,
	reason = "returns should be done implicitly, not explicitly"
)]
#![deny(clippy::indexing_slicing)]
#![deny(clippy::large_include_file)]
#![deny(clippy::let_underscore_must_use)]
#![deny(clippy::lossy_float_literal)]
#![deny(clippy::map_err_ignore)]
#![deny(clippy::mem_forget)]
#![deny(clippy::missing_docs_in_private_items)]
#![deny(clippy::missing_trait_methods)]
#![deny(clippy::mod_module_files)]
#![deny(clippy::multiple_inherent_impl)]
#![deny(clippy::mutex_atomic)]
#![deny(clippy::needless_return)]
#![deny(clippy::non_ascii_literal)]
#![deny(clippy::panic_in_result_fn)]
#![deny(clippy::pattern_type_mismatch)]
#![deny(clippy::rc_buffer)]
#![deny(clippy::rc_mutex)]
#![deny(clippy::rest_pat_in_fully_bound_structs)]
#![deny(clippy::same_name_method)]
#![deny(clippy::separated_literal_suffix)]
#![deny(clippy::str_to_string)]
#![deny(clippy::string_add)]
#![deny(clippy::string_slice)]
#![deny(clippy::string_to_string)]
#![allow(
	clippy::tabs_in_doc_comments,
	reason = "tabs are preferred for this project"
)]
#![deny(clippy::try_err)]
#![deny(clippy::undocumented_unsafe_blocks)]
#![deny(clippy::unnecessary_self_imports)]
#![deny(clippy::unneeded_field_pattern)]
#![deny(clippy::unwrap_in_result)]
#![deny(clippy::unwrap_used)]
#![warn(clippy::use_debug)]
#![deny(clippy::verbose_file_reads)]
#![deny(clippy::wildcard_dependencies)]
#![deny(clippy::wildcard_enum_match_arm)]
#![deny(missing_copy_implementations)]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
#![deny(single_use_lifetimes)]
#![deny(unsafe_code)]
#![deny(unused)]

//! Brainfuck RS
//!
//! Brainfuck interpreter written in Rust

use std::path::PathBuf;

use brainf_rs::{
	executor,
	utility::{execute_from_file, execute_from_str},
};
use clap::{Parser, Subcommand};
use miette::Context;

/// Representation of command line application for the Brainfuck interpreter.
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
struct App {
	/// Subcommands supported by the Brainfuck interpreter
	#[command(subcommand)]
	command: Command,
}

/// Implementation of subcommands for the Brainfuck interpreter.
#[derive(Subcommand)]
enum Command {
	/// Interprets Brainfuck code from a provided file.
	File {
		/// Path to the file to interpret with Brainfuck.
		path: PathBuf,
	},

	/// Interprets Brainfuck code from a text input on the command line.
	Text {
		/// Text input to be interpreted as Brainfuck.
		input: String,
	},
}

fn main() -> miette::Result<()> {
	let app = App::parse();

	let mut tape = vec![0u8; 1024];

	match app.command {
		Command::File { ref path } => {
			execute_from_file::<executor::U8>(path, &mut tape)
				.wrap_err("when executing from file")?;
		}
		Command::Text { ref input } => execute_from_str::<executor::U8>(input, &mut tape)?,
	};

	Ok(())
}