compiler: self-hosted analyzer compiles set literals (#{…})

Stage 1 Task 1. analyzer.clj punted set literals to the interpreter
((form-set? form) (uncompilable "set literal")); now it builds the set-node IR
(already defined in ir.clj) from (form-set-items form), and backend.janet emits
(make-phs e1 e2 …) — each element evaluated then the persistent set built,
mirroring compiler.janet's emit-set-expr and the interpreter's :jolt/set path.

Closes a self-hosted-analyzer vs bootstrap-compiler parity gap: #{…} no longer
forces interpreter fallback on the compile path.

Gate: conformance 262x3 (+4 set-literal cases incl computed elements / empty /
in-let), fixpoint, self-host, sci, suite 3981/66, specs+unit green; core-bench
neutral (A/B). set?/disj-as-fns remain deliberately interpreted (in-sync across
all three lists) — adjudicated in Task 2.
This commit is contained in:
Yogthos 2026-06-08 22:38:35 -04:00
parent fdf2c742c4
commit b6d9247b80
3 changed files with 16 additions and 3 deletions

View file

@ -50,6 +50,12 @@
["map as fn default" "99" "({:a 1} :z 99)"]
["set as fn" "2" "(#{1 2 3} 2)"]
["set as fn miss" "nil" "(#{1 2 3} 9)"]
# set literals compile (Stage 1 Task 1): computed elements are each evaluated
# then the persistent set is built, matching the interpreter.
["set literal computed" "true" "(= #{1 2} #{(inc 0) 2})"]
["empty set literal" "true" "(empty? #{})"]
["set literal count" "3" "(count #{1 2 3})"]
["set literal in let" "true" "(let [x 5] (= #{5 6} #{x (inc x)}))"]
["keyword as fn" "1" "(:a {:a 1})"]
["map fn over coll" "(quote (1 3))" "(map {:a 1 :b 3} [:a :b])"]