guix: gexp: Define gexp->approximate-sexp.
It will be used in the 'optional-tests' linter. * guix/gexp.scm (gexp->approximate-sexp): New procedure. * tests/gexp.scm ("no references", "unquoted gexp", "unquoted gexp (native)") ("spliced gexp", "unspliced gexp, approximated") ("unquoted gexp, approximated"): Test it. * doc/gexp.scm ("G-Expressions"): Document it. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org>master
parent
ebf07a06f0
commit
d9e0ae07db
|
@ -10046,6 +10046,16 @@ corresponding to @var{obj} for @var{system}, cross-compiling for
|
||||||
has an associated gexp compiler, such as a @code{<package>}.
|
has an associated gexp compiler, such as a @code{<package>}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Procedure} gexp->approximate-sexp @var{gexp}
|
||||||
|
Sometimes, it may be useful to convert a G-exp into a S-exp. For
|
||||||
|
example, some linters (@pxref{Invoking guix lint}) peek into the build
|
||||||
|
phases of a package to detect potential problems. This conversion can
|
||||||
|
be achieved with this procedure. However, some information can be lost
|
||||||
|
in the process. More specifically, lowerable objects will be silently
|
||||||
|
replaced with some arbitrary object -- currently the list
|
||||||
|
@code{(*approximate*)}, but this may change.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@node Invoking guix repl
|
@node Invoking guix repl
|
||||||
@section Invoking @command{guix repl}
|
@section Invoking @command{guix repl}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
;;; Copyright © 2018 Jan Nieuwenhuizen <janneke@gnu.org>
|
;;; Copyright © 2018 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||||
;;; Copyright © 2019, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
|
;;; Copyright © 2019, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
|
||||||
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
||||||
|
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
with-imported-modules
|
with-imported-modules
|
||||||
with-extensions
|
with-extensions
|
||||||
let-system
|
let-system
|
||||||
|
gexp->approximate-sexp
|
||||||
|
|
||||||
gexp-input
|
gexp-input
|
||||||
gexp-input?
|
gexp-input?
|
||||||
|
@ -157,6 +159,23 @@
|
||||||
"Return the source code location of GEXP."
|
"Return the source code location of GEXP."
|
||||||
(and=> (%gexp-location gexp) source-properties->location))
|
(and=> (%gexp-location gexp) source-properties->location))
|
||||||
|
|
||||||
|
(define* (gexp->approximate-sexp gexp)
|
||||||
|
"Return the S-expression corresponding to GEXP, but do not lower anything.
|
||||||
|
As a result, the S-expression will be approximate if GEXP has references."
|
||||||
|
(define (gexp-like? thing)
|
||||||
|
(or (gexp? thing) (gexp-input? thing)))
|
||||||
|
(apply (gexp-proc gexp)
|
||||||
|
(map (lambda (reference)
|
||||||
|
(match reference
|
||||||
|
(($ <gexp-input> thing output native)
|
||||||
|
(if (gexp-like? thing)
|
||||||
|
(gexp->approximate-sexp thing)
|
||||||
|
;; Simply returning 'thing' won't work in some
|
||||||
|
;; situations; see 'write-gexp' below.
|
||||||
|
'(*approximate*)))
|
||||||
|
(_ '(*approximate*))))
|
||||||
|
(gexp-references gexp))))
|
||||||
|
|
||||||
(define (write-gexp gexp port)
|
(define (write-gexp gexp port)
|
||||||
"Write GEXP on PORT."
|
"Write GEXP on PORT."
|
||||||
(display "#<gexp " port)
|
(display "#<gexp " port)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
||||||
|
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -89,6 +90,36 @@
|
||||||
|
|
||||||
(test-begin "gexp")
|
(test-begin "gexp")
|
||||||
|
|
||||||
|
(test-equal "no references"
|
||||||
|
'(display "hello gexp->approximate-sexp!")
|
||||||
|
(gexp->approximate-sexp #~(display "hello gexp->approximate-sexp!")))
|
||||||
|
|
||||||
|
(test-equal "unquoted gexp"
|
||||||
|
'(display "hello")
|
||||||
|
(let ((inside #~"hello"))
|
||||||
|
(gexp->approximate-sexp #~(display #$inside))))
|
||||||
|
|
||||||
|
(test-equal "unquoted gexp (native)"
|
||||||
|
'(display "hello")
|
||||||
|
(let ((inside #~"hello"))
|
||||||
|
(gexp->approximate-sexp #~(display #+inside))))
|
||||||
|
|
||||||
|
(test-equal "spliced gexp"
|
||||||
|
'(display '(fresh vegetables))
|
||||||
|
(let ((inside #~(fresh vegetables)))
|
||||||
|
(gexp->approximate-sexp #~(display '(#$@inside)))))
|
||||||
|
|
||||||
|
(test-equal "unspliced gexp, approximated"
|
||||||
|
;; (*approximate*) is really an implementation detail
|
||||||
|
'(display '(*approximate*))
|
||||||
|
(let ((inside (file-append coreutils "/bin/hello")))
|
||||||
|
(gexp->approximate-sexp #~(display '(#$@inside)))))
|
||||||
|
|
||||||
|
(test-equal "unquoted gexp, approximated"
|
||||||
|
'(display '(*approximate*))
|
||||||
|
(let ((inside (file-append coreutils "/bin/hello")))
|
||||||
|
(gexp->approximate-sexp #~(display '#$inside))))
|
||||||
|
|
||||||
(test-equal "no refs"
|
(test-equal "no refs"
|
||||||
'(display "hello!")
|
'(display "hello!")
|
||||||
(let ((exp (gexp (display "hello!"))))
|
(let ((exp (gexp (display "hello!"))))
|
||||||
|
|
Reference in New Issue