(defn analyze-let-bindings* [encl-env bindings]
(loop [bes []
env (assoc encl-env :context :expr)
bindings (seq (partition 2 bindings))]
(if-some [[name init] (first bindings)]
(let []
(when (or (some? (namespace name))
#?(:clj (.contains (str name) ".")
:cljs ^boolean (goog.string/contains (str name) ".")))
(throw (error encl-env (str "Invalid local name: " name))))
(let [init-expr (analyze-let-binding-init env init (cons {:params bes} *loop-lets*))
line (get-line name env)
col (get-col name env)
be {:name name
:line line
:column col
:init init-expr
:tag (get-let-tag name init-expr)
:local true
:shadow (-> env :locals name)
;; Give let* bindings same shape as var so
;; they get routed correctly in the compiler
:op :var
:env {:line line :column col}
:info {:name name
:shadow (-> env :locals name)}
:binding-form? true}
be (if (= :fn (:op init-expr))
;; TODO: can we simplify - David
(merge be
{:fn-var true
:variadic (:variadic init-expr)
:max-fixed-arity (:max-fixed-arity init-expr)
:method-params (map :params (:methods init-expr))})
be)]
(recur (conj bes be)
(assoc-in env [:locals name] be)
(next bindings))))
[bes env])))