hence/hence/src/bin/main.rs

109 lines
2.9 KiB
Rust
Raw Normal View History

2022-09-02 09:33:46 +00:00
use anyhow::{bail, Result};
2022-07-17 18:24:49 +00:00
use clap::{Parser, Subcommand};
use std::fs;
use std::fs::File;
use std::io::{BufReader, Read, Write};
use std::path::Path;
use hence::*;
#[derive(Debug, Parser)]
#[clap(author, version, about, long_about = None)]
struct Cli {
#[clap(subcommand)]
commands: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
#[clap(about = "Lexes source code and outputs tokens")]
Lex {
#[clap(value_parser)]
src: String,
},
#[clap(about = "Parses source code and outputs AST")]
Parse {
#[clap(value_parser)]
src: String,
},
#[clap(about = "Compiles binary from source code")]
Assemble {
#[clap(value_parser)]
src: String,
#[clap(value_parser)]
bin: Option<String>,
#[clap(long, action)]
dump: bool,
},
#[clap(about = "Emulates binary")]
Run {
#[clap(value_parser)]
bin: String,
},
}
2022-09-02 09:33:46 +00:00
fn main() -> Result<()> {
2022-07-17 18:24:49 +00:00
let args = Cli::parse();
match args.commands {
Commands::Lex { src } => {
2022-09-02 09:33:46 +00:00
let assembly = fs::read_to_string(src)?;
let tokens = lexer::lex(assembly)?;
2022-07-17 18:24:49 +00:00
dbg!(tokens);
2022-09-02 09:33:46 +00:00
Ok(())
2022-07-17 18:24:49 +00:00
}
Commands::Parse { src } => {
2022-09-02 09:33:46 +00:00
let assembly = fs::read_to_string(src)?;
let tokens = lexer::lex(assembly)?;
let ast = parser::parse(tokens)?;
2022-07-17 18:24:49 +00:00
dbg!(ast);
2022-09-02 09:33:46 +00:00
Ok(())
2022-07-17 18:24:49 +00:00
}
Commands::Assemble { src, bin, dump } => {
2022-09-02 09:33:46 +00:00
let assembly = fs::read_to_string(&src)?;
let tokens = lexer::lex(assembly)?;
let ast = parser::parse(tokens)?;
2022-07-17 18:24:49 +00:00
2022-08-23 14:20:38 +00:00
let mut data = assembler::Data::new(
2022-09-02 09:33:46 +00:00
match match Path::new(&src).parent() {
Some(x) => x.to_str().map(|y| y.to_string()),
None => None,
} {
Some(s) => s,
None => bail!("Could not get directory in which source code resides"),
2022-08-23 14:20:38 +00:00
},
2022-08-28 10:31:56 +00:00
ast,
2022-08-23 14:20:38 +00:00
);
2022-09-02 09:33:46 +00:00
data.assemble()?;
2022-07-17 18:24:49 +00:00
2022-08-26 13:02:48 +00:00
if let Some(x) = bin {
2022-09-02 09:33:46 +00:00
File::create(x)?.write_all(&data.program)?;
2022-07-17 18:24:49 +00:00
}
if dump {
println!("{}", rhexdump::hexdump(&data.program));
}
2022-09-02 09:33:46 +00:00
Ok(())
2022-07-17 18:24:49 +00:00
}
Commands::Run { bin } => {
2022-09-02 09:33:46 +00:00
let mut program_buf: Vec<u8> = vec![];
let file = File::open(bin)?;
BufReader::new(file).read_to_end(&mut program_buf)?;
2022-07-17 18:24:49 +00:00
if program_buf.len() < (32 * 1024) {
program_buf.append(&mut vec![0; 32 * 1024 - program_buf.len()]);
}
2022-09-02 09:33:46 +00:00
let program: [u8; 32 * 1024] = (&program_buf[0..(32 * 1024)]).try_into()?;
2022-07-17 18:24:49 +00:00
let mut data = emulator::Data::new(program);
2022-09-02 09:33:46 +00:00
emulator::emulate(&mut data)?;
Ok(())
2022-07-17 18:24:49 +00:00
}
}
}
2022-09-02 09:33:46 +00:00
#[cfg(test)]
mod tests {}