Simplify the main execution loop of the interpreter
Made the code easier to follow, and handle halt(N) as normally
happens in a Prolog implementation like SWI-Prolog.
diff --git a/src/builtin/PRED_$begin_exception_1.java b/src/builtin/PRED_$begin_exception_1.java
index 2d914e3..966e0cd 100644
--- a/src/builtin/PRED_$begin_exception_1.java
+++ b/src/builtin/PRED_$begin_exception_1.java
@@ -21,6 +21,7 @@
if (! a1.unify(new JavaObjectTerm(this), engine.trail))
return engine.fail();
+ PrologControl ctl = engine.control;
Operation code = cont;
int B = engine.stack.top();
this.outOfScope = false;
@@ -28,26 +29,11 @@
engine.trail.push(new OutOfLoop(this));
try {
- main_loop:while(true) {
- while (engine.exceptionRaised == 0) {
- if (engine.control.isEngineStopped())
- break main_loop;
- if (outOfLoop)
- break main_loop;
- code = code.exec(engine);
- }
- switch (engine.exceptionRaised) {
- case 1: // halt/0
- break main_loop;
- case 2: // freeze/2
- throw new SystemException("freeze/2 is not supported yet");
- // Do something here
- // engine.exceptionRaised = 0 ;
- // break
- default:
- break main_loop;
- }
- }
+ do {
+ if (ctl.isEngineStopped()) break;
+ if (outOfLoop) break;
+ code = code.exec(engine);
+ } while (engine.halt == 0);
} catch (PrologException e) {
if (outOfScope)
throw e;
diff --git a/src/builtin/PRED_$begin_sync_2.java b/src/builtin/PRED_$begin_sync_2.java
index 7822184..6f42d35 100644
--- a/src/builtin/PRED_$begin_sync_2.java
+++ b/src/builtin/PRED_$begin_sync_2.java
@@ -44,18 +44,8 @@
main_loop:while(true) {
synchronized (o) {
while (! outOfScope) {
- if (engine.exceptionRaised != 0) {
- switch (engine.exceptionRaised) {
- case 1: // halt/0
+ if (engine.halt != 0) {
break main_loop;
- case 2: // freeze/2
- throw new SystemException("freeze/2 is not supported yet");
- // Do something here
- // engine.exceptionRaised = 0 ;
- // break
- default:
- break main_loop;
- }
}
if (engine.control.isEngineStopped())
break main_loop;
@@ -66,18 +56,8 @@
}
while (outOfScope) {
- if (engine.exceptionRaised != 0) {
- switch (engine.exceptionRaised) {
- case 1: // halt/0
+ if (engine.halt != 0) {
break main_loop;
- case 2: // freeze/2
- throw new SystemException("freeze/2 is not supported yet");
- // Do something here
- // engine.exceptionRaised = 0 ;
- // break
- default:
- break main_loop;
- }
}
if (engine.control.isEngineStopped())
break main_loop;
diff --git a/src/builtin/PRED_halt_1.java b/src/builtin/PRED_halt_1.java
index 2aa4b92..0290a54 100644
--- a/src/builtin/PRED_halt_1.java
+++ b/src/builtin/PRED_halt_1.java
@@ -22,7 +22,7 @@
throw new PInstantiationException(this, 1);
if (! a1.isInteger())
throw new IllegalTypeException(this, 1, "integer", a1);
- engine.exceptionRaised = ((IntegerTerm)a1).intValue();
+ engine.halt = 1 + ((IntegerTerm)a1).intValue();
return cont;
}
}
diff --git a/src/builtin/builtins.pl b/src/builtin/builtins.pl
index c71f3f3..1fa2405 100644
--- a/src/builtin/builtins.pl
+++ b/src/builtin/builtins.pl
@@ -1767,11 +1767,9 @@
'$prolog_impl_flag'(print_stack_trace, [on,off], changeable(yes)).
:- public halt/0.
-%:- public halt/1. (written in Java)
:- public abort/0.
-halt :- halt(1).
-
+halt :- halt(0).
abort :- raise_exception('Execution aborted').
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/lang/Failure.java b/src/lang/Failure.java
index 7a716a7..e8001ae 100644
--- a/src/lang/Failure.java
+++ b/src/lang/Failure.java
@@ -12,7 +12,7 @@
public Operation exec(Prolog engine) {
engine.control.fail();
- engine.exceptionRaised = 1; // halt
+ engine.halt = 1; // halt(0)
return null;
}
diff --git a/src/lang/HaltException.java b/src/lang/HaltException.java
new file mode 100644
index 0000000..5dbd4ef
--- /dev/null
+++ b/src/lang/HaltException.java
@@ -0,0 +1,14 @@
+package com.googlecode.prolog_cafe.lang;
+
+public class HaltException extends SystemException {
+ private final int status;
+
+ public HaltException(int status) {
+ super("halt(" + status + ")");
+ this.status = status;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+}
diff --git a/src/lang/Prolog.java b/src/lang/Prolog.java
index 8f97c30..204cf88 100644
--- a/src/lang/Prolog.java
+++ b/src/lang/Prolog.java
@@ -50,10 +50,10 @@
* Exception level of continuation passing loop:
* <li><code>0</code> for no exception,
* <li><code>1</code> for <code>halt/0</code>,
- * <li><code>2</code> for <code>freeze/2</code> (not supported yet)
+ * <li><code>1+N</code> for <code>halt(N)</code>.
* </ul>
*/
- public int exceptionRaised;
+ public int halt;
/** <font color="red">Not supported yet</font>. Prolog implementation flag: <code>bounded</code>. */
protected boolean bounded = false;
@@ -246,7 +246,7 @@
initialFrame.timeStamp = ++CPFTimeStamp;
stack.push(initialFrame);
- exceptionRaised = 0;
+ halt = 0;
charConversion = "off";
debug = "off";
diff --git a/src/lang/PrologControl.java b/src/lang/PrologControl.java
index 2ee53da..fb3b87b 100644
--- a/src/lang/PrologControl.java
+++ b/src/lang/PrologControl.java
@@ -143,28 +143,24 @@
* @throws PrologException
* @throws JavaInterruptedException
*/
- protected void executePredicate()
- throws PrologException, JavaInterruptedException {
- engine.init();
- main_loop:while(true) {
- while (engine.exceptionRaised == 0) {
- if (isEngineStopped())
- break main_loop;
- code = code.exec(engine);
- }
- SymbolTerm.gc();
- switch (engine.exceptionRaised) {
- case 1: // halt/0
- break main_loop;
- case 2: // freeze/2
- throw new SystemException("freeze/2 is not supported yet");
- // Do something here
- // engine.exceptionRaised = 0 ;
- // break;
- default:
- throw new SystemException("Invalid value of exceptionRaised");
- }
- }
+ protected void executePredicate() throws PrologException, JavaInterruptedException {
+ Prolog engine = this.engine;
+ Operation code = this.code;
+ try {
+ engine.init();
+
+ do {
+ if (isEngineStopped()) return;
+ code = code.exec(engine);
+ } while (engine.halt == 0);
+
+ if (engine.halt != 1) {
+ throw new HaltException(engine.halt - 1);
+ }
+ } finally {
+ this.code = code;
+ SymbolTerm.gc();
+ }
}
/** @param err stack trace to print (or log). */
diff --git a/src/lang/PrologMain.java b/src/lang/PrologMain.java
index 7ab9b05..1e41c38 100644
--- a/src/lang/PrologMain.java
+++ b/src/lang/PrologMain.java
@@ -51,6 +51,8 @@
p.setPredicate(Prolog.BUILTIN, "initialization", arg1, arg2);
for (boolean r = p.call(); r; r = p.redo()) {}
System.exit(0);
+ } catch (HaltException e) {
+ System.exit(e.getStatus());
} catch (Exception e){
e.printStackTrace();
System.exit(1);