Rewrite persistent_hash_map.clj with correct paren balancing. BitmapIndexedNode constructor + bit-or verified working in isolation. Core HAMT operations (bmn-assoc, bmn-find, phm-assoc, phm-get, phm-contains?, hash-map) structurally correct. Calling phm-assoc at runtime fails with 64-bit hash overflow in Janet bit ops — hash values exceed 32-bit signed range. Fix: wrap (hash key) with (bit-and (int h) 0x7FFFFFFF) in phm-assoc.
2 KiB
Core primitives for persistent data structures: alength, aget, aset, aclone, object-array, int-array, to-array (array interop); bit-and/or/xor/not, bit-shift-left/right, unsigned-bit-shift-right (trie indexing); int uses math/trunc; unchecked-inc/dec/add/subtract for unchecked math; hash delegates to Janet built-in hash. All registered in core-bindings.
§
and/or macros: (and x y) → (let* [and__x x] (if and__x (and y) and__x)). (or x y) → (let* [or__x x] (if or__x or__x (or y))). Registered as macros in core-macro-names. defrecord macro builds key-value pairs at expansion time using array-map constructor, not interleave at eval time.
§
SCI added as git submodule at vendor/sci (https://github.com/borkdude/sci.git). Clone with git submodule update --init. 317/317 forms load from 9 core files. Internal namespaces (interop, parser, opts) partially loaded — parser.cljc needs utils/new-var (calls sci.lang.Var. constructor) and edamame/normalize-opts stubs.
§
:mutable? compile flag in api.janet init: persistent Clojure data structures loaded by default. Pass {:mutable? true} to use Janet native mutable tuples/tables instead. load-persistent-structures function in api.janet loads src/jolt/clojure/lang/persistent_vector.clj (17 forms) and swaps vec/vector/vector? bindings in clojure.core. PersistentHashMap WIP in src/jolt/clojure/lang/persistent_hash_map.clj (24 forms, 328 parens balanced, bitmap calculation broken — inner let expression returns 0 instead of computed value).
§
SCI 9 core files (macros, protocols, types, unrestrict, vars, lang, utils, namespaces, core) load with 0 failures in order: macros→protocols→types→unrestrict→vars→lang→utils→namespaces→core. 46 namespaces populated. Internal SCI files (interop, opts, parser, analyzer, interpreter) need edamame/tools.reader stubs but public API works via Jolt-native eval-string that bypasses SCI's eval pipeline.