2022-01-27 05:30:16 +00:00
|
|
|
use std::{fs::{read_to_string, File}, path::{Path, PathBuf}, io::{Write, Seek}, time::Instant, process::exit};
|
2022-01-24 20:08:41 +00:00
|
|
|
|
|
|
|
use structopt::StructOpt;
|
|
|
|
|
|
|
|
mod args;
|
|
|
|
use args::Args;
|
2022-01-21 23:43:50 +00:00
|
|
|
|
|
|
|
mod util;
|
2022-01-23 21:42:08 +00:00
|
|
|
use util::cover_paren;
|
|
|
|
|
2022-01-26 01:45:59 +00:00
|
|
|
mod compiler;
|
2022-01-26 08:35:40 +00:00
|
|
|
use compiler::{compile::Compiler, parser::{tokenize, Parser}};
|
2022-01-26 08:07:53 +00:00
|
|
|
|
|
|
|
mod vm;
|
2022-01-27 05:30:16 +00:00
|
|
|
use vm::{vm::VM, parser::parse_instr};
|
2022-01-25 22:06:57 +00:00
|
|
|
|
2022-01-21 23:43:50 +00:00
|
|
|
fn main() {
|
2022-01-26 04:05:42 +00:00
|
|
|
let start = Instant::now();
|
2022-01-24 20:08:41 +00:00
|
|
|
let args = Args::from_args();
|
2022-01-27 05:42:55 +00:00
|
|
|
|
|
|
|
let debug = match args.verbose {
|
|
|
|
0 => false,
|
|
|
|
1 => true,
|
|
|
|
2 => true,
|
|
|
|
_ => true,
|
|
|
|
};
|
2022-01-23 21:42:08 +00:00
|
|
|
|
2022-01-26 08:35:40 +00:00
|
|
|
match (args.compile, args.run) {
|
|
|
|
(true, true) => {
|
|
|
|
eprintln!("TODO: Compile and run at the same time.");
|
|
|
|
std::process::exit(1);
|
|
|
|
},
|
|
|
|
// Compile
|
|
|
|
(true, false) => {
|
|
|
|
let src = read_to_string(&args.file).unwrap();
|
2022-01-27 08:25:21 +00:00
|
|
|
compile_src(src, args.output, args.file, debug, start);
|
2022-01-26 08:35:40 +00:00
|
|
|
},
|
|
|
|
// Run
|
|
|
|
(false, true) => {
|
|
|
|
let src = read_to_string(&args.file).unwrap();
|
2022-01-27 05:42:55 +00:00
|
|
|
run_src(src, debug);
|
2022-01-26 08:35:40 +00:00
|
|
|
},
|
|
|
|
(false, false) => {
|
|
|
|
if args.file.extension() == Some("blsp".as_ref()) {
|
|
|
|
let src = read_to_string(&args.file).unwrap();
|
2022-01-27 08:25:21 +00:00
|
|
|
compile_src(src, args.output, args.file, debug, start);
|
2022-01-26 08:35:40 +00:00
|
|
|
} else if args.file.extension() == Some("bsm".as_ref()) {
|
|
|
|
let src = read_to_string(&args.file).unwrap();
|
2022-01-27 05:42:55 +00:00
|
|
|
run_src(src, debug);
|
2022-01-26 08:35:40 +00:00
|
|
|
} else {
|
|
|
|
panic!("No mode specified");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-01-27 08:25:21 +00:00
|
|
|
fn compile_src(src: String, path: Option<PathBuf>, file: PathBuf, debug: bool, start: Instant) {
|
2022-01-26 08:35:40 +00:00
|
|
|
let file_name = match path {
|
2022-01-26 08:07:53 +00:00
|
|
|
Some(path) => path,
|
2022-01-26 08:35:40 +00:00
|
|
|
None => Path::new(&file).to_path_buf(),
|
2022-01-26 08:07:53 +00:00
|
|
|
}.file_stem().unwrap().to_str().unwrap().to_string();
|
2022-01-23 21:42:08 +00:00
|
|
|
|
2022-01-26 08:35:40 +00:00
|
|
|
let tokens = tokenize(&cover_paren(src));
|
2022-01-24 20:08:41 +00:00
|
|
|
let mut parser = Parser::new(tokens.clone());
|
2022-01-23 21:42:08 +00:00
|
|
|
let result = parser.parse();
|
2022-01-27 08:25:21 +00:00
|
|
|
|
|
|
|
if debug { println!("{:#?}", &result); }
|
2022-01-26 08:07:53 +00:00
|
|
|
match result {
|
|
|
|
Ok(ast) => {
|
2022-01-26 08:35:40 +00:00
|
|
|
let mut compiler = Compiler::new();
|
|
|
|
let code = compiler.compile(ast, 0);
|
|
|
|
match code {
|
|
|
|
Ok(code) => {
|
|
|
|
let mut file = File::create(format!("{}.bsm", file_name)).unwrap();
|
|
|
|
for line in code {
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2022-01-26 04:05:42 +00:00
|
|
|
},
|
2022-01-26 08:07:53 +00:00
|
|
|
Err(e) => {
|
|
|
|
eprintln!("{}", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-26 04:05:42 +00:00
|
|
|
|
2022-01-27 05:42:55 +00:00
|
|
|
fn run_src(src: String, debug: bool) {
|
2022-01-26 08:35:40 +00:00
|
|
|
let instrs = parse_instr(&src);
|
2022-01-27 05:30:16 +00:00
|
|
|
let mut vm = VM::new();
|
2022-01-27 05:42:55 +00:00
|
|
|
match vm.run(instrs, debug) {
|
2022-01-27 05:30:16 +00:00
|
|
|
Ok(()) => {
|
|
|
|
exit(0);
|
|
|
|
},
|
|
|
|
Err(e) => {
|
|
|
|
eprintln!("{}", e);
|
|
|
|
exit(1);
|
|
|
|
}
|
2022-01-24 20:08:41 +00:00
|
|
|
}
|
2022-01-21 23:43:50 +00:00
|
|
|
}
|