///|
pub(all) enum ReplResult {
ReplAccepted(Value, Array[String])
ReplRejected(Array[Diagnostic])
}
///|
/// A deterministic incremental console. Accepted submissions are replayed as
/// one program, so declarations and assignments remain visible while failed
/// submissions leave the session unchanged.
pub struct ReplSession {
mut history : String
mut prior_output_lines : Int
max_steps : Int
}
///|
pub fn ReplSession::new(max_steps : Int) -> ReplSession {
{ history: "", prior_output_lines: 0, max_steps, }
}
///|
pub fn ReplSession::submit(self : ReplSession, source : String) -> ReplResult {
let candidate = if self.history.length() == 0 {
source + "\n"
} else {
self.history + source + "\n"
}
match run_with_limit(candidate, self.max_steps) {
ProgramFailed(issues, _) => ReplRejected(issues)
ProgramCompleted(value, output) => {
let fresh : Array[String] = []
for index = self.prior_output_lines
index < output.length()
index = index + 1 {
fresh.push(output[index])
}
self.history = candidate
self.prior_output_lines = output.length()
ReplAccepted(value, fresh)
}
}
}
///|
pub fn ReplSession::reset(self : ReplSession) -> Unit {
self.history = ""
self.prior_output_lines = 0
}
///|
pub fn ReplSession::source(self : ReplSession) -> String {
self.history
}