0
votes

I am creating a new language based on Racket and I don't want certain #x macros to work, such as the syntax-quote #'. How do I remove it so that #' does not do a syntax quote, but does whatever an unbound dispatch macro-char does?

I can do that with single-char macros by doing

(make-readtable (current-readtable)
                #\' #\a #f) ; set ' to be the same as a normal character

but I don't know how to do this for dispatch macros.

1
Not sure exactly the result you want. Do you want #' to be treated as ' -- e.g. #'x to become 'x and #'(x) to become '(x)? Or do you want the #' to be discarded completely? Or something else? - Greg Hendershott
This has as much to do with Scheme as it does with CommonLisp. Suggest removing the 'Scheme' tag. - GoZoner
@GregHendershott like I said, "How do I remove it so that #' does not do a syntax quote but does whatever an unbound dispatch macro-char does?" i.e. I #' should do what #@ and ## do (assuming the user has not programmed them to do something), which is do an error. - user3286380
What ## does is give an error: "read: bad syntax `##'". Is that what you want #' to do? - Greg Hendershott
@GregHendershott yes, exactly. I want to remove the functionality of it for my language, like I did in my example for the quote character. - user3286380

1 Answers

0
votes

Assuming you want #' to be treated as ':

Provide a reader-proc that simply calls the normal read-syntax:

#lang racket/base

(define (reader-proc ch in src line col pos)
  (read-syntax src in))

(define our-readtable (make-readtable (current-readtable)
                                      #\'
                                      'dispatch-macro
                                      reader-proc))

;; A `#:wrapper1` for `syntax/module-reader`, i.e. to use in your
;; lang/reader.rkt
(define (wrapper1 thk)
  (parameterize ([current-readtable our-readtable])
    (thk)))
(provide wrapper1)

;; tests
(module+ test
  (require rackunit
           racket/port)
  (parameterize ([current-readtable our-readtable])
    (check-equal? (with-input-from-string "#'foo" read)
                  'foo)
    (check-equal? (with-input-from-string "#'(foo)" read)
                  '(foo))
    (check-equal? (with-input-from-string "#'(foo #'(bar))" read)
                  '(foo (bar)))))

A slightly more complicated example of working with 'dispatch-macro is the lambda reader literal support I just recently added to #lang rackjure.


UPDATED

Assuming you want #' to cause a read error, "bad syntax: #'":

#lang racket/base

(require syntax/readerr)

(define (reader-proc ch in src line col pos)
  (raise-read-error (format "bad syntax: #~a" ch)
                    src line col pos 2))

(define our-readtable (make-readtable (current-readtable)
                                      #\'
                                      'dispatch-macro
                                      reader-proc))

;; A `#:wrapper1` for `syntax/module-reader`, i.e. to use in your
;; lang/reader.rkt
(define (wrapper1 thk)
  (parameterize ([current-readtable our-readtable])
    (thk)))
(provide wrapper1)

;; tests
(module+ test
  (require rackunit
           racket/port)
  (parameterize ([current-readtable our-readtable])
    (check-exn exn:fail? (λ () (with-input-from-string "#'foo" read)))))