diff --git a/lib/srfi/38.scm b/lib/srfi/38.scm index 63afc91c..dfa795dd 100644 --- a/lib/srfi/38.scm +++ b/lib/srfi/38.scm @@ -130,14 +130,26 @@ (if (not (or (eof-object? c) (eqv? c #\newline))) (skip-line in)))) +(define (skip-horizontal-whitespace in) + (case (peek-char in) + ((#\space #\tab) + (read-char in) + (skip-horizontal-whitespace in)))) + (define (skip-whitespace in) (case (peek-char in) ((#\space #\tab #\newline #\return) (read-char in) - (skip-whitespace in)) + (skip-whitespace in)))) + +(define (skip-whitespace-and-line-comments in) + (case (peek-char in) + ((#\space #\tab #\newline #\return) + (read-char in) + (skip-whitespace-and-line-comments in)) ((#\;) (skip-line in) - (skip-whitespace in)))) + (skip-whitespace-and-line-comments in)))) (define (skip-comment in depth) (case (read-char in) @@ -151,7 +163,7 @@ ;; returns #f if a trailing # was consumed (define (skip-whitespace-and-sexp-comments in read) - (skip-whitespace in) + (skip-whitespace-and-line-comments in) (cond ((eqv? #\# (peek-char in)) (read-char in) @@ -239,13 +251,44 @@ (read in)) (else (read-error "invalid type identifier syntax" ch))))) + (define (read-escape-sequence) + (let ((ch (read-char in))) + (cond + ((eof-object? ch) (read-incomplete-error "incomplete escape")) + (else + (case ch + ((#\a) #\alarm) ((#\b) #\backspace) + ((#\n) #\newline) ((#\r) #\return) + ((#\t) #\tab) + ((#\newline) (skip-horizontal-whitespace in) #f) + ((#\space #\tab) + (skip-line in) (skip-horizontal-whitespace in) #f) + ((#\x) + (let* ((n (read-number 16)) + (ch2 (read-char in))) + (if (not (and n (eqv? ch2 #\;))) + (read-error "invalid string escape" n ch2) + (integer->char n)))) + (else ch)))))) + (define (read-delimited terminal) + (let ((out (open-output-string))) + (let lp () + (let ((ch (read-char in))) + (cond + ((eof-object? ch) (read-incomplete-error "incomplete string")) + ((eqv? ch terminal) (get-output-string out)) + ((eqv? ch #\\) + (let ((ch2 (read-escape-sequence))) + (if ch2 (write-char ch2 out)) + (lp))) + (else (write-char ch out) (lp))))))) (define (read-object) (let ((name (read-name #f in))) - (skip-whitespace in) + (skip-whitespace-and-line-comments in) (let* ((id (read-type-id in)) (type (lookup-type name id))) (let lp ((ls '())) - (skip-whitespace in) + (skip-whitespace-and-line-comments in) (cond ((eof-object? (peek-char in)) (read-error "missing closing }")) @@ -401,6 +444,12 @@ ((#\{) (read-char in) (read-object)) + ((#\") + (read-char in) + (read-delimited #\")) + ((#\|) + (read-char in) + (string->symbol (read-delimited #\|))) ((#\') (read-char in) (list 'quote (read-one in))) ((#\`) (read-char in) (list 'quasiquote (read-one in))) ((#\,)