package kawa.standard;
import kawa.lang.*;
import gnu.mapping.*;

/**
 * Implement the Scheme standard function "call-with-current-continuation".
 * This is a restricted version, that only works for escape-like applications.
 * @author Per Bothner
 */

public class callcc extends Procedure1
{
  /** Call a precedure with the current continuation. */
  public static Object apply (Procedure proc) throws Throwable
  {
    kawa.lang.Continuation cont = new kawa.lang.Continuation ();
    try
      {
	return proc.apply1 (cont);
      }
    catch (CalledContinuation ex)
      {
	if (ex.continuation != cont)
	  throw ex;
	return ex.value;
      }
    finally
      {
	cont.invoked = true;
      }
  }

  public Object apply1 (Object arg1) throws Throwable
  {
    Procedure proc;
    try
      {
	proc = (Procedure) arg1;
      }
    catch (ClassCastException ex)
      {
	throw new GenericError ("argument to call/cc is not procedure");
      }
    return apply (proc);
  }

  /*
  public void apply (CallContext stack)
  {
    kawa.lang.Continuation cont = new Continuation ();
    cont.frame = stack.proc;
    cont.pc = stack.pc;
    stack.value = cont;
  }
  */
}

/*
class Continuation extends CpsProcedure
{
  Procedure frame;
  int pc;

  public void apply (CallContext stack)
  {
    Object result = Values.make(stack.args);
    stack.pc = pc;
    stack.proc = frame;
    stack.result = result;
  }
}
*/
