From f06a26f5b594b1d1865a41facca0ea65a3837901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Sun, 15 Mar 2020 14:27:09 +0100 Subject: 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(-) (limited to 'guix/repl.scm') 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 +;;; Copyright © 2018, 2019, 2020 Ludovic Courtès ;;; ;;; 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))))) -- cgit v1.2.3