From: Mark Thom Date: Mon, 26 Feb 2018 06:43:37 +0000 (-0700) Subject: fix exception handling when thrown by throw_exception, and within setup_call_cleanup... X-Git-Tag: v0.8.110~549 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=07675b3675fa4042584055b1e9b5c4410e61f4c6;p=scryer-prolog.git fix exception handling when thrown by throw_exception, and within setup_call_cleanup and call_with_inference_limit. --- diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index 1b719c2b..9721aea1 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -951,7 +951,8 @@ pub enum ArithmeticInstruction { pub enum BuiltInInstruction { CleanUpBlock, - CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm), + CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm), + DefaultRetryMeElse(usize), DefaultTrustMe, DefaultSetCutPoint(RegType), DynamicCompareNumber(CompareNumberQT), diff --git a/src/prolog/builtins.rs b/src/prolog/builtins.rs index feff8fa4..2ad9fa70 100644 --- a/src/prolog/builtins.rs +++ b/src/prolog/builtins.rs @@ -48,7 +48,7 @@ fn get_builtins() -> Code { put_unsafe_value!(1, 2)], deallocate!(), goto_execute!(44, 2), //21: goto end_block/2. - trust_me!(), + default_trust_me!(), allocate!(3), fact![get_var_in_fact!(perm_v!(2), 2), get_var_in_fact!(perm_v!(1), 3)], @@ -72,7 +72,7 @@ fn get_builtins() -> Code { query![put_value!(perm_v!(2), 1)], deallocate!(), execute_n!(1), - trust_me!(), + default_trust_me!(), unwind_stack!(), try_me_else!(9), // end_block/2, 44. allocate!(1), @@ -83,7 +83,7 @@ fn get_builtins() -> Code { deallocate!(), reset_block!(), proceed!(), - trust_me!(), // 53. + default_trust_me!(), // 53. allocate!(0), query![get_var_in_query!(temp_v!(3), 1), put_value!(temp_v!(2), 1)], @@ -446,7 +446,7 @@ fn get_builtins() -> Code { atom!("instantiation_error"), temp_v!(1))], goto_execute!(59, 1), - trust_me!(), + default_trust_me!(), query![get_var_in_query!(temp_v!(4), 2), put_value!(temp_v!(3), 2), get_var_in_query!(temp_v!(5), 3), @@ -468,7 +468,7 @@ fn get_builtins() -> Code { put_value!(perm_v!(1), 2)], deallocate!(), check_cp_execute!(), - retry_me_else!(12), + default_retry_me_else!(12), allocate!(2), query![put_value!(temp_v!(3), 1)], reset_block!(), @@ -480,7 +480,7 @@ fn get_builtins() -> Code { query![put_unsafe_value!(1, 1)], deallocate!(), goto_execute!(59, 1), // goto throw/1, 59. - trust_me!(), + default_trust_me!(), allocate!(0), goto_call!(354, 0), // goto run_cleaners_without_handling/0, 354. deallocate!(), @@ -497,7 +497,7 @@ fn get_builtins() -> Code { default_set_cp!(perm_v!(1)), deallocate!(), goto_execute!(342, 0), // goto run_cleaners_with_handling/0, 342. - trust_me!(), + default_trust_me!(), goto_execute!(382, 0), // goto restore_cut_points/0, 382. try_me_else!(10), // run_cleaners_without_handling/1, 354. allocate!(2), @@ -509,7 +509,7 @@ fn get_builtins() -> Code { default_set_cp!(perm_v!(1)), deallocate!(), goto_execute!(354, 0), // goto run_cleaners_without_handling/0, 354. - trust_me!(), + default_trust_me!(), goto_execute!(382, 0), // goto restore_cut_points/0, 382. allocate!(1), // sgc_on_success/2, 366. fact![get_var_in_fact!(perm_v!(1), 2)], diff --git a/src/prolog/io.rs b/src/prolog/io.rs index a91c8603..71139aea 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -207,6 +207,8 @@ impl fmt::Display for BuiltInInstruction { write!(f, "clean_up_block"), &BuiltInInstruction::DefaultSetCutPoint(r) => write!(f, "default_set_cp {}", r), + &BuiltInInstruction::DefaultRetryMeElse(o) => + write!(f, "default_retry_me_else {}", o), &BuiltInInstruction::DefaultTrustMe => write!(f, "default_trust_me"), &BuiltInInstruction::InstallInferenceCounter(r1, r2, r3) => diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 55e5fcc8..b5f9838b 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -71,7 +71,7 @@ pub(super) struct DuplicateBallTerm<'a> { impl<'a> DuplicateBallTerm<'a> { pub(super) fn new(state: &'a mut MachineState) -> Self { let hb = state.heap.len(); - DuplicateBallTerm { state: state, heap_boundary: hb } + DuplicateBallTerm { state, heap_boundary: hb } } } diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 4cc71ee7..7bb6be19 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -216,7 +216,7 @@ impl MachineState { let tr = self.tr; let val = self.trail[tr - 1]; self.trail[i] = val; - self.tr -= 1; // NEW. + self.tr -= 1; }, Ref::StackCell(fr, _) => { let b = self.b - 1; @@ -233,7 +233,7 @@ impl MachineState { let tr = self.tr; let val = self.trail[tr - 1]; self.trail[i] = val; - self.tr -= 1; // NEW. + self.tr -= 1; } } }; @@ -937,6 +937,9 @@ impl MachineState { fn throw_exception(&mut self, hcv: Vec) { let h = self.heap.h; + self.ball.0 = 0; + self.ball.1.truncate(0); + self.registers[1] = Addr::HeapCell(h); self.heap.append(hcv); @@ -1219,8 +1222,12 @@ impl MachineState { self.compare_numbers(cmp, n1, n2); }, &BuiltInInstruction::DefaultSetCutPoint(r) => { - let mut default_cut_policy = DefaultCutPolicy {}; - default_cut_policy.cut(self, r); + let mut cut_policy = DefaultCutPolicy {}; + cut_policy.cut(self, r); + }, + &BuiltInInstruction::DefaultRetryMeElse(o) => { + let mut call_policy = DefaultCallPolicy {}; + try_or_fail!(self, call_policy.retry_me_else(self, o)); }, &BuiltInInstruction::DefaultTrustMe => { let mut call_policy = DefaultCallPolicy {}; diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index d06aa922..fd0b5ea6 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -663,6 +663,12 @@ macro_rules! default_set_cp { ) } +macro_rules! default_retry_me_else { + ($o:expr) => ( + Line::BuiltIn(BuiltInInstruction::DefaultRetryMeElse($o)) + ) +} + macro_rules! default_trust_me { () => ( Line::BuiltIn(BuiltInInstruction::DefaultTrustMe) diff --git a/src/tests.rs b/src/tests.rs index d5f316ce..5b29072e 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1393,6 +1393,8 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "?- call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),display(S+G>B)), B=3, !), 100, R).", [["G = 2", "B = 3", "R = !", "S = 1"]]); + assert_prolog_success!(&mut wam, "?- call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),display(S+G>B)), B=3, !), 10, R).", + [["S = _1", "G = _4", "B = _14", "R = inference_limit_exceeded"]]); } #[test]