commit eeb39b653146973b7f7acf27d859c31ca9233ad1
parent 95531fb330388effe89f9bfff315d59e60b59a2f
Author: tomas <tomas@logand.com>
Date: Fri, 23 Oct 2009 23:33:56 +0200
exceptions, quit throw catch finally, fix run eval let let? applyC redo
Diffstat:
M | java.wl | | | 2 | ++ |
M | wl.java | | | 116 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------- |
2 files changed, 78 insertions(+), 40 deletions(-)
diff --git a/java.wl b/java.wl
@@ -458,3 +458,5 @@
(de <> @ (not (pass =)))
(de abs (N) (if (lt0 N) (- N) N))
+
+(de test (X . P) (println X (run P 1)))
diff --git a/wl.java b/wl.java
@@ -348,24 +348,26 @@ class wl implements Runnable {
Any xrun(Any P, int n, Any L) {
Any Z = NIL;
Any E = 0 < n ? undo(n, L) : NIL;
- if(P.isCons())
- while(NIL != P) {
- Z = eval(P.car());
- P = P.cdr();
- }
- else eval(P);
- if(NIL != E) redo(E);
+ try {
+ if(P.isCons())
+ while(NIL != P) {
+ Z = eval(P.car());
+ P = P.cdr();
+ }
+ else Z = eval(P);
+ } finally {redo(E);}
return Z;
}
Any xrun(Any P) {return xrun(P, 0, NIL);}
Any eval(Any X, int n, Any L) {
Any Z = NIL;
Any E = 0 < n ? undo(n, L) : NIL;
- if(X.isCons()) Z = apply(X);
- else if(X.isIsym()) Z = X.val();
- else if(X.isObj()) Z = X;
- else err(X, "Don't know how to eval");
- if(NIL != E) redo(E);
+ try {
+ if(X.isCons()) Z = apply(X);
+ else if(X.isIsym()) Z = X.val();
+ else if(X.isObj()) Z = X;
+ else err(X, "Don't know how to eval");
+ } finally {redo(E);}
return Z;
}
Any eval(Any X) {return eval(X, 0, NIL);}
@@ -403,8 +405,8 @@ class wl implements Runnable {
else bind(Fa, A);
}
} else err(Fa, "Don't know how to bind");
- Z = xrun(Fb);
- unframe();
+ try {Z = xrun(Fb);}
+ finally {unframe();}
return Z;
}
Any mapcarEval(Any E) {
@@ -568,23 +570,25 @@ class wl implements Runnable {
return Z;
}
void redo(Any E) {
- Any X = Env.val();
- while(NIL != E) {
- Any C = E.car();
- if(C.isCons()) {
- // swap
- Any K = C.car();
- Any V = K.val();
- K.val(C.cdr());
- C.cdr(V);
+ if(NIL != E) {
+ Any X = Env.val();
+ while(NIL != E) {
+ Any C = E.car();
+ if(C.isCons()) {
+ // swap
+ Any K = C.car();
+ Any V = K.val();
+ K.val(C.cdr());
+ C.cdr(V);
+ }
+ // flip
+ Any F = E;
+ E = E.cdr();
+ F.cdr(X);
+ X = F;
}
- // flip
- Any F = E;
- E = E.cdr();
- F.cdr(X);
- X = F;
+ Env.val(X);
}
- Env.val(X);
}
boolean eq(Any X, Any Y) {
boolean z = true;
@@ -883,14 +887,14 @@ class wl implements Runnable {
bind(K, V);
n++;
}
- Z = xrun(I.cdr());
- unbind(n);
+ try {Z = xrun(I.cdr());}
+ finally {unbind(n);}
} else if(L.isIsym()) { // (let L 'V . P)
I = I.cdr();
Any V = eval(I.car());
bind(L, V);
- Z = xrun(I.cdr());
- unbind();
+ try {Z = xrun(I.cdr());}
+ finally {unbind();}
} else err(E, "Don't know how to let");
return Z;
}});
@@ -902,8 +906,8 @@ class wl implements Runnable {
Any V = eval(I.car());
if(NIL != V) {
bind(L, V);
- Z = xrun(I.cdr());
- unbind();
+ try {Z = xrun(I.cdr());}
+ finally {unbind();}
}
return Z;
}});
@@ -918,12 +922,12 @@ class wl implements Runnable {
n++;
L = L.cdr();
}
- Z = xrun(I.cdr());
- unbind(n);
+ try {Z = xrun(I.cdr());}
+ finally {unbind(n);}
} else if(L.isIsym()) { // (use L . P)
bind(L);
- Z = xrun(I.cdr());
- unbind();
+ try {Z = xrun(I.cdr());}
+ finally {unbind();}
} else err(E, "Don't know how to let");
return Z;
}});
@@ -1092,7 +1096,7 @@ class wl implements Runnable {
}
return Z;
}});
- fn("finally", new Fn() {public Any fn(Any E) { // TODO
+ fn("finally", new Fn() {public Any fn(Any E) {
Any I = E.cdr();
Any F = I.car();
Any P = I.cdr();
@@ -1101,11 +1105,43 @@ class wl implements Runnable {
finally {eval(F);}
return Z;
}});
+ fn("quit", new Fn() {public Any fn(Any E) {
+ Any I = E.cdr();
+ Any C = eval(I.car());
+ Any M = eval(I.cdr().car());
+ throw new Exc(C, M);
+ }});
+ fn("throw", new Fn() {public Any fn(Any E) {
+ Any I = E.cdr();
+ Any C = eval(I.car());
+ Any M = eval(I.cdr().car());
+ throw new Exc(C, M);
+ }});
+ fn("catch", new Fn() {public Any fn(Any E) {
+ Any I = E.cdr();
+ Any C = eval(I.car());
+ Any P = I.cdr();
+ Any Z = NIL;
+ try {Z = xrun(P);}
+ catch(Exc e) {
+ if(T == C || C == e.cnd()) Z = e.msg();
+ else throw e;
+ }
+ return Z;
+ }});
fn("read", new Fn() {public Any fn(Any E) { // TODO
return read1(true);
}});
}
+ class Exc extends RuntimeException {
+ Any C, M;
+ public Exc(Any c, Any m) {C = c; M = m;}
+ public String toString() {return str(C) + " -- " + str(M);}
+ public Any cnd() {return C;}
+ public Any msg() {return M;}
+ }
+
void print(Any E) {
PrintStream S = (PrintStream) Out.val().obj();
if(E.isCons()) {