// A Lisp Driver to be embedded in Java Applications

// The contents of this file are subject to the Mozilla Public License
// Version 1.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is JAKLD code, released November 26, 2002.
//
// The Initial Developer of the Original Code is Taiichi Yuasa.
// Portions created by Taiichi Yuasa are Copyright (C) 2002
// Taiichi Yuasa. All Rights Reserved.
//
// Contributor(s): Taiichi Yuasa <yuasa@kuis.kyoto-u.ac.jp>

final class Promise {

  private Object expr;
  private Env env;
  private Object value;

  Promise(Object expr, Env env) {
    this.expr = expr;
    this.env = env;
    this.value = null;
  }

  static { Subr.defSpecial("Promise", "delay", 1, 0, false); }
  public static Promise delay(Object e, Env env) {
    return new Promise(e, env);
  }

  static { Subr.def("Promise", "force", 1); }
  public static Object force(Promise p) {
    if (p.value == null) {
      p.value = Eval.eval(p.expr, p.env);
      p.expr = p.env = null;
    }
    return p.value;
  }

  static Subr CSSubr
  = Subr.prepareSpecial("Promise", "consStream", 2, 0, false);
  
  public static Pair consStream(Object x, Object y, Env env) {
    return new Pair(Eval.eval(x, env), new Promise(y, env));
  }
  
  static boolean CSActivated = false;

  static { Subr.def("Promise", "activateCS", "activate-cons-stream", 0); }
  public static Boolean activateCS() {
    if (!CSActivated) {
      Subr.activateSpecial("cons-stream", CSSubr);
      CSActivated = true;
      return true;
    } else
      return false;
  }

  public String toString() {
    return "#<promise>";
  }

  static void init() {}
}
