2022-04-19 00:46:33 +02:00
|
|
|
use clap::Parser;
|
2022-05-01 19:26:17 +02:00
|
|
|
use crftng_intrprtrs::interpreter::world::World;
|
|
|
|
use crftng_intrprtrs::{lex, parse};
|
2022-04-19 00:46:33 +02:00
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::{fs, io};
|
2022-03-21 15:47:35 +01:00
|
|
|
use tracing::Level;
|
|
|
|
use tracing_subscriber::{EnvFilter, FmtSubscriber};
|
|
|
|
|
2022-04-19 00:46:33 +02:00
|
|
|
#[derive(Parser, Debug)]
|
|
|
|
struct Args {
|
|
|
|
#[clap(parse(from_os_str))]
|
|
|
|
file: Option<PathBuf>,
|
|
|
|
|
|
|
|
#[clap(short)]
|
|
|
|
dump_ast: bool,
|
|
|
|
#[clap(short)]
|
|
|
|
no_run: bool,
|
|
|
|
}
|
|
|
|
|
2022-05-01 19:26:17 +02:00
|
|
|
fn run(code: &str, args: &Args, world: &mut World) {
|
2022-04-19 00:46:33 +02:00
|
|
|
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 {
|
2022-05-01 19:26:17 +02:00
|
|
|
println!("{:?}", world.exec(ast));
|
2022-04-19 00:46:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run_file(args: &Args) -> Result<(), io::Error> {
|
|
|
|
let src = fs::read_to_string(args.file.as_ref().unwrap())?;
|
2022-05-01 19:26:17 +02:00
|
|
|
run(&src, args, &mut World::new());
|
2022-03-21 15:47:35 +01:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2022-04-19 00:46:33 +02:00
|
|
|
fn run_repl(args: &Args) {
|
|
|
|
assert!(args.file.is_none());
|
|
|
|
|
2022-05-01 19:26:17 +02:00
|
|
|
let mut world = World::new();
|
2022-03-21 18:42:47 +01:00
|
|
|
let mut line_buf = String::new();
|
2022-03-21 15:47:35 +01:00
|
|
|
loop {
|
|
|
|
match io::stdin().read_line(&mut line_buf) {
|
2022-04-02 21:36:06 +02:00
|
|
|
Ok(n) => {
|
|
|
|
// Check for EOF
|
|
|
|
if n == 0 {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-03-21 15:47:35 +01:00
|
|
|
let line = line_buf.trim();
|
2022-04-02 21:36:06 +02:00
|
|
|
if !line.is_empty() {
|
2022-05-01 19:26:17 +02:00
|
|
|
run(&line_buf, args, &mut world);
|
2022-04-02 21:36:06 +02:00
|
|
|
line_buf.clear();
|
|
|
|
}
|
2022-03-21 15:47:35 +01:00
|
|
|
}
|
2022-04-02 21:36:06 +02:00
|
|
|
Err(e) => panic!("{:?}", e),
|
2022-03-21 15:47:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
dotenv::dotenv().ok();
|
2022-04-02 21:23:47 +02:00
|
|
|
color_eyre::install().expect("Failed to install color-eyre");
|
2022-03-21 15:47:35 +01:00
|
|
|
let subscriber = FmtSubscriber::builder()
|
|
|
|
.with_max_level(Level::TRACE)
|
|
|
|
.with_env_filter(EnvFilter::from_env("LOG"))
|
|
|
|
.finish();
|
2022-04-02 21:23:47 +02:00
|
|
|
|
2022-03-21 15:47:35 +01:00
|
|
|
tracing::subscriber::set_global_default(subscriber).unwrap();
|
|
|
|
|
2022-04-19 00:46:33 +02:00
|
|
|
let args = Args::parse();
|
|
|
|
|
|
|
|
if args.file.is_some() {
|
|
|
|
run_file(&args).unwrap();
|
2022-03-21 15:47:35 +01:00
|
|
|
} else {
|
2022-04-19 00:46:33 +02:00
|
|
|
run_repl(&args)
|
2022-03-21 15:47:35 +01:00
|
|
|
}
|
|
|
|
}
|