01: package kawa.standard;
02:
03: import kawa.lang.*;
04: import gnu.mapping.*;
05:
06: /**
07: * Implement the Scheme standard function "call-with-current-continuation".
08: * This is a restricted version, that only works for escape-like applications.
09: * @author Per Bothner
10: */
11:
12: public class callcc extends MethodProc {
13: public static final callcc callcc = new callcc();
14:
15: public int numArgs() {
16: return 0x1001;
17: }
18:
19: public int match1(Object proc, CallContext ctx) {
20: if (!(proc instanceof Procedure))
21: return NO_MATCH_BAD_TYPE;
22: return super .match1(proc, ctx);
23: }
24:
25: public void apply(CallContext ctx) throws Throwable {
26: Procedure proc = (Procedure) ctx.value1;
27: Continuation cont = new Continuation(ctx);
28: proc.check1(cont, ctx);
29: proc = ctx.proc;
30: ctx.proc = null;
31: try {
32: proc.apply(ctx);
33: ctx.runUntilDone();
34: } catch (CalledContinuation ex) {
35: if (ex.continuation != cont)
36: throw ex;
37: Object[] values = ex.values;
38: int nvalues = values.length;
39: for (int i = 0; i < nvalues; i++)
40: ctx.consumer.writeObject(ex.values[i]);
41: } finally {
42: cont.invoked = true;
43: }
44: }
45:
46: /*
47: public void apply (CallContext stack)
48: {
49: kawa.lang.Continuation cont = new Continuation ();
50: cont.frame = stack.proc;
51: cont.pc = stack.pc;
52: stack.value = cont;
53: }
54: */
55: }
56:
57: /*
58: class Continuation extends MethodProc
59: {
60: Procedure frame;
61: int pc;
62:
63: public void apply (CallContext stack)
64: {
65: Object result = Values.make(stack.args);
66: stack.pc = pc;
67: stack.proc = frame;
68: stack.result = result;
69: }
70: }
71: */
|