【问题标题】:Creating a readtable with a disabled dispatch reader macro使用禁用的调度阅读器宏创建可读表
【发布时间】:2014-03-12 03:35:31
【问题描述】:

我正在创建一种基于 Racket 的新语言,我不希望某些 #x 宏起作用,例如语法引用 #'。如何删除它,以便 #' 不执行语法引用,而是执行未绑定调度宏字符的任何操作?

我可以用单字符宏来做到这一点

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

但我不知道如何为调度宏执行此操作。

【问题讨论】:

  • 不确定究竟你想要的结果。您是否希望 #' 被视为 ' - 例如#'x 变成 'x#'(x) 变成 '(x)?还是您希望完全丢弃#'?还是别的什么?
  • 这与 Scheme 的关系和与 CommonLisp 的关系一样多。建议删除“方案”标签。
  • @GregHendershott 就像我说的,“我如何删除它,以便 #' 不执行语法引用,但执行 unbound 调度宏字符的任何操作?”即我 #' 应该做 #@## 做的事情(假设用户没有编程他们做某事),这是一个错误。
  • ## 所做的是给出一个错误:"read: bad syntax `##'"。这就是你想让#' 做的事情吗?
  • @GregHendershott 是的,完全正确。我想为我的语言删除它的功能,就像我在我的示例中为引号字符所做的那样。

标签: macros racket reader-macro


【解决方案1】:

假设您希望 #' 被视为 '

提供一个简单地调用普通read-syntaxreader-proc

#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 的一个稍微复杂一点的例子是lambda reader literal support I just recently added#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)))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多