erlang: round-out BIFs (+40 tests), full plan ticked at 530/530
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 10s

This commit is contained in:
2026-04-25 08:06:17 +00:00
parent a8cfd84f18
commit 44dc32aa54
5 changed files with 429 additions and 6 deletions

View File

@@ -690,6 +690,14 @@
(= name "is_reference") (er-bif-is-reference vs)
(= name "is_binary") (er-bif-is-binary vs)
(= name "byte_size") (er-bif-byte-size vs)
(= name "abs") (er-bif-abs vs)
(= name "min") (er-bif-min vs)
(= name "max") (er-bif-max vs)
(= name "tuple_to_list") (er-bif-tuple-to-list vs)
(= name "list_to_tuple") (er-bif-list-to-tuple vs)
(= name "integer_to_list") (er-bif-integer-to-list vs)
(= name "list_to_integer") (er-bif-list-to-integer vs)
(= name "is_function") (er-bif-is-function vs)
(= name "self") (er-bif-self vs)
(= name "spawn") (er-bif-spawn vs)
(= name "exit") (er-bif-exit vs)
@@ -730,6 +738,16 @@
(= name "reverse") (er-bif-lists-reverse vs)
(= name "map") (er-bif-lists-map vs)
(= name "foldl") (er-bif-lists-foldl vs)
(= name "seq") (er-bif-lists-seq vs)
(= name "sum") (er-bif-lists-sum vs)
(= name "nth") (er-bif-lists-nth vs)
(= name "last") (er-bif-lists-last vs)
(= name "member") (er-bif-lists-member vs)
(= name "append") (er-bif-lists-append vs)
(= name "filter") (er-bif-lists-filter vs)
(= name "any") (er-bif-lists-any vs)
(= name "all") (er-bif-lists-all vs)
(= name "duplicate") (er-bif-lists-duplicate vs)
:else (error
(str "Erlang: undefined 'lists:" name "/" (len vs) "'")))))
@@ -1571,3 +1589,325 @@
(cond
(= e 0) 1
:else (* b (er-int-pow b (- e 1))))))
;; ── extra erlang BIFs ───────────────────────────────────────────
(define
er-bif-abs
(fn
(vs)
(let
((v (er-bif-arg1 vs "abs")))
(cond
(not (= (type-of v) "number"))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
(< v 0) (- 0 v)
:else v))))
(define
er-bif-min
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: min/2: arity")
:else (let
((a (nth vs 0)) (b (nth vs 1)))
(if (er-lt? b a) b a)))))
(define
er-bif-max
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: max/2: arity")
:else (let
((a (nth vs 0)) (b (nth vs 1)))
(if (er-lt? a b) b a)))))
(define
er-bif-tuple-to-list
(fn
(vs)
(let
((v (er-bif-arg1 vs "tuple_to_list")))
(cond
(not (er-tuple? v))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
:else (let
((elems (get v :elements)) (out (er-mk-nil)))
(for-each
(fn
(i)
(let
((j (- (- (len elems) 1) i)))
(set! out (er-mk-cons (nth elems j) out))))
(range 0 (len elems)))
out)))))
(define
er-bif-list-to-tuple
(fn
(vs)
(let
((v (er-bif-arg1 vs "list_to_tuple")) (elems (list)))
(er-list-to-elem-list v elems)
(er-mk-tuple elems))))
(define
er-list-to-elem-list
(fn
(lst out)
(cond
(er-nil? lst) nil
(er-cons? lst)
(do
(append! out (get lst :head))
(er-list-to-elem-list (get lst :tail) out))
:else (raise (er-mk-error-marker (er-mk-atom "badarg"))))))
(define
er-bif-integer-to-list
(fn
(vs)
(let
((v (er-bif-arg1 vs "integer_to_list")))
(cond
(not (= (type-of v) "number"))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
:else (str v)))))
(define
er-bif-list-to-integer
(fn
(vs)
(let
((v (er-bif-arg1 vs "list_to_integer")))
(cond
(not (= (type-of v) "string"))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
:else (let
((n (parse-number v)))
(cond
(= n nil)
(raise (er-mk-error-marker (er-mk-atom "badarg")))
:else n))))))
(define
er-bif-is-function
(fn
(vs)
(cond
(= (len vs) 1) (er-bool (er-fun? (nth vs 0)))
(= (len vs) 2)
(let
((v (nth vs 0)) (n (nth vs 1)))
(cond
(not (er-fun? v)) (er-bool false)
:else (er-bool (er-fun-has-arity? v n))))
:else (error "Erlang: is_function: arity"))))
(define
er-fun-has-arity?
(fn
(fv n)
(let
((clauses (get fv :clauses)) (found (list false)))
(for-each
(fn
(i)
(when
(= (len (get (nth clauses i) :patterns)) n)
(set-nth! found 0 true)))
(range 0 (len clauses)))
(nth found 0))))
;; ── extra lists BIFs ───────────────────────────────────────────
(define
er-bif-lists-seq
(fn
(vs)
(cond
(= (len vs) 2) (er-lists-seq-build (nth vs 0) (nth vs 1) 1)
(= (len vs) 3) (er-lists-seq-build (nth vs 0) (nth vs 1) (nth vs 2))
:else (error "Erlang: lists:seq: arity"))))
(define
er-lists-seq-build
(fn
(from to step)
(let
((acc (er-mk-nil)))
(for-each
(fn
(i)
(let
((v (- to (* i step))))
(when
(and (>= v from) (<= v to))
(set! acc (er-mk-cons v acc)))))
(range 0 (+ 1 (truncate (/ (- to from) step)))))
acc)))
(define
er-bif-lists-sum
(fn
(vs)
(let
((lst (er-bif-arg1 vs "lists:sum")))
(er-lists-sum-iter lst 0))))
(define
er-lists-sum-iter
(fn
(lst acc)
(cond
(er-nil? lst) acc
(er-cons? lst)
(er-lists-sum-iter (get lst :tail) (+ acc (get lst :head)))
:else (raise (er-mk-error-marker (er-mk-atom "badarg"))))))
(define
er-bif-lists-nth
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: lists:nth: arity")
:else (er-lists-nth-iter (nth vs 1) (nth vs 0)))))
(define
er-lists-nth-iter
(fn
(lst i)
(cond
(or (<= i 0) (er-nil? lst))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
(= i 1) (get lst :head)
:else (er-lists-nth-iter (get lst :tail) (- i 1)))))
(define
er-bif-lists-last
(fn
(vs)
(let
((lst (er-bif-arg1 vs "lists:last")))
(cond
(er-nil? lst)
(raise (er-mk-error-marker (er-mk-atom "badarg")))
:else (er-lists-last-iter lst)))))
(define
er-lists-last-iter
(fn
(lst)
(cond
(and (er-cons? lst) (er-nil? (get lst :tail))) (get lst :head)
(er-cons? lst) (er-lists-last-iter (get lst :tail))
:else (raise (er-mk-error-marker (er-mk-atom "badarg"))))))
(define
er-bif-lists-member
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: lists:member: arity")
:else (er-bool (er-lists-member-iter (nth vs 0) (nth vs 1))))))
(define
er-lists-member-iter
(fn
(target lst)
(cond
(er-nil? lst) false
(er-cons? lst)
(cond
(er-equal? target (get lst :head)) true
:else (er-lists-member-iter target (get lst :tail)))
:else false)))
(define
er-bif-lists-append
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: lists:append: arity")
:else (er-list-append (nth vs 0) (nth vs 1)))))
(define
er-bif-lists-filter
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: lists:filter: arity")
:else (er-lists-filter-build
(nth vs 0)
(nth vs 1)
(er-mk-nil)))))
(define
er-lists-filter-build
(fn
(pred lst acc)
(cond
(er-nil? lst) (er-list-reverse-iter acc (er-mk-nil))
(er-cons? lst)
(let
((kept
(cond
(er-truthy? (er-apply-fun pred (list (get lst :head))))
(er-mk-cons (get lst :head) acc)
:else acc)))
(er-lists-filter-build pred (get lst :tail) kept))
:else (raise (er-mk-error-marker (er-mk-atom "badarg"))))))
(define
er-bif-lists-any
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: lists:any: arity")
:else (er-bool (er-lists-any-iter (nth vs 0) (nth vs 1))))))
(define
er-lists-any-iter
(fn
(pred lst)
(cond
(er-nil? lst) false
(er-cons? lst)
(cond
(er-truthy? (er-apply-fun pred (list (get lst :head)))) true
:else (er-lists-any-iter pred (get lst :tail)))
:else false)))
(define
er-bif-lists-all
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: lists:all: arity")
:else (er-bool (er-lists-all-iter (nth vs 0) (nth vs 1))))))
(define
er-lists-all-iter
(fn
(pred lst)
(cond
(er-nil? lst) true
(er-cons? lst)
(cond
(er-truthy? (er-apply-fun pred (list (get lst :head))))
(er-lists-all-iter pred (get lst :tail))
:else false)
:else false)))
(define
er-bif-lists-duplicate
(fn
(vs)
(cond
(not (= (len vs) 2)) (error "Erlang: lists:duplicate: arity")
:else (let
((n (nth vs 0)) (v (nth vs 1)) (out (er-mk-nil)))
(for-each
(fn (_) (set! out (er-mk-cons v out)))
(range 0 n))
out))))