package kawa;

import kawa.lang.*;
import kawa.standard.*;

import java.io.*;

public class Shell
{
  public static void run (InPort inp, Interpreter interp,
			  boolean pflag, boolean dflag)
  {
    java.io.PrintStream pout = interp.out;
    java.io.PrintStream perr = interp.err;
    kawa.lang.Interpreter interpreter = interp;
    boolean prompt = pflag;
    boolean display = dflag;

    Environment env = new Environment (interpreter);
    for (;;)
      {
	try
	  {
            if (prompt)
	      {
		pout.print("kawa>");
		pout.flush();
	      }

	    Object sexp = inp.readSchemeObject ();
	    if (sexp==Interpreter.eofObject)
	      {
		if (prompt)
		  pout.println ();
		return;
	      }

	    interpreter.errors = 0;
	    Expression exp = interpreter.rewrite (sexp);

	    /* DEBUGGING:
	    perr.print ("[Re-written expression: ");
	    exp.print (perr);
	    perr.print ("\nbefore eval<"+exp.getClass().getName()+">");
	    perr.println();
	    perr.flush();
	    */

	    if (interpreter.errors == 0)
	      {
		Object result = exp.eval (env);
		if (result == null)
		  pout.println ("[null returned]\n");
		else if (display && result != Interpreter.voidObject)
		  {
		    kawa.lang.print.print (result, pout);
		    pout.println();
		    pout.flush();
		  }
	      }
	  }
	catch (kawa.lang.WrongArguments e)
	  {
	    perr.println("Wrong arguments to procedure "+e.procname
			 +",expected "+e.number+".");
	    perr.println("usage: "+e.usage);
	    e.printStackTrace(perr);
	  }
	catch (kawa.lang.WrongType e)
	  {
	    perr.println("Argument "+e.number+" to "+e.procname
			 +" must be of type "+e.typeExpected);
	    e.printStackTrace(perr);
	  }
	catch (java.lang.ClassCastException e)
	  {
	    perr.println("Invalid parameter, should be: "+ e.getMessage());
	    e.printStackTrace(perr);
	  }
	catch (kawa.lang.ReadError e)
	  {
	    perr.println (e);
	  }
	catch (Exception e)
	  {
	    e.printStackTrace(perr);
	  }
      }
  }

  public static void runString (String str, Interpreter interp, boolean dflag)
  {
    InPort str_port = call_with_input_string.open_input_string (str);
    run (str_port, interp, false, dflag);
  }

  public static void runFile (String fname, Interpreter interp,
			      boolean dflag)
  {
    try
      {
	
	InPort iport;
	if (fname.equals ("-"))
	  iport = InPort.inDefault ();
	else
	  iport = new InPort (new FileInputStream(fname), fname);
	run (iport, interp, false, dflag);
      }
    catch (FileNotFoundException e)
      {
	System.out.println("Cannot open file "+fname);
	System.exit(1);
      }
  }
  
}

@@ -403,20 +403,16 @@
 nt env =
- new
  Environ
@@ -415,29 +415,23 @@
 ironment
- (interpreter
+.user (
 );%0A    f
@@ -717,55 +717,317 @@
  0;%0A
+%0A
 %09    
-Expression exp = interpreter.rewrite (sexp
+LambdaExp lexp = new LambdaExp (ModuleBody.formals,%0A%09%09%09%09%09    new Pair (sexp, List.Empty),%0A%09%09%09%09%09    interpreter);%0A%09    lexp.setName (Symbol.make (%22atInteractiveLevel%22));  // FIXME%0A%09    String filename = inp.getName ();%0A%09    if (filename == null)%0A%09      filename = %22%3Cunknown%3E%22;%0A%09    lexp.setFile (filename
 );%0A%0A
@@ -1293,16 +1293,17 @@
 t = 
+l
 exp.eval
  (en
@@ -1298,16 +1298,23 @@
 exp.eval
+_module
  (env);%0A

Update for ModuleBody now takes Environment.