commit cef3bc5f654eb56def1bcedac661fb681ca6ae9e
Author: Chouser <chouser@n01se.net>
Date:   Fri Jan 16 02:47:42 2009 -0500

    ClojureScript support

diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 9b18b00..297eb71 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -321,7 +321,7 @@
           (if more
             (recur (. sb  (append (str (first more)))) (rest more))
             (str sb)))
-      (new StringBuilder #^String (str x)) ys)))
+      (clojure.lang.RT/makeStringBuilder (str x)) ys)))
 
 
 (defn symbol?
@@ -559,7 +559,7 @@
   {:inline (fn [x y] `(. clojure.lang.Numbers (add ~x ~y)))
    :inline-arities #{2}}
   ([] 0)
-  ([x] (cast Number x))
+  ([x] (clojure.lang.RT/numberCast x))
   ([x y] (. clojure.lang.Numbers (add x y)))
   ([x y & more]
    (reduce + (+ x y) more)))
@@ -569,7 +569,7 @@
   {:inline (fn [x y] `(. clojure.lang.Numbers (multiply ~x ~y)))
    :inline-arities #{2}}
   ([] 1)
-  ([x] (cast Number x))
+  ([x] (clojure.lang.RT/numberCast x))
   ([x y] (. clojure.lang.Numbers (multiply x y)))
   ([x y & more]
    (reduce * (* x y) more)))
@@ -1501,12 +1501,12 @@
 (defn range
   "Returns a lazy seq of nums from start (inclusive) to end
   (exclusive), by step, where start defaults to 0 and step to 1."
-  ([end] (if (and (> end 0) (<= end (. Integer MAX_VALUE)))
+  ([end] (if (and (> end 0) (<= end clojure.lang.RT/IntegerMaxValue))
            (new clojure.lang.Range 0 end)
            (take end (iterate inc 0))))
   ([start end] (if (and (< start end)
-                        (>= start (. Integer MIN_VALUE))
-                        (<= end (. Integer MAX_VALUE)))
+                        (>= start clojure.lang.RT/IntegerMinValue)
+                        (<= end clojure.lang.RT/IntegerMaxValue))
                  (new clojure.lang.Range start end)
                  (take (- end start) (iterate inc start))))
   ([start end step]
@@ -1573,7 +1573,7 @@
   ([#^java.util.Comparator comp coll]
    (when (and coll (not (zero? (count coll))))
      (let [a (to-array coll)]
-       (. java.util.Arrays (sort a comp))
+       (clojure.lang.RT/sortArray a comp)
        (seq a)))))
 
 (defn sort-by
@@ -1663,7 +1663,7 @@
   [& agents]
   (io! "await in transaction"
     (when *agent*
-      (throw (new Exception "Can't await in agent action")))
+      (throw (clojure.lang.RT/makeException "Can't await in agent action")))
     (let [latch (new java.util.concurrent.CountDownLatch (count agents))
           count-down (fn [agent] (. latch (countDown)) agent)]
       (doseq [agent agents]
@@ -1683,7 +1683,7 @@
   [timeout-ms & agents]
     (io! "await-for in transaction"
      (when *agent*
-       (throw (new Exception "Can't await in agent action")))
+       (throw (clojure.lang.RT/makeException "Can't await in agent action")))
      (let [latch (new java.util.concurrent.CountDownLatch (count agents))
            count-down (fn [agent] (. latch (countDown)) agent)]
        (doseq [agent agents]
@@ -2007,6 +2007,7 @@
 
 
 (import '(java.lang.reflect Array))
+(import '(clojure.lang RT))
 
 (defn alength
   "Returns the length of the Java array. Works on arrays of all
@@ -2026,7 +2027,7 @@
   {:inline (fn [a i] `(. clojure.lang.RT (aget ~a ~i)))
    :inline-arities #{2}}
   ([array idx]
-   (clojure.lang.Reflector/prepRet (. Array (get array idx))))
+   (clojure.lang.Reflector/prepRet (RT/aget array idx)))
   ([array idx & idxs]
    (apply aget (aget array idx) idxs)))
 
@@ -2036,7 +2037,7 @@
   {:inline (fn [a i v] `(. clojure.lang.RT (aset ~a ~i ~v)))
    :inline-arities #{3}}
   ([array idx val]
-   (. Array (set array idx val))
+   (RT/aset array idx val)
    val)
   ([array idx idx2 & idxv]
    (apply aset (aget array idx) idx2 idxv)))
@@ -2193,6 +2194,10 @@
   "Returns a set of the distinct elements of coll."
   [coll] (apply hash-set coll))
 
+(defn class?
+  "Returns true if x is an instance of Class"
+  [x] (instance? Class x))
+
 (defn #^{:private true}
   filter-key [keyfn pred amap]
     (loop [ret {} es (seq amap)]
@@ -2228,7 +2233,7 @@
   [x]
   (if (instance? clojure.lang.Namespace x) 
     x 
-    (or (find-ns x) (throw (Exception. (str "No namespace: " x " found"))))))
+    (or (find-ns x) (throw (RT/makeException (str "No namespace: " x " found"))))))
 
 (defn ns-name
   "Returns the name of the namespace, a symbol."
@@ -2261,7 +2266,7 @@
 (defn ns-imports
   "Returns a map of the import mappings for the namespace."
   [ns]
-  (filter-key val (partial instance? Class) (ns-map ns)))
+  (filter-key val class? (ns-map ns)))
 
 (defn refer
   "refers to all public vars of ns, subject to filters.
@@ -2279,7 +2284,8 @@
   to a symbol different from the var's name, in order to prevent
   clashes. Use :use in the ns macro in preference to calling this directly."
   [ns-sym & filters]
-    (let [ns (or (find-ns ns-sym) (throw (new Exception (str "No namespace: " ns-sym))))
+    (let [ns (or (find-ns ns-sym)
+                 (throw (RT/makeException (str "No namespace: " ns-sym))))
           fs (apply hash-map filters)
           nspublics (ns-publics ns)
           rename (or (:rename fs) {})
@@ -2411,7 +2417,7 @@
                                                      true)
                                 (= firstb :as) (pb ret (second bs) gvec)
                                 :else (if seen-rest?
-                                        (throw (new Exception "Unsupported binding form, only :as can follow & parameter"))
+                                        (throw (RT/makeException "Unsupported binding form, only :as can follow & parameter"))
                                         (recur (pb ret firstb  (list `nth gvec n nil))
                                                (inc n)
                                                (rest bs)
@@ -2442,7 +2448,7 @@
                   (symbol? b) (-> bvec (conj b) (conj v))
                   (vector? b) (pvec bvec b v)
                   (map? b) (pmap bvec b v)
-                  :else (throw (new Exception (str "Unsupported binding form: " b))))))
+                  :else (throw (RT/makeException (str "Unsupported binding form: " b))))))
         process-entry (fn [bvec b] (pb bvec (key b) (val b)))]
     (if (every? symbol? (keys bmap))
       bindings
@@ -2590,7 +2596,7 @@
   StringWriter.  Returns the string created by any nested printing
   calls."
   [& body]
-  `(let [s# (new java.io.StringWriter)]
+  `(let [s# (clojure.lang.RT/makeStringWriter)]
      (binding [*out* s#]
        ~@body
        (str s#))))
@@ -2636,7 +2642,7 @@
  logical true."
   [x]
   `(when-not ~x
-     (throw (new Exception (str "Assert failed: " (pr-str '~x))))))
+     (throw (clojure.lang.RT/makeException (str "Assert failed: " (pr-str '~x))))))
 
 (defn test
   "test [v] finds fn at key :test in var metadata and calls it,
@@ -2710,7 +2716,7 @@
 (defn rand
   "Returns a random floating point number between 0 (inclusive) and
   1 (exclusive)."
-  ([] (. Math (random)))
+  ([] (RT/random))
   ([n] (* n (rand))))
 
 (defn rand-int
@@ -2820,7 +2826,7 @@
   "Reads the file named by f into a string and returns it."
   [#^String f]
   (with-open [r (new java.io.BufferedReader (new java.io.FileReader f))]
-    (let [sb (new StringBuilder)]
+    (let [sb (RT/makeStringBuilder)]
       (loop [c (. r (read))]
         (if (neg? c)
           (str sb)
@@ -3104,10 +3110,6 @@
      (send-off agt fill)
      (drain))))
 
-(defn class?
-  "Returns true if x is an instance of Class"
-  [x] (instance? Class x))
-
 (defn alter-var-root
   "Atomically alters the root binding of var v by applying f to its
   current value plus any args"
@@ -3193,7 +3195,7 @@
   relationships."
   ([tag] (descendants global-hierarchy tag))
   ([h tag] (if (class? tag)
-             (throw (java.lang.UnsupportedOperationException. "Can't get descendants of classes"))
+             (throw (RT/makeUnsupportedException "Can't get descendants of classes"))
              (not-empty (get (:descendants h) tag)))))
 
 (defn derive
@@ -3223,9 +3225,9 @@
      (or 
       (when-not (contains? (tp tag) parent)
         (when (contains? (ta tag) parent)
-          (throw (Exception. (print-str tag "already has" parent "as ancestor"))))
+          (throw (RT/makeException (print-str tag "already has" parent "as ancestor"))))
         (when (contains? (ta parent) tag)
-          (throw (Exception. (print-str "Cyclic derivation:" parent "has" tag "as ancestor"))))        
+          (throw (RT/makeException (print-str "Cyclic derivation:" parent "has" tag "as ancestor"))))
         {:parents (assoc (:parents h) tag (conj (get tp tag #{}) parent))     
          :ancestors (tf (:ancestors h) tag td parent ta)
          :descendants (tf (:descendants h) parent ta tag td)})
@@ -3366,7 +3368,7 @@
   [pred fmt & args]
   (when pred
     (let [message (apply format fmt args)
-          exception (Exception. message)
+          exception (RT/makeException message)
           raw-trace (.getStackTrace exception)
           boring? #(not= (.getMethodName %) "doInvoke")
           trace (into-array (drop 2 (drop-while boring? raw-trace)))]
diff --git a/src/clj/clojure/core_print.clj b/src/clj/clojure/core_print.clj
index 7a79a90..1ecc597 100644
--- a/src/clj/clojure/core_print.clj
+++ b/src/clj/clojure/core_print.clj
@@ -75,14 +75,14 @@
 
 (defn print-ctor [o print-args #^Writer w]
   (.write w "#=(")
-  (.write w (.getName #^Class (class o)))
+  (.write w (RT/className (class o)))
   (.write w ". ")
   (print-args o w)
   (.write w ")"))
 
 (defmethod print-method :default [o, #^Writer w]
   (.write w "#<")
-  (.write w (.getSimpleName (class o)))
+  (.write w (RT/simpleClassName (class o)))
   (.write w " ")
   (.write w (str o))
   (.write w ">"))
@@ -148,7 +148,7 @@
 (defmethod print-dup clojure.lang.IPersistentCollection [o, #^Writer w]
   (print-meta o w)
   (.write w "#=(")
-  (.write w (.getName #^Class (class o)))
+  (.write w (RT/className (class o)))
   (.write w "/create ")
   (print-sequential "[" print-dup " " "]" o w)
   (.write w ")"))
@@ -202,7 +202,7 @@
 (defmethod print-dup clojure.lang.IPersistentMap [m, #^Writer w]
   (print-meta m w)
   (.write w "#=(")
-  (.write w (.getName (class m)))
+  (.write w (RT/className (class m)))
   (.write w "/create ")
   (print-map m print-dup w)
   (.write w ")"))
@@ -252,7 +252,7 @@
    Short/TYPE "Short/TYPE"})
 
 (defmethod print-method Class [#^Class c, #^Writer w]
-  (.write w (.getName c)))
+  (.write w (RT/className c)))
 
 (defmethod print-dup Class [#^Class c, #^Writer w]
   (cond
@@ -262,11 +262,11 @@
                        (.write w ")"))
     (.isArray c) (do
                    (.write w "#=(java.lang.Class/forName \"")
-                   (.write w (.getName c))
+                   (.write w (RT/className c))
                    (.write w "\")"))
     :else (do
             (.write w "#=")
-            (.write w (.getName c)))))
+            (.write w (RT/className c)))))
 
 (defmethod print-method java.math.BigDecimal [b, #^Writer w]
   (.write w (str b))
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index d9033ac..eb4890a 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -202,7 +202,8 @@ static final public Var NEXT_LOCAL_NUM = Var.create(0);
 static final public Var RET_LOCAL_NUM = Var.create();
 
 //DynamicClassLoader
-static final public Var LOADER = Var.create();
+static final public Var LOADER = Var.intern(Namespace.findOrCreate(Symbol.create("clojure.core")),
+                                                 Symbol.create("*private-compiler-loader*"));
 
 public enum C{
 	STATEMENT,  //value ignored
@@ -2975,7 +2976,8 @@ static public class FnExpr implements Expr{
 			{
 			Var.popThreadBindings();
 			}
-		fn.compile();
+		if(! RT.booleanCast(RT.COMPILER_ANALYZE_ONLY.get()))
+			fn.compile();
 		return fn;
 	}
 
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index a277f89..699c0d1 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -32,6 +32,9 @@ static final public Boolean T = Boolean.TRUE;//Keyword.intern(Symbol.create(null
 static final public Boolean F = Boolean.FALSE;//Keyword.intern(Symbol.create(null, "t"));
 static final public String LOADER_SUFFIX = "__init";
 
+static final public Integer IntegerMaxValue = Integer.MAX_VALUE;
+static final public Integer IntegerMinValue = Integer.MIN_VALUE;
+
 //simple-symbol->class
 final static IPersistentMap DEFAULT_IMPORTS = map(
 //												  Symbol.create("RT"), "clojure.lang.RT",
@@ -202,6 +205,7 @@ final static Var PRINT_READABLY = Var.intern(CLOJURE_NS, Symbol.create("*print-r
 final static Var PRINT_DUP = Var.intern(CLOJURE_NS, Symbol.create("*print-dup*"), F);
 final static Var WARN_ON_REFLECTION = Var.intern(CLOJURE_NS, Symbol.create("*warn-on-reflection*"), F);
 final static Var ALLOW_UNRESOLVED_VARS = Var.intern(CLOJURE_NS, Symbol.create("*allow-unresolved-vars*"), F);
+final static Var COMPILER_ANALYZE_ONLY = Var.intern(CLOJURE_NS, Symbol.create("*compiler-analyze-only*"), F);
 
 final static Var IN_NS_VAR = Var.intern(CLOJURE_NS, Symbol.create("in-ns"), F);
 final static Var NS_VAR = Var.intern(CLOJURE_NS, Symbol.create("ns"), F);
@@ -963,6 +967,10 @@ static public double doubleCast(double x){
 	return x;
 }
 
+static public Number numberCast(Object x){
+	return (Number)x;
+}
+
 static public IPersistentMap map(Object... init){
     if(init == null)
         return PersistentArrayMap.EMPTY;
@@ -1707,4 +1715,43 @@ synchronized public static DynamicClassLoader getRootClassLoader() {
         ROOT_CLASSLOADER = new DynamicClassLoader();
     return ROOT_CLASSLOADER;
     }
+
+////////////// ClojureScript support /////////////////////////////////
+
+static public StringBuilder makeStringBuilder(){
+	return new StringBuilder();
+}
+
+static public StringBuilder makeStringBuilder(String x){
+	return new StringBuilder(x);
+}
+
+static public StringWriter makeStringWriter(){
+	return new StringWriter();
+}
+
+static public Exception makeException(String msg){
+	return new Exception(msg);
+}
+
+static public Exception makeUnsupportedException(String msg){
+	return new UnsupportedOperationException(msg);
+}
+
+static public void sortArray(Object[] a, Comparator c){
+	Arrays.sort(a, c);
+}
+
+static public double random(){
+	return Math.random();
+}
+
+static public String className(Class c){
+	return c.getName();
+}
+
+static public String simpleClassName(Class c){
+	return c.getSimpleName();
+}
+
 }
