case*
special form | since v0.0-2227 | Edit |
(defmethod parse 'case*
[op env [_ sym tests thens default :as form] name _]
(assert (symbol? sym) "case* must switch on symbol")
(assert (every? vector? tests) "case* tests must be grouped in vectors")
(let [expr-env (assoc env :context :expr)
v (disallowing-recur (analyze expr-env sym))
tests (mapv #(mapv (fn [t] (analyze expr-env t)) %) tests)
thens (mapv #(analyze env %) thens)
nodes (mapv (fn [tests then]
{:op :case-node
:env env
:tests (mapv (fn [test]
{:op :case-test
:form (:form test)
:env expr-env
:test test
:children [:test]})
tests)
:then {:op :case-then
:form (:form then)
:env env
:then then
:children [:then]}
:children [:tests :then]})
tests
thens)
default (analyze env default)]
(assert (every? (fn [t]
(or
(-> t :info :const)
(and (= :const (:op t))
((some-fn number? string? char?) (:form t)))))
(apply concat tests))
"case* tests must be numbers, strings, or constants")
{:env env :op :case :form form
:test v :nodes nodes :default default
:children [:test :nodes :default]}))