~ chicken-core (chicken-5) d6a53663e299c67e3819adde66ee8f32aebd8be8
commit d6a53663e299c67e3819adde66ee8f32aebd8be8 Author: Peter Bex <peter.bex@xs4all.nl> AuthorDate: Sun May 26 21:33:41 2013 +0200 Commit: Peter Bex <peter.bex@xs4all.nl> CommitDate: Sun May 26 22:54:57 2013 +0200 Add support for R7RS's "indented string" escape syntax. This allows the user to "escape" all whitespace surrounding *one* newline with a backslash, causing all of this to be completely collapsed to nothing. This is useful when writing long string literals which should be broken up into multiple lines. This also adds some tests for other R7RS escape syntax, most of which we already supported anyway. There's only the escaped hex scalar value left, which is ambiguous with regard to the old CHICKEN hex scalar syntax. diff --git a/library.scm b/library.scm index cd33b097..68165d9e 100644 --- a/library.scm +++ b/library.scm @@ -2521,6 +2521,22 @@ EOF (loop (##sys#read-char-0 port) (r-cons-codepoint n lst)) ))) ((#\\ #\' #\" #\|) (loop (##sys#read-char-0 port) (cons c lst))) + ((#\newline #\space #\tab) + ;; Read "escaped" <intraline ws>* <nl> <intraline ws>* + (let eat-ws ((c c) (nl? #f)) + (case c + ((#\space #\tab) + (eat-ws (##sys#read-char-0 port) nl?)) + ((#\newline) + (if nl? + (loop c lst) + (eat-ws (##sys#read-char-0 port) #t))) + (else + (unless nl? + (##sys#read-warning + port + "escaped whitespace, but no newline - collapsing anyway")) + (loop c lst))))) (else (cond ((and (char-numeric? c) (char>=? c #\0) diff --git a/tests/r7rs-tests.scm b/tests/r7rs-tests.scm index 368f9f4b..c0f6ebda 100644 --- a/tests/r7rs-tests.scm +++ b/tests/r7rs-tests.scm @@ -89,11 +89,44 @@ +(SECTION 6 7) + + +;; We try to avoid using the very constructs that we are testing here, +;; hence the slightly cumbersome string construction of <x> -> "\"\\<x>\"" +(define (read-escaped-string x) + (with-input-from-string (string-append (string #\" #\\) x (string #\")) + read)) +(define (escaped-char x) + (string-ref (read-escaped-string x) 0)) + +(test #\alarm escaped-char "a") +(test #\backspace escaped-char "b") +(test #\tab escaped-char "t") +(test #\newline escaped-char "n") +(test #\return escaped-char "r") +(test #\" escaped-char "\"") +(test #\\ escaped-char "\\") +(test #\| escaped-char "|") +;; *ONE* line ending following a backslash escape, along with any +;; preceding or trailing intraline whitespace is collapsed and ignored. +(test #\E escaped-char (string-append (string #\newline) " END")) +(test #\E escaped-char (string-append " " (string #\newline) "END")) +(test #\E escaped-char (string-append " " (string #\newline) "END")) +(test #\E escaped-char (string-append " " (string #\newline) " END")) +;; But not more than one! +(test #\newline escaped-char (string-append " " (string #\newline) " " (string #\newline) " END")) +;; Tabs count as intraline whitespace too +(test #\E escaped-char (string-append (string #\tab) (string #\newline) (string #\tab) " END")) +;; Edge case +(test "" read-escaped-string (string-append " " (string #\newline) " ")) + ;; NOT YET (is ambiguous with existing \xNN syntax in Chicken) #;(test #\tab escaped-char "x9;") #;(test #\tab escaped-char "x09;") + (SECTION 6 8) ;; Symbols are implicitly quoted inside self-evaluating vectors.Trap