Skip to content

Commit

Permalink
Make Erlang nil atom survive roundtrip
Browse files Browse the repository at this point in the history
Before, the Erlang atom "nil" was represented by the Emacs symbol
"nil" which encodes to the Erlang empty list "[]". This commit makes
conversion bijective, by instead mapping Erlang "nil" to a special
Emacs term that does not get conflated with nil.
  • Loading branch information
axelf4 committed Sep 10, 2023
1 parent fbfb1ea commit df6d8a7
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 10 deletions.
22 changes: 13 additions & 9 deletions derl.el
Expand Up @@ -19,8 +19,8 @@
;; is cooperative, not preemptive---processes must voluntarily give
;; other processes the opportunity to run by calling `derl-yield' or
;; `derl-receive'. Inter-process communication happens solely through
;; asynchronous message passing. The following example (which uses "!"
;; as a shorthand for `derl-send') illustrates spawning a process that
;; asynchronous message passing. The following example (where "!" is a
;; shorthand for `derl-send') illustrates spawning a process that
;; replies once with the number it received plus one:

;; (let ((pid (derl-spawn
Expand All @@ -37,15 +37,17 @@
;; Erlang <=> Emacs Lisp
;; ---------------------------------
;; [] / [a | b] nil / (a . b)
;; nil [EXT nil]
;; {a, b} [a b]
;; #{...} #s(hash-table ...)
;; "foo" (?f ?o ?o)
;; <<"foo">> "foo"

;; In addition, atoms/symbols; integers; and floats are converted to
;; their respective counterparts, and Erlang process identifiers and
;; references are translated to opaque ELisp objects. Bitstrings are
;; not yet supported.
;; where "EXT" denotes the value of `derl-tag'. In addition, integers;
;; floats; and other atoms/symbols are converted to their respective
;; counterparts, and Erlang process identifiers and references are
;; translated to opaque ELisp objects. Bitstrings are not yet
;; supported.

;; If a local Erlang VM was started with e.g. "erl -sname arnie", you
;; may connect to it and perform an RPC using:
Expand Down Expand Up @@ -202,7 +204,8 @@ return the port in a blocking fashion."
((or (and 118 (let n (read2))) ; ATOM_UTF8_EXT
(and 119 (let n (progn (forward-char) (char-before))))) ; SMALL_ATOM_UTF8_EXT
(forward-char n)
(intern (decode-coding-region (- (point) n) (point) 'utf-8 t)))
(or (intern (decode-coding-region (- (point) n) (point) 'utf-8 t))
`[,derl-tag nil]))
(tag (error "Unknown tag `%s'" tag)))))

(defvar derl--write-connection)
Expand Down Expand Up @@ -249,6 +252,7 @@ return the port in a blocking fashion."
(push (logand id #xffffffff) xs) (setq id (ash id -32)) finally
(write2 (length xs)) (derl-write node) (write4 creation)
(dolist (x xs) (write4 x))))
(`[,(pred (eq derl-tag)) nil] (derl-write (eval-when-compile (make-symbol "nil"))))
((pred vectorp)
(if (<= (length term) #xff) (insert 104 (length term)) ; SMALL_TUPLE_EXT
(insert 105) ; LARGE_TUPLE_EXT
Expand Down Expand Up @@ -370,7 +374,7 @@ FUN should be a generator."
(let* ((id (cl-incf derl--next-pid)) m
(f (lambda (op value)
(let ((derl--mailbox m)) (funcall fun op value) (setq m derl--mailbox)))))
(puthash id (vector id f () nil ()) derl--processes)
(puthash id (vector id f () nil) derl--processes)
(derl--schedule)
`[,derl-tag pid nil ,id 0 nil]))

Expand Down Expand Up @@ -411,7 +415,7 @@ FUN should be a generator."
(pcase--expand `(car ,cell) `(,@arms (,x (setq ,continue t))))))
,continue)
finally (if ,prev (setcdr ,prev (cdr ,cell)) (pop derl--mailbox))
,@(when `((when ,timer (cancel-timer ,timer)))) finally return ,result))
,@(when timeout `((when ,timer (cancel-timer ,timer)))) finally return ,result))

(defun derl-send (dest msg)
"Send MSG to DEST and return MSG.
Expand Down
2 changes: 1 addition & 1 deletion test/derl-tests.el
Expand Up @@ -39,7 +39,7 @@
(should (equal (derl-term-to-binary 1.1337) "\203F?\362#\242\234w\232k")))

(ert-deftest derl-ext-roundtrip-test ()
(let ((x [atom 0.1]))
(dolist (x `((0 . "x") [atom 0.1] [,derl-tag nil]))
(should (equal (derl-binary-to-term (derl-term-to-binary x)) x))))

(ert-deftest derl-reference-unique-test ()
Expand Down

0 comments on commit df6d8a7

Please sign in to comment.