49 lines
1.1 KiB
Rust
49 lines
1.1 KiB
Rust
use std::cell::RefCell;
|
|
|
|
use rustyline::error::ReadlineError;
|
|
use scoped_tls::scoped_thread_local;
|
|
|
|
use crate::parsing::{Interner, parse};
|
|
|
|
mod parsing;
|
|
|
|
#[derive(Default)]
|
|
struct Session {
|
|
interner: RefCell<Interner>,
|
|
}
|
|
|
|
scoped_thread_local!(static SESSION: Session);
|
|
|
|
fn with_session<R>(f: impl FnOnce(&Session) -> R) -> R {
|
|
SESSION.with(f)
|
|
}
|
|
|
|
fn create_session_then<R>(f: impl FnOnce() -> R) -> R {
|
|
assert!(!SESSION.is_set());
|
|
let session = Default::default();
|
|
SESSION.set(&session, f)
|
|
}
|
|
|
|
fn eval(line: &str) {
|
|
for expr in parse(line) {
|
|
println!("{expr:?}");
|
|
}
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
create_session_then(|| {
|
|
let mut rl = rustyline::DefaultEditor::new()?;
|
|
|
|
loop {
|
|
match rl.readline("> ") {
|
|
Ok(line) => {
|
|
rl.add_history_entry(line.clone())?;
|
|
eval(&line);
|
|
}
|
|
Err(ReadlineError::Interrupted) => (),
|
|
Err(ReadlineError::Eof) => break Ok(()),
|
|
Err(e) => break Err(e.into()),
|
|
}
|
|
}
|
|
})
|
|
}
|