Numeric tower (is-integer?/float?/number?, float/trunc/round/abs/max/min), div/rem (quotient/remainder), bitwise (band/bor/bxor/bnot/bsl/bsr), sets module (new/add/member/union/intersection/subtract/size/to-list/from-list), re module (run/replace/replace-all/match-groups/split), list BIFs (hd/tl/length/member/reverse/nth/foldl/foldr/seq/flatten/zip), type conversions (integer-to-list, list-to-integer, atom-to-list, etc.), ok/error tuple helpers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
231 lines
7.2 KiB
Plaintext
231 lines
7.2 KiB
Plaintext
;; lib/erlang/runtime.sx — Erlang BIFs and stdlib wrappers on SX primitives
|
|
;;
|
|
;; Provides Erlang-idiomatic wrappers. Thin where spec primitives match;
|
|
;; inline where Erlang semantics differ (e.g. rem sign, integer division).
|
|
;;
|
|
;; Primitives used from spec:
|
|
;; integer?/float? (Phase 2)
|
|
;; remainder/quotient (Phase 2 / Phase 15)
|
|
;; bitwise-and/or/xor/not (Phase 7)
|
|
;; arithmetic-shift (Phase 7)
|
|
;; make-set/set-add!/etc (Phase 18)
|
|
;; make-regexp/regexp-match/etc (Phase 20)
|
|
;; gcd (Phase 15)
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; 1. Numeric tower — type predicates + conversions
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
(define er-is-integer? integer?)
|
|
(define er-is-float? float?)
|
|
(define (er-is-number? x) (or (integer? x) (float? x)))
|
|
(define (er-is-atom? x) (= (type-of x) "symbol"))
|
|
(define er-is-list? list?)
|
|
(define er-is-binary? bytevector?)
|
|
|
|
;; Erlang float/1 coerces an integer to float
|
|
(define (er-float x) (* 1 x))
|
|
|
|
;; Erlang trunc/1 — truncate toward zero
|
|
(define er-trunc truncate)
|
|
|
|
;; Erlang round/1 — round to nearest integer
|
|
(define er-round round)
|
|
|
|
;; Erlang abs/1
|
|
(define er-abs abs)
|
|
|
|
;; Erlang max/min (BIFs in OTP 26)
|
|
(define (er-max a b) (if (>= a b) a b))
|
|
(define (er-min a b) (if (<= a b) a b))
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; 2. Integer arithmetic — div + rem (Erlang semantics)
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
;; Erlang div: integer division truncating toward zero
|
|
(define er-div quotient)
|
|
|
|
;; Erlang rem: remainder with sign of dividend (matches remainder primitive)
|
|
(define er-rem remainder)
|
|
|
|
;; Erlang gcd (non-standard BIF but useful)
|
|
(define er-gcd gcd)
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; 3. Bitwise ops — band / bor / bxor / bnot / bsl / bsr
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
(define er-band bitwise-and)
|
|
(define er-bor bitwise-or)
|
|
(define er-bxor bitwise-xor)
|
|
(define er-bnot bitwise-not)
|
|
|
|
;; bsl: bit shift left by N positions
|
|
(define (er-bsl x n) (arithmetic-shift x n))
|
|
|
|
;; bsr: bit shift right by N positions
|
|
(define (er-bsr x n) (arithmetic-shift x (- 0 n)))
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; 4. Sets module — thin wrappers matching Erlang sets API
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
(define er-sets-new make-set)
|
|
(define er-sets-add-element set-add!)
|
|
(define er-sets-is-element set-member?)
|
|
(define er-sets-del-element set-remove!)
|
|
(define er-sets-union set-union)
|
|
(define er-sets-intersection set-intersection)
|
|
(define er-sets-subtract set-difference)
|
|
(define er-sets-to-list set->list)
|
|
(define er-sets-from-list list->set)
|
|
(define (er-sets-size s) (len (set->list s)))
|
|
(define (er-sets-is-set? x) (set? x))
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; 5. Regexp — re module wrappers
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
;; er-re-run: returns match dict or nil (no match)
|
|
(define
|
|
(er-re-run subject pattern)
|
|
(regexp-match (make-regexp pattern) subject))
|
|
|
|
;; er-re-replace: replace first match
|
|
(define
|
|
(er-re-replace subject pattern replacement)
|
|
(regexp-replace (make-regexp pattern) subject replacement))
|
|
|
|
;; er-re-replace-all: global replace
|
|
(define
|
|
(er-re-replace-all subject pattern replacement)
|
|
(regexp-replace-all (make-regexp pattern) subject replacement))
|
|
|
|
;; er-re-match-groups: extract capture groups from a match result
|
|
(define (er-re-match-groups m) (if (= m nil) nil (get m :groups)))
|
|
|
|
;; er-re-split: split string on regexp delimiter
|
|
(define
|
|
(er-re-split subject pattern)
|
|
(let
|
|
((re (make-regexp pattern))
|
|
(ms (regexp-match-all (make-regexp pattern) subject)))
|
|
(if
|
|
(= (len ms) 0)
|
|
(list subject)
|
|
(letrec
|
|
((go (fn (matches pos acc) (if (= (len matches) 0) (append acc (list (substring subject pos (len subject)))) (let ((m (first matches)) (start (get (first matches) :start)) (end (get (first matches) :end))) (go (rest matches) end (append acc (list (substring subject pos start)))))))))
|
|
(go ms 0 (list))))))
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; 6. List BIFs — hd/tl/length + lists module
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
(define (er-hd lst) (first lst))
|
|
(define (er-tl lst) (rest lst))
|
|
(define (er-length lst) (len lst))
|
|
|
|
;; lists:member/2
|
|
(define
|
|
(er-lists-member elem lst)
|
|
(cond
|
|
((= (len lst) 0) false)
|
|
((= elem (first lst)) true)
|
|
(else (er-lists-member elem (rest lst)))))
|
|
|
|
;; lists:reverse/1
|
|
(define er-lists-reverse reverse)
|
|
|
|
;; lists:append/2
|
|
(define er-lists-append append)
|
|
|
|
;; lists:flatten/1
|
|
(define
|
|
(er-lists-flatten lst)
|
|
(cond
|
|
((= (len lst) 0) (list))
|
|
((list? (first lst))
|
|
(append (er-lists-flatten (first lst)) (er-lists-flatten (rest lst))))
|
|
(else (cons (first lst) (er-lists-flatten (rest lst))))))
|
|
|
|
;; lists:nth/2 — 1-indexed
|
|
(define (er-lists-nth n lst) (nth lst (- n 1)))
|
|
|
|
;; lists:map/2
|
|
(define er-lists-map map)
|
|
|
|
;; lists:filter/2
|
|
(define er-lists-filter filter)
|
|
|
|
;; lists:foldl/3 — (Fun, Acc0, List)
|
|
(define
|
|
(er-lists-foldl f acc lst)
|
|
(if
|
|
(= (len lst) 0)
|
|
acc
|
|
(er-lists-foldl f (f (first lst) acc) (rest lst))))
|
|
|
|
;; lists:foldr/3
|
|
(define
|
|
(er-lists-foldr f acc lst)
|
|
(if
|
|
(= (len lst) 0)
|
|
acc
|
|
(f (first lst) (er-lists-foldr f acc (rest lst)))))
|
|
|
|
;; lists:zip/2
|
|
(define
|
|
(er-lists-zip a b)
|
|
(if
|
|
(or (= (len a) 0) (= (len b) 0))
|
|
(list)
|
|
(cons (list (first a) (first b)) (er-lists-zip (rest a) (rest b)))))
|
|
|
|
;; lists:seq/2 — generate integer range (1-indexed like Erlang)
|
|
(define
|
|
(er-lists-seq from to)
|
|
(if
|
|
(> from to)
|
|
(list)
|
|
(cons from (er-lists-seq (+ from 1) to))))
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; 7. Type conversion BIFs
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
;; atom_to_list/1 — convert atom (symbol) to its name string
|
|
(define (er-atom-to-list a) (symbol->string a))
|
|
|
|
;; list_to_atom/1 — convert string to atom (symbol)
|
|
(define (er-list-to-atom s) (make-symbol s))
|
|
|
|
;; integer_to_list/1
|
|
(define (er-integer-to-list n) (str n))
|
|
|
|
;; list_to_integer/1
|
|
(define (er-list-to-integer s) (truncate (parse-number s)))
|
|
|
|
;; float_to_list/1
|
|
(define (er-float-to-list f) (str f))
|
|
|
|
;; list_to_float/1
|
|
(define (er-list-to-float s) (* 1 (parse-number s)))
|
|
|
|
;; integer_to_list/2 — with radix (e.g. 16 for hex)
|
|
(define (er-integer-to-list-radix n radix) (number->string n radix))
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; 8. ok/error tuple helpers — Erlang idiom {ok, Val} / {error, Reason}
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
(define (er-ok val) (list "ok" val))
|
|
(define (er-error reason) (list "error" reason))
|
|
(define
|
|
(er-is-ok? t)
|
|
(and (list? t) (= (len t) 2) (= (first t) "ok")))
|
|
(define
|
|
(er-is-error? t)
|
|
(and (list? t) (= (len t) 2) (= (first t) "error")))
|
|
(define (er-unwrap t) (nth t 1))
|