Issue #407 - Modified the reader to handle escaped intraline whitespace properly, per R7RS.

This commit is contained in:
Justin Ethier 2020-09-16 23:05:02 -04:00
parent d18b776fa2
commit 457ca32279
3 changed files with 46 additions and 2 deletions

View file

@ -11,9 +11,10 @@ Bug Fixes
- Updated the `Dockerfile` to use a non-interactive install. This prevents build problems with the official image on DockerHub.
- Improved `(scheme lazy)` to allow `force` and `make-promise` to accept an argument of any type. Improved representation of promises to more precisely differentiate them from other objects.
- Updated `(scheme lazy)` such that `force` will recursively force promises.
- Add type checking to record type accessor functions. We now raise an error if the passed object is of the wrong record type.
- Fix issues with expanding `cond-expand` expressions in libraries. Previously there would be issues with the expansion if the code needed to be within the context of a `begin`.
- Updated `(scheme lazy)` such that `force` will recursively force promises.
- Modified the reader to handle escaped intraline whitespace properly, per R7RS.
## 0.20 - August 14, 2020

View file

@ -7118,7 +7118,8 @@ static int _read_is_hex_digit(char c)
static void _read_string(void *data, object cont, port_type *p)
{
char c;
int escaped = 0;
int escaped = 0, escaped_whitespace = 0,
ewrn = 0; // esc whitespace read newline
while(1) {
// Read more data into buffer, if needed
if (p->buf_idx == p->mem_buf_len) {
@ -7129,6 +7130,28 @@ static void _read_string(void *data, object cont, port_type *p)
c = p->mem_buf[p->buf_idx++];
p->col_num++;
if (escaped_whitespace) {
switch (c) {
case '\t':
case ' ':
p->col_num++;
continue;
break;
case '\n':
if (ewrn == 0) {
ewrn = 1;
p->line_num++;
p->col_num = 1;
continue;
}
break;
default:
escaped_whitespace = 0;
ewrn = 0;
break;
}
}
if (escaped) {
escaped = 0;
switch (c) {
@ -7192,6 +7215,18 @@ static void _read_string(void *data, object cont, port_type *p)
}
break;
}
case '\t':
case ' ':
escaped_whitespace = 1;
ewrn = 0;
p->col_num++;
break;
case '\n':
escaped_whitespace = 1;
ewrn = 1;
p->line_num++;
p->col_num = 1;
break;
default:
_read_error(data, p, "invalid escape character in string"); // TODO: char
break;

View file

@ -165,6 +165,14 @@
"abcde")
(assert:equal "string-for-each" v '(101 100 99 98 97)))
(assert:equal "interline whitespace" "1 2 \
3 4" "1 2 3 4")
(assert:equal "interline whitespace" "1 2 \
3 4" "1 2 \n\n3 4")
;; UTF-8 / Strings
(assert:equal "UTF8 string length" (string-length (make-string 1 (integer->char 128))) 1)
(assert:equal "UTF8 bv length" (bytevector-length (string->utf8 (make-string 1 (integer->char 128)))) 2)