Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 检查标识符是否在宏扩展点进行词汇绑定?_Macros_Scheme_R6rs_Chez Scheme - Fatal编程技术网

Macros 检查标识符是否在宏扩展点进行词汇绑定?

Macros 检查标识符是否在宏扩展点进行词汇绑定?,macros,scheme,r6rs,chez-scheme,Macros,Scheme,R6rs,Chez Scheme,这可能是一个新手问题,但我正在尝试编写一个宏来检测标识符是否在宏扩展点进行词汇绑定,并相应地更改其输出。这在R6RS方案中是否可能,如果可能,如何实现 为什么我想知道 我正在用Chez方案编写一个玩具Objective-C绑定层,使用宏,我最初的挑战是如何有效地处理Objective-C选择器。程序必须在运行时查询Objective-C运行时,查询与每个选择器名称对应的实际SEL对象。在扩展过程中,程序中使用的选择器名称是静态的,让我的宏插入查询代码很容易,但我希望避免重复查询相同的选择器名称

这可能是一个新手问题,但我正在尝试编写一个宏来检测标识符是否在宏扩展点进行词汇绑定,并相应地更改其输出。这在R6RS方案中是否可能,如果可能,如何实现

为什么我想知道 我正在用Chez方案编写一个玩具Objective-C绑定层,使用宏,我最初的挑战是如何有效地处理Objective-C选择器。程序必须在运行时查询Objective-C运行时,查询与每个选择器名称对应的实际
SEL
对象。在扩展过程中,程序中使用的选择器名称是静态的,让我的宏插入查询代码很容易,但我希望避免重复查询相同的选择器名称

我的第一个想法是为绑定到
SEL
外部对象的方案定义制定一些命名约定。这样,我就可以为每个唯一的选择器提供一个
(define)
,从而为每个选择器提供一个运行时查询。这取决于我的宏能够检测任何给定选择器的这些绑定,并在它们不存在时引入它们,因此我的问题是


这个解决方案仍然不完善,因为我的宏可能在内部范围内展开,但这对我来说是最明显的。是否有更好的方法在扩展时“实习”表达式?

我不完全确定这是否可以通过良好的指定行为实现,但您可以按照以下方式进行:

#!r6rs
(library (bound helper)
    (export make-binding-check)
    (import (rnrs))
(define-syntax make-binding-check
  (lambda (x)
    (syntax-case x ()
      ((_ if bound?)
       #'(begin
           (define-syntax if
             (lambda (xx)
               (syntax-case xx ()
                 ((_ b then els)
                  (free-identifier=? (datum->syntax #'if (syntax->datum #'b)) #'b)
                  #'els)
                 ((_ b then els)
                  #'then))))
           (define-syntax bound?
             (lambda (xx)
               (syntax-case xx ()
                 ((_ b)
                  #'(if b #t #f))))))))))
)
(library (bound)
    (export bound? if-bound)
    (import (bound helper))
(make-binding-check if-bound bound?)
)

(import (rnrs) (bound))

(display (bound? foo)) ;; #f
(let ((foo 1))
  (display (bound? foo))) ;; #t
(newline)
其思想是使用
自由标识符=?
检查给定标识符是否绑定。
make binding check
宏使用两个标识符,当宏展开时,这两个标识符都应解除绑定。为了生成这样的未绑定标识符,代码由两部分组成:实现和环境:第一部分是
(绑定帮助器)
,它提供了标识符比较的实现。另一个是
(绑定)
,它几乎不提供绑定环境

将使用从环境库传递的标识符和要检查的实际标识符进行比较。如果实际标识符绑定到任何东西,那么它将与未绑定标识符不同,因此
bound?
应返回
\f
。(如果您定义
进行绑定检查
并进行检查,它将返回#t,因为它是在
(绑定)
库中定义的。)

小心 这可能有效,也可能无效,这取决于您使用的实现,我不确定这是否适用于Chez