handball/src/main.rs

81 lines
2.0 KiB
Rust

#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(crate_visibility_modifier)]
#![feature(let_else)]
use std::cell::RefCell;
use std::io;
use std::rc::Rc;
use rustyline::validate::{
MatchingBracketValidator, ValidationContext, ValidationResult, Validator,
};
use rustyline::Editor;
use rustyline_derive::{Completer, Helper, Highlighter, Hinter};
mod ast;
mod eval;
#[allow(clippy::all)]
mod grammar;
mod prims;
#[cfg(test)]
mod tests;
mod value;
fn main() {
let args = std::env::args().collect::<Vec<_>>();
match &args[..] {
[_] => repl(),
[_, file] => run_file(file).unwrap(),
_ => panic!("To many args `{:?}`", args),
}
}
fn run_file(file: &str) -> io::Result<()> {
let src = std::fs::read_to_string(file)?;
let tree = grammar::FileParser::new().parse(&src).unwrap();
let env = Rc::new(RefCell::new(eval::default_env()));
for i in tree {
eval::eval(&i, Rc::clone(&env)).unwrap();
}
Ok(())
}
fn repl() {
let mut rl = Editor::new();
rl.set_helper(Some(InputValidator {
brackets: MatchingBracketValidator::new(),
}));
let env = Rc::new(RefCell::new(eval::default_env()));
while let Ok(line) = rl.readline("> ") {
rl.add_history_entry(&line);
let tree = grammar::TreeParser::new().parse(&line).unwrap();
// dbg!(&tree);
match eval::eval(&tree, Rc::clone(&env)) {
Ok(v) => {
// Cant use == because it will panic. This is the only
// valid comparison to trap
if !matches!(v, value::Value::Trap) {
println!("{}", v)
}
}
Err(e) => println!("! {}", e.0),
}
}
}
#[derive(Completer, Helper, Highlighter, Hinter)]
struct InputValidator {
brackets: MatchingBracketValidator,
}
impl Validator for InputValidator {
fn validate(&self, ctx: &mut ValidationContext) -> rustyline::Result<ValidationResult> {
self.brackets.validate(ctx)
}
}