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:
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"language": "erlang",
|
||||
"total_pass": 490,
|
||||
"total": 490,
|
||||
"total_pass": 530,
|
||||
"total": 530,
|
||||
"suites": [
|
||||
{"name":"tokenize","pass":62,"total":62,"status":"ok"},
|
||||
{"name":"parse","pass":52,"total":52,"status":"ok"},
|
||||
{"name":"eval","pass":306,"total":306,"status":"ok"},
|
||||
{"name":"eval","pass":346,"total":346,"status":"ok"},
|
||||
{"name":"runtime","pass":39,"total":39,"status":"ok"},
|
||||
{"name":"ring","pass":4,"total":4,"status":"ok"},
|
||||
{"name":"ping-pong","pass":4,"total":4,"status":"ok"},
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Erlang-on-SX Scoreboard
|
||||
|
||||
**Total: 490 / 490 tests passing**
|
||||
**Total: 530 / 530 tests passing**
|
||||
|
||||
| | Suite | Pass | Total |
|
||||
|---|---|---|---|
|
||||
| ✅ | tokenize | 62 | 62 |
|
||||
| ✅ | parse | 52 | 52 |
|
||||
| ✅ | eval | 306 | 306 |
|
||||
| ✅ | eval | 346 | 346 |
|
||||
| ✅ | runtime | 39 | 39 |
|
||||
| ✅ | ring | 4 | 4 |
|
||||
| ✅ | ping-pong | 4 | 4 |
|
||||
|
||||
@@ -1043,6 +1043,88 @@
|
||||
(ev "T1 = ets:new(t13, [set]), T2 = ets:new(t14, [set]), ets:insert(T1, {x, 1}), ets:insert(T2, {x, 99}), [{x, A}] = ets:lookup(T1, x), [{x, B}] = ets:lookup(T2, x), A + B")
|
||||
100)
|
||||
|
||||
;; ── more BIFs ─────────────────────────────────────────────────
|
||||
(er-eval-test "abs neg" (ev "abs(-7)") 7)
|
||||
(er-eval-test "abs pos" (ev "abs(42)") 42)
|
||||
(er-eval-test "abs zero" (ev "abs(0)") 0)
|
||||
|
||||
(er-eval-test "min" (ev "min(3, 5)") 3)
|
||||
(er-eval-test "min equal" (ev "min(7, 7)") 7)
|
||||
(er-eval-test "max" (ev "max(3, 5)") 5)
|
||||
(er-eval-test "max neg" (ev "max(-10, -2)") -2)
|
||||
|
||||
(er-eval-test "tuple_to_list head"
|
||||
(nm (ev "hd(tuple_to_list({a, b, c}))")) "a")
|
||||
(er-eval-test "tuple_to_list len"
|
||||
(ev "length(tuple_to_list({1, 2, 3, 4, 5}))") 5)
|
||||
(er-eval-test "list_to_tuple roundtrip"
|
||||
(ev "tuple_size(list_to_tuple([10, 20, 30]))") 3)
|
||||
|
||||
(er-eval-test "integer_to_list" (ev "integer_to_list(42)") "42")
|
||||
(er-eval-test "integer_to_list neg" (ev "integer_to_list(-99)") "-99")
|
||||
(er-eval-test "list_to_integer" (ev "list_to_integer(\"123\")") 123)
|
||||
(er-eval-test "list_to_integer roundtrip"
|
||||
(ev "list_to_integer(integer_to_list(7))") 7)
|
||||
|
||||
(er-eval-test "is_function fun"
|
||||
(nm (ev "F = fun (X) -> X end, is_function(F)")) "true")
|
||||
(er-eval-test "is_function not"
|
||||
(nm (ev "is_function(42)")) "false")
|
||||
(er-eval-test "is_function arity match"
|
||||
(nm (ev "F = fun (X, Y) -> X + Y end, is_function(F, 2)")) "true")
|
||||
(er-eval-test "is_function arity mismatch"
|
||||
(nm (ev "F = fun (X) -> X end, is_function(F, 5)")) "false")
|
||||
|
||||
;; lists module
|
||||
(er-eval-test "lists:seq 1..5"
|
||||
(ev "length(lists:seq(1, 5))") 5)
|
||||
(er-eval-test "lists:seq head"
|
||||
(ev "hd(lists:seq(10, 20))") 10)
|
||||
(er-eval-test "lists:seq sum"
|
||||
(ev "lists:sum(lists:seq(1, 100))") 5050)
|
||||
(er-eval-test "lists:seq with step"
|
||||
(ev "length(lists:seq(0, 20, 2))") 11)
|
||||
(er-eval-test "lists:seq empty"
|
||||
(get (ev "lists:seq(5, 1)") :tag) "nil")
|
||||
|
||||
(er-eval-test "lists:sum empty" (ev "lists:sum([])") 0)
|
||||
(er-eval-test "lists:sum 5"
|
||||
(ev "lists:sum([1, 2, 3, 4, 5])") 15)
|
||||
|
||||
(er-eval-test "lists:nth 1" (ev "lists:nth(1, [10, 20, 30])") 10)
|
||||
(er-eval-test "lists:nth mid"
|
||||
(nm (ev "lists:nth(2, [a, b, c])")) "b")
|
||||
(er-eval-test "lists:last"
|
||||
(nm (ev "lists:last([a, b, c, d])")) "d")
|
||||
(er-eval-test "lists:last single" (ev "lists:last([42])") 42)
|
||||
|
||||
(er-eval-test "lists:member yes"
|
||||
(nm (ev "lists:member(3, [1, 2, 3, 4])")) "true")
|
||||
(er-eval-test "lists:member no"
|
||||
(nm (ev "lists:member(99, [1, 2, 3])")) "false")
|
||||
|
||||
(er-eval-test "lists:append"
|
||||
(ev "length(lists:append([1, 2], [3, 4, 5]))") 5)
|
||||
|
||||
(er-eval-test "lists:filter"
|
||||
(ev "length(lists:filter(fun (X) -> X > 2 end, [1, 2, 3, 4, 5]))") 3)
|
||||
(er-eval-test "lists:filter sum"
|
||||
(ev "lists:sum(lists:filter(fun (X) -> X rem 2 =:= 0 end, lists:seq(1, 20)))") 110)
|
||||
|
||||
(er-eval-test "lists:any false"
|
||||
(nm (ev "lists:any(fun (X) -> X > 100 end, [1, 2, 3])")) "false")
|
||||
(er-eval-test "lists:any true"
|
||||
(nm (ev "lists:any(fun (X) -> X > 2 end, [1, 2, 3])")) "true")
|
||||
(er-eval-test "lists:all true"
|
||||
(nm (ev "lists:all(fun (X) -> X > 0 end, [1, 2, 3])")) "true")
|
||||
(er-eval-test "lists:all false"
|
||||
(nm (ev "lists:all(fun (X) -> X > 1 end, [1, 2, 3])")) "false")
|
||||
|
||||
(er-eval-test "lists:duplicate len"
|
||||
(ev "length(lists:duplicate(5, foo))") 5)
|
||||
(er-eval-test "lists:duplicate val"
|
||||
(nm (ev "hd(lists:duplicate(3, marker))")) "marker")
|
||||
|
||||
(define
|
||||
er-eval-test-summary
|
||||
(str "eval " er-eval-test-pass "/" er-eval-test-count))
|
||||
|
||||
@@ -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