Round 2 of the persistent-collections work. Add a real 32-way branching-trie persistent vector (src/jolt/pv.janet) with a tail buffer: O(log32 n) conj/assoc/nth/pop, with unchanged subtrees shared by identity. Vector literals and vec/vector/conj/assoc/subvec/etc. now produce and maintain these in the default (immutable) build, replacing the old tuple-based vectors. Every core seq op, the destructurer, IFn application, the printers, =, and the evaluator's literal/splice paths were taught to handle the pvec type. Define several Clojure seq fns that were silently leaking to Janet builtins (some, keep, interleave, flatten, mapcat, interpose) and broke once vectors became tables; normalize collections through realize-for-iteration everywhere. Build-time JOLT_MUTABLE flag now selects fast Janet-native mutable collections: in that mode vectors are arrays (conj appends in place, vector? true, print []), sharing one representation with lists. Default build is immutable. Tests: conformance 206/206, features 71/71, jank 119 (baseline). Test helpers normalized so Janet-level = compares against tuple literals regardless of repr. The 2 test-load-sci failures (bit-clear/get-method) pre-date this work.
77 lines
3.4 KiB
Text
77 lines
3.4 KiB
Text
(use ../src/jolt/api)
|
|
(defn ct-eval [ctx s] (normalize-pvecs (eval-string ctx s)))
|
|
(print "=== CLJS Ported Part 2 ===")
|
|
(print "12: atoms...")
|
|
(let [ctx (init)]
|
|
(assert (= 0 (ct-eval ctx "(deref (atom 0))")) "deref")
|
|
(assert (= 1 (ct-eval ctx "(let [a (atom 0)] (swap! a inc) (deref a))")) "swap!")
|
|
(assert (= true (ct-eval ctx "(atom? (atom 0))")) "atom?"))
|
|
(print " ok")
|
|
(print "13: special forms...")
|
|
(let [ctx (init)]
|
|
(assert (= 30 (ct-eval ctx "(let [x 10 y 20] (+ x y))")) "let")
|
|
(assert (= :a (ct-eval ctx "(if true :a :b)")) "if true")
|
|
(assert (= :b (ct-eval ctx "(if false :a :b)")) "if false")
|
|
(assert (= 2 (ct-eval ctx "(do 1 2)")) "do")
|
|
(assert (= 3 (ct-eval ctx "(loop [x 0] (if (< x 3) (recur (inc x)) x))")) "loop")
|
|
(assert (= "caught" (ct-eval ctx "(try (throw 42) (catch Exception e \"caught\"))")) "try catch"))
|
|
(print " ok")
|
|
(print "14: macros...")
|
|
(let [ctx (init)]
|
|
(ct-eval ctx "(defn add [a b] (+ a b))")
|
|
(assert (= 7 (ct-eval ctx "(add 3 4)")) "defn")
|
|
(assert (= 42 (ct-eval ctx "(when true 42)")) "when")
|
|
(assert (= 3 (ct-eval ctx "(and 1 2 3)")) "and")
|
|
(assert (= 1 (ct-eval ctx "(or 1 2 3)")) "or")
|
|
(assert (= 49 (ct-eval ctx "((fn [x] (* x x)) 7)")) "fn"))
|
|
(print " ok")
|
|
(print "15: constructors...")
|
|
(let [ctx (init)]
|
|
(assert (= 3 (ct-eval ctx "(count (vector 1 2 3))")) "vector count")
|
|
(assert (= 2 (ct-eval ctx "(count (hash-map :a 1 :b 2))")) "hash-map count")
|
|
(assert (= 3 (ct-eval ctx "(count (hash-set 1 2 3))")) "hash-set count")
|
|
(assert (= 3 (ct-eval ctx "(count (zipmap [:a :b :c] [1 2 3]))")) "zipmap count"))
|
|
(print " ok")
|
|
(print "16: printing...")
|
|
(let [ctx (init)]
|
|
(assert (= "hello" (ct-eval ctx "(str \"hello\")")) "str")
|
|
(assert (= "42" (ct-eval ctx "(str 42)")) "str number")
|
|
(assert (= "a" (ct-eval ctx "(name :a)")) "name")
|
|
(assert (= ":hello" (ct-eval ctx "(pr-str :hello)")) "pr-str keyword"))
|
|
(print " ok")
|
|
(print "17: apply...")
|
|
(let [ctx (init)]
|
|
(assert (= 3 (ct-eval ctx "(apply + [1 2])")) "apply +")
|
|
(assert (= 3 (ct-eval ctx "(apply max [1 3 2])")) "apply max"))
|
|
(print " ok")
|
|
(print "18: equality...")
|
|
(let [ctx (init)]
|
|
(assert (= true (ct-eval ctx "(= {:a 1 :b 2} {:b 2 :a 1})")) "map order-independent")
|
|
(assert (= false (ct-eval ctx "(= {:a 1} {:a 2})")) "map different values")
|
|
(assert (= 1 (ct-eval ctx "(:a (with-meta {:a 1} {:c 3}))")) "with-meta preserves value")
|
|
(assert (= 3 (ct-eval ctx "(:c (with-meta {:a 1} {:c 3}))")) "with-meta preserves meta via get"))
|
|
(print " ok")
|
|
(print "19: higher-order...")
|
|
(let [ctx (init)]
|
|
(assert (= 3 (ct-eval ctx "((comp inc inc) 1)")) "comp")
|
|
(assert (function? (ct-eval ctx "(partial + 1 2)")) "partial returns fn")
|
|
(assert (= 3 (ct-eval ctx "(identity 3)")) "identity"))
|
|
(print " ok")
|
|
(print "20: seq edge cases...")
|
|
(let [ctx (init)]
|
|
(assert (= nil (ct-eval ctx "(seq [])")) "seq empty")
|
|
(assert (= nil (ct-eval ctx "(seq nil)")) "seq nil")
|
|
(assert (= nil (ct-eval ctx "(first nil)")) "first nil")
|
|
(assert (= 1 (ct-eval ctx "(first [1 2 3])")) "first vector"))
|
|
(print " ok")
|
|
(print "21: atoms extended...")
|
|
(let [ctx (init)]
|
|
(ct-eval ctx "(def a (atom 10))")
|
|
(assert (= 10 (ct-eval ctx "(deref a)")) "deref")
|
|
(ct-eval ctx "(reset! a 42)")
|
|
(assert (= 42 (ct-eval ctx "(deref a)")) "reset!")
|
|
(ct-eval ctx "(swap! a inc)")
|
|
(assert (= 43 (ct-eval ctx "(deref a)")) "swap! inc")
|
|
(assert (= 43 (ct-eval ctx "@a")) "@ deref macro"))
|
|
(print " ok")
|
|
(print "\nAll CLJS Ported Part 2 tests passed!")
|