Index: src/clj/clojure/main.clj
===================================================================
--- src/clj/clojure/main.clj	(revision 1162)
+++ src/clj/clojure/main.clj	(working copy)
@@ -1,5 +1,5 @@
 ;; Copyright (c) Rich Hickey All rights reserved. The use and
-;; distribution terms for this software are covered by the Common Public
+;; distribution terms for this software are covered by the Eclipse Public
 ;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can be found
 ;; in the file epl-v10.html at the root of this distribution. By using this
 ;; software in any fashion, you are agreeing to be bound by the terms of
@@ -9,9 +9,11 @@
 ;; Originally contributed by Stephen C. Gilardi
 
 (ns clojure.main
-  (:gen-class)
   (:import (clojure.lang Compiler Compiler$CompilerException RT)))
 
+(def #^{:private true}
+     eof (Object.))
+
 (defmacro with-bindings
   "Executes body in the context of thread-local bindings for several vars
   that often need to be set!"
@@ -40,6 +42,36 @@
       (recur cause)
       cause)))
 
+(defn- process-return
+  "Processes stream s after reading CR such that both CR and CRLF are
+  handled as a single end of line."
+  [s]
+  (let [c (.read s)]
+    (when-not (or (= c (int \newline)) (= c -1))
+      (.unread s c))))
+
+(defn skip-whitespace
+  "Skips whitespace characters on stream s. Returns :line-start after
+  skipping end of line, :stream-end on reaching end of stream, or
+  :line-body after pushing a non-whitespace character back onto s.
+  Interprets comma as whitespace and semicolon as comment to end of line."
+  [s]
+  (loop [c (.read s)]
+    (cond
+     (= c (int \newline)) :line-start
+     (= c (int \return)) (do (process-return s) :line-start)
+     (= c (int \;)) (do (.readLine s) :line-start)
+     (= c -1) :stream-end
+     (or (Character/isWhitespace c) (= c (int \,))) (recur (.read s))
+     :else (do (.unread s c) :line-body))))
+
+(defn repl-prompt
+  "Prints repl prompt if the next character on *in* will begin a new line
+  of input"
+  [where]
+  (when (= where :line-start)
+    (printf "%s=> " (ns-name *ns*))))
+
 (defn repl-exception
   "Returns CompilerExceptions in tact, but only the root cause of other
   throwables"
@@ -48,6 +80,24 @@
     throwable
     (root-cause throwable)))
 
+(def
+ #^{:private true
+    :doc "Tracks the location of the next character on *in*"}
+ *where*)
+
+(defn- skip-ws
+  "Skips whitespace on *in* after :line-start and udpates *where*"
+  []
+  (when-not (= *where* :line-start)
+    (set! *where* (skip-whitespace *in*))))
+
+(defn- skip-rest
+  "Skips rest of line on *in* and updates *where*"
+  []
+  (when-not (= *where* :line-start)
+    (.readLine *in*)
+    (set! *where* :line-start)))
+
 (defn repl
   "Generic, reusable, read-eval-print loop. Options are sequential
   keyword-value pairs. Available options and their defaults:
@@ -55,8 +105,10 @@
      - :init, function of no arguments, initialization hook
        default: #()
 
-     - :prompt, function of no arguments, prompts for more input
-       default: #(printf \"%s=> \" (ns-name *ns*))
+     - :prompt, function of one argument, prompts for more input. The
+       argument indicates the location of the next character on the input
+       stream, either :line-start, or :line-body.
+       default: repl-prompt
 
      - :flush, function of no arguments, flushes output
        default: flush
@@ -78,34 +130,41 @@
   [& options]
   (let [{:keys [init prompt flush read eval print caught]
          :or {init    #()
-              prompt  #(printf "%s=> " (ns-name *ns*))
+              prompt  repl-prompt
               flush   flush
               read    #(read *in* false %)
               eval    eval
               print   prn
               caught  #(.println *err* (repl-exception %))}}
-        (apply hash-map options)
-        eof (Object.)]
+        (apply hash-map options)]
     (with-bindings
-     (init)
-     (loop []
-       (prompt)
-       (flush)
-       (when-not
-        (= eof
-           (try
-            (let [input (read eof)]
-              (if (= input eof)
-                eof
-                (let [value (eval input)]
-                  (print value)
-                  (set! *3 *2)
-                  (set! *2 *1)
-                  (set! *1 value))))
-            (catch Throwable e
-              (caught e)
-              (set! *e e))))
-        (recur))))))
+     (binding [*where* :line-start]
+       (init)
+       (loop []
+         (when-not (= *where* :stream-end)
+           (prompt *where*)
+           (flush)
+           (set! *where* (skip-whitespace *in*))
+           (when (= *where* :line-body)
+             (try
+              (let [input (read eof)]
+                (if (= input eof)
+                  (do
+                    (set! *where* :stream-end)
+                    (recur))
+                  (do
+                    (skip-ws)
+                    (let [value (eval input)]
+                      (print value)
+                      (set! *3 *2)
+                      (set! *2 *1)
+                      (set! *1 value)))))
+              (catch Throwable e
+                (caught e)
+                (set! *e e)
+                (skip-rest)))
+             (skip-ws))
+           (recur)))))))
 
 (defn load-script
   "Loads Clojure source from a file or resource given its path. Paths
@@ -122,11 +181,15 @@
   (load-script path))
 
 (defn- eval-opt
-  "Eval expr, print the result if it's not nil"
-  [expr]
-  (let [value (with-in-str expr (eval (read)))]
-    (when-not (nil? value)
-      (println value))))
+  "Evals expressions in str, prints each non-nil result using prn"
+  [str]
+  (with-in-str str
+    (loop [input (read *in* false eof)]
+      (when-not (= input eof)
+        (let [value (eval input)]
+          (when-not (nil? value)
+            (prn value))
+          (recur (read *in* false eof)))))))
 
 (defn- init-dispatch
   "Returns the handler associated with an init opt"
@@ -178,15 +241,15 @@
 
 init options:
 
-  -i, --init path  Load a file or resource
-  -e, --eval expr  Evaluate an expression and print its value if non-nil
+  -i, --init path   Load a file or resource
+  -e, --eval string Evaluate expressions in string; print non-nil values
 
 main options:
 
-  -r, --repl       Run a repl
-  path             Run a script from from a file or resource
-  -                Run a script from standard input
-  -h, -?, --help   Print this help message and exit
+  -r, --repl        Run a repl
+  path              Run a script from from a file or resource
+  -                 Run a script from standard input
+  -h, -?, --help    Print this help message and exit
 
 operation:
 
@@ -216,7 +279,21 @@
      "-?"     help-opt} opt)
    script-opt))
 
-(defn- -main
+(defn- legacy-repl
+  "Called by the clojure.lang.Repl.main stub to run a repl with args
+  specified the old way"
+  [args]
+  (let [[inits [sep & args]] (split-with (complement #{"--"}) args)]
+    (repl-opt (concat ["-r"] args) (map vector (repeat "-i") inits))))
+
+(defn- legacy-script
+  "Called by the clojure.lang.Script.main stub to run a script with args
+  specified the old way"
+  [args]
+  (let [[inits [sep & args]] (split-with (complement #{"--"}) args)]
+    (null-opt args (map vector (repeat "-i") inits))))
+
+(defn main
   "Flexible main for Clojure"
   [& args]
   (try
Index: src/jvm/clojure/lang/LineNumberingPushbackReader.java
===================================================================
--- src/jvm/clojure/lang/LineNumberingPushbackReader.java	(revision 1162)
+++ src/jvm/clojure/lang/LineNumberingPushbackReader.java	(working copy)
@@ -18,6 +18,9 @@
 
 public class LineNumberingPushbackReader extends PushbackReader{
 
+final static private int CR = (int) '\r';
+final static private int LF = (int) '\n';
+
 public LineNumberingPushbackReader(Reader r){
 	super(new LineNumberReader(r));
 }
@@ -27,6 +30,20 @@
 }
 
 public String readLine() throws IOException{
-	return ((LineNumberReader)in).readLine();
+    int first = read();
+    switch (first) {
+    case -1:
+        return null;
+    case LF:
+        return "";
+    case CR:
+        int second = read();
+        if (second != LF && second != -1)
+            unread(second);
+        return "";
+    default:
+        return String.valueOf((char) first) +
+            ((LineNumberReader)in).readLine();
+    }
 }
 }
Index: src/jvm/clojure/lang/Repl.java
===================================================================
--- src/jvm/clojure/lang/Repl.java	(revision 1162)
+++ src/jvm/clojure/lang/Repl.java	(working copy)
@@ -12,111 +12,11 @@
 
 package clojure.lang;
 
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
+import clojure.main;
 
-public class Repl{
-static final Symbol USER = Symbol.create("user");
-static final Symbol CLOJURE = Symbol.create("clojure.core");
+class Repl {
 
-static final Var in_ns = RT.var("clojure.core", "in-ns");
-static final Var refer = RT.var("clojure.core", "refer");
-static final Var ns = RT.var("clojure.core", "*ns*");
-static final Var compile_path = RT.var("clojure.core", "*compile-path*");
-static final Var warn_on_reflection = RT.var("clojure.core", "*warn-on-reflection*");
-static final Var print_meta = RT.var("clojure.core", "*print-meta*");
-static final Var print_length = RT.var("clojure.core", "*print-length*");
-static final Var print_level = RT.var("clojure.core", "*print-level*");
-static final Var star1 = RT.var("clojure.core", "*1");
-static final Var star2 = RT.var("clojure.core", "*2");
-static final Var star3 = RT.var("clojure.core", "*3");
-static final Var stare = RT.var("clojure.core", "*e");
-
 public static void main(String[] args) throws Exception{
-
-//	RT.init();
-
-	try
-		{
-		//*ns* must be thread-bound for in-ns to work
-		//thread-bind *warn-on-reflection* so it can be set!
-		//thread-bind *1,*2,*3,*e so each repl has its own history
-		//must have corresponding popThreadBindings in finally clause
-		Var.pushThreadBindings(
-				RT.map(ns, ns.get(),
-				       warn_on_reflection, warn_on_reflection.get(),
-				       print_meta, print_meta.get(),
-				       print_length, print_length.get(),
-				       print_level, print_level.get(),
-				       compile_path, "classes",
-				       star1, null,
-				       star2, null,
-				       star3, null,
-				       stare, null));
-
-		//create and move into the user namespace
-		in_ns.invoke(USER);
-		refer.invoke(CLOJURE);
-
-		//load any supplied files
-		for(String file : RT.processCommandLine(args))
-			try
-				{
-				Compiler.loadFile(file);
-				}
-			catch(Exception e)
-				{
-				e.printStackTrace((PrintWriter) RT.ERR.get());
-				}
-
-		//repl IO support
-		LineNumberingPushbackReader rdr = new LineNumberingPushbackReader(new InputStreamReader(System.in, RT.UTF8));
-		OutputStreamWriter w = (OutputStreamWriter) RT.OUT.get();//new OutputStreamWriter(System.out);
-		Object EOF = new Object();
-
-		//start the loop
-		w.write("Clojure\n");
-		for(; ;)
-			{
-			try
-				{
-				w.write(Compiler.currentNS().name + "=> ");
-				w.flush();
-				Object r = LispReader.read(rdr, false, EOF, false);
-				if(r == EOF)
-					{
-					w.write("\n");
-					w.flush();
-					break;
-					}
-				Object ret = Compiler.eval(r);
-				RT.print(ret, w);
-				w.write('\n');
-				//w.flush();
-				star3.set(star2.get());
-				star2.set(star1.get());
-				star1.set(ret);
-				}
-			catch(Throwable e)
-				{
-				Throwable c = e;
-				while(c.getCause() != null)
-					c = c.getCause();
-				((PrintWriter) RT.ERR.get()).println(e instanceof Compiler.CompilerException ? e : c);
-				stare.set(e);
-				}
-			}
-		}
-	catch(Exception e)
-		{
-		e.printStackTrace((PrintWriter) RT.ERR.get());
-		}
-	finally
-		{
-		Var.popThreadBindings();
-		}
-	System.exit(0);
+    main.legacy_repl(args);
 }
-
 }
Index: src/jvm/clojure/lang/Script.java
===================================================================
--- src/jvm/clojure/lang/Script.java	(revision 1162)
+++ src/jvm/clojure/lang/Script.java	(working copy)
@@ -12,73 +12,11 @@
 
 package clojure.lang;
 
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.IOException;
-import java.util.List;
-import java.util.Arrays;
+import clojure.main;
 
-/**
- * <code>Script</code> provides a way to run one or more Clojure files
- * from a command line.  Example usage:
- * <p>
- * <pre>java -cp clojure.jar script1.clj @/dir/script2.clj -- [arguments]</pre>
- * </p>
- * <p>
- * The example above will:
- * <ol>
- * <li>bind *command-line-args* to a seq containing the (optional) arguments provided
- *     after the two dashes (--); this provides a way to provide command-line arguments
- *     to your scripts</li>
- * <li>load the Clojure file <i>at the filesystem path</i> <code>script1.clj</code></li>
- * <li>load the Clojure file with the name <code>dir/script2.clj</code> <i>from the
- *     current Java classpath</i>.  Files to be loaded from the classpath must be prefixed
- *     with a '@' character, and must be an "absolute path" to the classpath resource.
- *     Note that the "path" will be treated as absolute within the classpath, whether it is
- *     prefixed with a slash or not.</li>
- * </ol>
- * </p>
- * <p>
- * Any number of Clojure files can be provided as path arguments; these
- * files are loaded in order, as if via <code>load-file</code>.  Filesystem and classpath
- * paths may be provided in any order, and be intermixed as necessary.
- * </p>
- * <p>
- * Once the final script path has been loaded, the java process exits.
- * </p>
- */
-public class Script{
+class Script {
 
 public static void main(String[] args) throws Exception{
-    try
-		{
-		for(String file : RT.processCommandLine(args))
-            {
-            if (file.startsWith("@"))
-                {
-                // trim leading slash if it's there -- loadResourceScript prepends its
-                // own slash to every name it's given
-                RT.loadResourceScript(file.substring(file.startsWith("@/") ? 2 : 1));
-                }
-            else
-                {
-                Compiler.loadFile(file);
-                }
-            }
-		}
-	finally
-		{
-		OutputStreamWriter w = (OutputStreamWriter) RT.OUT.get();
-		try
-			{
-			w.flush();
-			w.close();
-			}
-		catch(IOException e)
-			{
-			e.printStackTrace((PrintWriter)RT.ERR.get());
-			}
-		}
+    main.legacy_script(args);
 }
 }
-
Index: src/jvm/clojure/main.java
===================================================================
--- src/jvm/clojure/main.java	(revision 0)
+++ src/jvm/clojure/main.java	(revision 0)
@@ -0,0 +1,41 @@
+/**
+ *   Copyright (c) Rich Hickey. All rights reserved.
+ *   The use and distribution terms for this software are covered by the
+ *   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+ *   which can be found in the file epl-v10.html at the root of this distribution.
+ *   By using this software in any fashion, you are agreeing to be bound by
+ * 	 the terms of this license.
+ *   You must not remove this notice, or any other, from this software.
+ **/
+
+package clojure;
+
+import clojure.lang.Symbol;
+import clojure.lang.Namespace;
+import clojure.lang.Var;
+import clojure.lang.RT;
+
+public class main{
+
+final static private Symbol CLOJURE_MAIN = Symbol.create("clojure.main");
+final static private Namespace CLOJURE_MAIN_NS = Namespace.findOrCreate(CLOJURE_MAIN);
+final static private Var REQUIRE = Var.intern(RT.CLOJURE_NS, Symbol.create("require"));
+final static private Var LEGACY_REPL = Var.intern(CLOJURE_MAIN_NS, Symbol.create("legacy-repl"));
+final static private Var LEGACY_SCRIPT = Var.intern(CLOJURE_MAIN_NS, Symbol.create("legacy-script"));
+final static private Var MAIN = Var.intern(CLOJURE_MAIN_NS, Symbol.create("main"));
+
+public static void legacy_repl(String[] args) throws Exception{
+    REQUIRE.invoke(CLOJURE_MAIN);
+    LEGACY_REPL.invoke(RT.seq(args));
+}
+
+public static void legacy_script(String[] args) throws Exception{
+    REQUIRE.invoke(CLOJURE_MAIN);
+    LEGACY_SCRIPT.invoke(RT.seq(args));
+}
+
+public static void main(String[] args) throws Exception{
+    REQUIRE.invoke(CLOJURE_MAIN);
+    MAIN.applyTo(RT.seq(args));
+}
+}
Index: build.xml
===================================================================
--- build.xml	(revision 1162)
+++ build.xml	(working copy)
@@ -1,8 +1,8 @@
-<project name="clojure" default="jar">
+<project name="clojure" default="all">
 
   <description>
     Build with "ant jar" and then start the REPL with:
-    "java -jar clojure.jar"
+    "java -cp clojure.jar clojure.main"
   </description>
 
   <property name="src" location="src"/>
@@ -10,19 +10,20 @@
   <property name="cljsrc" location="${src}/clj"/>
   <property name="build" location="classes"/>
   <property name="clojure_jar" location="clojure.jar"/>
-
+  <property name="slim_jar" location="clojure-slim.jar"/>
+  
   <target name="init">
     <tstamp/>
     <mkdir dir="${build}"/>
   </target>
-
-  <target name="compile_java" depends="init"
+  
+  <target name="compile-java" depends="init"
           description="Compile Java sources.">
     <javac srcdir="${jsrc}" destdir="${build}" includeJavaRuntime="yes"
            debug="true" target="1.5"/>
   </target>
 
-  <target name="compile_clojure" depends="compile_java"
+  <target name="compile-clojure" depends="compile-java"
           description="Compile Clojure sources.">
     <java classname="clojure.lang.Compile"
           classpath="${build}:${cljsrc}">
@@ -36,8 +37,8 @@
     </java>
   </target>
 
-  <target name="jar" depends="compile_clojure"
-          description="Create jar file.">
+  <target name="clojure" depends="compile-clojure"
+          description="Create clojure jar file.">
     <jar jarfile="${clojure_jar}" basedir="${build}">
       <fileset dir="${cljsrc}" includes="**/*.clj"/>
       <manifest>
@@ -47,9 +48,27 @@
     </jar>
   </target>
 
+  <target name="clojure-slim" depends="compile-java"
+          description="Create clojure-slim jar file (omits compiled Clojure code)">
+    <jar jarfile="${slim_jar}">
+      <fileset dir="${build}" includes="clojure/asm/**"/>
+      <fileset dir="${build}" includes="clojure/lang/**"/>
+      <fileset dir="${build}" includes="clojure/main.class"/>
+      <fileset dir="${cljsrc}" includes="**/*.clj"/>
+      <manifest>
+        <attribute name="Main-Class" value="clojure.main"/>
+        <attribute name="Class-Path" value="."/>
+      </manifest>
+    </jar>
+  </target>
+
+  <target name="jar" depends="clojure"/>
+
+  <target name="all" depends="clojure,clojure-slim"/>
+  
   <target name="clean"
           description="Remove autogenerated files and directories.">
     <delete dir="${build}"/>
   </target>
-
+  
 </project>
