Carl Friedrich Bolz  committed aa127d3

fix exceptions when variables occur

  • Participants
  • Parent commits f18f2cc
  • Branches default

Comments (0)

Files changed (3)

File prolog/builtin/

     scont = continuation.CutScopeNotifier(engine, scont, fcont)
     scont = continuation.BodyContinuation(engine, module, scont, goal)
     #continuation.view(scont, fcont, heap)
-    return scont, fcont, heap
+    return scont, fcont, heap.branch()
 @expose_builtin("throw", unwrap_spec=["obj"], handles_continuation=True)
 def impl_throw(engine, heap, exc, scont, fcont):

File prolog/interpreter/

     def throw(self, exc, scont, fcont, heap):
-        # XXX write tests for catching non-ground things
+        from prolog.interpreter import memo
+        # copy to make sure that variables in the exception that are
+        # backtracked by the revert_upto below have the right value.
+        exc = exc.copy(heap, memo.CopyMemo())
         while not scont.is_done():
             if not isinstance(scont, CatchingDelimiter):
                 scont = scont.nextcont

File prolog/interpreter/test/

     e = get_engine('f :- repeat, !, fail.')
     assert_false('f.', e)
     assert_true('f; true.', e)
 def test_exception_handling():
     assert_true("catch(f, E, true).")
     assert_true("catch(catch(throw(error), failure, fail), error, true).")
     assert_true("catch((X = y, throw(X)), E, E == y).")
+def test_exception_forces_backtracking():
+    assert_true("catch((X = 1, throw(f(X))), Y, (var(X), Y == f(1))), var(X).")
 def test_between():
     assert_true("between(12, 15, 12).")
     assert_true("between(-5, 15, 0).")