|
391 | 391 | (println "})()"))))
|
392 | 392 |
|
393 | 393 | (defmethod emit :fn
|
394 |
| - [{:keys [name env methods max-fixed-arity variadic recur-frames]}] |
| 394 | + [{:keys [name env methods max-fixed-arity variadic recur-frames loop-lets]}] |
395 | 395 | ;;fn statements get erased, serve no purpose and can pollute scope if named
|
396 | 396 | (when-not (= :statement (:context env))
|
397 |
| - (let [loop-locals (seq (mapcat :names (filter #(and % @(:flag %)) recur-frames)))] |
| 397 | + (let [loop-locals (seq (concat |
| 398 | + (mapcat :names (filter #(and % @(:flag %)) recur-frames)) |
| 399 | + (mapcat :name loop-lets)))] |
398 | 400 | (when loop-locals
|
399 | 401 | (when (= :return (:context env))
|
400 | 402 | (print "return "))
|
|
586 | 588 | (def specials '#{if def fn* do let* loop* throw try* recur new set! ns deftype* defrecord* . js* & quote})
|
587 | 589 |
|
588 | 590 | (def ^:dynamic *recur-frames* nil)
|
| 591 | +(def ^:dynamic *loop-lets* nil) |
589 | 592 |
|
590 | 593 | (defmacro disallowing-recur [& body]
|
591 | 594 | `(binding [*recur-frames* (cons nil *recur-frames*)] ~@body))
|
|
720 | 723 | max-fixed-arity (apply max (map :max-fixed-arity methods))
|
721 | 724 | variadic (boolean (some :variadic methods))]
|
722 | 725 | ;;todo - validate unique arities, at most one variadic, variadic takes max required args
|
723 |
| - {:env env :op :fn :name mname :methods methods :variadic variadic :recur-frames *recur-frames* |
| 726 | + {:env env :op :fn :name mname :methods methods :variadic variadic |
| 727 | + :recur-frames *recur-frames* :loop-lets *loop-lets* |
724 | 728 | :jsdoc [(when variadic "@param {...*} var_args")]
|
725 | 729 | :max-fixed-arity max-fixed-arity}))
|
726 | 730 |
|
|
748 | 752 | [bes env])))
|
749 | 753 | recur-frame (when is-loop {:names (vec (map :name bes)) :flag (atom nil)})
|
750 | 754 | {:keys [statements ret children]}
|
751 |
| - (binding [*recur-frames* (if recur-frame (cons recur-frame *recur-frames*) *recur-frames*)] |
| 755 | + (binding [*recur-frames* (if recur-frame (cons recur-frame *recur-frames*) *recur-frames*) |
| 756 | + *loop-lets* (cond |
| 757 | + is-loop () |
| 758 | + *loop-lets* (cons {:names (vec (map :name bes))} *loop-lets*))] |
752 | 759 | (analyze-block (assoc env :context (if (= :expr context) :return context)) exprs))]
|
753 | 760 | {:env encl-env :op :let :loop is-loop
|
754 | 761 | :bindings bes :statements statements :ret ret :form form :children (into [children] (map :init bes))}))
|
|
0 commit comments