summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs187
1 files changed, 0 insertions, 187 deletions
diff --git a/src/main.rs b/src/main.rs
deleted file mode 100644
index f271bcd..0000000
--- a/src/main.rs
+++ /dev/null
@@ -1,187 +0,0 @@
-mod compiler;
-mod parsers;
-mod report;
-mod tokens;
-mod formats;
-
-pub use compiler::*;
-pub use parsers::*;
-pub use report::*;
-pub use tokens::*;
-pub use formats::*;
-
-pub use assembler::*;
-use log::{info, fatal};
-use switchboard::{Switchboard, SwitchQuery};
-
-use std::io::{Read, Write};
-use std::str::FromStr;
-
-
-fn print_version() -> ! {
- let version = env!("CARGO_PKG_VERSION");
- eprintln!("torque assembler, version {version}");
- eprintln!("written by ben bridle");
- std::process::exit(0);
-}
-
-fn main() {
- let mut args = Switchboard::from_env();
- if args.named("version").as_bool() {
- print_version();
- }
- if args.named("verbose").short('v').as_bool() {
- log::set_log_level(log::LogLevel::Info);
- }
- let source_path = args.positional("source").as_path_opt().map(
- |p| p.canonicalize().unwrap_or_else(|e| fatal!("{p:?}: {e:?}")));
- let destination_path = args.positional("destination").as_path_opt();
- let extension = args.named("ext").default("tq").as_string();
-
- let no_libs = args.named("no-libs").as_bool();
- let no_project_libs = args.named("no-project-libs").as_bool();
- let no_environment_libs = args.named("no-env-libs").as_bool();
-
- let format = args.named("format").default("debug").as_string();
- let print_tree = args.named("tree").as_bool();
- let dry_run = args.named("dry-run").short('n').as_bool();
-
- let Ok(format) = Format::from_str(format.as_str()) else {
- fatal!("Unknown format '{format}', expected 'debug', 'inhx', 'inhx32', 'raw', or 'source'. ");
- };
-
- // -----------------------------------------------------------------------
-
- let mut compiler = if let Some(path) = &source_path {
- info!("Reading program source from {path:?}");
- Compiler::from_path(path).unwrap_or_else(|err| match err {
- FileError::InvalidExtension => fatal!(
- "File {path:?} has invalid extension, must be '.{extension}'"),
- FileError::NotFound => fatal!(
- "File {path:?} was not found"),
- FileError::InvalidUtf8 => fatal!(
- "File {path:?} does not contain valid UTF-8 text"),
- FileError::NotReadable => fatal!(
- "File {path:?} is not readable"),
- FileError::IsADirectory => fatal!(
- "File {path:?} is a directory"),
- FileError::Unknown => fatal!(
- "Unknown error while attempting to read from {path:?}")
- })
- } else {
- let mut source_code = String::new();
- info!("Reading program source from standard input");
- if let Err(err) = std::io::stdin().read_to_string(&mut source_code) {
- fatal!("Could not read from standard input\n{err:?}");
- }
- Compiler::from_string(source_code, "<standard input>")
- };
- if compiler.error().is_some() && !no_libs && !no_project_libs {
- compiler.include_libs_from_parent(&extension);
- }
- if compiler.error().is_some() && !no_libs && !no_environment_libs {
- compiler.include_libs_from_path_variable("TORQUE_LIBS", &extension);
- }
-
- if print_tree {
- compiler.resolver.hierarchy().report()
- }
-
- if let Some(error) = compiler.error() {
- error.report();
- std::process::exit(1);
- }
-
- let merged_source = compiler.get_compiled_source().unwrap_or_else(|error| {
- error.report();
- std::process::exit(1);
- });
- if format == Format::Source && !dry_run {
- write_bytes_and_exit(merged_source.as_bytes(), destination_path.as_ref());
- }
-
- // -----------------------------------------------------------------------
-
- // Parse syntactic tokens from merged source code.
- let path = Some("<merged source>");
- let syntactic_tokens = SyntacticParser::new(&merged_source, path).parse();
- report_syntactic_errors(&syntactic_tokens, &merged_source);
-
- let program = SemanticParser::new(syntactic_tokens).parse();
- report_semantic_errors(&program, &merged_source);
-
- // program.print_definitions();
- let assembled_tokens = program.assemble();
- report_assembler_errors(&assembled_tokens, &merged_source);
-
- let bytecode = BytecodeGenerator::new(&assembled_tokens).generate();
- report_bytecode_errors(&bytecode, &merged_source);
-
- if !dry_run {
- match format {
- Format::Debug => {
- let mut output = String::new();
- for word in &bytecode.words {
- output.push_str(&word.to_string());
- output.push('\n');
- }
- write_bytes_and_exit(output.as_bytes(), destination_path.as_ref());
- }
- Format::Inhx => {
- let output = format_inhx(&bytecode.words);
- write_bytes_and_exit(output.as_bytes(), destination_path.as_ref());
- }
- Format::Inhx32 => {
- let output = format_inhx32(&bytecode.words);
- write_bytes_and_exit(output.as_bytes(), destination_path.as_ref());
- }
- Format::Raw => {
- let mut output = Vec::new();
- for word in &bytecode.words {
- let value = word.value as u16;
- output.extend(value.to_be_bytes());
- }
- write_bytes_and_exit(&output, destination_path.as_ref());
- }
- Format::Source => unreachable!(),
- }
- }
-}
-
-
-fn write_bytes_and_exit<P: AsRef<Path>>(bytes: &[u8], path: Option<&P>) -> ! {
- match path {
- Some(path) => match std::fs::write(path, bytes) {
- Ok(_) => info!("Wrote output to path {:?}", path.as_ref()),
- Err(err) => fatal!("Could not write to path {:?}\n{err:?}", path.as_ref()),
- }
- None => match std::io::stdout().write_all(bytes) {
- Ok(_) => info!("Wrote output to standard output"),
- Err(err) => fatal!("Could not write to standard output\n{err:?}"),
- }
- }
- std::process::exit(0);
-}
-
-#[derive(PartialEq)]
-enum Format {
- Debug,
- Inhx,
- Inhx32,
- Raw,
- Source,
-}
-
-impl FromStr for Format {
- type Err = ();
- fn from_str(string: &str) -> Result<Self, ()> {
- match string {
- "debug" => Ok(Self::Debug),
- "inhx" => Ok(Self::Inhx),
- "inhx32" => Ok(Self::Inhx32),
- "raw" => Ok(Self::Raw),
- "source" => Ok(Self::Source),
- _ => Err(()),
- }
- }
-}