summaryrefslogtreecommitdiffstats
path: root/share/txr/stdlib
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-06-11 07:46:11 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-06-11 07:46:11 -0700
commit2c72da160c2f43828316c262855c92e638872a70 (patch)
tree99f6815576b25ad7931fa40d95f2fd0de87e1d37 /share/txr/stdlib
parent607a764714e1d0391c663146a0c4701c19e15e35 (diff)
downloadtxr-2c72da160c2f43828316c262855c92e638872a70.tar.gz
txr-2c72da160c2f43828316c262855c92e638872a70.tar.bz2
txr-2c72da160c2f43828316c262855c92e638872a70.zip
pic: support quasiliteral as format string.
* share/txr/stdlib/pic.tl (pic): Refactor string compilation code into local function which has access to the overall argument list. Recognize the quasiliteral case and translate by compiling all the string parts, then forming a recombined quasiliteral where the compiled parts are substituted. * tests/018/format.tl: test case for this. * txr.1: Documented.
Diffstat (limited to 'share/txr/stdlib')
-rw-r--r--share/txr/stdlib/pic.tl46
1 files changed, 30 insertions, 16 deletions
diff --git a/share/txr/stdlib/pic.tl b/share/txr/stdlib/pic.tl
index a6228334..f2805554 100644
--- a/share/txr/stdlib/pic.tl
+++ b/share/txr/stdlib/pic.tl
@@ -88,23 +88,37 @@
(t (compile-error f "unrecognized format string ~s" fmt))))
(defmacro pic (:form f :env e bigfmt . args)
- (unless (stringp bigfmt)
- (compile-error f "~s is required to be a format string" bigfmt))
(let* ((regex #/[+\-]?0?#+([.!]#+|!)?| \
<+| \
>+| \
\|+| \
- \~.|\~/)
- (items (collect-each ((piece (tok regex t bigfmt)))
- (cond
- ((m^$ regex piece)
- (cond
- ((starts-with "~" piece)
- (expand-pic f piece nil))
- (args
- (expand-pic f piece (pop args)))
- (t (compile-error f "insufficient arguments for format"))))
- (t piece)))))
- (if args
- (compile-warning f "excess arguments"))
- (pic-join-opt ^(join ,*items))))
+ \~.|\~/))
+ (labels ((pic-compile-string (fmtstr)
+ (let ((items (collect-each ((piece (tok regex t fmtstr)))
+ (cond
+ ((m^$ regex piece)
+ (cond
+ ((starts-with "~" piece)
+ (expand-pic f piece nil))
+ (args
+ (expand-pic f piece (pop args)))
+ (t (compile-error
+ f "insufficient arguments for format"))))
+ (t piece)))))
+ (pic-join-opt ^(join ,*items)))))
+ (match-case bigfmt
+ (@(stringp @s)
+ (let ((out (pic-compile-string s)))
+ (if args
+ (compile-warning f "excess arguments"))
+ out))
+ ((@(or sys:quasi) . @qargs)
+ (let ((nqargs (build (each ((q qargs))
+ (if (stringp q)
+ (add (pic-compile-string q))
+ (add q))))))
+ (if args
+ (compile-warning f "excess arguments"))
+ ^(sys:quasi ,*nqargs)))
+ (@else (compile-error
+ f "~s is required to be a string or quasiliteral" else))))))