Merge pull request #62 from jolt-lang/native-ops-batch2

backend: extend native-ops — mod/rem///bit ops emit janet opcodes
This commit is contained in:
Dmitri Sotnikov 2026-06-10 19:08:51 -04:00 committed by GitHub
commit 599c0468f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 28 additions and 3 deletions

View file

@ -230,11 +230,25 @@
# core fn. Matches numeric semantics; relaxes the non-number checks (a documented
# perf-mode divergence, same as the bootstrap's core-renames).
(def- native-ops
{"+" '+ "-" '- "*" '* "<" '< ">" '> "<=" '<= ">=" '>= "inc" '++ "dec" '--})
{"+" '+ "-" '- "*" '* "/" '/ "<" '< ">" '> "<=" '<= ">=" '>=
"inc" '++ "dec" '--
# verified semantic parity with the jolt fns (incl. negative operands):
# mod is floored, rem (janet %) truncates, / is variadic with (/ x) -> 1/x.
# quot is deliberately ABSENT: janet div floors where Clojure truncates.
"mod" 'mod "rem" '%
# jolt's bit fns are 2-arg (unlike Clojure's variadic), so these emit native
# only at exactly the arity the interpreted fn accepts; bit-not is unary.
"bit-and" 'band "bit-or" 'bor "bit-xor" 'bxor
"bit-shift-left" 'blshift "bit-shift-right" 'brshift "bit-not" 'bnot})
(def- unary-ops {'++ true '-- true 'bnot true})
(def- binary-ops {'mod true '% true 'band true 'bor true 'bxor true
'blshift true 'brshift true})
(defn- native-op
"If fnode is a clojure.core ref (or host ref) to a native-op primitive, return
the Janet op symbol, else nil. inc/dec are unary so only at arity 1."
the Janet op symbol, else nil — only at an arity where the janet op and the
jolt fn agree."
[fnode nargs]
(def nm (case (fnode :op)
:var (when (= "clojure.core" (fnode :ns)) (fnode :name))
@ -243,7 +257,8 @@
(def op (and nm (get native-ops nm)))
(cond
(nil? op) nil
(and (or (= op '++) (= op '--)) (not= nargs 1)) nil
(and (get unary-ops op) (not= nargs 1)) nil
(and (get binary-ops op) (not= nargs 2)) nil
op))
(defn- emit-invoke [ctx node]

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)"]