summaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/app')
-rw-r--r--src/app/init.rs108
-rw-r--r--src/app/main.rs48
-rw-r--r--src/app/print_help.rs50
-rw-r--r--src/app/print_version.rs35
-rw-r--r--src/app/run.rs56
5 files changed, 297 insertions, 0 deletions
diff --git a/src/app/init.rs b/src/app/init.rs
new file mode 100644
index 0000000..8ed43ac
--- /dev/null
+++ b/src/app/init.rs
@@ -0,0 +1,108 @@
+/*
+ Copyright 2023 Gabriel Jensen.
+
+ This file is part of aas.
+
+ aas is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ General Public License as published by the Free
+ Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ aas is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU
+ General Public License along with aas. If not,
+ see <https://www.gnu.org/licenses/>.
+*/
+
+use crate::app::App;
+use crate::cpu::Cpu;
+use crate::format::Format;
+
+use std::env::args;
+use std::str::FromStr;
+
+macro_rules! use_remainder {
+ ($destination: ident, $argument: expr, $index: expr) => {{
+ let argument: &[char] = $argument;
+ let index: usize = $index + 0x1;
+
+ if argument.len() <= index {
+ let c = argument[index - 0x1];
+ Err(format!("missing value for short '{}'", c))
+ } else {
+ let value: String = argument[$index + 0x1..].iter().collect();
+ $destination = Some(value);
+
+ break;
+ }
+ }};
+}
+
+impl App {
+ pub fn init() -> Result<Self, String> {
+ if args().len() < 0x2 { Self::print_help() };
+
+ let mut input: Option<String> = None;
+ let mut output: Option<String> = None;
+ let mut cpu: Option<String> = None;
+ let mut format: Option<String> = None;
+
+ let mut handle_short = |argument: &String| -> Result<(), String> {
+ let argument: Vec<char> = argument.chars().collect();
+
+ for (index, c) in argument.iter().enumerate().skip(0x1) {
+ match c {
+ 'f' => use_remainder!(format, &argument, index)?,
+ 'h' => Self::print_help(),
+ 'o' => use_remainder!(output, &argument, index)?,
+ 'm' => use_remainder!(cpu, &argument, index)?,
+ 'v' => Self::print_version(),
+
+ _ => { return Err(format!("invalid short parameter '{c}'")) },
+ };
+ }
+
+ return Ok(());
+ };
+
+ for argument in args().skip(0x1) {
+ if argument.is_empty() { continue };
+
+ if argument.chars().nth(0x0) != Some('-') {
+ // This argument is the input path.
+
+ if input.is_some() { return Err(format!("input pathy is already set (to \"{}\")", input.as_ref().unwrap())) };
+
+ input = Some(argument.to_owned());
+ continue;
+ }
+
+ handle_short(&argument)?;
+ }
+
+ // Check if any of the mandatory parameters have
+ // been set.
+ if input.is_none() { return Err("missing input path".to_string()) };
+ if output.is_none() { output = Some("a.out".to_string()) };
+ if cpu.is_none() { return Err("missing cpu".to_string()) };
+
+ let format = match format {
+ Some(format) => Format::from_str(&format)?,
+ _ => Format::default(),
+ };
+
+ return Ok(Self {
+ input: input.unwrap(),
+ output: output.unwrap(),
+
+ cpu: Cpu::from_str(&cpu.unwrap())?,
+ format,
+ });
+ }
+}
diff --git a/src/app/main.rs b/src/app/main.rs
new file mode 100644
index 0000000..bd82623
--- /dev/null
+++ b/src/app/main.rs
@@ -0,0 +1,48 @@
+/*
+ Copyright 2023 Gabriel Jensen.
+
+ This file is part of aas.
+
+ aas is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ General Public License as published by the Free
+ Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ aas is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU
+ General Public License along with aas. If not,
+ see <https://www.gnu.org/licenses/>.
+*/
+
+use crate::log;
+use crate::app::App;
+
+use std::process::exit;
+
+impl App {
+ pub fn main() -> ! {
+ let app = match App::init() {
+ Ok(app) => app,
+
+ Err(message) => {
+ log!(error, "{message}");
+ exit(0x1);
+ },
+ };
+
+ exit(match app.run() {
+ Err(message) => {
+ log!(error, "{message}");
+ 0x1
+ },
+
+ _ => 0x0,
+ });
+ }
+}
diff --git a/src/app/print_help.rs b/src/app/print_help.rs
new file mode 100644
index 0000000..1df895e
--- /dev/null
+++ b/src/app/print_help.rs
@@ -0,0 +1,50 @@
+/*
+ Copyright 2023 Gabriel Jensen.
+
+ This file is part of aas.
+
+ aas is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ General Public License as published by the Free
+ Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ aas is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU
+ General Public License along with aas. If not,
+ see <https://www.gnu.org/licenses/>.
+*/
+
+use crate::app::App;
+use crate::cpu::Cpu;
+use crate::format::Format;
+
+use enum_iterator::all;
+use std::process::exit;
+
+impl App {
+ pub fn print_help() -> ! {
+ println!("\u{1B}[1mUsage\u{1B}[0m: \u{1B}[1maas\u{1B}[0m \u{1B}[3m[options]\u{1B}[0m <input>");
+ println!();
+ println!("\u{1B}[1mOptions\u{1B}[0m:");
+ println!(" \u{1B}[1m-f\u{1B}[0m\u{1B}[3m<format>\u{1B}[0m set the target executable format (see below)");
+ println!(" \u{1B}[1m-h\u{1B}[0m print help");
+ println!(" \u{1B}[1m-m\u{1B}[0m\u{1B}[3m<target>\u{1B}[0m set the target cpu (see below)");
+ println!(" \u{1B}[1m-v\u{1B}[0m print version");
+
+ println!();
+ println!("\u{1B}[1mCPUs\u{1B}[0m:");
+ for cpu in all::<Cpu>() { println!(" \u{1B}[3m{cpu}\u{1B}[0m") }
+
+ println!();
+ println!("\u{1B}[1mFormats\u{1B}[0m:");
+ for format in all::<Format>() { println!(" \u{1B}[3m{format}\u{1B}[0m") }
+
+ exit(0x0);
+ }
+}
diff --git a/src/app/print_version.rs b/src/app/print_version.rs
new file mode 100644
index 0000000..d28e457
--- /dev/null
+++ b/src/app/print_version.rs
@@ -0,0 +1,35 @@
+/*
+ Copyright 2023 Gabriel Jensen.
+
+ This file is part of aas.
+
+ aas is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ General Public License as published by the Free
+ Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ aas is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU
+ General Public License along with aas. If not,
+ see <https://www.gnu.org/licenses/>.
+*/
+
+use crate::VERSION;
+use crate::app::App;
+
+use std::process::exit;
+
+impl App {
+ pub fn print_version() -> ! {
+ println!("\u{1B}[1maas\u{1B}[0m {:X}.{:X}.{:X}", VERSION.0, VERSION.1, VERSION.2);
+ println!("\u{1B}[3mCopyright \u{A9} 2023 Gabriel Bj\u{F8}rnager Jensen\u{1B}[0m.");
+
+ exit(0x0);
+ }
+}
diff --git a/src/app/run.rs b/src/app/run.rs
new file mode 100644
index 0000000..88d0983
--- /dev/null
+++ b/src/app/run.rs
@@ -0,0 +1,56 @@
+/*
+ Copyright 2023 Gabriel Jensen.
+
+ This file is part of aas.
+
+ aas is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ General Public License as published by the Free
+ Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ aas is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU
+ General Public License along with aas. If not,
+ see <https://www.gnu.org/licenses/>.
+*/
+
+use crate::app::App;
+use crate::token::Token;
+
+use std::fs::read_to_string;
+
+impl App {
+ #[must_use]
+ pub fn run(self) -> Result<(), String> {
+ if cfg!(debug_assertions) {
+ println!("\u{1B}[1mSettings\u{1B}[0m:");
+ println!("\u{B7} input \u{1B}[3m\"{}\"\u{1B}[0m", self.input);
+ println!("\u{B7} output \u{1B}[3m\"{}\"\u{1B}[0m", self.output);
+ println!();
+ println!("\u{B7} cpu \u{1B}[3m{}\u{1B}[0m", self.cpu);
+ println!("\u{B7} format \u{1B}[3m{}\u{1B}[0m", self.format);
+ println!();
+ }
+
+ let input = match read_to_string(&self.input) {
+ Ok(content) => content,
+
+ _ => return Err(format!("unable to read file \"{}\"", &self.input)),
+ };
+
+ let tokens = Token::tokenise(&input)?;
+
+ eprintln!("\u{1B}[1mTokens\u{1B}[0m:");
+ for token in &tokens {
+ eprintln!("\u{B7} {token:?}");
+ }
+
+ return Ok(());
+ }
+}