0

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.

Greg Hendershott
  • 16,100
  • 6
  • 36
  • 53
user3286380
  • 574
  • 4
  • 10
  • 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 Mar 12 '14 at 13:46
  • 1
    This has as much to do with Scheme as it does with CommonLisp. Suggest removing the 'Scheme' tag. – GoZoner Mar 12 '14 at 14:24
  • @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 Mar 12 '14 at 14:31
  • What `##` does is give an error: `"read: bad syntax \`##'"`. Is that what you want `#'` to do? – Greg Hendershott Mar 12 '14 at 14:44
  • @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 Mar 12 '14 at 14:54
  • I updated my answer. In that case I guess you simply have the `'dispatch-macro` call `raise-read-error`. – Greg Hendershott Mar 12 '14 at 16:21

1 Answers1

0

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)))))
Greg Hendershott
  • 16,100
  • 6
  • 36
  • 53