72 lines
2.1 KiB
Rust
72 lines
2.1 KiB
Rust
use std::{fs, panic::{self, PanicInfo}, process::ExitCode};
|
|
|
|
use backtrace::Backtrace;
|
|
use complexpr::{interpreter::interpret, env::Environment};
|
|
|
|
mod helper;
|
|
mod repl;
|
|
|
|
fn panic_hook(info: &PanicInfo) {
|
|
eprintln!("{:?}", Backtrace::new());
|
|
eprintln!("!!! Internal interpreter error occured !!!");
|
|
if let Some(s) = std::thread::current().name() {
|
|
eprintln!("Thread: {}", s);
|
|
}
|
|
if let Some(loc) = info.location() {
|
|
eprintln!("Location: {}:{}:{}", loc.file(), loc.line(), loc.column())
|
|
}
|
|
if let Some(s) = info.payload().downcast_ref::<&str>() {
|
|
eprintln!("Message: {}", s);
|
|
} else if let Some(s) = info.payload().downcast_ref::<String>() {
|
|
eprintln!("Message: {}", s);
|
|
}
|
|
}
|
|
|
|
fn create_env() -> Environment {
|
|
let mut env = Environment::new();
|
|
|
|
complexpr_stdlib::prelude::load(&mut env);
|
|
complexpr_stdlib::io::load(&mut env);
|
|
complexpr_stdlib::iter::load(&mut env);
|
|
complexpr_stdlib::math::load(&mut env);
|
|
|
|
env
|
|
}
|
|
|
|
fn main() -> ExitCode {
|
|
panic::set_hook(Box::new(panic_hook));
|
|
let args: Vec<String> = std::env::args().collect();
|
|
if args.len() >= 2 {
|
|
let fname = &args[1];
|
|
let src = match fs::read_to_string(fname) {
|
|
Ok(src) => src,
|
|
Err(e) => {
|
|
eprintln!("Error reading file: {}", e);
|
|
return ExitCode::from(2);
|
|
}
|
|
};
|
|
|
|
let env = create_env().wrap();
|
|
|
|
let res = interpret(&src, Some(fname.into()), Some(env), false);
|
|
if let Err(e) = res {
|
|
eprintln!("Error: {}", e);
|
|
return ExitCode::from(1);
|
|
}
|
|
} else {
|
|
#[cfg(feature = "repl")]
|
|
{
|
|
if let Err(e) = repl::repl() {
|
|
eprintln!("Error: {}", e);
|
|
return ExitCode::from(4)
|
|
}
|
|
}
|
|
#[cfg(not(feature = "repl"))]
|
|
{
|
|
eprintln!("Expected a file to execute. To use complexpr in repl mode, enable the 'repl' feature (enabled by default).");
|
|
return ExitCode::from(3)
|
|
}
|
|
}
|
|
ExitCode::SUCCESS
|
|
}
|