backend: extend native-ops — mod/rem///bit ops emit janet opcodes (jolt-5lm)

The native-ops table grows from 9 to 16, each verified for semantic parity
with the jolt fn before inclusion (incl. negative operands): mod is floored
on both sides, rem (janet %) truncates, / is variadic with (/ x) -> 1/x.
quot is deliberately absent — janet div floors where Clojure truncates.
jolt's bit fns are 2-arg (unlike Clojure's variadic), so the bit ops emit
native only at exactly that arity; bit-not is unary. Eight new conformance
rows pin compile=interpret on the new ops at their guarded arities (334x3).

map-read 10.8 -> 9.2 ms (the (mod i 100) in its loop inlines). From the
flatiron review's unchecked-primitive-loops idea.
This commit is contained in:
Yogthos 2026-06-10 19:02:16 -04:00
parent 377fe706e9
commit e64c1f1b36
2 changed files with 28 additions and 3 deletions

View file

@ -119,6 +119,16 @@
["update-in fnil" "{:a {:b 1}}" "(update-in {} [:a :b] (fnil inc 0))"]
["get-in" "1" "(get-in {:a {:b {:c 1}}} [:a :b :c])"]
### ---- native-op parity (compile emits janet ops at guarded arities) ----
["native mod floored" "2" "(mod -7 3)"]
["native rem truncated" "-1" "(rem -7 3)"]
["native unary div" "0.5" "(/ 2)"]
["native chained div" "1" "(/ 6 3 2)"]
["native bit-and" "8" "(bit-and 12 10)"]
["native bit-xor" "6" "(bit-xor 12 10)"]
["native bit-not" "-6" "(bit-not 5)"]
["native shifts" "[16 2]" "[(bit-shift-left 4 2) (bit-shift-right 8 2)]"]
### ---- HIGH: str semantics ----
["str nil empty" "\"\"" "(str nil)"]
["str concat nil" "\"a1\"" "(str \"a\" 1 nil)"]