This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: A useful syntax for regexps and other things



> >The doubling can easily be removed from my implementation (which was
> >done independent of the SCSH version), and change the macro character
> >from q to <. However, I still claim that it is broken for a token
> >introduced by #< to be meaningful to the reader; reading #<some
> >unreadable object> from a port should throw an error immediately.
>
> The fix may be to change Guile to use #{some unreadable object}.

That's already meaningful to the reader (or at least #{some unreadable
object}# is) and I think having that as a symbol escape notation is
useful. 

Keeping #<some unreadable object> has a lot of general Lisp tradition
behind it, and Guile as well as apps that extend Guile would need to
be changed in a lot of places.

However, #[some unreadable object] is not in use by guile, and seems
to be what is used by a lot of Scheme interpreters (MIT Scheme and STk
for instance), so I'd find that more reasonable. However, this cuts
into the number of useful delimiter pairs for user reader extensions.

In any case, here's a simpler implementation of here strings that
should be scsh-compatible, according to the scsh manual, but free from
SCSH's non-GPL-compatible copyright. First an example:

guile> #</test/
"test"
guile> #</test//
"test"
guile> #<primitive-procedure />
guile> #<<HERE
one line test
HERE
"one line test"
guile> #<<HERE
multi-line
example
HERE
"multi-line
example"
guile> #<$ Escapes \\ are preserved \n $
" Escapes \\\\ are preserved \\n "


And the code (note that read-line-delimited may be useful in itself as
well):

(define (read-line-delimited delim-line . maybe-port)
  (let ((port (if (null? maybe-port) (current-input-port) (car maybe-port))))
    (let loop ((str "")
	       (line (read-line port))
	       (maybe-newline ""))
      (cond
       ((eof-object? line)
	(error "End of file in here string."))
       ((string=? line delim-line)
	(unread-char #\nl port)
	str)
       (else (loop (string-append str maybe-newline line) 
		   (read-line port) "\n"))))))

(read-hash-extend #\<
                  (lambda (c port)
                    (let ((delimiter (read-char port)))
		      (if (char=? delimiter #\<)
			  (read-line-delimited (read-line port) port)
			  (read-delimited (string delimiter) port)))))