Skip to content

Commit

Permalink
* src/clj/cljs/compiler.clj: add *loop-lets* dynamic var for tracking…
Browse files Browse the repository at this point in the history
… let bindings in loops
  • Loading branch information
swannodette committed Feb 22, 2012
1 parent 986ef58 commit 6feae43
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions src/clj/cljs/compiler.clj
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,12 @@
(println "})()"))))

(defmethod emit :fn
[{:keys [name env methods max-fixed-arity variadic recur-frames]}]
[{:keys [name env methods max-fixed-arity variadic recur-frames loop-lets]}]
;;fn statements get erased, serve no purpose and can pollute scope if named
(when-not (= :statement (:context env))
(let [loop-locals (seq (mapcat :names (filter #(and % @(:flag %)) recur-frames)))]
(let [loop-locals (seq (concat
(mapcat :names (filter #(and % @(:flag %)) recur-frames))
(mapcat :name loop-lets)))]
(when loop-locals
(when (= :return (:context env))
(print "return "))
Expand Down Expand Up @@ -586,6 +588,7 @@
(def specials '#{if def fn* do let* loop* throw try* recur new set! ns deftype* defrecord* . js* & quote})

(def ^:dynamic *recur-frames* nil)
(def ^:dynamic *loop-lets* nil)

(defmacro disallowing-recur [& body]
`(binding [*recur-frames* (cons nil *recur-frames*)] ~@body))
Expand Down Expand Up @@ -720,7 +723,8 @@
max-fixed-arity (apply max (map :max-fixed-arity methods))
variadic (boolean (some :variadic methods))]
;;todo - validate unique arities, at most one variadic, variadic takes max required args
{:env env :op :fn :name mname :methods methods :variadic variadic :recur-frames *recur-frames*
{:env env :op :fn :name mname :methods methods :variadic variadic
:recur-frames *recur-frames* :loop-lets *loop-lets*
:jsdoc [(when variadic "@param {...*} var_args")]
:max-fixed-arity max-fixed-arity}))

Expand Down Expand Up @@ -748,7 +752,10 @@
[bes env])))
recur-frame (when is-loop {:names (vec (map :name bes)) :flag (atom nil)})
{:keys [statements ret children]}
(binding [*recur-frames* (if recur-frame (cons recur-frame *recur-frames*) *recur-frames*)]
(binding [*recur-frames* (if recur-frame (cons recur-frame *recur-frames*) *recur-frames*)
*loop-lets* (cond
is-loop ()
*loop-lets* (cons {:names (vec (map :name bes))} *loop-lets*))]
(analyze-block (assoc env :context (if (= :expr context) :return context)) exprs))]
{:env encl-env :op :let :loop is-loop
:bindings bes :statements statements :ret ret :form form :children (into [children] (map :init bes))}))
Expand Down

0 comments on commit 6feae43

Please sign in to comment.