erlang: lists sublist/2,3 + nthtail/2 + split/2 + droplast/1 (854/854)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s
Slicing family in lib/erlang/lists-ext.sx. sublist lenient; nthtail and split strict (badarg when list shorter than N); droplast raises on []. lists_ext suite 70 -> 83. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -422,6 +422,68 @@
|
||||
(fn (vs)
|
||||
(er-ext-unzip (er-bif-arg1 vs "lists:unzip") (er-mk-nil) (er-mk-nil))))
|
||||
|
||||
;; ── slicing (sublist / nthtail / split / droplast) ────────────────
|
||||
(define
|
||||
er-ext-sublist2
|
||||
(fn (lst n)
|
||||
(cond
|
||||
(or (<= n 0) (er-nil? lst)) (er-mk-nil)
|
||||
(er-cons? lst)
|
||||
(er-mk-cons (get lst :head) (er-ext-sublist2 (get lst :tail) (- n 1)))
|
||||
:else (er-mk-nil))))
|
||||
|
||||
;; lenient drop (used by sublist/3); never raises
|
||||
(define
|
||||
er-ext-drop-cons
|
||||
(fn (lst n)
|
||||
(cond
|
||||
(or (<= n 0) (er-nil? lst)) lst
|
||||
(er-cons? lst) (er-ext-drop-cons (get lst :tail) (- n 1))
|
||||
:else lst)))
|
||||
|
||||
;; strict drop (used by nthtail/2 + split/2); raises if list too short
|
||||
(define
|
||||
er-ext-nthtail
|
||||
(fn (n lst)
|
||||
(cond
|
||||
(<= n 0) lst
|
||||
(er-cons? lst) (er-ext-nthtail (- n 1) (get lst :tail))
|
||||
:else (raise (er-mk-error-marker (er-mk-atom "badarg"))))))
|
||||
|
||||
(define
|
||||
er-bif-lists-sublist
|
||||
(fn (vs)
|
||||
(cond
|
||||
(= (len vs) 2) (er-ext-sublist2 (nth vs 0) (nth vs 1))
|
||||
(= (len vs) 3)
|
||||
(er-ext-sublist2
|
||||
(er-ext-drop-cons (nth vs 0) (- (nth vs 1) 1))
|
||||
(nth vs 2))
|
||||
:else (error "Erlang: lists:sublist: wrong arity"))))
|
||||
|
||||
(define
|
||||
er-bif-lists-nthtail
|
||||
(fn (vs) (er-ext-nthtail (nth vs 0) (nth vs 1))))
|
||||
|
||||
(define
|
||||
er-bif-lists-split
|
||||
(fn (vs)
|
||||
(let ((n (nth vs 0)) (lst (nth vs 1)))
|
||||
(er-mk-tuple
|
||||
(list (er-ext-sublist2 lst n) (er-ext-nthtail n lst))))))
|
||||
|
||||
(define
|
||||
er-ext-droplast
|
||||
(fn (lst)
|
||||
(cond
|
||||
(and (er-cons? lst) (er-nil? (get lst :tail))) (er-mk-nil)
|
||||
(er-cons? lst) (er-mk-cons (get lst :head) (er-ext-droplast (get lst :tail)))
|
||||
:else (raise (er-mk-error-marker (er-mk-atom "badarg"))))))
|
||||
|
||||
(define
|
||||
er-bif-lists-droplast
|
||||
(fn (vs) (er-ext-droplast (er-bif-arg1 vs "lists:droplast"))))
|
||||
|
||||
;; ── register ──────────────────────────────────────────────────────
|
||||
;; Hook into er-register-builtin-bifs! rather than registering once:
|
||||
;; the registry can be reset + rebuilt mid-run (tests/runtime.sx does
|
||||
@@ -449,7 +511,12 @@
|
||||
(er-register-pure-bif! "lists" "min" 1 er-bif-lists-min)
|
||||
(er-register-pure-bif! "lists" "zip" 2 er-bif-lists-zip)
|
||||
(er-register-pure-bif! "lists" "zipwith" 3 er-bif-lists-zipwith)
|
||||
(er-register-pure-bif! "lists" "unzip" 1 er-bif-lists-unzip)))
|
||||
(er-register-pure-bif! "lists" "unzip" 1 er-bif-lists-unzip)
|
||||
(er-register-pure-bif! "lists" "sublist" 2 er-bif-lists-sublist)
|
||||
(er-register-pure-bif! "lists" "sublist" 3 er-bif-lists-sublist)
|
||||
(er-register-pure-bif! "lists" "nthtail" 2 er-bif-lists-nthtail)
|
||||
(er-register-pure-bif! "lists" "split" 2 er-bif-lists-split)
|
||||
(er-register-pure-bif! "lists" "droplast" 1 er-bif-lists-droplast)))
|
||||
|
||||
(define er-ext-prev-register-builtins er-register-builtin-bifs!)
|
||||
(define er-register-builtin-bifs!
|
||||
|
||||
Reference in New Issue
Block a user