>From 641a075ed3bb077731f0971048c807f350caba2c Mon Sep 17 00:00:00 2001 From: Matt Lilley Date: Thu, 15 Dec 2011 10:57:48 +1300 Subject: [PATCH] Support executing cleanup code when backtracking Support executing cleanup code when backtracking --- src/gnu/prolog/vm/BacktrackInfoWithCleanup.java | 63 +++++++++++++++++++++++ src/gnu/prolog/vm/Interpreter.java | 12 ++++ 2 files changed, 75 insertions(+), 0 deletions(-) create mode 100644 src/gnu/prolog/vm/BacktrackInfoWithCleanup.java diff --git a/src/gnu/prolog/vm/BacktrackInfoWithCleanup.java b/src/gnu/prolog/vm/BacktrackInfoWithCleanup.java new file mode 100644 index 0000000..57e78b6 --- /dev/null +++ b/src/gnu/prolog/vm/BacktrackInfoWithCleanup.java @@ -0,0 +1,63 @@ +/* GNU Prolog for Java + * Copyright (C) 1997-1999 Constantine Plotnikov + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. The text of license can be also found + * at http://www.gnu.org/copyleft/lgpl.html + */ +package gnu.prolog.vm; + +import gnu.prolog.term.Term; + +/** back track information with cleanup information included */ +public class BacktrackInfoWithCleanup extends BacktrackInfo +{ + /** + * a constructor + * + * @param undoPosition + * address@hidden #undoPosition} + * @param codePosition + * address@hidden #codePosition} + * @param cleanup + * address@hidden #codePosition} + * */ + public BacktrackInfoWithCleanup(int undoPosition, int codePosition, Term cleanup) + { + super(undoPosition, codePosition); + this.cleanup = cleanup; + } + + public BacktrackInfoWithCleanup(BacktrackInfo backtrackInfo, Term cleanup) + { + super(backtrackInfo.undoPosition, backtrackInfo.codePosition); + this.cleanup = cleanup; + } + + private Term cleanup; + + public void cleanup(Interpreter interpreter) + { + if (cleanup != null) + { + try + { + gnu.prolog.vm.interpreter.Predicate_call.staticExecute(interpreter, false, cleanup); + } + catch(PrologException e) + { + /* Ignore exceptions and return status for cleanup */ + } + } + } +} diff --git a/src/gnu/prolog/vm/Interpreter.java b/src/gnu/prolog/vm/Interpreter.java index da1be1e..7d148d2 100644 --- a/src/gnu/prolog/vm/Interpreter.java +++ b/src/gnu/prolog/vm/Interpreter.java @@ -142,6 +142,10 @@ public final class Interpreter implements HasEnvironment public BacktrackInfo popBacktrackInfo() { BacktrackInfo rc = backtrackInfoStack[--backtrackInfoAmount]; + if (rc instanceof BacktrackInfoWithCleanup) + { + ((BacktrackInfoWithCleanup)rc).cleanup(this); + } backtrackInfoStack[backtrackInfoAmount] = null; return rc; } @@ -159,6 +163,10 @@ public final class Interpreter implements HasEnvironment } for (int i = pos + 1; i < backtrackInfoAmount; i++) { + if (backtrackInfoStack[i] instanceof BacktrackInfoWithCleanup) + { + ((BacktrackInfoWithCleanup)backtrackInfoStack[i]).cleanup(this); + } backtrackInfoStack[i] = null; } backtrackInfoAmount = pos + 1; @@ -606,6 +614,10 @@ public final class Interpreter implements HasEnvironment for (int i = 0; i < backtrackInfoAmount; i++) { + if (backtrackInfoStack[i] instanceof BacktrackInfoWithCleanup) + { + ((BacktrackInfoWithCleanup)backtrackInfoStack[i]).cleanup(this); + } backtrackInfoStack[i] = null; } backtrackInfoAmount = 0; -- 1.7.7.msysgit.1