spelufo
spelufo

Reputation: 634

Removing racket's default reader procedure from the readtable for the character |

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

Answers (1)

spelufo
spelufo

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

Related Questions