[mpd] Lispify the MPD query

Write a small DSL for converting a simple lisp expression to an MPD query
format. This turns, for example:

    (and (= artist "Katatonia") (= album "Last Fair Deal Gone Down"))

Into:

    ((artist == "Katatonia") AND (album == "Last Fair Deal Gone Down"))

The expressions inside ‘query’ are quasi-quoted, so that variable substitution
is possible.
This commit is contained in:
Tom Willemse 2022-03-03 01:08:16 -08:00
parent 79df03a72a
commit c454bde37c
2 changed files with 26 additions and 3 deletions

View file

@ -1,7 +1,7 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# -*- mode: scheme; -*- # -*- mode: scheme; -*-
IFS=" " IFS=" "
exec scsh -s "$0" "$@" exec scsh -ll mpd.scm -o mpd -s "$0" "$@"
!# !#
(define (randomize-all-albums) (define (randomize-all-albums)
@ -12,8 +12,9 @@ exec scsh -s "$0" "$@"
(define (randomize-albums-by-artist artist) (define (randomize-albums-by-artist artist)
(for-each (lambda (album) (for-each (lambda (album)
(display (run/string (mpc findadd ,(string-append "((artist == \"" artist "\") AND (album == \"" album "\"))"))))) (run (mpc findadd ,(query (and (= artist ,artist)
(run/strings (pipe (mpc list album ,(string-append "((artist == \"" artist "\"))")) (= album ,album))))))
(run/strings (pipe (mpc list album ,(query (= artist ,artist)))
(shuf))))) (shuf)))))
(run (mpc clear) (run (mpc clear)

View file

@ -0,0 +1,22 @@
(define-structure mpd (export query)
(open scheme-with-scsh)
(begin
(define-syntax query
(syntax-rules ()
((_ a)
(mpd-query-1 `a))))
(define (mpd-query-equals params)
(apply format #f "~s == ~s" params))
(define (mpd-query-and params)
(format #f "~a AND ~a"
(mpd-query-1 (car params))
(mpd-query-1 (cadr params))))
(define (mpd-query-1 query)
(format #f "(~a)"
(let ((op (car query)))
(case op
('= (mpd-query-equals (cdr query)))
('and (mpd-query-and (cdr query)))))))))