diff --git a/src/uclj/core.clj b/src/uclj/core.clj index 6ac5459..170183d 100644 --- a/src/uclj/core.clj +++ b/src/uclj/core.clj @@ -595,9 +595,12 @@ (gen-eval-node (aget #^objects &b index))) (if (var? (resolve expr)) (let [^clojure.lang.Var resolved-expr (resolve expr)] - (if (and (bound? resolved-expr) (not (.isDynamic resolved-expr))) - (let [expr-val @resolved-expr] (gen-eval-node {::var resolved-expr} expr-val)) - (gen-eval-node {::unbound-var resolved-expr} @resolved-expr))) ;; var was unbound at compile time so we need to deref in in runtime + (cond (.isMacro resolved-expr) + (throw (new RuntimeException (str "Can't take value of a macro: " resolved-expr))) + (and (bound? resolved-expr) (not (.isDynamic resolved-expr))) + (let [expr-val @resolved-expr] (gen-eval-node {::var resolved-expr} expr-val)) + :else + (gen-eval-node {::unbound-var resolved-expr} @resolved-expr))) ;; var was unbound at compile time so we need to deref in in runtime (if-let [parent (some-> expr namespace symbol resolve)] (if (class? parent) (gen-eval-node (clojure.lang.Reflector/getStaticField ^Class parent (name expr))) diff --git a/test/uclj/core_test.clj b/test/uclj/core_test.clj index 6a03ca5..29cb180 100644 --- a/test/uclj/core_test.clj +++ b/test/uclj/core_test.clj @@ -28,6 +28,10 @@ (evaluator '(let [~@(interleave varnames (range i))] (+ ~@(take i varnames))))))))))) +(deftest test-eval-sym + (testing "taking value of macro" + (is (thrown? RuntimeException (evaluator '(do ->)))))) + (deftest test-eval-try (testing "try-catch maintains sybol usage across closure" (is (= 2 (evaluator '(let [a 1 b 2 c 3]