From 5d6ca7a88e4c9bf4bc8793d1e8184c90ef109275 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 19 Apr 2020 12:58:44 -0600 Subject: [PATCH] throw '' whenever an interrupt is made (#365, #366) --- src/prolog/lib/iso_ext.pl | 4 ++-- src/prolog/machine/machine_errors.rs | 12 ++++++++++++ src/prolog/machine/machine_state_impl.rs | 11 +++++++++-- src/prolog/toplevel.pl | 3 +++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/prolog/lib/iso_ext.pl b/src/prolog/lib/iso_ext.pl index a1944d13..68708250 100644 --- a/src/prolog/lib/iso_ext.pl +++ b/src/prolog/lib/iso_ext.pl @@ -22,9 +22,9 @@ bb_put(Key, _) :- throw(error(type_error(atom, Key), bb_put/2)). bb_b_put(Key, NewValue) :- ( '$bb_get_with_offset'(Key, OldValue, OldOffset) -> 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), - 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). diff --git a/src/prolog/machine/machine_errors.rs b/src/prolog/machine/machine_errors.rs index c5173afc..68b7a3ff 100644 --- a/src/prolog/machine/machine_errors.rs +++ b/src/prolog/machine/machine_errors.rs @@ -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) fn evaluation_error(eval_error: EvalError) -> Self { let stub = functor!("evaluation_error", [atom(eval_error.as_str())]); diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 941fa4cb..dfcb08be 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -3089,6 +3089,14 @@ impl MachineState { 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( &mut self, indices: &mut IndexStore, @@ -3105,8 +3113,7 @@ impl MachineState { let interrupted = INTERRUPT.load(std::sync::atomic::Ordering::Relaxed); if INTERRUPT.compare_and_swap(interrupted, false, std::sync::atomic::Ordering::Relaxed) { - self.reset(); - self.fail = true; + self.throw_interrupt_exception(); return; } diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index d826b1b5..099bc9f9 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -214,6 +214,9 @@ gather_goals([Var = Value | Pairs], VarList, Goals) :- ). 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)]), writeq(E), nl. -- 2.54.0