Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.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
Racket 将符号列表转换为宏中使用的标识符列表_Racket - Fatal编程技术网

Racket 将符号列表转换为宏中使用的标识符列表

Racket 将符号列表转换为宏中使用的标识符列表,racket,Racket,考虑这样一个场景,我想使用Racket宏指定一个非常简单的actor语言。参与者由一种行为定义,该行为定义了一些本地状态和实现某些逻辑的消息处理程序。消息处理程序的主体既可以使用消息的形式参数,也可以使用状态变量。下面的代码实现了一个示例 代码中有相当多的上下文,这可能甚至不是必需的。但是,为了提供一个运行的示例,我将其包括在内,而且我需要使用语法参数化这一事实可能会使解决方案复杂化。特别需要注意的是消息宏中的with syntax子句,其中我需要(局部状态变量…模式匹配标识符列表,当前为#'局

考虑这样一个场景,我想使用Racket宏指定一个非常简单的actor语言。参与者由一种行为定义,该行为定义了一些本地状态和实现某些逻辑的消息处理程序。消息处理程序的主体既可以使用消息的形式参数,也可以使用状态变量。下面的代码实现了一个示例

代码中有相当多的上下文,这可能甚至不是必需的。但是,为了提供一个运行的示例,我将其包括在内,而且我需要使用
语法参数化
这一事实可能会使解决方案复杂化。特别需要注意的是
消息
宏中的
with syntax
子句,其中我需要
(局部状态变量…
模式匹配标识符列表,当前为
#'局部状态变量
,这是一个符号列表(受
ACTOR
宏中的
syntax parameterize
约束),因此不匹配。到目前为止,我还没有找到解决方案,尽管这似乎并不十分困难。我是否遗漏了一些明显的问题

#lang racket

(require (for-syntax syntax/parse))
(require racket/stxparam)

(define LOCAL_STATE
  (lambda (stx)
    (raise-syntax-error 'LOCAL_STATE "should only be used inside an actor" stx)))

; Define some syntax classes because abstractions are nice
(begin-for-syntax
  (define-syntax-class actor-local-state
    #:description "actor local state"
    #:literals (LOCAL_STATE)
    (pattern (LOCAL_STATE state-variable:id ...)))

  (define-syntax-class message-pattern
    #:description "actor message pattern"
    (pattern (identifier:id argument:id ...))))


(define-syntax-parameter local-state-variables
  (lambda (stx)
    (raise-syntax-error 'local-state-variables "reserved keyword for actors" stx)))


(define-syntax (MESSAGE stx)
  (syntax-parse stx
    [(_ pattern:message-pattern body:expr ...+)
     ; Currently there is a "binding match failed" error on the following line, but replacing #'local-state-variables with #'(a b) (a list of identifiers) needless to say works. 
     (with-syntax ([(local-state-variable ...) #'local-state-variables])
       ; For simplicity just display the state variables - this is normally where some magic happens
       #'(display '(local-state-variable ...)))]))


(define-syntax (ACTOR stx)
  (syntax-parse stx
    [(_ state:actor-local-state handler:expr ...+)
     #'(syntax-parameterize
           ([local-state-variables '(state.state-variable ...)])
         ; For the sake of simplicity, an actor is currently a list of message handlers
         (list handler ...))]))


; in this proof-of-concept code this should print (a b)
(define behaviour
  (ACTOR (LOCAL_STATE a b)
         (MESSAGE (add x y) (+ a b x y))))

将任何数据(包括符号列表)转换为标识符的最简单方法。(您也可以使用,但这仅适用于单个标识符。)使用这些函数,您可以为希望新标识符具有的作用域传入一个语法对象,或者#f(如果希望它继承当前宏正在生成的作用域)。1获取标识符列表(作为一个语法对象,只需:

(syntax->datum stx '(a b c))
其中
”(a b c)
是您的标识符列表。最后,您可以使用语法将其添加到
中:

(with-syntax ([(local-state-variables ...) (datum->syntax stx ...)])
  ...)
作为旁注,回答问题标题的方法是,使用
map
在列表上迭代,使用
格式id
生成一个新列表:

(map (curry format-id stx "~a") '(a b c)
1除非我错了,否则请更正此错误。

使用。以下是使用语法参数管理变量列表的示例:

;; vars : syntax parameter of (Listof Identifier)
(define-syntax-parameter vars null)

;; with-vars: like let, but set vars
(define-syntax (with-vars stx)
  (syntax-parse stx
    [(_ ([var:id rhs:expr] ...) . body)
     #'(let ([var rhs] ...)
         (syntax-parameterize ([vars (list (quote-syntax var) ...)])
           . body))]))

;; get-vars: get vars (symbolic name) and their values
(define-syntax (get-vars stx)
  (syntax-parse stx
    [(_)
     (with-syntax ([(var ...) (syntax-parameter-value #'vars)])
       #'(list (list (quote var) var) ...))]))

;; Examples:    

(get-vars)
;; => '()

(with-vars ([x 1])
  (get-vars))
;; => '((x 1))

(with-vars ([x 1])
  (with-vars ([y 2] [z 3])
    (set! z 17)
    (get-vars)))
;; => '((y 2) (z 17))

这确实是一个简单的解决方案,但是
(map(curry format id stx“~a”)局部状态变量)
抛出一个未绑定的标识符错误(对于
局部状态变量
)使用
#“local-state-variables
将其解释为标识符
local-state-variables
的语法对象。困难似乎在于引用语法参数。更广泛地说,使状态变量可访问始终包含在
ACTOR
macr中的
消息
宏o(其中状态变量已确定)。