diff options
author | Ludovic Courtès <ludo@gnu.org> | 2020-03-15 14:27:09 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2020-03-19 15:14:08 +0100 |
commit | f06a26f5b594b1d1865a41facca0ea65a3837901 (patch) | |
tree | f6d0f1391b5769a6188efe75a93e6f4a450a3d42 | |
parent | ac75bd010260f6a722e1723b35992b04fd79d44c (diff) | |
download | patches-f06a26f5b594b1d1865a41facca0ea65a3837901.tar patches-f06a26f5b594b1d1865a41facca0ea65a3837901.tar.gz |
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.
-rw-r--r-- | guix/repl.scm | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/guix/repl.scm b/guix/repl.scm index 0f75f9cd0b..a141003812 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 <ludo@gnu.org> +;;; Copyright © 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> ;;; ;;; 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))))) |