crftng-intrprtrs/src/main.rs

100 lines
1.9 KiB
Rust

use clap::Parser;
use crftng_intrprtrs::interpreter::world::World;
use crftng_intrprtrs::{lex, parse};
use std::path::PathBuf;
use std::{fs, io};
use tracing::Level;
use tracing_subscriber::{EnvFilter, FmtSubscriber};
#[derive(Parser, Debug)]
struct Args {
#[clap(parse(from_os_str))]
file: Option<PathBuf>,
#[clap(short)]
dump_ast: bool,
#[clap(short)]
no_run: bool,
}
fn run(code: &str, args: &Args, world: &mut World) {
let src_file = args.file.as_ref().map(|f| f.to_string_lossy().to_string());
let tokens = match lex(code, src_file.as_deref()) {
Ok(v) => v,
Err(e) => {
for error in e {
println!("{}", error);
}
return;
}
};
let ast = match parse(tokens) {
Ok(v) => v,
Err(e) => {
for error in e {
println!("{}", error);
}
return;
}
};
if args.dump_ast {
for node in &ast {
println!("{:?}", node);
}
}
if !args.no_run {
println!("{:?}", world.exec(ast));
}
}
fn run_file(args: &Args) -> Result<(), io::Error> {
let src = fs::read_to_string(args.file.as_ref().unwrap())?;
run(&src, args, &mut World::new());
Ok(())
}
fn run_repl(args: &Args) {
assert!(args.file.is_none());
let mut world = World::new();
let mut line_buf = String::new();
loop {
match io::stdin().read_line(&mut line_buf) {
Ok(n) => {
// Check for EOF
if n == 0 {
break;
}
let line = line_buf.trim();
if !line.is_empty() {
run(&line_buf, args, &mut world);
line_buf.clear();
}
}
Err(e) => panic!("{:?}", e),
}
}
}
fn main() {
dotenv::dotenv().ok();
color_eyre::install().expect("Failed to install color-eyre");
let subscriber = FmtSubscriber::builder()
.with_max_level(Level::TRACE)
.with_env_filter(EnvFilter::from_env("LOG"))
.finish();
tracing::subscriber::set_global_default(subscriber).unwrap();
let args = Args::parse();
if args.file.is_some() {
run_file(&args).unwrap();
} else {
run_repl(&args)
}
}