Создание читаемой таблицы с отключенным макросом диспетчера чтения
Я создаю новый язык, основанный на Racket, и я не хочу определенных #x
макросы для работы, такие как синтаксическая кавычка #'
, Как мне удалить это так, чтобы #'
не делает синтаксическую кавычку, но делает то, что делает несвязанный макро-символ отправки?
Я могу сделать это с помощью макросов с одним символом, выполнив
(make-readtable (current-readtable)
#\' #\a #f) ; set ' to be the same as a normal character
но я не знаю, как это сделать для макроса отправки.
1 ответ
Решение
Предполагая, что вы хотите #'
рассматриваться как '
:
Обеспечить reader-proc
это просто называет нормальным 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)))))
Несколько более сложный пример работы с 'dispatch-macro
является литеральная поддержка лямбда-ридер, которую я недавно добавил в #lang rackjure
,
ОБНОВЛЕНО
Предполагая, что вы хотите #'
вызвать ошибку чтения, "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)))))