diff options
author | Chouser <chouser@n01se.net> | 2009-01-12 07:54:16 +0000 |
---|---|---|
committer | Chouser <chouser@n01se.net> | 2009-01-12 07:54:16 +0000 |
commit | 2b1e44f04489b5d70faff703bf824f07b74432d2 (patch) | |
tree | 2bc686386c956028744f7411a4404f59efca9115 /clojurescript/src/clojure | |
parent | 6e53cf73c313d2bf76f5ee3c9a847548665b32e2 (diff) |
Rearrange ClojureScript code for AOT compilation and its eventual place in clojure.contrib. Also fix major breaking errors for Clojure SVN 1205, but it's not well tested with this latest version.
Diffstat (limited to 'clojurescript/src/clojure')
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript.clj | 357 | ||||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/cli.clj | 95 | ||||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/core.js | 3525 | ||||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/repl/blank.gif | bin | 0 -> 48 bytes | |||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/repl/clojure-logo-anim-03.gif | bin | 0 -> 4919 bytes | |||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/repl/dots.png | bin | 0 -> 437 bytes | |||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/repl/repl.cljs | 91 | ||||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/repl/repl.html | 60 | ||||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/repl/repl.js | 89 | ||||
-rw-r--r-- | clojurescript/src/clojure/contrib/clojurescript/rt.js | 2057 |
10 files changed, 6274 insertions, 0 deletions
diff --git a/clojurescript/src/clojure/contrib/clojurescript.clj b/clojurescript/src/clojure/contrib/clojurescript.clj new file mode 100644 index 00000000..66e7eac3 --- /dev/null +++ b/clojurescript/src/clojure/contrib/clojurescript.clj @@ -0,0 +1,357 @@ +; Copyright (c) Chris Houser, Sep 2008-Jan 2009. 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. + +; Reads Clojure code and emits equivalent JavaScript + +(ns clojure.contrib.clojurescript + (:import (clojure.lang Compiler Compiler$C Compiler$BodyExpr + Compiler$DefExpr Compiler$InstanceMethodExpr)) + (:require [clojure.contrib.duck-streams :as ds])) + +(defn- vstr [v] + (let [sb (StringBuilder.) + lvl (fn lvl [v] + (doseq [i v] + (if (vector? i) + (lvl i) + (.append sb (str i)))))] + (lvl v) + (str sb))) + +(def *debug-fn-names* true) +(def *debug-comments* true) +(def *eval-defmacro* true) + +; used internally +(def *has-recur*) +(def *local-names* {}) + +(defmulti #^{:private true} tojs (fn [e ctx] (class e))) + +(defn- fnmethod [fm maxm ctx] + (let [lm (into {} (for [[lb lb] (.locals fm)] + [lb (str (.name lb) "_" (.idx lb))])) + thisfn (first (filter #(= 0 (.idx %)) (keys lm))) + [body has-recur] (binding [*has-recur* false] + [(tojs (.body fm) + (merge-with merge ctx {:localmap lm})) + *has-recur*]) + mparm (into {} (for [p (.reqParms maxm)] [(.idx p) p])) + inits (concat + (when has-recur ["_cnt" "_rtn"]) + (vals (reduce dissoc lm + (conj (.reqParms fm) thisfn (.restParm fm)))) + (when (:fnname ctx) [(str (lm thisfn) "=arguments.callee")]) + (when (not= fm maxm) + (for [lb (.reqParms fm) + :when (not= (.name lb) (.name (mparm (.idx lb))))] + [(lm lb) "=arguments[" (dec (.idx lb)) "]"])) + (when-let [lb (.restParm fm)] + [(str (lm lb) "=clojure.JS.rest_args(this,arguments," + (count (.reqParms fm)) ")")]))] + (.reqParms maxm) + (vstr [(when (seq inits) + [(apply vector "var " (interpose "," inits)) ";\n"]) + (if has-recur + ["do{_cnt=0;_rtn=" + body + "\n}while(_cnt);return _rtn;"] + ["return (" body ")"])]))) + +(defmethod tojs clojure.lang.Compiler$FnExpr [e ctx] + (let [maxm (or (.variadicMethod e) + (-> (into (sorted-map) + (for [fm (.methods e) + :when (not= fm (.variadicMethod e))] + [(count (.reqParms fm)) fm])) + last val)) + manym (< 1 (count (.methods e))) + newctx (assoc ctx :fnname (.thisName e)) + [methods local-names] (binding [*local-names* *local-names*] + [(into {} (for [fm (.methods e)] + [fm (fnmethod fm maxm newctx)])) + *local-names*])] + (vstr [(when (.variadicMethod e) + ["clojure.JS.variadic(" (count (.reqParms maxm)) ","]) + "(function" + (when *debug-fn-names* + [" __" (.replaceAll (.name e) "[\\W_]+" "_")]) + "(" + (vec (interpose "," (for [lb (.reqParms maxm)] + [(.name lb) "_" (.idx lb)]))) + "){" + ;"\n//" (vec (interpose "," (vals local-names))) "\n" + (when manym + ["switch(arguments.length){" + (vec (for [[fm body] methods :when (not= fm maxm)] + ["\ncase " (count (.reqParms fm)) ":" body])) + "}"]) + "\n" + (methods maxm) "})" + (when (.variadicMethod e) + ")") + ]))) + +(defmethod tojs clojure.lang.Compiler$BodyExpr [e ctx] + (apply str (interpose ",\n" (map #(tojs % ctx) (.exprs e))))) + +(defmethod tojs clojure.lang.Compiler$LetExpr [e ctx] + (let [inits (vec (interpose ",\n" (for [bi (.bindingInits e)] + ["(" ((:localmap ctx) (.binding bi)) + "=" (tojs (.init bi) ctx) ")"])))] + (if (.isLoop e) + (binding [*has-recur* false] + (vstr ["((function" + (when *debug-fn-names* " __loop") + "(){var _rtn,_cnt;" + inits ";" + "do{_cnt=0;\n_rtn=" (tojs (.body e) ctx) + "}while(_cnt);return _rtn;})())"])) + (vstr ["(" inits ",\n" (tojs (.body e) ctx) ")"])))) + +(defmethod tojs clojure.lang.Compiler$VectorExpr [e ctx] + (vstr ["clojure.JS.lit_vector([" + (vec (interpose "," (map #(tojs % ctx) (.args e)))) + "])"])) + +(defn- const-str [c] + (cond + (or (instance? Character c) + (string? c)) (pr-str (str c)) + (keyword? c) (str "clojure.core.keyword(\"" (namespace c) "\",\"" (name c) "\")") + (symbol? c) (str "clojure.core.symbol(\"" c "\")") + (class? c) (.getCanonicalName c) + (list? c) (vstr ["clojure.JS.lit_list([" + (vec (interpose "," (map const-str c))) + "])"]) + (fn? c) (str \" c \") + (instance? java.util.regex.Pattern c) (str "(/" + (.replace (str c) "/" "\\/") + "/)") + :else (str "(" c ")"))) + +(defmethod tojs clojure.lang.Compiler$ConstantExpr [e ctx] + (const-str (.v e))) + +(def js-reserved '#{import boolean short byte char class}) + +(defn- var-munge [x] + (let [n (-> x str Compiler/munge (.replace "." "_DOT_"))] + (if (js-reserved (symbol n)) + (str n "_") + n))) + +(defn- var-parts [e] + (let [{:keys [name ns]} ^(.var e)] + [(Compiler/munge (str (.getName ns))) (var-munge name)])) + +(defmethod tojs clojure.lang.Compiler$UnresolvedVarExpr [e ctx] + (vstr ["clojure.JS.resolveVar(\"" + (var-munge (name (.symbol e))) "\"," + (Compiler/munge (name (.name *ns*))) ")"])) + +(defmethod tojs clojure.lang.Compiler$VarExpr [e ctx] + (let [[vns vname] (var-parts e)] + (if (and (= vns "clojurescript.js") (#{"this"} vname)) + vname + (str vns "." vname)))) + +(defmethod tojs clojure.lang.Compiler$TheVarExpr [e ctx] + (let [[vns vname] (var-parts e)] + (str vns "._var_" vname))) + +(defmethod tojs clojure.lang.Compiler$AssignExpr [e ctx] + (let [target (.target e)] + (if (instance? clojure.lang.Compiler$InstanceFieldExpr target) + (vstr ["(" (tojs (.target target) ctx) "." + (var-munge (.fieldName target)) "=" (tojs (.val e) ctx) ")"]) + (let [[vns vname] (var-parts target)] + (str vns "._var_" vname ".set(" (tojs (.val e) ctx) ")"))))) + +(defmethod tojs clojure.lang.Compiler$DefExpr [e ctx] + (let [[vns vname] (var-parts e)] + (str "clojure.JS.def(" vns ",\"" vname "\"," (tojs (.init e) ctx) ")"))) + + +(defmethod tojs clojure.lang.Compiler$InvokeExpr [e ctx] + (vstr [(tojs (.fexpr e) ctx) + ".apply(null,[" + (vec (interpose "," (map #(tojs % ctx) (.args e)))) + "])"])) + +(defmethod tojs clojure.lang.Compiler$LocalBindingExpr [e ctx] + (let [local-name ((:localmap ctx) (.b e))] + (set! *local-names* (assoc *local-names* (.b e) local-name)) + local-name)) + +(defmethod tojs clojure.lang.Compiler$NilExpr [e ctx] + "null") + +(defmethod tojs clojure.lang.Compiler$EmptyExpr [e ctx] + (str (.getCanonicalName (class (.coll e))) ".EMPTY")) + +(defmethod tojs clojure.lang.Compiler$StringExpr [e ctx] + (const-str (.str e))) + +(defmethod tojs clojure.lang.Compiler$KeywordExpr [e ctx] + (const-str (.k e))) + +(defmethod tojs clojure.lang.Compiler$StaticFieldExpr [e ctx] + (str "clojure.JS.getOrRun(" (.getCanonicalName (.c e)) ",\"" + (var-munge (.fieldName e)) "\")")) + +(defmethod tojs clojure.lang.Compiler$StaticMethodExpr [e ctx] + (vstr [(.getCanonicalName (.c e)) "." (.methodName e) "(" + (vec (interpose "," (map #(tojs % ctx) (.args e)))) + ")"])) + +(defmethod tojs clojure.lang.Compiler$NewExpr [e ctx] + (vstr ["(new " (.getCanonicalName (.c e)) "(" + (vec (interpose "," (map #(tojs % ctx) (.args e)))) + "))"])) + +(defmethod tojs clojure.lang.Compiler$InstanceMethodExpr [e ctx] + (vstr ["(" (tojs (.target e) ctx) ")." (var-munge (.methodName e)) + "(" (vec (interpose "," (map #(tojs % ctx) (.args e)))) ")"])) + +(defmethod tojs clojure.lang.Compiler$InstanceFieldExpr [e ctx] + (vstr ["clojure.JS.getOrRun(" (tojs (.target e) ctx) ",\"" + (var-munge (.fieldName e)) "\")"])) + +(defmethod tojs clojure.lang.Compiler$IfExpr [e ctx] + (str "((" (tojs (.testExpr e) ctx) + ")?(" (tojs (.thenExpr e) ctx) + "):(" (tojs (.elseExpr e) ctx) "))")) + +(defmethod tojs clojure.lang.Compiler$RecurExpr [e ctx] + (set! *has-recur* true) + (vstr ["(_cnt=1,_rtn=[" + (vec (interpose "," (map #(tojs % ctx) (.args e)))) + "]" + (vec (map #(str "," ((:localmap ctx) %1) "=_rtn[" %2 "]") + (.loopLocals e) (iterate inc 0))) + ")"])) + +(defmethod tojs clojure.lang.Compiler$MapExpr [e ctx] + (vstr ["clojure.core.hash_map(" + (vec (interpose "," (map #(tojs % ctx) (.keyvals e)))) + ")"])) + +(defmethod tojs clojure.lang.Compiler$SetExpr [e ctx] + (vstr ["clojure.core.hash_set(" + (vec (interpose "," (map #(tojs % ctx) (.keys e)))) + ")"])) + +(defmethod tojs clojure.lang.Compiler$BooleanExpr [e ctx] + (if (.val e) "true" "false")) + +(defmethod tojs clojure.lang.Compiler$ThrowExpr [e ctx] + (vstr ["(function" + (when *debug-fn-names* " __throw") + "(){throw " (tojs (.excExpr e) ctx) "})()"])) + +(defmethod tojs clojure.lang.Compiler$TryExpr [e ctx] + (vstr ["(function" + (when *debug-fn-names* " __try") + "(){try{var _rtn=(" + (tojs (.tryExpr e) ctx) + ")}" + (when (seq (.catchExprs e)) + (when (not= 1 (count (.catchExprs e))) + (throw (Exception. "tojs only supports one catch clause per try"))) + (let [cc (first (.catchExprs e))] + ["\ncatch(" ((:localmap ctx) (.lb cc)) "){_rtn=" + (tojs (.handler cc) ctx) + "}"])) + (when (.finallyExpr e) + ["\nfinally{" + (tojs (.finallyExpr e) ctx) + "}"]) + "return _rtn})()"])) + + +(defmulti toclj class) +(defmethod toclj clojure.lang.Compiler$KeywordExpr [e] (.k e)) +(defmethod toclj clojure.lang.Compiler$StringExpr [e] (.str e)) +(defmethod toclj clojure.lang.Compiler$ConstantExpr [e] (.v e)) + + +(def skip-def '#{;-- implemented directly in clj.js + seq instance? assoc apply refer first rest import + hash-map count find keys vals get class contains? + print-method class? number? string? integer? nth + to-array cons keyword symbol load + ;-- not supported yet + make-array to-array-2d re-pattern re-matcher re-groups + re-seq re-matches re-find format + ;-- macros defined without using defmacro + let loop fn defn defmacro + ;-- will probably never be supported in clojurescript + eval resolve ns-resolve await await-for macroexpand + macroexpand-1 load-reader load-string special-symbol? + bigint bigdec floats doubles ints longs float-array + double-array int-array long-array aset-int + aset-long aset-boolean aset-float aset-double + aset-short aset-char aset-byte slurp seque + decimal? float? pmap primitives-classnames}) + +(def skip-method #{"java.lang.Class"}) + +(defn formtojs [f] + (when-not (and (coll? f) (= 'definline (first f))) + (binding [*allow-unresolved-vars* true + *private-compiler-loader* (clojure.lang.RT/makeClassLoader)] + (let [expr (Compiler/analyze Compiler$C/STATEMENT `((fn [] ~f))) + mainexpr (-> expr .fexpr .methods first .body .exprs first) + defmacro? (and (instance? Compiler$BodyExpr mainexpr) + (instance? Compiler$DefExpr (first (.exprs mainexpr))) + (instance? Compiler$InstanceMethodExpr (second (.exprs mainexpr))) + (= "setMacro" (.methodName (second (.exprs mainexpr)))))] + (if defmacro? + (when *eval-defmacro* + (eval f) + nil) + (when-not (or (and (instance? Compiler$DefExpr mainexpr) + (skip-def (:name ^(.var mainexpr)))) + (and (instance? Compiler$InstanceMethodExpr mainexpr) + (or (= "setMacro" (.methodName mainexpr)) + (and (= "addMethod" (.methodName mainexpr)) + (skip-method (tojs (first (.args mainexpr)) + nil))))) + (and (instance? Compiler$BodyExpr mainexpr) + (instance? Compiler$DefExpr (first (.exprs mainexpr))) + (instance? Compiler$InstanceMethodExpr (second (.exprs mainexpr))) + (= "setMacro" (.methodName (second (.exprs mainexpr)))))) + (tojs expr {:localmap {}}))))))) + +(defn filetojs [filename & optseq] + (let [reader (java.io.PushbackReader. (ds/reader filename)) + opts (apply array-map optseq)] + (binding [*ns* (create-ns 'user) + *debug-fn-names* (:debug-fn-names opts true) + *debug-comments* (:debug-comments opts true) + *eval-defmacro* (:eval-defmacro opts true)] + (loop [] + (let [f (read reader false reader false)] + (when-not (identical? f reader) + (if-let [js (formtojs f)] + (do + (when *debug-comments* + (println "\n//======") + (print "//") + (prn f) + (println "//---")) + (println (str js ";")) + (when (and (coll? f) + (or (= 'ns (first f)) + (= 'in-ns (first f)))) + (eval f))) + (when *debug-comments* + (print "// Skipping: ") + (prn f))) + (recur))))))) diff --git a/clojurescript/src/clojure/contrib/clojurescript/cli.clj b/clojurescript/src/clojure/contrib/clojurescript/cli.clj new file mode 100644 index 00000000..da823b75 --- /dev/null +++ b/clojurescript/src/clojure/contrib/clojurescript/cli.clj @@ -0,0 +1,95 @@ +; Copyright (c) Chris Houser, Sep 2008-Jan 2009. 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. + +; Command Line Interface for generating JavaScript from Clojure code. + +(ns clojure.contrib.clojurescript.cli + (:import (java.io PrintWriter StringReader) + (java.net URLDecoder)) + (:use [clojure.contrib.command-line :only (with-command-line)] + [clojure.contrib.clojurescript :only (formtojs filetojs)]) + (:require [clojure.contrib.duck-streams :as ds])) + +(defn start-server [port] + ;(println "Opening port" port) + (loop [server (java.net.ServerSocket. port)] ; TODO bind only to 127.0.0.1 + (send-off (agent (.accept server)) + (fn [socket] + (with-open [socket socket] + (binding [*out* (-> socket .getOutputStream ds/writer)] + (try + (print "HTTP/1.0 200 OK\nContent-Type: text/javascript\n\n") + (let [line1 (-> socket .getInputStream ds/reader .readLine) + [_ url] (re-find #"^GET /\?(.*?) HTTP" line1) + codestr (URLDecoder/decode url) + js (with-out-str (filetojs (StringReader. codestr) + :debug-fn-names false + :debug-comments false + :eval-defmacro false))] + (println "jsrepl.state('compiled');try{") + (println "jsrepl.lastval=" js ) + (println "jsrepl.state('done');}catch(e){jsrepl.err(e)};")) + (catch Exception e + (if (= (.getMessage e) "EOF while reading") + (println "jsrepl.state('incomplete');") + (let [trace (with-out-str + (.printStackTrace e (PrintWriter. *out*)))] + (println "jsrepl.state('error',\"" + (.replace trace "\n" "\\n") "\");"))))))))) + (recur server))) + +(defn mkcore [] + (binding [*out* (ds/writer "core.js")] + (doseq [file ["clojure/core.clj" "clojure/core_print.clj"]] + (filetojs (.getResourceAsStream (clojure.lang.RT/baseLoader) file))))) + +(defn simple-tests [] + (println (formtojs + '(defn foo + ([a b c & d] (prn 3 a b c)) + ([c] + ;(String/asd "hello") + ;(.foo 55) + (let [[a b] [1 2]] + (prn a b c) + "hi"))))) + + (println (formtojs + '(defn foo [a] + (prn "hi") + (let [a 5] + (let [a 10] + (prn "yo") + (prn a)) + (prn a)) + (prn a)))) + + (println (formtojs + '(defn x [] (conj [] (loop [i 5] (if (pos? i) (recur (- i 2)) i)))))) + + ;(println (formtojs '(binding [*out* 5] (set! *out* 10)))) + (println (formtojs '(.replace "a/b/c" "/" "."))) + (println (formtojs '(.getName ":foo"))) + (println (formtojs '(list '(1 "str" 'sym :key) 4 "str2" 6 #{:set 9 8}))) + (println (formtojs '(fn forever[] (forever)))) + (println (formtojs '(fn forever[] (loop [] (recur)))))) + +(when-not *compile-files* + (with-command-line *command-line-args* + "clojurescript.cli -- Compile ClojureScript to JavaScript" + [[simple? "Runs some simple built-in tests"] + [serve "Starts a repl server on the given port" 8081] + [mkcore? "Generates a core.js file"] + [v? "Includes extra fn names and comments in js"] + filenames] + (cond + simple? (simple-tests) + serve (start-server (Integer/parseInt serve)) + mkcore? (mkcore) + :else (doseq [filename filenames] + (filetojs filename :debug-fn-names v? :debug-comments v?))))) diff --git a/clojurescript/src/clojure/contrib/clojurescript/core.js b/clojurescript/src/clojure/contrib/clojurescript/core.js new file mode 100644 index 00000000..7726b43f --- /dev/null +++ b/clojurescript/src/clojure/contrib/clojurescript/core.js @@ -0,0 +1,3525 @@ + +//====== +//(ns clojure.core) +//--- +(function __user_fn_538(){ +return (clojure.core.in_ns.apply(null,[clojure.core.symbol("clojure.core")]))}).apply(null,[]); + +//====== +//(def unquote) +//--- +(function __clojure_core_fn_544(){ +return (clojure.JS.def(clojure.core,"unquote",null))}).apply(null,[]); + +//====== +//(def list (. clojure.lang.PersistentList creator)) +//--- +(function __clojure_core_fn_547(){ +return (clojure.JS.def(clojure.core,"list",clojure.JS.getOrRun(clojure.lang.PersistentList,"creator")))}).apply(null,[]); +// Skipping: (def cons (fn* cons [x seq] (. clojure.lang.RT (cons x seq)))) +// Skipping: (def let (fn* let [& decl] (cons (quote let*) decl))) +// Skipping: (def loop (fn* loop [& decl] (cons (quote loop*) decl))) +// Skipping: (def fn (fn* fn [& decl] (cons (quote fn*) decl))) +// Skipping: (def first (fn first [coll] (. clojure.lang.RT (first coll)))) +// Skipping: (def rest (fn rest [x] (. clojure.lang.RT (rest x)))) + +//====== +//(def conj (fn conj ([coll x] (. clojure.lang.RT (conj coll x))) ([coll x & xs] (if xs (recur (conj coll x) (first xs) (rest xs)) (conj coll x))))) +//--- +(function __clojure_core_fn_580(){ +return (clojure.JS.def(clojure.core,"conj",clojure.JS.variadic(2,(function __clojure_core_fn_580_conj_582(coll_1,x_2){switch(arguments.length){ +case 2:var conj_0=arguments.callee; +return (clojure.lang.RT.conj(coll_1,x_2))} +var _cnt,_rtn,conj_0=arguments.callee,xs_3=clojure.JS.rest_args(this,arguments,2); +do{_cnt=0;_rtn=((xs_3)?((_cnt=1,_rtn=[conj_0.apply(null,[coll_1,x_2]),clojure.core.first.apply(null,[xs_3]),clojure.core.rest.apply(null,[xs_3])],coll_1=_rtn[0],x_2=_rtn[1],xs_3=_rtn[2])):(conj_0.apply(null,[coll_1,x_2]))) +}while(_cnt);return _rtn;}))))}).apply(null,[]); + +//====== +//(def second (fn second [x] (first (rest x)))) +//--- +(function __clojure_core_fn_585(){ +return (clojure.JS.def(clojure.core,"second",(function __clojure_core_fn_585_second_587(x_1){ +var second_0=arguments.callee; +return (clojure.core.first.apply(null,[clojure.core.rest.apply(null,[x_1])]))})))}).apply(null,[]); + +//====== +//(def ffirst (fn ffirst [x] (first (first x)))) +//--- +(function __clojure_core_fn_590(){ +return (clojure.JS.def(clojure.core,"ffirst",(function __clojure_core_fn_590_ffirst_592(x_1){ +var ffirst_0=arguments.callee; +return (clojure.core.first.apply(null,[clojure.core.first.apply(null,[x_1])]))})))}).apply(null,[]); + +//====== +//(def rfirst (fn rfirst [x] (rest (first x)))) +//--- +(function __clojure_core_fn_595(){ +return (clojure.JS.def(clojure.core,"rfirst",(function __clojure_core_fn_595_rfirst_597(x_1){ +var rfirst_0=arguments.callee; +return (clojure.core.rest.apply(null,[clojure.core.first.apply(null,[x_1])]))})))}).apply(null,[]); + +//====== +//(def frest (fn frest [x] (first (rest x)))) +//--- +(function __clojure_core_fn_600(){ +return (clojure.JS.def(clojure.core,"frest",(function __clojure_core_fn_600_frest_602(x_1){ +var frest_0=arguments.callee; +return (clojure.core.first.apply(null,[clojure.core.rest.apply(null,[x_1])]))})))}).apply(null,[]); + +//====== +//(def rrest (fn rrest [x] (rest (rest x)))) +//--- +(function __clojure_core_fn_605(){ +return (clojure.JS.def(clojure.core,"rrest",(function __clojure_core_fn_605_rrest_607(x_1){ +var rrest_0=arguments.callee; +return (clojure.core.rest.apply(null,[clojure.core.rest.apply(null,[x_1])]))})))}).apply(null,[]); +// Skipping: (def seq (fn seq [coll] (. clojure.lang.RT (seq coll)))) +// Skipping: (def instance? (fn instance? [c x] (. c (isInstance x)))) + +//====== +//(def seq? (fn seq? [x] (instance? clojure.lang.ISeq x))) +//--- +(function __clojure_core_fn_620(){ +return (clojure.JS.def(clojure.core,"seq_QMARK_",(function __clojure_core_fn_620_seq_QMARK_622(x_1){ +var seq_QMARK__0=arguments.callee; +return (clojure.core.instance_QMARK_.apply(null,[clojure.lang.ISeq,x_1]))})))}).apply(null,[]); +// Skipping: (def string? (fn string? [x] (instance? String x))) + +//====== +//(def map? (fn map? [x] (instance? clojure.lang.IPersistentMap x))) +//--- +(function __clojure_core_fn_630(){ +return (clojure.JS.def(clojure.core,"map_QMARK_",(function __clojure_core_fn_630_map_QMARK_632(x_1){ +var map_QMARK__0=arguments.callee; +return (clojure.core.instance_QMARK_.apply(null,[clojure.lang.IPersistentMap,x_1]))})))}).apply(null,[]); + +//====== +//(def vector? (fn vector? [x] (instance? clojure.lang.IPersistentVector x))) +//--- +(function __clojure_core_fn_635(){ +return (clojure.JS.def(clojure.core,"vector_QMARK_",(function __clojure_core_fn_635_vector_QMARK_637(x_1){ +var vector_QMARK__0=arguments.callee; +return (clojure.core.instance_QMARK_.apply(null,[clojure.lang.IPersistentVector,x_1]))})))}).apply(null,[]); + +//====== +//(def sigs (fn [fdecl] (if (seq? (first fdecl)) (loop [ret [] fdecl fdecl] (if fdecl (recur (conj ret (first (first fdecl))) (rest fdecl)) (seq ret))) (list (first fdecl))))) +//--- +(function __clojure_core_fn_640(){ +return (clojure.JS.def(clojure.core,"sigs",(function __clojure_core_fn_640_sigs_642(fdecl_1){ +var ret_2,fdecl_3; +return (((clojure.core.seq_QMARK_.apply(null,[clojure.core.first.apply(null,[fdecl_1])]))?(((function __loop(){var _rtn,_cnt;(ret_2=clojure.lang.PersistentVector.EMPTY), +(fdecl_3=fdecl_1);do{_cnt=0; +_rtn=((fdecl_3)?((_cnt=1,_rtn=[clojure.core.conj.apply(null,[ret_2,clojure.core.first.apply(null,[clojure.core.first.apply(null,[fdecl_3])])]),clojure.core.rest.apply(null,[fdecl_3])],ret_2=_rtn[0],fdecl_3=_rtn[1])):(clojure.core.seq.apply(null,[ret_2])))}while(_cnt);return _rtn;})())):(clojure.core.list.apply(null,[clojure.core.first.apply(null,[fdecl_1])]))))})))}).apply(null,[]); +// Skipping: (def assoc (fn assoc ([map key val] (. clojure.lang.RT (assoc map key val))) ([map key val & kvs] (let [ret (assoc map key val)] (if kvs (recur ret (first kvs) (second kvs) (rrest kvs)) ret))))) + +//====== +//(def meta (fn meta [x] (if (instance? clojure.lang.IMeta x) (. x (meta))))) +//--- +(function __clojure_core_fn_651(){ +return (clojure.JS.def(clojure.core,"meta",(function __clojure_core_fn_651_meta_653(x_1){ +var meta_0=arguments.callee; +return (((clojure.core.instance_QMARK_.apply(null,[clojure.lang.IMeta,x_1]))?((x_1).meta()):(null)))})))}).apply(null,[]); + +//====== +//(def with-meta (fn with-meta [x m] (. x (withMeta m)))) +//--- +(function __clojure_core_fn_656(){ +return (clojure.JS.def(clojure.core,"with_meta",(function __clojure_core_fn_656_with_meta_658(x_1,m_2){ +var with_meta_0=arguments.callee; +return ((x_1).withMeta(m_2))})))}).apply(null,[]); + +//====== +//(def last (fn last [s] (if (rest s) (recur (rest s)) (first s)))) +//--- +(function __clojure_core_fn_661(){ +return (clojure.JS.def(clojure.core,"last",(function __clojure_core_fn_661_last_663(s_1){ +var _cnt,_rtn,last_0=arguments.callee; +do{_cnt=0;_rtn=((clojure.core.rest.apply(null,[s_1]))?((_cnt=1,_rtn=[clojure.core.rest.apply(null,[s_1])],s_1=_rtn[0])):(clojure.core.first.apply(null,[s_1]))) +}while(_cnt);return _rtn;})))}).apply(null,[]); + +//====== +//(def butlast (fn butlast [s] (loop [ret [] s s] (if (rest s) (recur (conj ret (first s)) (rest s)) (seq ret))))) +//--- +(function __clojure_core_fn_666(){ +return (clojure.JS.def(clojure.core,"butlast",(function __clojure_core_fn_666_butlast_668(s_1){ +var ret_2,s_3,butlast_0=arguments.callee; +return (((function __loop(){var _rtn,_cnt;(ret_2=clojure.lang.PersistentVector.EMPTY), +(s_3=s_1);do{_cnt=0; +_rtn=((clojure.core.rest.apply(null,[s_3]))?((_cnt=1,_rtn=[clojure.core.conj.apply(null,[ret_2,clojure.core.first.apply(null,[s_3])]),clojure.core.rest.apply(null,[s_3])],ret_2=_rtn[0],s_3=_rtn[1])):(clojure.core.seq.apply(null,[ret_2])))}while(_cnt);return _rtn;})()))})))}).apply(null,[]); +// Skipping: (def defn (fn defn [name & fdecl] (let [m (if (string? (first fdecl)) {:doc (first fdecl)} {}) fdecl (if (string? (first fdecl)) (rest fdecl) fdecl) m (if (map? (first fdecl)) (conj m (first fdecl)) m) fdecl (if (map? (first fdecl)) (rest fdecl) fdecl) fdecl (if (vector? (first fdecl)) (list fdecl) fdecl) m (if (map? (last fdecl)) (conj m (last fdecl)) m) fdecl (if (map? (last fdecl)) (butlast fdecl) fdecl) m (conj {:arglists (list (quote quote) (sigs fdecl))} m)] (list (quote def) (with-meta name (conj (if (meta name) (meta name) {}) m)) (cons (quote clojure.core/fn) fdecl))))) +// Skipping: (. (var defn) (setMacro)) + +//====== +//(defn cast "Throws a ClassCastException if x is not a c, else returns x." [c x] (. c (cast x))) +//--- +(function __clojure_core_fn_679(){ +return (clojure.JS.def(clojure.core,"cast",(function __clojure_core_fn_679_cast_681(c_1,x_2){ +return ((c_1).cast(x_2))})))}).apply(null,[]); +// Skipping: (defn to-array "Returns an array of Objects containing the contents of coll, which\n can be any Collection. Maps to java.util.Collection.toArray()." [coll] (. clojure.lang.RT (toArray coll))) + +//====== +//(defn vector "Creates a new vector containing the args." ([] []) ([& args] (. clojure.lang.LazilyPersistentVector (create args)))) +//--- +(function __clojure_core_fn_691(){ +return (clojure.JS.def(clojure.core,"vector",clojure.JS.variadic(0,(function __clojure_core_fn_691_vector_693(){switch(arguments.length){ +case 0:return (clojure.lang.PersistentVector.EMPTY)} +var args_1=clojure.JS.rest_args(this,arguments,0); +return (clojure.lang.LazilyPersistentVector.create(args_1))}))))}).apply(null,[]); + +//====== +//(defn vec "Creates a new vector containing the contents of coll." ([coll] (. clojure.lang.LazilyPersistentVector (createOwning (to-array coll))))) +//--- +(function __clojure_core_fn_698(){ +return (clojure.JS.def(clojure.core,"vec",(function __clojure_core_fn_698_vec_700(coll_1){ +return (clojure.lang.LazilyPersistentVector.createOwning(clojure.core.to_array.apply(null,[coll_1])))})))}).apply(null,[]); +// Skipping: (defn hash-map "keyval => key val\n Returns a new hash map with supplied mappings." ([] {}) ([& keyvals] (. clojure.lang.PersistentHashMap (create keyvals)))) + +//====== +//(defn hash-set "Returns a new hash set with supplied keys." ([] #{}) ([& keys] (. clojure.lang.PersistentHashSet (create keys)))) +//--- +(function __clojure_core_fn_711(){ +return (clojure.JS.def(clojure.core,"hash_set",clojure.JS.variadic(0,(function __clojure_core_fn_711_hash_set_713(){switch(arguments.length){ +case 0:return (clojure.lang.PersistentHashSet.EMPTY)} +var keys_1=clojure.JS.rest_args(this,arguments,0); +return (clojure.lang.PersistentHashSet.create(keys_1))}))))}).apply(null,[]); + +//====== +//(defn sorted-map "keyval => key val\n Returns a new sorted map with supplied mappings." ([& keyvals] (. clojure.lang.PersistentTreeMap (create keyvals)))) +//--- +(function __clojure_core_fn_718(){ +return (clojure.JS.def(clojure.core,"sorted_map",clojure.JS.variadic(0,(function __clojure_core_fn_718_sorted_map_720(){ +var keyvals_1=clojure.JS.rest_args(this,arguments,0); +return (clojure.lang.PersistentTreeMap.create(keyvals_1))}))))}).apply(null,[]); + +//====== +//(defn sorted-set "Returns a new sorted set with supplied keys." ([& keys] (. clojure.lang.PersistentTreeSet (create keys)))) +//--- +(function __clojure_core_fn_724(){ +return (clojure.JS.def(clojure.core,"sorted_set",clojure.JS.variadic(0,(function __clojure_core_fn_724_sorted_set_726(){ +var keys_1=clojure.JS.rest_args(this,arguments,0); +return (clojure.lang.PersistentTreeSet.create(keys_1))}))))}).apply(null,[]); + +//====== +//(defn sorted-map-by "keyval => key val\n Returns a new sorted map with supplied mappings, using the supplied comparator." ([comparator & keyvals] (. clojure.lang.PersistentTreeMap (create comparator keyvals)))) +//--- +(function __clojure_core_fn_730(){ +return (clojure.JS.def(clojure.core,"sorted_map_by",clojure.JS.variadic(1,(function __clojure_core_fn_730_sorted_map_by_732(comparator_1){ +var keyvals_2=clojure.JS.rest_args(this,arguments,1); +return (clojure.lang.PersistentTreeMap.create(comparator_1,keyvals_2))}))))}).apply(null,[]); +// Skipping: (def defmacro (fn [name & args] (list (quote do) (cons (quote clojure.core/defn) (cons name args)) (list (quote .) (list (quote var) name) (quote (setMacro)))))) +// Skipping: (. (var defmacro) (setMacro)) +// Skipping: (defmacro when "Evaluates test. If logical true, evaluates body in an implicit do." [test & body] (list (quote if) test (cons (quote do) body))) +// Skipping: (defmacro when-not "Evaluates test. If logical false, evaluates body in an implicit do." [test & body] (list (quote if) test nil (cons (quote do) body))) + +//====== +//(defn nil? "Returns true if x is nil, false otherwise." {:tag Boolean} [x] (identical? x nil)) +//--- +(function __clojure_core_fn_763(){ +return (clojure.JS.def(clojure.core,"nil_QMARK_",(function __clojure_core_fn_763_nil_QMARK_765(x_1){ +return (clojure.core.identical_QMARK_.apply(null,[x_1,null]))})))}).apply(null,[]); + +//====== +//(defn false? "Returns true if x is the value false, false otherwise." {:tag Boolean} [x] (identical? x false)) +//--- +(function __clojure_core_fn_769(){ +return (clojure.JS.def(clojure.core,"false_QMARK_",(function __clojure_core_fn_769_false_QMARK_771(x_1){ +return (clojure.core.identical_QMARK_.apply(null,[x_1,false]))})))}).apply(null,[]); + +//====== +//(defn true? "Returns true if x is the value true, false otherwise." {:tag Boolean} [x] (identical? x true)) +//--- +(function __clojure_core_fn_775(){ +return (clojure.JS.def(clojure.core,"true_QMARK_",(function __clojure_core_fn_775_true_QMARK_777(x_1){ +return (clojure.core.identical_QMARK_.apply(null,[x_1,true]))})))}).apply(null,[]); + +//====== +//(defn not "Returns true if x is logical false, false otherwise." {:tag Boolean} [x] (if x false true)) +//--- +(function __clojure_core_fn_781(){ +return (clojure.JS.def(clojure.core,"not",(function __clojure_core_fn_781_not_783(x_1){ +return (((x_1)?(false):(true)))})))}).apply(null,[]); + +//====== +//(defn str "With no args, returns the empty string. With one arg x, returns\n x.toString(). (str nil) returns the empty string. With more than\n one arg, returns the concatenation of the str values of the args." {:tag String} ([] "") ([x] (if (nil? x) "" (. x (toString)))) ([x & ys] ((fn [sb more] (if more (recur (. sb (append (str (first more)))) (rest more)) (str sb))) (clojure.lang.RT/makeStringBuilder (str x)) ys))) +//--- +(function __clojure_core_fn_787(){ +return (clojure.JS.def(clojure.core,"str",clojure.JS.variadic(1,(function __clojure_core_fn_787_str_789(x_1){switch(arguments.length){ +case 0:return ("") +case 1:return (((clojure.core.nil_QMARK_.apply(null,[x_1]))?(""):((x_1).toString())))} +var ys_2=clojure.JS.rest_args(this,arguments,1); +return ((function __clojure_core_fn_787_str_789_fn_793(sb_1,more_2){ +var _cnt,_rtn; +do{_cnt=0;_rtn=((more_2)?((_cnt=1,_rtn=[(sb_1).append(clojure.core.str.apply(null,[clojure.core.first.apply(null,[more_2])])),clojure.core.rest.apply(null,[more_2])],sb_1=_rtn[0],more_2=_rtn[1])):(clojure.core.str.apply(null,[sb_1]))) +}while(_cnt);return _rtn;}).apply(null,[clojure.lang.RT.makeStringBuilder(clojure.core.str.apply(null,[x_1])),ys_2]))}))))}).apply(null,[]); + +//====== +//(defn symbol? "Return true if x is a Symbol" [x] (instance? clojure.lang.Symbol x)) +//--- +(function __clojure_core_fn_798(){ +return (clojure.JS.def(clojure.core,"symbol_QMARK_",(function __clojure_core_fn_798_symbol_QMARK_800(x_1){ +return (clojure.core.instance_QMARK_.apply(null,[clojure.lang.Symbol,x_1]))})))}).apply(null,[]); + +//====== +//(defn keyword? "Return true if x is a Keyword" [x] (instance? clojure.lang.Keyword x)) +//--- +(function __clojure_core_fn_804(){ +return (clojure.JS.def(clojure.core,"keyword_QMARK_",(function __clojure_core_fn_804_keyword_QMARK_806(x_1){ +return (clojure.core.instance_QMARK_.apply(null,[clojure.lang.Keyword,x_1]))})))}).apply(null,[]); +// Skipping: (defn symbol "Returns a Symbol with the given namespace and name." ([name] (if (symbol? name) name (. clojure.lang.Symbol (intern name)))) ([ns name] (. clojure.lang.Symbol (intern ns name)))) +// Skipping: (defn keyword "Returns a Keyword with the given namespace and name. Do not use :\n in the keyword strings, it will be added automatically." ([name] (if (keyword? name) name (. clojure.lang.Keyword (intern nil name)))) ([ns name] (. clojure.lang.Keyword (intern ns name)))) + +//====== +//(defn gensym "Returns a new symbol with a unique name. If a prefix string is\n supplied, the name is prefix# where # is some unique number. If\n prefix is not supplied, the prefix is 'G__'." ([] (gensym "G__")) ([prefix-string] (. clojure.lang.Symbol (intern (str prefix-string (str (. clojure.lang.RT (nextID)))))))) +//--- +(function __clojure_core_fn_824(){ +return (clojure.JS.def(clojure.core,"gensym",(function __clojure_core_fn_824_gensym_826(prefix_string_1){switch(arguments.length){ +case 0:return (clojure.core.gensym.apply(null,["G__"]))} +return (clojure.lang.Symbol.intern(clojure.core.str.apply(null,[prefix_string_1,clojure.core.str.apply(null,[clojure.lang.RT.nextID()])])))})))}).apply(null,[]); +// Skipping: (defmacro cond "Takes a set of test/expr pairs. It evaluates each test one at a\n time. If a test returns logical true, cond evaluates and returns\n the value of the corresponding expr and doesn't evaluate any of the\n other tests or exprs. (cond) returns nil." [& clauses] (when clauses (list (quote if) (first clauses) (if (rest clauses) (second clauses) (throw (IllegalArgumentException. "cond requires an even number of forms"))) (cons (quote clojure.core/cond) (rest (rest clauses)))))) + +//====== +//(defn spread {:private true} [arglist] (cond (nil? arglist) nil (nil? (rest arglist)) (seq (first arglist)) :else (cons (first arglist) (spread (rest arglist))))) +//--- +(function __clojure_core_fn_840(){ +return (clojure.JS.def(clojure.core,"spread",(function __clojure_core_fn_840_spread_842(arglist_1){ |