throw '' whenever an interrupt is made (#365, #366)

This commit is contained in:
Mark Thom
2020-04-19 12:58:44 -06:00
parent 3798dcb98d
commit 5d6ca7a88e
4 changed files with 26 additions and 4 deletions

View File

@@ -22,9 +22,9 @@ bb_put(Key, _) :- throw(error(type_error(atom, Key), bb_put/2)).
bb_b_put(Key, NewValue) :- bb_b_put(Key, NewValue) :-
( '$bb_get_with_offset'(Key, OldValue, OldOffset) -> ( '$bb_get_with_offset'(Key, OldValue, OldOffset) ->
call_cleanup((store_global_var_with_offset(Key, NewValue) ; false), call_cleanup((store_global_var_with_offset(Key, NewValue) ; false),
reset_global_var_at_offset(Key, OldValue, OldOffset)) reset_global_var_at_offset(Key, OldValue, OldOffset))
; call_cleanup((store_global_var_with_offset(Key, NewValue) ; false), ; call_cleanup((store_global_var_with_offset(Key, NewValue) ; false),
reset_global_var_at_key(Key)) reset_global_var_at_key(Key))
). ).
store_global_var_with_offset(Key, Value) :- '$store_global_var_with_offset'(Key, Value). store_global_var_with_offset(Key, Value) :- '$store_global_var_with_offset'(Key, Value).

View File

@@ -154,6 +154,18 @@ impl MachineError {
) )
} }
#[inline]
pub(super)
fn interrupt_error() -> Self {
let stub = functor!("$interrupt_thrown");
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
pub(super) pub(super)
fn evaluation_error(eval_error: EvalError) -> Self { fn evaluation_error(eval_error: EvalError) -> Self {
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]); let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);

View File

@@ -3089,6 +3089,14 @@ impl MachineState {
self.p += 1; self.p += 1;
} }
fn throw_interrupt_exception(&mut self) {
let err = MachineError::interrupt_error();
let src = functor!("repl");
let err = self.error_form(err, src);
self.throw_exception(err);
}
fn handle_call_clause( fn handle_call_clause(
&mut self, &mut self,
indices: &mut IndexStore, indices: &mut IndexStore,
@@ -3105,8 +3113,7 @@ impl MachineState {
let interrupted = INTERRUPT.load(std::sync::atomic::Ordering::Relaxed); let interrupted = INTERRUPT.load(std::sync::atomic::Ordering::Relaxed);
if INTERRUPT.compare_and_swap(interrupted, false, std::sync::atomic::Ordering::Relaxed) { if INTERRUPT.compare_and_swap(interrupted, false, std::sync::atomic::Ordering::Relaxed) {
self.reset(); self.throw_interrupt_exception();
self.fail = true;
return; return;
} }

View File

@@ -214,6 +214,9 @@ gather_goals([Var = Value | Pairs], VarList, Goals) :-
). ).
print_exception(E) :- print_exception(E) :-
( E == error('$interrupt_thrown', repl) -> nl % print the exception on a newline to evade "^C".
; true
),
write_term('caught: ', [quoted(false), max_depth(20)]), write_term('caught: ', [quoted(false), max_depth(20)]),
writeq(E), writeq(E),
nl. nl.