branch: externals/poke
commit 943fdf7d84082e19f8ea300fc430810c0c774276
Author: Jose E. Marchesi <[email protected]>
Commit: Jose E. Marchesi <[email protected]>

    poke.el: new pokelet protocol infrastructure and convert poke-elval
    
    * emacs/poke.el (poke-pk): Define.
    (poke): Evaluate poke-pk at startup.
---
 poke.el | 137 ++++++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 91 insertions(+), 46 deletions(-)

diff --git a/poke.el b/poke.el
index c47814781e..011fdb1918 100644
--- a/poke.el
+++ b/poke.el
@@ -109,13 +109,86 @@
                         :command (list poke-poked-program)))
     (set-process-query-on-exit-flag poke-poked-process nil)))
 
-;;;; generic pokelet stuff
+;;;; pokelet protocol
+
+;; The filter function below implements the poke daemon message
+;; protocol.  The pokelet processes are required to have the following
+;; attributes in their alist:
+;;
+;;  pokelet-state
+;;    One of the POKE_STATE_* values below.  Initially must
+;;    be POKE_STATE_LENGTH.
+;;
+;;  pokelet-buf
+;;    This is a string that accumulates the input received
+;;    by the pokelet.  Initially "".
+;;
+;;  pokelet-msg-length
+;;    Lenght of the message being processed.  Initially 0.
+;;
+;;  pokelet-msg-handler
+;;    Function that gets the process, a command number
+;;    and a command argument.  This function can error
+;;    if there is a protocol error.
+
+(defconst PLET_STATE_LENGTH 0) ; Collecting length bytes.
+(defconst PLET_STATE_MSG 1) ; Collecting message data.
+
+(defun poke-pokelet-filter (proc string)
+  (process-put proc 'pokelet-buf
+               (concat (process-get proc 'pokelet-buf) string))
+  (while (or (and (= (process-get proc 'pokelet-state) PLET_STATE_LENGTH)
+                  (>= (length (process-get proc 'pokelet-buf)) 2))
+             (and (= (process-get proc 'pokelet-state) PLET_STATE_MSG)
+                  (>= (length (process-get proc 'pokelet-buf))
+                      (process-get proc 'pokelet-msg-length))))
+    (if (= (process-get proc 'pokelet-state) POKE_STATE_LENGTH)
+        (let ((pokelet-buf (process-get proc 'pokelet-buf)))
+          ;; The message lenght is encoded as an unsigned
+          ;; little-endian 16 bit number.  Collect and skipt it.
+          (process-put proc
+                       'pokelet-msg-length
+                       (logior (ash (aref pokelet-buf 1) 8)
+                               (aref pokelet-buf 0)))
+          (process-put proc 'pokelet-buf (substring pokelet-buf 2))
+          ;; We are now waiting for the message data.
+          (process-put proc 'pokelet-state PLET_STATE_MSG))
+      ;; We are collecting message data.
+      (when (>= (length (process-get proc 'pokelet-buf))
+                (process-get proc 'pokelet-msg-length))
+       ;; Action on the message according to the command.
+        (let ((cmd (aref (process-get proc 'pokelet-buf) 0))
+              (msg-data (substring (process-get proc 'pokelet-buf)
+                                   1
+                                   (- (process-get proc 'pokelet-msg-length) 
1))))
+          (apply (process-get proc 'pokelet-msg-handler) (list proc cmd 
msg-data)))
+       ;; Discard used portion of poke-elval-buf and go back to
+        ;; waiting for a message length.
+        (process-put proc
+                     'pokelet-buf
+                     (substring (process-get proc 'pokelet-buf)
+                                (process-get proc 'pokelet-msg-length)))
+        (process-put proc 'pokelet-state PLET_STATE_LENGTH)))))
+
+(defun poke-make-pokelet-process-new (name ctrl msg-handler)
+   (let ((proc (make-network-process :name name
+                                     :buffer (concat "*" name "*")
+                                     :family 'local
+                                     :service poked-socket)))
+     (process-put proc 'pokelet-state PLET_STATE_LENGTH)
+     (process-put proc 'pokelet-buf "")
+     (process-put proc 'pokelet-msg-length 0)
+     (process-put proc 'pokelet-msg-handler msg-handler)
+     (set-process-query-on-exit-flag proc nil)
+     (set-process-filter proc #'poke-pokelet-filter)
+     (process-send-string proc ctrl)
+     proc))
 
 (defun poke-make-pokelet-process (name ctrl)
-  (let ((proc (make-network-process :name name
-                                    :buffer (concat "*" name "*")
-                                    :family 'local
-                                    :service poked-socket)))
+   (let ((proc (make-network-process :name name
+                                     :buffer (concat "*" name "*")
+                                     :family 'local
+                                     :service poked-socket)))
     (process-send-string proc ctrl)
     proc))
 
@@ -495,14 +568,6 @@ Commands:
 
 ;;;; poke-elval
 
-(defvar poke-elval-process nil)
-(defvar poke-elval-buf "")
-(defvar poke-elval-length 0)
-
-(defconst poke-elval-state-waiting-for-length 0)
-(defconst poke-elval-state-waiting-for-msg 1)
-(defvar poke-elval-state poke-elval-state-waiting-for-length)
-
 (defconst poke-elval-init-pk
   "\
 var PLET_ELVAL_CMD_EVAL = 0UB;
@@ -516,46 +581,26 @@ fun plet_elval = (string s) void:
 }
 ")
 
-(defun poke-elval-filter (proc string)
-  (setq poke-elval-buf (concat poke-elval-buf string))
-  (while (or (and (= poke-elval-state poke-elval-state-waiting-for-length)
-                  (>= (length poke-elval-buf) 2))
-             (and (= poke-elval-state poke-elval-state-waiting-for-msg)
-                  (>= (length poke-elval-buf) poke-elval-length)))
-    (if (= poke-elval-state poke-elval-state-waiting-for-length)
-        (progn
-          (setq poke-elval-length
-                (logior (ash (aref poke-elval-buf 1) 8) (aref poke-elval-buf 
0)))
-          (setq poke-elval-buf (substring poke-elval-buf 2))
-          (setq poke-elval-state poke-elval-state-waiting-for-msg))
-      ;; state is poke-elval-state-waiting-for-msg.
-      (when (>= (length poke-elval-buf) poke-elval-length)
-       ;; Action on the message according to the command.
-       (pcase (aref poke-elval-buf 0)
-          (0 ;; EVAL
-           (ignore-errors
-             (let* ((code (substring poke-elval-buf 1 (- poke-elval-length 1)))
-                    (form (read-from-string code)))
-               (eval (car form)))))
-          (_ ;; Protocol error
-          (setq poke-elval-buf "")
-          (setq poke-elval-length 0)
-          (error "pokelet protocol error")))
-       ;; Discard used portion of poke-elval-buf and reset state.
-        (setq poke-elval-buf (substring poke-elval-buf poke-elval-length))
-        (setq poke-elval-state poke-elval-state-waiting-for-length)))))
+(defvar poke-elval-process nil)
+
+(defun poke-elval-handle-cmd (proc cmd data)
+  (pcase cmd
+    (0 ;; EVAL
+     (ignore-errors
+       (eval (car (read-from-string data)))))
+    (_ ;; Protocol error
+     (process-put proc 'pokelet-buf "")
+     (process-put proc 'pokelet-msg-lenght 0)
+     (error "pokelet protocol error"))))
 
 (defun poke-elval ()
   (interactive)
   (when (not (process-live-p poke-elval-process))
     (poke-code)
     (poke-code-send poke-elval-init-pk)
-    (setq poke-elval-buf "")
-    (setq poke-elval-length 0)
     (setq poke-elval-process
-          (poke-make-pokelet-process "poke-elval" "\xe4"))
-    (set-process-query-on-exit-flag poke-elval-process nil)
-    (set-process-filter poke-elval-process #'poke-elval-filter)))
+          (poke-make-pokelet-process-new "poke-elval" "\xe4"
+                                         #'poke-elval-handle-cmd))))
 
 ;;;; poke-repl
 

Reply via email to