guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/09: repl: Allow clients to send their protocol version.


From: guix-commits
Subject: 01/09: repl: Allow clients to send their protocol version.
Date: Thu, 19 Mar 2020 10:14:29 -0400 (EDT)

civodul pushed a commit to branch master
in repository guix.

commit f06a26f5b594b1d1865a41facca0ea65a3837901
Author: Ludovic Courtès <address@hidden>
AuthorDate: Sun Mar 15 14:27:09 2020 +0100

    repl: Allow clients to send their protocol version.
    
    * guix/repl.scm (send-repl-response): Add #:version.
    (machine-repl): Make 'loop' an internal define with a
    'version' parameter.  Pass VERSION to 'send-repl-response'.
    Send (0 1) as the protocol version.
    If the first element read from INPUT matches (() repl-version _ ...),
    interpret it as the client's protocol version.
---
 guix/repl.scm | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/guix/repl.scm b/guix/repl.scm
index 0f75f9c..a141003 100644
--- a/guix/repl.scm
+++ b/guix/repl.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2018, 2019 Ludovic Courtès <address@hidden>
+;;; Copyright © 2018, 2019, 2020 Ludovic Courtès <address@hidden>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -39,9 +39,10 @@
     (one-of symbol? string? keyword? pair? null? array?
             number? boolean? char?)))
 
-(define (send-repl-response exp output)
+(define* (send-repl-response exp output
+                             #:key (version '(0 0)))
   "Write the response corresponding to the evaluation of EXP to PORT, an
-output port."
+output port.  VERSION is the client's protocol version we are targeting."
   (define (value->sexp value)
     (if (self-quoting? value)
         `(value ,value)
@@ -72,13 +73,26 @@ The protocol of this REPL is meant to be machine-readable 
and provides proper
 support to represent multiple-value returns, exceptions, objects that lack a
 read syntax, and so on.  As such it is more convenient and robust than parsing
 Guile's REPL prompt."
-  (write `(repl-version 0 0) output)
+  (define (loop exp version)
+    (match exp
+      ((? eof-object?) #t)
+      (exp
+       (send-repl-response exp output
+                           #:version version)
+       (loop (read input) version))))
+
+  (write `(repl-version 0 1) output)
   (newline output)
   (force-output output)
 
-  (let loop ()
-    (match (read input)
-      ((? eof-object?) #t)
-      (exp
-       (send-repl-response exp output)
-       (loop)))))
+  ;; In protocol version (0 0), clients would not send their supported
+  ;; protocol version.  Thus, the code below checks for two case: (1) a (0 0)
+  ;; client that directly sends an expression to evaluate, and (2) a more
+  ;; recent client that sends (() repl-version ...).  This form is chosen to
+  ;; be unambiguously distinguishable from a regular Scheme expression.
+
+  (match (read input)
+    ((() 'repl-version version ...)
+     (loop (read input) version))
+    (exp
+     (loop exp '(0 0)))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]