use sim_kernel::{Cx, Ref, Result, Symbol};
use sim_lib_control::{ControlResultValue, LabeledPrompt, NonLocalExit, escape_to_label};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RubyBlockScope {
label: Symbol,
prompt: Ref,
}
impl RubyBlockScope {
pub fn new(label: Symbol) -> Self {
let prompt = Ref::Symbol(Symbol::qualified("ruby/block-prompt", label.to_string()));
Self { label, prompt }
}
pub fn label(&self) -> &Symbol {
&self.label
}
pub fn prompt(&self) -> &Ref {
&self.prompt
}
pub fn labeled_prompt(&self) -> LabeledPrompt {
LabeledPrompt::new(self.label.clone(), self.prompt.clone())
}
}
pub fn ruby_break(cx: &mut Cx, scope: &RubyBlockScope, value: Ref) -> Result<ControlResultValue> {
escape_to_label(
cx,
&[scope.labeled_prompt()],
NonLocalExit::break_to(scope.label.clone(), value),
)
}
pub fn ruby_next(cx: &mut Cx, scope: &RubyBlockScope, value: Ref) -> Result<ControlResultValue> {
escape_to_label(
cx,
&[scope.labeled_prompt()],
NonLocalExit::next_to(scope.label.clone(), value),
)
}