Reputation: 634
I'm trying to write a racket reader extension procedure that disables the special treatment of the pipe character |
.
I have two files: mylang/lang/reader.rkt
to implement the lang reader and mylang/testing.rkt
to try it out. I've run raco pkg install --link
to install the lang.
Here is reader.rkt
:
#lang s-exp syntax/module-reader
racket
#:read my-read
#:read-syntax my-read-syntax
(define (parse-pipe char in srcloc src linum colnum)
#'\|)
(define my-readtable
(make-readtable #f #\| 'terminating-macro parse-pipe))
(define (my-read-syntax src in)
(parameterize ((current-readtable my-readtable))
(read-syntax src in)))
(define (my-read in)
(syntax->datum
(my-read-syntax #f in)))
With testing.rkt
like this:
#lang mylang
(define | 3)
(+ 3 2)
runs and produces 5 as expected. But this next one doesn't:
#lang mylang
(define |+ 3)
(+ |+ 2)
complaining that define: bad syntax (multiple expressions after identifier) in: (define \| + 3)
which is reasonable since parse-pipe
produces a syntax object, not a string, so it terminates the reading of the symbol prematurely.
One thing I can do is keep reading until the end of the symbol, but that is hackish at best because I would be reimplementing symbol parsing and it wouldn't fix the case that the symbol has the pipe char in the middle, or if | is inside a string, etc.
What I would like to do is remove the default reader procedure for | from the readtable, but I don't know how/if it can be done.
Upvotes: 4
Views: 160
Reputation: 634
OK, I've found a way. The documentation for make-readtable
says:
char like-char readtable — causes char to be parsed in the same way that like-char is parsed in readtable, where readtable can be #f to indicate the default readtable.
so I can make the reader read |
like a normal character like a
with:
(define my-readtable
(make-readtable #f #\| #\a #f))
And it works
(define hawdy|+ "hello")
(string-append hawdy|+ "|world")
; => "hello|world"
Upvotes: 6