1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-09-28 09:17:41 +00:00
bobbylisp/blspc/src/main.rs

85 lines
2.4 KiB
Rust

use std::{fs::{read_to_string, File}, path::{Path, PathBuf}, io::{Write, Seek}, time::Instant, process::exit};
use structopt::StructOpt;
mod args;
use args::Opts;
mod util;
use util::cover_paren;
mod compiler;
use compiler::{compile::Compiler, parser::{tokenize, Parser}};
mod vm;
use vm::{vm::VM, parser::parse_instr};
fn main() {
let start = Instant::now();
let args = Opts::from_args();
match args.commands {
args::Args::Compile(args) => {
let src = read_to_string(&args.file).unwrap();
let debug = args.debug;
compile_src(src, args.output, args.file, debug, start);
},
args::Args::Run(args) => {
let src = read_to_string(&args.file).unwrap();
let debug = args.debug;
run_src(src, debug);
},
}
}
fn compile_src(src: String, path: Option<PathBuf>, file: PathBuf, debug: bool, start: Instant) {
let file_name = match path {
Some(path) => path,
None => Path::new(&file).to_path_buf(),
}.file_stem().unwrap().to_str().unwrap().to_string();
let tokens = tokenize(&cover_paren(src));
let mut parser = Parser::new(tokens.clone());
let result = parser.parse();
if debug { println!("{:#?}", &result); }
match result {
Ok(ast) => {
let mut compiler = Compiler::new();
let code = compiler.compile(ast);
match code {
Ok(code) => {
let mut file = File::create(format!("{}.bsm", file_name)).unwrap();
for line in code {
if line.to_string().starts_with(";") { continue; }
write!(file, "{}\n", line).unwrap();
}
file.seek(std::io::SeekFrom::End(-1)).unwrap(); // Trim last newline
let elapsed = start.elapsed();
println!("Compiled in {}.{}s", elapsed.as_secs(), elapsed.subsec_millis());
},
Err(err) => {
eprintln!("{}", err);
}
}
},
Err(e) => {
eprintln!("{}", e);
}
}
}
fn run_src(src: String, debug: bool) {
let instrs = parse_instr(&src);
let mut vm = VM::new();
match vm.run(instrs, debug) {
Ok(()) => {
exit(0);
},
Err(e) => {
eprintln!("{}", e);
exit(1);
}
}
}