-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhereis.scm
66 lines (59 loc) · 2.27 KB
/
hereis.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
;;; hereis.scm - like python longstrings
;;;
;;; Copyright (C) 2023-2024 Matthew Wette
;;;
;;; This library is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU Lesser General Public
;;; License as published by the Free Software Foundation; either
;;; version 3 of the License, or (at your option) any later version.
(define-module (hereis)
#:export (enable-hereis disable-hereis read-hereis-text))
;; @deffn {procedure} read-hereis-text reader-char port
;; This reader macro procedure reads extended strings using the
;; delimiter @code{"""}. Enable and disable its use via the
;; syntax @code{(enable-hereis)} and @code{(disable-hereis)}.
;; Example use:
;; @example
;; (define text #"""
;; "Run. Matt. Run.", he said.
;; """)
;; @end example
;; @end deffn
(define (read-hereis-text reader-char port)
"- procedure: read-hereis-text reader-char port
This reader macro procedure reads extended strings using the
delimiter ‘\"\"\"’. Enable and disable its use via the syntax
‘(enable-hereis)’ and ‘(disable-hereis)’. Example use:
(define text #\"\"\"
\"Run. Matt. Run.\", he said.
\"\"\")"
(define start-sq '(#\" #\" #\"))
(define end-sq '(#\" #\" #\"))
(define (skip-seq seq ch)
(let loop ((bs seq) (ch ch))
(cond
((null? bs) ch)
((eof-object? ch) (error "bad hereis expression"))
((char=? ch (car bs)) (loop (cdr bs) (read-char port)))
(else (error "hereis: coding error")))))
(let loop ((chl '()) (ex '()) (es end-sq)
(ch (let ((ch (skip-seq start-sq reader-char)))
(if (char=? #\newline ch) (read-char port) ch))))
(cond
((eof-object? ch) (error "bad hereis expression"))
((char=? ch (car es))
(let ((es (cdr es)))
(if (null? es)
(reverse-list->string chl)
(loop chl (cons ch ex) es (read-char port)))))
((pair? ex) (loop (append ex chl) '() end-sq ch))
(else (loop (cons ch chl) ex es (read-char port))))))
(define-syntax-rule (enable-hereis)
(eval-when (expand load eval)
(read-hash-extend #\" read-hereis-text)
(if #f #f)))
(define-syntax-rule (disable-hereis)
(eval-when (expand load eval)
(read-hash-extend #\" #f)
(if #f #f)))
;; --- last line ---