erlang: proplists module (get_value/get_all_values/is_defined/lookup/delete) (874/874)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s

proplists BIFs in lib/erlang/lists-ext.sx (now lists + proplists).
Bare-atom shorthand {A,true}, first-match lookups, get_value default
undefined, lookup -> tuple | none. lists_ext suite 91 -> 103.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-30 14:00:13 +00:00
parent 394d5790ad
commit 3d8607a40a
5 changed files with 165 additions and 7 deletions

View File

@@ -1,4 +1,4 @@
;; lib/erlang/lists-ext.sx — extra `lists` module BIFs.
;; lib/erlang/lists-ext.sx — extra stdlib BIFs (`lists` + `proplists`).
;;
;; Loaded AFTER runtime.sx so the BIF registry + transpile helpers
;; (er-mk-cons, er-lt?, er-equal?, er-bool, er-truthy?, er-apply-fun,
@@ -558,6 +558,114 @@
er-bif-lists-search
(fn (vs) (er-ext-search (nth vs 0) (nth vs 1))))
;; ── proplists module ──────────────────────────────────────────────
;; A property list element is either a bare atom A (shorthand for
;; {A, true}) or a tuple whose first element is the key (value = its
;; second element, or true for a 1-tuple). Lookups use the FIRST match.
(define
er-ext-pl-key-of
(fn (e)
(cond
(er-atom? e) e
(and (er-tuple? e) (>= (len (get e :elements)) 1)) (nth (get e :elements) 0)
:else nil)))
(define
er-ext-pl-val-of
(fn (e)
(cond
(and (er-tuple? e) (>= (len (get e :elements)) 2)) (nth (get e :elements) 1)
:else (er-mk-atom "true"))))
(define
er-ext-pl-match?
(fn (key e)
(let ((k (er-ext-pl-key-of e)))
(and (not (= k nil)) (er-equal? key k)))))
(define
er-ext-pl-get-value
(fn (key lst default)
(cond
(er-nil? lst) default
(er-cons? lst)
(if (er-ext-pl-match? key (get lst :head))
(er-ext-pl-val-of (get lst :head))
(er-ext-pl-get-value key (get lst :tail) default))
:else default)))
(define
er-bif-pl-get-value
(fn (vs)
(cond
(= (len vs) 2)
(er-ext-pl-get-value (nth vs 0) (nth vs 1) (er-mk-atom "undefined"))
(= (len vs) 3)
(er-ext-pl-get-value (nth vs 0) (nth vs 1) (nth vs 2))
:else (error "Erlang: proplists:get_value: wrong arity"))))
(define
er-ext-pl-all
(fn (key lst acc)
(cond
(er-nil? lst) (er-list-reverse-iter acc (er-mk-nil))
(er-cons? lst)
(er-ext-pl-all key (get lst :tail)
(if (er-ext-pl-match? key (get lst :head))
(er-mk-cons (er-ext-pl-val-of (get lst :head)) acc)
acc))
:else (er-list-reverse-iter acc (er-mk-nil)))))
(define
er-bif-pl-get-all-values
(fn (vs) (er-ext-pl-all (nth vs 0) (nth vs 1) (er-mk-nil))))
(define
er-ext-pl-defined?
(fn (key lst)
(cond
(er-nil? lst) false
(er-cons? lst)
(if (er-ext-pl-match? key (get lst :head))
true
(er-ext-pl-defined? key (get lst :tail)))
:else false)))
(define
er-bif-pl-is-defined
(fn (vs) (er-bool (er-ext-pl-defined? (nth vs 0) (nth vs 1)))))
(define
er-ext-pl-lookup
(fn (key lst)
(cond
(er-nil? lst) (er-mk-atom "none")
(er-cons? lst)
(if (er-ext-pl-match? key (get lst :head))
(let ((e (get lst :head)))
(if (er-tuple? e) e (er-mk-tuple (list e (er-mk-atom "true")))))
(er-ext-pl-lookup key (get lst :tail)))
:else (er-mk-atom "none"))))
(define
er-bif-pl-lookup
(fn (vs) (er-ext-pl-lookup (nth vs 0) (nth vs 1))))
(define
er-ext-pl-delete
(fn (key lst)
(cond
(er-nil? lst) (er-mk-nil)
(er-cons? lst)
(if (er-ext-pl-match? key (get lst :head))
(er-ext-pl-delete key (get lst :tail))
(er-mk-cons (get lst :head) (er-ext-pl-delete key (get lst :tail))))
:else lst)))
(define
er-bif-pl-delete
(fn (vs) (er-ext-pl-delete (nth vs 0) (nth vs 1))))
;; ── register ──────────────────────────────────────────────────────
;; Hook into er-register-builtin-bifs! rather than registering once:
;; the registry can be reset + rebuilt mid-run (tests/runtime.sx does
@@ -594,7 +702,13 @@
(er-register-pure-bif! "lists" "flatmap" 2 er-bif-lists-flatmap)
(er-register-pure-bif! "lists" "filtermap" 2 er-bif-lists-filtermap)
(er-register-pure-bif! "lists" "mapfoldl" 3 er-bif-lists-mapfoldl)
(er-register-pure-bif! "lists" "search" 2 er-bif-lists-search)))
(er-register-pure-bif! "lists" "search" 2 er-bif-lists-search)
(er-register-pure-bif! "proplists" "get_value" 2 er-bif-pl-get-value)
(er-register-pure-bif! "proplists" "get_value" 3 er-bif-pl-get-value)
(er-register-pure-bif! "proplists" "get_all_values" 2 er-bif-pl-get-all-values)
(er-register-pure-bif! "proplists" "is_defined" 2 er-bif-pl-is-defined)
(er-register-pure-bif! "proplists" "lookup" 2 er-bif-pl-lookup)
(er-register-pure-bif! "proplists" "delete" 2 er-bif-pl-delete)))
(define er-ext-prev-register-builtins er-register-builtin-bifs!)
(define er-register-builtin-bifs!