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);