如何为生成的语法提供绑定箭头?

How to provide binding arrow for the generated syntax?

这里是完整的源代码:https://gist.github.com/dannypsnl/d84af132553ab18328844bc1a41389a6

问题是我可以将 (-> a name) 中的 name 引用到 Car-name 吗?在 -> 形式中,它首先获取实例的 class,然后生成一个字符串 <class-name>-<field-name> 并将其转换为 accessor 的语法。最后产生#'(accessor instance)得到最终结果

一般来说,这意味着我可以从生成的语法中引用原始定义吗?

像这样附加 class 名称和字段名称是一种脆弱的方法。如果我能建议另一种方法,最好使用 struct-field-info

如何使用 struct-field-info 的示例:

(define-for-syntax (get-accessor type-id field-symbol)
  (define type-info (syntax-local-value type-id))
  ; both fields and accessors are reversed,
  ; but that's okay since they're consistent with each other
  (define fields (struct-field-info-list type-info))
  (define accessors (fourth (extract-struct-info type-info)))
  (list-ref accessors (index-of fields field-symbol)))

并在您的 -> 宏中使用它:

(define-syntax-parser ->
  [(_ instance field-name)
   (define (class-of stx) ....)
   (define accessor-id
     (get-accessor (class-of #'instance) (syntax->datum #'field-name)))
   (with-syntax ([accessor accessor-id])
     #'(accessor instance))])

现在,你的实际问题是:

如何提供绑定箭头

假设您想要一个从 class 定义中的字段名称到 -> 表达式中的相同字段名称的绑定箭头,可以使用语法属性 'disappeared-binding'disappeared-use.

class 定义需要额外的语法 属性 'disappeared-binding 包含 field 标识符,

(define-syntax-parser class
  [(_ name field ...)
   (syntax-property #'(struct name (field ...))
                    'disappeared-binding
                    (stx-map syntax-local-introduce #'(field ...)))])

-> 表达式将需要 'disappeared-use 及其 field-name 标识符。

(define-syntax-parser ->
  [(_ instance field-name)
   (define (class-of stx)
     (car (syntax-property (local-expand stx 'expression '()) 'type)))
   (define accessor-id
     (get-accessor (class-of #'instance) (syntax->datum #'field-name)))
   (with-syntax ([accessor accessor-id])
     (syntax-property #'(accessor instance)
                      'disappeared-use
                      (list (syntax-local-introduce #'field-name))))])

现在,从 (class Car name price) 中的 name(-> a name) 中的 name 以及从 price 中的 price 都有蓝色的语法检查箭头(class Car name price)(-> a price) 中的 price

但是,从 (class Car name price) 中的 price(-> b price) 中的 price 有一个紫色问号检查语法箭头,其原因在函数定义(define (foo a b) (+ a (-> b price)))中,不确定b是什么类型,所以它并不知道price是否指的是Car价格。