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
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 10s
This commit is contained in:
@@ -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))))
|
||||
|
||||
Reference in New Issue
Block a user