#![warn(anonymous_parameters, bad_style, missing_docs)]
#![warn(
unused,
unused_extern_crates,
unused_import_braces,
unused_qualifications
)]
#![warn(unsafe_code)]
use endbasic;
use failure::Fallible;
use std::env;
use std::fs::File;
use std::io::{self, BufRead, Write};
use std::path::Path;
use std::process;
fn program_name(mut args: env::Args, default_name: &'static str) -> (String, env::Args) {
let name = match args.next() {
Some(arg0) => match Path::new(&arg0).file_stem() {
Some(basename) => match basename.to_str() {
Some(s) => s.to_owned(),
None => default_name.to_owned(),
},
None => default_name.to_owned(),
},
None => default_name.to_owned(),
};
(name, args)
}
#[derive(Default)]
struct StdioConsole {}
impl endbasic::Console for StdioConsole {
fn input(&mut self, prompt: &str) -> Fallible<String> {
if !prompt.is_empty() {
print!("{}", prompt);
io::stdout().lock().flush()?;
}
let mut answer = String::new();
{
let stdin = io::stdin();
let mut handle = stdin.lock();
handle.read_line(&mut answer)?;
}
Ok(answer.trim_end().to_owned())
}
fn print(&mut self, text: &str) -> Fallible<()> {
println!("{}", text);
Ok(())
}
}
fn run<P: AsRef<Path>>(path: P) -> Fallible<()> {
let mut console = StdioConsole::default();
let mut machine = endbasic::Machine::new(&mut console);
let mut input = File::open(path)?;
machine.exec(&mut input)
}
fn main() {
let (progname, args) = program_name(env::args(), "endbasic");
let args: Vec<String> = args.collect();
match args.as_slice() {
[file] => match run(file) {
Ok(()) => (),
Err(e) => {
eprintln!("{}: E: Execution failed: {}", progname, e);
process::exit(1);
}
},
[_, ..] => {
eprintln!("{}: E: Too many arguments", progname);
process::exit(1);
}
[] => {
eprintln!("{}: E: No program specified", progname);
process::exit(1);
}
}
}