需要帮助减少我的 Scheme 宏中的样板

问题描述

我在 Guile Scheme 工作。我正在制作宏,但我发现我在输出中重复了很多样板。 我对 Scheme 还很陌生,所以如果有比语法案例更好的方法解决这个问题,我愿意接受建议。

在这个宏中,输入只有一个区别,“set”和“setconst”,输出只有一个区别,“elementReference”和“stringValue”。我尝试使用 #` 和 #,来取消引用,但我收到错误消息,例如“语法:表单中缺少省略号(语法集)”。理想情况下,我想在我的宏中放入一些方案代码来区分 set 和 setconst,并相应地更改输出,但正如我所说,这是新的,如果有更好的方法来获得我的结果,我是开放的。>

这是我的代码

  (define-Syntax assign
    (lambda (stx)
      (Syntax-case stx (then)
        ((assign aname then target (set to from) ...) #'(assignments (name aname) 
                                                                     (label aname) 
                                                                     (locationX 50) 
                                                                     (locationY 50) 
                                                                     ((assignmentItems 
                                                                       (operator Assign) 
                                                                       (assignToReference to) 
                                                                       (value (elementReference from))) ...)
                                                                     (connector (targetReference target))))
        ((assign aname then target (setconst to from) ...) #'(assignments (name aname) 
                                                                     (label aname) 
                                                                     (locationX 50) 
                                                                     (locationY 50) 
                                                                     ((assignmentItems 
                                                                       (operator Assign) 
                                                                       (assignToReference to) 
                                                                       (value (stringValue from))) ...)
                                                                     (connector (targetReference target))))
        )))

解决方法

我已经提出了一个解决方案,但我仍然欢迎提供更好的方法来实现这一点。 我没有使用 if-fing 或取消引用,而是为了区别而制作了一个更简单的宏,并在我更大的宏中调用它。这应该会在我扩展 DSL 时起作用。

(define-syntax assign-from
  (lambda (stx)
    (syntax-case stx (set setconst)
      ((assign-operator set to from) #'(elementReference from))
      ((assign-operator setconst to from) #'(stringValue from)))))

(define-syntax assign
  (lambda (stx)
    (syntax-case stx (then)
      ((assign aname then target (set to from) ...) #'(assignments (name aname) 
                                                                   (label aname) 
                                                                   (locationX 50) 
                                                                   (locationY 50)
                                                                   ((assignmentItems 
                                                                     (assignToReference to) 
                                                                     (operator Assign) 
                                                                     (value (assign-from set to from))) ...)
                                                                   (connector (targetReference target))))
      )))