| author | Alan Dipert
<alan@dipert.org> 2026-11-11 03:24:01 UTC |
| committer | Alan Dipert
<alan@dipert.org> 2026-11-11 03:24:01 UTC |
| parent | 2014360db343c62d6d7d0930bee900f0b5b97b92 |
| test/com/tailrecursion/blacktide/assignment_test.clj | +3 | -4 |
| test/com/tailrecursion/blacktide/backend_fixture.clj | +14 | -2 |
| test/com/tailrecursion/blacktide/case_test.clj | +17 | -17 |
| test/com/tailrecursion/blacktide/collections_test.clj | +1 | -1 |
| test/com/tailrecursion/blacktide/control_test.clj | +4 | -4 |
| test/com/tailrecursion/blacktide/invocation_test.clj | +3 | -6 |
| test/com/tailrecursion/blacktide/jumps_test.clj | +2 | -2 |
| test/com/tailrecursion/blacktide/jvm_fixture.clj | +50 | -11 |
| test/com/tailrecursion/blacktide/jvm_test.clj | +4 | -20 |
| test/com/tailrecursion/blacktide/lookup_test.clj | +3 | -15 |
| test/com/tailrecursion/blacktide/loops_test.clj | +19 | -19 |
| test/com/tailrecursion/blacktide/native_sites_test.clj | +3 | -4 |
| test/com/tailrecursion/blacktide/source_loops_test.clj | +11 | -12 |
| test/com/tailrecursion/blacktide/source_test.clj | +4 | -5 |
| test/com/tailrecursion/blacktide/subset_test.clj | +3 | -3 |
diff --git a/test/com/tailrecursion/blacktide/assignment_test.clj b/test/com/tailrecursion/blacktide/assignment_test.clj index 0e26566..a235757 100644 --- a/test/com/tailrecursion/blacktide/assignment_test.clj +++ b/test/com/tailrecursion/blacktide/assignment_test.clj @@ -7,7 +7,6 @@ [clojure.test.check.properties :as prop] [com.tailrecursion.blacktide :as lh :refer [loophole setq psetq]] [com.tailrecursion.blacktide.backend-fixture :as backend] - [com.tailrecursion.blacktide.source-test :as source] [com.tailrecursion.assignment-model :as oracle])) (defn add [a b] (+ a b)) @@ -60,10 +59,10 @@ ['(setq [x] 1) :invalid-assignment] ['(psetq missing 1) :unknown-assignment] ['(let [x 3] (setq x 4)) :immutable-assignment]]] - (is (= kind (:kind (source/rejection (list 'loophole '[x 1] body)))))) + (is (= kind (:kind (backend/rejection (list 'loophole '[x 1] body)))))) (is (= [1 2] (loophole [setq vector] (setq 1 2)))) (is (= [3] (loophole [psetq vector] (psetq 3)))) - (is (= :immutable-assignment (:kind (source/rejection '(let [outside 1] (loophole [] (setq outside 2))))))) + (is (= :immutable-assignment (:kind (backend/rejection '(let [outside 1] (loophole [] (setq outside 2))))))) (is (= 2 (loophole [x 1] (lh/setq x 2))))) (defn render [node] @@ -103,7 +102,7 @@ (let [args (concat (map #(list 'setq 'x %) (range 1 (inc n))) ['(do (setq f list) x) 'x]) form (list 'loophole '[f vector x 0] [(cons 'f args) '(f :after) 'x]) expected [(vec (concat (range 1 (inc n)) [n n])) '(:after) n]] - (is (= expected (source/run-form form)) (pr-str {:arity (+ n 2) :form form}))))) + (is (= expected (backend/run-form form)) (pr-str {:arity (+ n 2) :form form}))))) (defspec generated-effectful-conditions {:num-tests 100 :seed 20261104} (prop/for-all [test (gen/elements [(oracle/batch :psetq 'x (oracle/read-var 'y) 'y (oracle/read-var 'x)) diff --git a/test/com/tailrecursion/blacktide/backend_fixture.clj b/test/com/tailrecursion/blacktide/backend_fixture.clj index 1076334..576b63b 100644 --- a/test/com/tailrecursion/blacktide/backend_fixture.clj +++ b/test/com/tailrecursion/blacktide/backend_fixture.clj @@ -13,9 +13,21 @@ compiler/compile-program)] (f))) +(defn run-form + ([form] (run-form 'com.tailrecursion.blacktide.backend-fixture form)) + ([namespace form] (binding [*ns* (the-ns namespace)] (eval form)))) + +(defn root-error [error] + (if-let [cause (ex-cause error)] (recur cause) error)) + +(defn rejection + ([form] (rejection 'com.tailrecursion.blacktide.backend-fixture form)) + ([namespace form] + (try (run-form namespace form) nil + (catch Throwable error (ex-data (root-error error)))))) + (defn compile-program [form mode] - (binding [*ns* (the-ns 'com.tailrecursion.blacktide.backend-fixture)] - (with-backend mode #(eval (list 'fn '[events] form))))) + (with-backend mode #(run-form (list 'fn '[events] form)))) (defn capture [pass form] (let [result (atom nil) original @pass] diff --git a/test/com/tailrecursion/blacktide/case_test.clj b/test/com/tailrecursion/blacktide/case_test.clj index c8ee1da..90767f7 100644 --- a/test/com/tailrecursion/blacktide/case_test.clj +++ b/test/com/tailrecursion/blacktide/case_test.clj @@ -7,8 +7,8 @@ [clojure.test.check.properties :as prop] [clojure.walk :as walk] [com.tailrecursion.blacktide :refer [loophole setq psetq label goto]] - [com.tailrecursion.blacktide.jvm-test :as jvm] - [com.tailrecursion.blacktide.source-test :as source])) + [com.tailrecursion.blacktide.jvm-fixture :as jvm] + [com.tailrecursion.blacktide.backend-fixture :as backend])) (defn compile-function [form] (binding [*ns* (the-ns 'com.tailrecursion.blacktide.case-test)] @@ -57,10 +57,10 @@ (is (= 0 (loophole [x 0] (case (setq x 1) :default) (setq x 0)))) (is (= [:string :long :object :object] (loophole [x 1] - [(.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser (case x 1 "x" "y")) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser (case x 1 2 3)) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser (case x 1 true false)) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser (case x 1 2 nil))])))) + [(.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser (case x 1 "x" "y")) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser (case x 1 2 3)) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser (case x 1 true false)) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser (case x 1 2 nil))])))) (deftest case-jumps-do-not-fall-through (is (= :done (loophole [] @@ -81,8 +81,8 @@ (0 1 2) (do (setq sum (+ sum i)) (recur (inc i))) 3 (do (setq sum (+ sum i)) [i sum])))))) (doseq [form '[(loop [i 3] (case i 0 :done (recur (dec i)))) - (loop [i 1] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice chooser (case i 1 i 0))) - (loop [i 1] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice chooser (case i 1 "a" nil))) + (loop [i 1] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice chooser (case i 1 i 0))) + (loop [i 1] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice chooser (case i 1 "a" nil))) (loop [i 0] (case i 0 (let [i 1] (case i 1 :yes :no)) :wrong))]] (is (= (jvm/outcome form) (jvm/outcome (list 'loophole [] form))) (pr-str form))) (is (= :done (loophole [] (loop [i 1] (case i 0 :done (do (setq) (psetq) (recur 0)))))))) @@ -95,7 +95,7 @@ (deftest case-macro-environments-and-initialization (reset! expansions []) (is (= :group - (source/run-form + (backend/run-form '(com.tailrecursion.blacktide/loophole [] (case :a (:a :b) (com.tailrecursion.blacktide.case-test/expanded :group :group) @@ -111,7 +111,7 @@ (is (= :marker-position (try (eval form) nil (catch Throwable error - (:kind (ex-data (loop [error error] (if-let [cause (ex-cause error)] (recur cause) error))))))))))) + (:kind (ex-data (backend/root-error error)))))))))) (deftest native-case-errors-and-source-validation (doseq [form '[(case 1 1 :a 1 :b) @@ -122,12 +122,12 @@ (is (= (:error (jvm/outcome form)) (:error (jvm/outcome (list 'loophole [] form)))) (pr-str form))) ;; The public diagnostic contract distinguishes a missing dispatch expression ;; from core case's constant/default errors. - (is (= :invalid-case (:kind (source/rejection '(loophole [] (case)))))) - (is (= :marker-position (:kind (source/rejection '(loophole [] (case 1 1 (label same) 2 (label same))))))) - (is (= :undefined-label (:kind (source/rejection '(loophole [] (case 1 1 :ok 2 (goto missing))))))) + (is (= :invalid-case (:kind (backend/rejection '(loophole [] (case)))))) + (is (= :marker-position (:kind (backend/rejection '(loophole [] (case 1 1 (label same) 2 (label same))))))) + (is (= :undefined-label (:kind (backend/rejection '(loophole [] (case 1 1 :ok 2 (goto missing))))))) (is (= :marker-position - (:kind (source/rejection '(loophole [] (goto inside) (+ 1 (case 0 0 (do (label inside) 2) 3))))))) - (is (= :invalid-recur (:kind (source/rejection '(loophole [] (loop [] (inc (case 0 0 (recur) 1))))))))) + (:kind (backend/rejection '(loophole [] (goto inside) (+ 1 (case 0 0 (do (label inside) 2) 3))))))) + (is (= :invalid-recur (:kind (backend/rejection '(loophole [] (loop [] (inc (case 0 0 (recur) 1))))))))) (deftest prepared-dispatch-and-expansion-equivalence (doseq [body '[(case input 0 :zero 2 :two :other) @@ -153,7 +153,7 @@ (case input 1 "x" nil) (case input 1 nil "x")]] (let [form (list 'let '[input 1] - (list '.choose (with-meta 'chooser {:tag 'com.tailrecursion.blacktide.jvm_test.Choice}) body))] + (list '.choose (with-meta 'chooser {:tag 'com.tailrecursion.blacktide.jvm_fixture.Choice}) body))] (is (= (jvm/outcome form) (jvm/outcome (list 'loophole [] form))))))) (defn command-model [{:keys [tokens a b weight width]}] @@ -199,7 +199,7 @@ (label ~'finished) [~'m ~'n ~'i ~'out])) (defn command-outcome [config wrap] - (try {:value (source/run-form (wrap (command-program config)))} + (try {:value (backend/run-form (wrap (command-program config)))} (catch Throwable error {:error (class error) :message (ex-message error)}))) (defspec generated-case-loop-jump-programs {:num-tests 120 :seed 173205} diff --git a/test/com/tailrecursion/blacktide/collections_test.clj b/test/com/tailrecursion/blacktide/collections_test.clj index 46bca6c..1fed09e 100644 --- a/test/com/tailrecursion/blacktide/collections_test.clj +++ b/test/com/tailrecursion/blacktide/collections_test.clj @@ -57,7 +57,7 @@ (deftest constant-duplicates-are-compile-errors (doseq [body [(array-map '(key-a) 1 '(key-b) 2)] form [body (list 'loophole [] body)]] - (let [error (try (observe form) nil (catch Throwable e (loop [e e] (if-let [cause (ex-cause e)] (recur cause) e))))] + (let [error (try (observe form) nil (catch Throwable e (backend/root-error e)))] (is (instance? IllegalArgumentException error)))) ;; Native constant sets coalesce macro-expanded duplicates. Metadata prevents ;; that constant folding, so the same duplicates then fail during construction. diff --git a/test/com/tailrecursion/blacktide/control_test.clj b/test/com/tailrecursion/blacktide/control_test.clj index 5c08b27..4a20282 100644 --- a/test/com/tailrecursion/blacktide/control_test.clj +++ b/test/com/tailrecursion/blacktide/control_test.clj @@ -2,7 +2,7 @@ "Source control flow and live values across state-machine transitions." (:require [clojure.test :refer [deftest is]] [com.tailrecursion.blacktide :refer [loophole setq psetq]] - [com.tailrecursion.blacktide.source-test :as source])) + [com.tailrecursion.blacktide.backend-fixture :as backend])) (defn record! [events tag value] (swap! events conj tag) value) @@ -54,8 +54,8 @@ (record! events :after :bad)) (catch Throwable e e)))) (is (= [:first 1] @events))) - (is (= :unresolved-symbol (:kind (source/rejection '(loophole [] (if true 1 missing)))))) - (is (= :unresolved-symbol (:kind (source/rejection '(loophole [] (throw nil) missing))))) + (is (= :unresolved-symbol (:kind (backend/rejection '(loophole [] (if true 1 missing)))))) + (is (= :unresolved-symbol (:kind (backend/rejection '(loophole [] (throw nil) missing))))) (doseq [form ['(if true) '(if true 1 2 3) '(throw) '(throw nil nil)]] (is (= (if (= 'if (first form)) :invalid-if :invalid-throw) - (:kind (source/rejection (list 'loophole [] form))))))) + (:kind (backend/rejection (list 'loophole [] form))))))) diff --git a/test/com/tailrecursion/blacktide/invocation_test.clj b/test/com/tailrecursion/blacktide/invocation_test.clj index 3e72e58..78f72cb 100644 --- a/test/com/tailrecursion/blacktide/invocation_test.clj +++ b/test/com/tailrecursion/blacktide/invocation_test.clj @@ -3,7 +3,8 @@ method Var. Compare values, failures and evaluation traces with Clojure." (:require [clojure.test :refer [deftest is]] [clojure.core.protocols :as p] - [com.tailrecursion.blacktide.backend-fixture :as backend])) + [com.tailrecursion.blacktide.backend-fixture :as backend] + [com.tailrecursion.blacktide.jvm-fixture])) (deftype DirectReduction [events] p/CollReduce @@ -112,10 +113,6 @@ (def java-list {:on 'java.util.List :method-map {:list-set :set}}) (defn list-set [& _] :fallback) (alter-meta! #'list-set assoc :protocol #'java-list) -(def java-map {:on 'java.util.Map :method-map {:map-compute :compute}}) -(defn map-compute [_ k f] (f k :fallback)) -(alter-meta! #'map-compute assoc :protocol #'java-map) - (deftest interface-conversions-are-conditional-and-ordered (let [observe (fn [body mode location direct?] (let [events (atom []) f ((backend/compile-program (wrapped body location) mode) nil) @@ -131,7 +128,7 @@ (pr-str [index direct? mode]))))) (deftest interface-functional-arguments - (let [body '(com.tailrecursion.blacktide.invocation-test/map-compute target :key + (let [body '(com.tailrecursion.blacktide.jvm-fixture/map-compute target :key (do (swap! events conj :argument) vector)) observe (fn [mode location direct?] (let [events (atom []) f ((backend/compile-program (wrapped body location) mode) nil) diff --git a/test/com/tailrecursion/blacktide/jumps_test.clj b/test/com/tailrecursion/blacktide/jumps_test.clj index c751675..cdd7e2e 100644 --- a/test/com/tailrecursion/blacktide/jumps_test.clj +++ b/test/com/tailrecursion/blacktide/jumps_test.clj @@ -5,7 +5,7 @@ [clojure.test.check.generators :as gen] [clojure.test.check.properties :as prop] [com.tailrecursion.blacktide :refer [loophole label goto setq psetq]] - [com.tailrecursion.blacktide.source-test :as source])) + [com.tailrecursion.blacktide.backend-fixture :as backend])) (defn step [n] (dec n)) (defn more? [n] (pos? n)) @@ -43,7 +43,7 @@ ['(setq x (do (goto done) 1)) :marker-position] ['(loophole [] 1) :unsupported-form]] prefix [[] ['(goto done)]]] - (is (= kind (:kind (source/rejection (list* 'loophole '[x 0] (concat prefix [body '(label done)]))))) + (is (= kind (:kind (backend/rejection (list* 'loophole '[x 0] (concat prefix [body '(label done)]))))) (pr-str [prefix body])))) (defn sum-through [input] diff --git a/test/com/tailrecursion/blacktide/jvm_fixture.clj b/test/com/tailrecursion/blacktide/jvm_fixture.clj index 874a34d..7db9df1 100644 --- a/test/com/tailrecursion/blacktide/jvm_fixture.clj +++ b/test/com/tailrecursion/blacktide/jvm_fixture.clj @@ -1,18 +1,57 @@ (ns com.tailrecursion.blacktide.jvm-fixture - "Compile the small Java-only syntax fixture once into a temporary directory." - (:require [clojure.java.io :as io])) + "Shared JVM dispatch and lookup fixtures, with a native Clojure outcome oracle." + (:require [clojure.java.io :as io] + [com.tailrecursion.blacktide :refer [loophole setq psetq label goto]] + [com.tailrecursion.blacktide.backend-fixture :as backend])) (def fixture-class (let [directory (.toFile (java.nio.file.Files/createTempDirectory "blacktide-jvm-fixture-" (make-array java.nio.file.attribute.FileAttribute 0))) source (io/file directory "HostFixture.java") compiler (javax.tools.ToolProvider/getSystemJavaCompiler)] - (with-open [input (io/input-stream (io/resource "com/tailrecursion/blacktide/fixtures/HostFixture.java"))] - (io/copy input source)) - (when-not (zero? (.run compiler nil nil nil - (into-array String ["--release" "17" "-d" (.getPath directory) (.getPath source)]))) - (throw (ex-info "Java fixture compilation failed" {:directory directory}))) - (.defineClass ^clojure.lang.DynamicClassLoader (clojure.lang.RT/baseLoader) - "com.tailrecursion.blacktide.fixtures.HostFixture" - (java.nio.file.Files/readAllBytes - (.toPath (io/file directory "com/tailrecursion/blacktide/fixtures/HostFixture.class"))) nil))) + (try + (with-open [input (io/input-stream (io/resource "com/tailrecursion/blacktide/fixtures/HostFixture.java"))] + (io/copy input source)) + (when-not (zero? (.run compiler nil nil nil + (into-array String ["--release" "17" "-d" (.getPath directory) (.getPath source)]))) + (throw (ex-info "Java fixture compilation failed" {:directory directory}))) + (.defineClass ^clojure.lang.DynamicClassLoader (clojure.lang.RT/baseLoader) + "com.tailrecursion.blacktide.fixtures.HostFixture" + (java.nio.file.Files/readAllBytes + (.toPath (io/file directory "com/tailrecursion/blacktide/fixtures/HostFixture.class"))) nil) + (finally (doseq [file (reverse (file-seq directory))] (io/delete-file file)))))) + +(definterface Choice + (choose [^boolean x]) (choose [^long x]) (choose [^int x]) (choose [^double x]) + (choose [^String x]) (choose [^chars x]) (choose [^Object x]) (choose [^Number x])) +(def chooser + (reify Choice + (choose [_ ^boolean x] :boolean) (choose [_ ^long x] :long) (choose [_ ^int x] :int) (choose [_ ^double x] :double) + (choose [_ ^String x] :string) (choose [_ ^chars x] :chars) + (choose [_ ^Object x] :object) (choose [_ ^Number x] :number))) +(defn ^String text [] "x") +(defn primitive ^long [] 1) +(defn outcome [form] + (try + {:value (binding [*ns* (the-ns 'com.tailrecursion.blacktide.jvm-fixture)] + (eval (list (list 'fn [] form))))} + (catch Throwable error + {:error (class (backend/root-error error))}))) + +(deftype ObservedLookup [events entries] + clojure.lang.ILookup + (valAt [_ key] (swap! events conj [:val key]) (get entries key)) + (valAt [_ key default] (swap! events conj [:default key]) (get entries key default)) + clojure.lang.IKeywordLookup + (getLookupThunk [_ key] + (swap! events conj [:install key]) + (reify clojure.lang.ILookupThunk + (get [thunk target] + (if (instance? ObservedLookup target) + (do (swap! (.-events ^ObservedLookup target) conj [:get key]) + (get (.-entries ^ObservedLookup target) key)) + thunk))))) + +(def java-map {:on 'java.util.Map :method-map {:map-compute :compute}}) +(defn map-compute [_ k f] (f k :fallback)) +(alter-meta! #'map-compute assoc :protocol #'java-map) diff --git a/test/com/tailrecursion/blacktide/jvm_test.clj b/test/com/tailrecursion/blacktide/jvm_test.clj index 2a73e6d..4a6312b 100644 --- a/test/com/tailrecursion/blacktide/jvm_test.clj +++ b/test/com/tailrecursion/blacktide/jvm_test.clj @@ -5,31 +5,15 @@ [clojure.test.check.clojure-test :refer [defspec]] [clojure.test.check.generators :as gen] [clojure.test.check.properties :as prop] - [com.tailrecursion.blacktide.jvm-fixture] - [com.tailrecursion.blacktide :refer [loophole setq psetq label goto]])) - -(definterface Choice - (choose [^boolean x]) (choose [^long x]) (choose [^int x]) (choose [^double x]) - (choose [^String x]) (choose [^chars x]) (choose [^Object x]) (choose [^Number x])) -(def chooser - (reify Choice - (choose [_ ^boolean x] :boolean) (choose [_ ^long x] :long) (choose [_ ^int x] :int) (choose [_ ^double x] :double) - (choose [_ ^String x] :string) (choose [_ ^chars x] :chars) - (choose [_ ^Object x] :object) (choose [_ ^Number x] :number))) -(defn ^String text [] "x") -(defn primitive ^long [] 1) + [com.tailrecursion.blacktide.jvm-fixture :refer [chooser text primitive outcome]] + [com.tailrecursion.blacktide :refer [loophole setq psetq label goto]]) + (:import [com.tailrecursion.blacktide.jvm_fixture Choice])) + (def ^:dynamic *value* :root) (defmacro .answer [] 42) (defmacro constructed. [] 43) (defmacro inferred-tag [sym] (list 'quote (:tag (get &env sym)))) -(defn outcome [form] - (try - {:value (binding [*ns* (the-ns 'com.tailrecursion.blacktide.jvm-test)] - (eval (list (list 'fn [] form))))} - (catch Throwable error - {:error (class (loop [e error] (if-let [cause (ex-cause e)] (recur cause) e)))}))) - (deftest overloads-preserve-source-types (doseq [expr '[1 1.5 1N 1M 1/2 "x" nil false \a (int 1) (long 1) (double 1) (char-array [\a]) diff --git a/test/com/tailrecursion/blacktide/lookup_test.clj b/test/com/tailrecursion/blacktide/lookup_test.clj index 875dba5..67dc025 100644 --- a/test/com/tailrecursion/blacktide/lookup_test.clj +++ b/test/com/tailrecursion/blacktide/lookup_test.clj @@ -2,21 +2,9 @@ "Keyword call syntax determines cached IKeywordLookup versus ordinary ILookup dispatch. Native emission must preserve call sites, effects and cache faults." (:require [clojure.test :refer [deftest is]] - [com.tailrecursion.blacktide.backend-fixture :as backend])) - -(deftype ObservedLookup [events entries] - clojure.lang.ILookup - (valAt [_ key] (swap! events conj [:val key]) (get entries key)) - (valAt [_ key default] (swap! events conj [:default key]) (get entries key default)) - clojure.lang.IKeywordLookup - (getLookupThunk [_ key] - (swap! events conj [:install key]) - (reify clojure.lang.ILookupThunk - (get [thunk target] - (if (instance? ObservedLookup target) - (do (swap! (.-events ^ObservedLookup target) conj [:get key]) - (get (.-entries ^ObservedLookup target) key)) - thunk))))) + [com.tailrecursion.blacktide.backend-fixture :as backend] + [com.tailrecursion.blacktide.jvm-fixture]) + (:import [com.tailrecursion.blacktide.jvm_fixture ObservedLookup])) (deftype UncachedLookup [events entries] clojure.lang.ILookup diff --git a/test/com/tailrecursion/blacktide/loops_test.clj b/test/com/tailrecursion/blacktide/loops_test.clj index 7291329..b8d58ef 100644 --- a/test/com/tailrecursion/blacktide/loops_test.clj +++ b/test/com/tailrecursion/blacktide/loops_test.clj @@ -6,8 +6,8 @@ [clojure.test.check.generators :as gen] [clojure.test.check.properties :as prop] [com.tailrecursion.blacktide :refer [loophole label goto setq psetq]] - [com.tailrecursion.blacktide.source-test :as source] - [com.tailrecursion.blacktide.jvm-test :as jvm])) + [com.tailrecursion.blacktide.backend-fixture :as backend] + [com.tailrecursion.blacktide.jvm-fixture :as jvm])) (deftest source-recursion-and-macro-loops (is (= [2 1] (loophole [] (loop [n 3 a 1 b 2] (if (zero? n) [a b] (recur (dec n) b a)))))) @@ -49,13 +49,13 @@ (recur (dec n)))) x)))) (deftest native-loop-inference - (doseq [form '[(loop [i 1] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice chooser i)) - (loop [i (int 1)] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice chooser i)) - (loop [i (float 1)] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice chooser i)) + (doseq [form '[(loop [i 1] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice chooser i)) + (loop [i (int 1)] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice chooser i)) + (loop [i (float 1)] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice chooser i)) (loop [n 1 value 0] (if (pos? n) (recur (dec n) "string") value)) (loop [n 1 value 0] (if (pos? n) (recur (dec n) 1.5) (class value))) (loop [n 1 value 0] (if (pos? n) (recur (dec n) 1.5) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice chooser value))) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice chooser value))) (loop [a (java.util.ArrayList. [1 2 3]) i (int 1)] (.remove a i) (vec a)) (loop [x "abc"] (let [snapshot x] (String/.substring snapshot 1))) (loop [n 0] (if (zero? n) (recur 1) ^{:value n} [n])) @@ -66,7 +66,7 @@ (is (= (jvm/outcome form) (jvm/outcome (list 'loophole '[touched nil] body))) (pr-str [lowered? form]))) (is (= :long (loophole [x 1] (loop [n 2] (setq x n) - (loop [n 1] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser n)))))) + (loop [n 1] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser n)))))) ;; DSL writes retain the same initializer promotions as ordinary Clojure. (is (= (loop [i (int 1)] (class i)) (loophole [x nil] (loop [i (int 1)] (setq x true) (class i))))) (is (= (loop [i (float 1)] (class i)) (loophole [x nil] (loop [i (float 1)] (setq x true) (class i)))))) @@ -77,7 +77,7 @@ (defmacro make-constant [] (alter-meta! #'changing-value assoc :const true) nil) (deftest native-types-survive-later-macro-expansion - (let [body '[(loop [] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser tagged-value)) (erase-tag)] + (let [body '[(loop [] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser tagged-value)) (erase-tag)] evaluate (fn [wrap] (alter-meta! #'tagged-value assoc :tag 'String) (binding [*ns* (the-ns 'com.tailrecursion.blacktide.loops-test)] @@ -99,19 +99,19 @@ (alter-var-root #'changing-value (constantly :old)))))) (deftest lowered-loop-interop-boundary - (doseq [body '[(.choose ^com.tailrecursion.blacktide.jvm_test.Choice com.tailrecursion.blacktide.jvm-test/chooser i) - (let [copy i] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice com.tailrecursion.blacktide.jvm-test/chooser copy)) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice com.tailrecursion.blacktide.jvm-test/chooser (inc i)) - (loop [] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice com.tailrecursion.blacktide.jvm-test/chooser i)) - (loop [copy i] (.choose ^com.tailrecursion.blacktide.jvm_test.Choice com.tailrecursion.blacktide.jvm-test/chooser copy))]] + (doseq [body '[(.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice com.tailrecursion.blacktide.jvm-fixture/chooser i) + (let [copy i] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice com.tailrecursion.blacktide.jvm-fixture/chooser copy)) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice com.tailrecursion.blacktide.jvm-fixture/chooser (inc i)) + (loop [] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice com.tailrecursion.blacktide.jvm-fixture/chooser i)) + (loop [copy i] (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice com.tailrecursion.blacktide.jvm-fixture/chooser copy))]] (let [form (list 'loophole '[x 0] (list 'loop '[i 1] '(setq x 1) body))] (is (= (jvm/outcome (list 'loop '[i 1] body)) (jvm/outcome form)) (pr-str form)))) (is (= :int (loophole [x 0] (loop [i 1] (setq x 1) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser (int i)))))) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser (int i)))))) (is (= :object (loophole [x 0] (loop [i (identity 1)] (setq x 1) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser i))))) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser i))))) (is (= :long (loophole [x 0] (loop [i 1] (setq x 1) - (^{:param-tags [long]} com.tailrecursion.blacktide.jvm_test.Choice/.choose jvm/chooser i)))))) + (^{:param-tags [long]} com.tailrecursion.blacktide.jvm_fixture.Choice/.choose jvm/chooser i)))))) (deftest recur-legality-and-loop-scopes (doseq [[form kind] @@ -128,7 +128,7 @@ ['(loophole [] (goto body) (loop [] (label body))) :marker-position] ['(loophole [] (loop [] (goto other)) (loop [] (label other))) :marker-position] ['(loophole [] (goto done) (loop [] (recur 1)) (label done)) :recur-arity]]] - (is (= kind (:kind (source/rejection form))) (pr-str form)))) + (is (= kind (:kind (backend/rejection form))) (pr-str form)))) (deftest illegal-primitive-recur-conversions (doseq [cast '[byte short char]] @@ -136,7 +136,7 @@ lowered (list 'loop '[n 0] '(setq x n) (list 'recur (list cast 1)))] (is (= IllegalArgumentException (:error (jvm/outcome body)))) (is (= :invalid-recur-type - (:kind (source/rejection (list 'loophole '[x nil] lowered)))))))) + (:kind (backend/rejection (list 'loophole '[x nil] lowered)))))))) (defn loop-model [{:keys [limit cut width a b weight]}] (loop [i 0 a a b b history []] @@ -161,7 +161,7 @@ (label ~'done) ~'result)) (defn loop-outcome [config wrap] - (try {:value (source/run-form (wrap (loop-program config)))} + (try {:value (backend/run-form (wrap (loop-program config)))} (catch Throwable error {:error (class error) :message (ex-message error)}))) (defspec generated-nested-loops {:num-tests 240 :seed 161803} diff --git a/test/com/tailrecursion/blacktide/native_sites_test.clj b/test/com/tailrecursion/blacktide/native_sites_test.clj index a028312..2372b13 100644 --- a/test/com/tailrecursion/blacktide/native_sites_test.clj +++ b/test/com/tailrecursion/blacktide/native_sites_test.clj @@ -8,8 +8,7 @@ [com.tailrecursion.blacktide.compiler.passes.structure :as structure] [com.tailrecursion.blacktide.backend-fixture :as backend] [com.tailrecursion.blacktide :refer [loophole setq label goto]] - [com.tailrecursion.blacktide.invocation-test] - [com.tailrecursion.blacktide.lookup-test :as lookup])) + [com.tailrecursion.blacktide.jvm-fixture :as jvm])) (def flags [true false false true]) (defn identity-pattern [values] @@ -27,7 +26,7 @@ #(.apply ^java.util.function.BiFunction % :left :right)] ['(java.util.Map/.compute target :key callback) #(.apply ^java.util.function.BiFunction % :left :right)] - ['(com.tailrecursion.blacktide.invocation-test/map-compute target :key callback) + ['(com.tailrecursion.blacktide.jvm-fixture/map-compute target :key callback) #(.apply ^java.util.function.BiFunction % :left :right)]] mode [:default :dispatcher]] (let [ordinary (list 'let ['values '(if flag [1 2] [3 4])] (list 'vector 'values tail)) @@ -43,7 +42,7 @@ (defn cached-lookups [mode wrapped?] (let [lookup '(:k target) body `(do (if ~'flag (swap! ~'events conj :yes) (swap! ~'events conj :no)) ~lookup) - events (atom []) target (lookup/->ObservedLookup events {:k 42}) + events (atom []) target (jvm/->ObservedLookup events {:k 42}) f ((backend/compile-program (list 'fn '[flag target] (if wrapped? (list 'loophole [] body) body)) mode) events) values (mapv #(f % target) flags)] [values @events])) diff --git a/test/com/tailrecursion/blacktide/source_loops_test.clj b/test/com/tailrecursion/blacktide/source_loops_test.clj index 61c941d..4159d51 100644 --- a/test/com/tailrecursion/blacktide/source_loops_test.clj +++ b/test/com/tailrecursion/blacktide/source_loops_test.clj @@ -8,9 +8,8 @@ [clojure.walk :as walk] [com.tailrecursion.blacktide :refer [loophole]] [com.tailrecursion.blacktide.backend-fixture :as backend] - [com.tailrecursion.blacktide.jvm-test :as jvm])) + [com.tailrecursion.blacktide.jvm-fixture :as jvm])) -(defn root-error [e] (if-let [cause (ex-cause e)] (recur cause) e)) (defn canonical [value] (cond (instance? Double value) [(class value) (Double/doubleToLongBits value)] @@ -40,7 +39,7 @@ (try (binding [*ns* (the-ns 'com.tailrecursion.blacktide.source-loops-test)] (backend/with-backend mode #(eval (list 'fn '[events input n] (enclose body mode))))) - (catch Throwable e {:compile (class (root-error e))}))) + (catch Throwable e {:compile (class (backend/root-error e))}))) (defn outcome [f input n] (if (map? f) f (let [events (atom [])] @@ -92,8 +91,8 @@ (loop [~'i 0 ~'x ~init ~'y (+ ~'x 1)] (if (< ~'i ~'n) (recur (inc ~'i) (~'step ~'x) (~'step ~'y)) - [(.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser ~'x) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser ~'y) + [(.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser ~'x) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser ~'y) ~'x ~'y]))) ordinary (compile-body body :ordinary)]] (doseq [mode [:default :dispatcher] @@ -128,20 +127,20 @@ (doseq [body '[(let [step (fn ^long [^long x] (inc x))] (loop [i 0 x 1000] (if (< i n) (recur (inc i) (step x)) - [(.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser x) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser i)]))) + [(.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser x) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser i)]))) (let [step (fn ^long [^long x] (inc x))] (loop [i 0 x 1000 y x] (if (< i n) (recur (inc i) (step x) x) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser y)))) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser y)))) (let [step (fn ^double [^double x] (+ x 0.5))] (loop [i 0 x 1000.0] (if (< i n) (recur (inc i) (step x)) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser x)))) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser x)))) (let [step (fn [x] input)] (loop [i 0 x 1000] (if (< i n) (recur (inc i) (step x)) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser x)))) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser x)))) (let [step (fn ^long [^long x] (inc x))] (loop [i 0 x 1000] (if (< i n) (recur (inc i) (step x)) (Math/abs x)))) @@ -180,8 +179,8 @@ initial (if literal? (if double? 1.5 1000) (list cast 'input)) result (if scalar? '(- y y) '[x y (class x) (class y) (identical? x x) (identical? x y) (identical? i i) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser x) - (.choose ^com.tailrecursion.blacktide.jvm_test.Choice jvm/chooser y)]) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser x) + (.choose ^com.tailrecursion.blacktide.jvm_fixture.Choice jvm/chooser y)]) body `(let [~'bias ~(if double? (double k) k) ~'step (fn ~parameters ~compute)] (loop [~'i ~(if double? 0.0 0) diff --git a/test/com/tailrecursion/blacktide/source_test.clj b/test/com/tailrecursion/blacktide/source_test.clj index 8dd4ab5..36456cc 100644 --- a/test/com/tailrecursion/blacktide/source_test.clj +++ b/test/com/tailrecursion/blacktide/source_test.clj @@ -6,7 +6,8 @@ [clojure.test.check.generators :as gen] [clojure.test.check.properties :as prop] [com.tailrecursion.blacktide :as lh :refer [loophole label goto setq psetq]] - [com.tailrecursion.blacktide.source-fixture :as fixture])) + [com.tailrecursion.blacktide.source-fixture :as fixture] + [com.tailrecursion.blacktide.backend-fixture :as backend])) (defn sum [a b] (+ a b)) (defn record! [events tag value] (swap! events conj tag) value) @@ -20,11 +21,9 @@ (defn change-operator [x] (set! *operator* (constantly :new)) x) (defn run-form [form] - (binding [*ns* (the-ns 'com.tailrecursion.blacktide.source-test)] (eval form))) + (backend/run-form 'com.tailrecursion.blacktide.source-test form)) (defn rejection [form] - (try (run-form form) nil - (catch Throwable e - (loop [e e] (if-let [cause (ex-cause e)] (recur cause) (ex-data e)))))) + (backend/rejection 'com.tailrecursion.blacktide.source-test form)) (deftest sequential-scopes-and-results (is (nil? (loophole []))) diff --git a/test/com/tailrecursion/blacktide/subset_test.clj b/test/com/tailrecursion/blacktide/subset_test.clj index 6b4db4a..ae73295 100644 --- a/test/com/tailrecursion/blacktide/subset_test.clj +++ b/test/com/tailrecursion/blacktide/subset_test.clj @@ -3,7 +3,7 @@ callers may freely use Clojure outside the region. Quoted data stays opaque." (:require [clojure.test :refer [deftest is]] [com.tailrecursion.blacktide :refer [loophole label goto setq]] - [com.tailrecursion.blacktide.source-test :as source])) + [com.tailrecursion.blacktide.backend-fixture :as backend])) (defmacro hidden-function [] `(fn [] :hidden)) (defmacro hidden-label [] `(label ~'hidden)) @@ -18,7 +18,7 @@ (com.tailrecursion.blacktide.subset-test/hidden-function)] prefix [[] ['(goto done)]]] (is (= :unsupported-form - (:kind (source/rejection (list* 'loophole '[x 0] (concat prefix [body '(label done)]))))) + (:kind (backend/rejection (list* 'loophole '[x 0] (concat prefix [body '(label done)]))))) (pr-str [prefix body])))) (deftest operands-cannot-hide-transfers @@ -34,7 +34,7 @@ (identity (loop [] (goto done))) ^{:note (do (goto done) 1)} [1] (let [] (com.tailrecursion.blacktide.subset-test/hidden-label))]] - (is (= :marker-position (:kind (source/rejection (list 'loophole '[x 0] body '(label done))))) (pr-str body))) + (is (= :marker-position (:kind (backend/rejection (list 'loophole '[x 0] body '(label done))))) (pr-str body))) (is (= :ok (loophole [] (do (label a) (do (goto b))) :wrong (label b) :ok))) (is (= '(fn [] (goto missing)) (loophole [] '(fn [] (goto missing))))))