erlang: register/whereis, Phase 5 complete (+12 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-25 05:43:57 +00:00
parent 47a59343a1
commit 8e809614ba
6 changed files with 202 additions and 17 deletions

View File

@@ -149,6 +149,7 @@
:next-ref 0
:current nil
:processes {}
:registered {}
:runnable (er-q-new)})))
(define er-sched (fn () (nth er-scheduler 0)))
@@ -324,6 +325,104 @@
er-bif-is-reference
(fn (vs) (er-bool (er-ref? (er-bif-arg1 vs "is_reference")))))
;; ── name registry ─────────────────────────────────────────────
(define er-registered (fn () (get (er-sched) :registered)))
(define
er-bif-register
(fn
(vs)
(if
(not (= (len vs) 2))
(error "Erlang: register/2: arity")
(let
((name (nth vs 0)) (pid (nth vs 1)))
(cond
(not (er-atom? name))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
(not (er-pid? pid))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
(not (er-proc-exists? pid))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
(dict-has? (er-registered) (get name :name))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
:else (do
(dict-set! (er-registered) (get name :name) pid)
(er-mk-atom "true")))))))
(define
er-bif-unregister
(fn
(vs)
(let
((name (er-bif-arg1 vs "unregister")))
(cond
(not (er-atom? name))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
(not (dict-has? (er-registered) (get name :name)))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
:else (do
(dict-delete! (er-registered) (get name :name))
(er-mk-atom "true"))))))
(define
er-bif-whereis
(fn
(vs)
(let
((name (er-bif-arg1 vs "whereis")))
(cond
(not (er-atom? name))
(raise (er-mk-error-marker (er-mk-atom "badarg")))
(dict-has? (er-registered) (get name :name))
(get (er-registered) (get name :name))
:else (er-mk-atom "undefined")))))
(define
er-bif-registered
(fn
(vs)
(if
(not (= (len vs) 0))
(error "Erlang: registered/0: arity")
(let
((ks (keys (er-registered))) (out (er-mk-nil)))
(for-each
(fn
(i)
(let
((k (nth ks (- (- (len ks) 1) i))))
(set! out (er-mk-cons (er-mk-atom k) out))))
(range 0 (len ks)))
out))))
;; Find the registered name for a pid, if any. Returns string or nil.
(define
er-find-registration
(fn
(pid)
(let
((reg (er-registered)) (ks (keys reg)) (found (list nil)))
(for-each
(fn
(i)
(when
(= (nth found 0) nil)
(let
((k (nth ks i)))
(when (er-pid-equal? (get reg k) pid) (set-nth! found 0 k)))))
(range 0 (len ks)))
(nth found 0))))
;; Drop pid from the registry (called on process death).
(define
er-unregister-pid!
(fn
(pid)
(let
((name (er-find-registration pid)))
(when (not (= name nil)) (dict-delete! (er-registered) name)))))
(define
er-bif-process-flag
(fn
@@ -643,12 +742,14 @@
(er-proc-set! pid :exit-reason (get r :reason))
(er-proc-set! pid :exit-result nil)
(er-proc-set! pid :continuation nil)
(er-unregister-pid! pid)
(er-propagate-exit! pid (get r :reason)))
:else (do
(er-proc-set! pid :state "dead")
(er-proc-set! pid :exit-reason (er-mk-atom "normal"))
(er-proc-set! pid :exit-result r)
(er-proc-set! pid :continuation nil)
(er-unregister-pid! pid)
(er-propagate-exit! pid (er-mk-atom "normal"))))))
(er-sched-set-current! nil)))