[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 1/2] Add reader extension for interpolated strings.
From: |
Olivier Dion |
Subject: |
[RFC PATCH 1/2] Add reader extension for interpolated strings. |
Date: |
Sat, 10 Dec 2022 17:17:23 -0500 |
From: Olivier dion <olivier-dion@proton.me>
Interpolate strings of the form #"The string @(eval this)".
When no interpolation is required, simply return the raw string. For
example, #"foo" will return "foo".
When interpolation is required, return an expression that format the
string with the embedded expressions withing it. For example
#"1+1=@(+ 1 1)" will return (format #f "1+1=~a" (+ 1 1)).
* module/ice-9/boot-9.scm: Extend read hash for strings interpolation.
---
module/ice-9/boot-9.scm | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index a46145ed5..5c0f2eef2 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -2254,6 +2254,43 @@ name extensions listed in %load-extensions."
(error
"#. read expansion found and read-eval? is #f."))))
+
+(letrec ((interpolate
+ (lambda (port chars exps)
+ (let ((char (read-char port)))
+ (cond
+ ((eof-object? char)
+ (values
+ (reverse-list->string chars)
+ (reverse exps)))
+ ((char=? char #\@)
+ (let ((ahead (peek-char port)))
+ (cond
+ ((eof-object? ahead)
+ (interpolate port chars exps))
+ ((char=? ahead #\@)
+ (read-char port)
+ (interpolate port
+ (cons #\@ chars)
+ exps))
+ (else
+ (interpolate port
+ (cons #\a (cons #\~ chars))
+ (cons (read port) exps))))))
+ (else
+ (interpolate port (cons char chars) exps)))))))
+ (read-hash-extend #\"
+ (lambda (char port)
+ (unread-char char port)
+ (call-with-values
+ (lambda () (call-with-input-string (read port)
+ (lambda (port)
+ (interpolate port '() '()))))
+ (lambda (fmt args)
+ (if (null? args)
+ fmt
+ `(format #f ,fmt ,@args)))))))
+
;;; {Low Level Modules}
--
2.38.1