From e4cc54104e8f41606e39bcca5df60abfcfff4a93 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 4 Mar 2019 22:34:17 -0700 Subject: [PATCH] add another test, add unwind_protect! --- src/prolog/machine/compile.rs | 12 ++++++++---- src/prolog/macros.rs | 9 +++++++++ src/tests.rs | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 91882632..77a460b4 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -219,11 +219,13 @@ impl ListingCompiler { let mod_name = self.get_module_name(); if let Some(mut submodule) = wam_indices.take_module(submodule) { - indices.use_module(code_repo, flags, &submodule)?; + unwind_protect!(indices.use_module(code_repo, flags, &submodule), + wam_indices.insert_module(submodule)); if let &mut Some(ref mut module) = &mut self.module { module.remove_module(mod_name, &submodule); - module.use_module(code_repo, flags, &submodule)?; + unwind_protect!(module.use_module(code_repo, flags, &submodule), + wam_indices.insert_module(submodule)); } else { submodule.inserted_expansions = true; wam_indices.remove_module(clause_name!("user"), &submodule); @@ -243,11 +245,13 @@ impl ListingCompiler { let mod_name = self.get_module_name(); if let Some(mut submodule) = wam_indices.take_module(submodule) { - indices.use_qualified_module(code_repo, flags, &submodule, exports)?; + unwind_protect!(indices.use_qualified_module(code_repo, flags, &submodule, exports), + wam_indices.insert_module(submodule)); if let &mut Some(ref mut module) = &mut self.module { module.remove_module(mod_name, &submodule); - module.use_qualified_module(code_repo, flags, &submodule, exports)?; + unwind_protect!(module.use_qualified_module(code_repo, flags, &submodule, exports), + wam_indices.insert_module(submodule)); } else { submodule.inserted_expansions = true; wam_indices.remove_module(clause_name!("user"), &submodule); diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index f1cc166e..c8f5ddf3 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -244,6 +244,15 @@ macro_rules! get_level_and_unify { ) } +macro_rules! unwind_protect { + ($e: expr, $protected: expr) => ( + match $e { + Err(e) => { $protected; return Err(e); }, + _ => {} + } + ) +} + macro_rules! discard_result { ($f: expr) => ( match $f { diff --git a/src/tests.rs b/src/tests.rs index fdd92c49..b2ece073 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1898,6 +1898,20 @@ foo(X) :- call(X) -> call(X)."); assert_prolog_failure!(&mut wam, "?- retract( (atom(X) :- X == '[]') )."); assert_prolog_success!(&mut wam, "?- catch(retract( (atom(X) :- X == '[]') ), error(permission_error(modify, static_procedure, atom/1), _), true)."); + /* This example shows why machine::compile::localize_self_calls is necessary. */ +submit(&mut wam, " +:- dynamic(p/1). + +p(a). +p(b). +p(c) :- p(d). +p(d)."); + + assert_prolog_success!(&mut wam, "?- p(X), retract(p(_)).", + [["X = a"], + ["X = a"], + ["X = a"]]); + submit(&mut wam, " :- dynamic(foo/1). foo(X) :- call(X), call(X). -- 2.54.0