mod common;
use common::{Calc, Reply};
use diag_lang::Renderer;
use repl_lang::{Feed, Session};
enum Step {
Line(&'static str),
Interrupt,
}
const SCRIPT: &[Step] = &[
Step::Line("let rate = 7 # percent"),
Step::Line(""),
Step::Line("let principal = 2_500"),
Step::Line("let interest = principal * rate /"),
Step::Line(" 100"),
Step::Line("interest + principal"),
Step::Line("(principal -"),
Step::Interrupt,
Step::Line("let rate = 9"),
Step::Line("interest / (rate - 7)"),
Step::Line("2 ^ 64"),
Step::Line("1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16"),
];
fn main() {
let mut session = Session::with_limit(64);
let mut calc = Calc::new();
let renderer = Renderer::new();
for step in SCRIPT {
let line = match step {
Step::Line(line) => *line,
Step::Interrupt => {
if session.cancel() {
println!(" ^C (entry discarded)");
}
continue;
}
};
let cell = session.len() + 1;
if session.is_pending() {
println!(" ...: {line}");
} else {
println!("In [{cell}]: {line}");
}
match session.feed(line, |input| calc.run(input)) {
Ok(Feed::Complete { entry, value }) => {
let n = entry.number();
match value {
Ok(Reply::Value(v)) => println!("Out[{n}]: {v}"),
Ok(Reply::Bound { name, value }) => println!("Out[{n}]: {name} = {value}"),
Err(diagnostics) => {
for diagnostic in &diagnostics {
print!("{}", renderer.render(diagnostic, session.sources()));
}
}
}
println!();
}
Ok(Feed::Incomplete) => {}
Ok(Feed::Empty) => println!(),
Err(error) => println!("error: {error}\n"),
}
}
println!("The session holds {} entries:", session.len());
let indent = format!("\n{}", " ".repeat(12));
for (_, entry) in session.sources().iter() {
let text = entry.text().trim_end().replace('\n', &indent);
println!(" {:<9} {text}", entry.name());
}
}