aboutsummaryrefslogtreecommitdiff
path: root/clojurescript
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2008-09-16 03:08:13 +0000
committerChouser <chouser@n01se.net>2008-09-16 03:08:13 +0000
commitd610e924360349f418d3ec46e085c94773d7c6b7 (patch)
treec8cd5f79f76ddb65c6f7378ebd6bf23a2d5aea17 /clojurescript
parentf2483b3b722c6b59bc9ef192f3a7c649f030f768 (diff)
ClojureScript: reduce number of local variables emitted.
Diffstat (limited to 'clojurescript')
-rw-r--r--clojurescript/tojs.clj54
1 files changed, 36 insertions, 18 deletions
diff --git a/clojurescript/tojs.clj b/clojurescript/tojs.clj
index 5653a7bd..3145f297 100644
--- a/clojurescript/tojs.clj
+++ b/clojurescript/tojs.clj
@@ -12,6 +12,8 @@
(lvl v)
(str sb)))
+(def *arity-check* false)
+
(defmulti tojs (fn [e ctx] (class e)))
(defmethod tojs clojure.lang.Var [e ctx]
@@ -21,16 +23,18 @@
(defmethod tojs clojure.lang.Compiler$DefExpr [e ctx]
(str (tojs (.var e) ctx) "=" (tojs (.init e) ctx) ";\n"))
-(defn fnmethod [fm ctx]
+(defn fnmethod [fm maxm ctx]
(let [lm (into {} (map (fn [[lb lb] i] [lb (str (.name lb) "_" i)])
- (.locals fm) (iterate inc 0)))]
- (vstr ["var " (vec (interpose "," (vals lm))) ";\n"
- (when-let thisfn (some #(when (= (.name %)
- (.thisName (:fnexpr ctx))) %)
- (keys lm))
- [(lm thisfn) "=" (.simpleName (:fnexpr ctx)) ";\n"])
- (vec (for [lb (.reqParms fm)]
- [(lm lb) "=arguments[" (dec (.idx lb)) "];\n"]))
+ (.locals fm) (iterate inc 0)))
+ thisfn (some #(when (= (.name %) (:fnname ctx)) %) (keys lm))
+ mainvars (vals (reduce dissoc lm (cons thisfn (when (= fm maxm)
+ (.reqParms fm)))))]
+ (.reqParms maxm)
+ (vstr [(when mainvars ["var " (vec (interpose "," mainvars)) ";\n"])
+ (when thisfn ["var " (lm thisfn) "=arguments.callee;\n"])
+ (when (not= fm maxm)
+ (vec (for [lb (.reqParms fm)]
+ [(lm lb) "=arguments[" (dec (.idx lb)) "];\n"])))
(when-let lb (.restParm fm)
["var " (lm lb) "=clojure.JS.rest_args(arguments,"
(count (.reqParms fm)) ");\n"])
@@ -39,15 +43,29 @@
";\n}while(_cnt);return _rtn;"])))
(defmethod tojs clojure.lang.Compiler$FnExpr [e ctx]
- (vstr ["(function " (.simpleName e) "(){\n"
- (vec (for [fm (.methods e) :when (not= fm (.variadicMethod e))]
- ["if(arguments.length==" (count (.argLocals fm)) "){\n"
- (fnmethod fm (assoc ctx :fnexpr e))
- "}\n"]))
- (if (.variadicMethod e)
- [(fnmethod (.variadicMethod e) ctx) "\n"]
- ["throw \"Wrong number of args passed to: " (.thisName e) "\";\n"])
- "})"]))
+ (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))]
+ (vstr ["(function("
+ (vec (interpose "," (map #(vector (.name %) "_" (.idx %))
+ (.reqParms maxm))))
+ "){\n"
+ (vec (for [fm (.methods e) :when (not= fm (.variadicMethod e))]
+ [(when manym
+ ["if(arguments.length==" (count (.reqParms fm)) "){\n"])
+ (fnmethod fm maxm newctx)
+ (when manym "}\n")]))
+ (if (.variadicMethod e)
+ [(fnmethod (.variadicMethod e) maxm newctx) "\n"]
+ (when *arity-check*
+ ["throw \"Wrong number of args passed to: "
+ (.thisName e) "\";\n"]))
+ "})"])))
(defmethod tojs clojure.lang.Compiler$BodyExpr [e ctx]
(apply str (interpose ",\n" (map #(tojs % ctx) (.exprs e)))))