宏模式不匹配
Macro pattern not matching
所以我有一个制作对象的宏,它的用法如下:
(define ob
(class (a 10) (b 20)
(set-a! (lambda (x) (set! a x)))
(set-b! (lambda (x) (set! b x)))
(foo (lambda (x)
(* (+ a b) (- a b))))))
(ob 'a) -> 10
(ob 'b) -> 20
(ob 'set-a! 50)
(ob 'a) -> 50
(ob 'foo) -> 2100
我为 public 和私有成员添加了另一个模式,
(define ob
(class private
(a 10) (b 20)
public
(get-a (lambda (x) a))
(set-a! (lambda (x) (set! a x)))))
这行得通,但出于某种原因,它不匹配此模式:
(define ob2
(class private
(a 10) (b 20) (c '())
public
(get-a (lambda (x) a))
(get-b (lambda (x) b))
(set-a! (lambda (x) (set! a x)))
(set-b! (lambda (x) (set! b x)))
(push-c! (lambda (x)
(set! c (cons x c))))
(pop-c! (lambda (x)
(if (not (eq? c '()))
(set! c (cdr c))
(error "stack empty!"))))))
尝试使用 ob2 的错误消息在源中
据我所知,第一个示例也不应该工作,事实上,我无法让它工作。我认为您不能在同一级别上使用两个省略号。因此,定义类似
的东西会更容易
(define-syntax class
(syntax-rules (public private)
((class (public (?var ?val) ...) (private (?var1 ?val1) ...))
(list (list ?var ?val) ... (list ?var1 ?val1) ...))))
但是,如果您必须在同一句法级别上执行所有操作,则可以通过递归应用宏来实现,具体如下:
(define-syntax testclass
(syntax-rules (public private)
((testclass public (var val) . rest)
(testclass ((var val)) public . rest))
((testclass ((var val) ...) public (var1 val1) . rest)
(testclass ((var val) ... (var1 val1)) public . rest))
((testclass lst public private . rest)
(list (quote lst) (quote rest)))))
为了使其更加健壮,您必须为空 public 和私有表达式添加规则。
所以我有一个制作对象的宏,它的用法如下:
(define ob
(class (a 10) (b 20)
(set-a! (lambda (x) (set! a x)))
(set-b! (lambda (x) (set! b x)))
(foo (lambda (x)
(* (+ a b) (- a b))))))
(ob 'a) -> 10
(ob 'b) -> 20
(ob 'set-a! 50)
(ob 'a) -> 50
(ob 'foo) -> 2100
我为 public 和私有成员添加了另一个模式,
(define ob
(class private
(a 10) (b 20)
public
(get-a (lambda (x) a))
(set-a! (lambda (x) (set! a x)))))
这行得通,但出于某种原因,它不匹配此模式:
(define ob2
(class private
(a 10) (b 20) (c '())
public
(get-a (lambda (x) a))
(get-b (lambda (x) b))
(set-a! (lambda (x) (set! a x)))
(set-b! (lambda (x) (set! b x)))
(push-c! (lambda (x)
(set! c (cons x c))))
(pop-c! (lambda (x)
(if (not (eq? c '()))
(set! c (cdr c))
(error "stack empty!"))))))
尝试使用 ob2 的错误消息在源中
据我所知,第一个示例也不应该工作,事实上,我无法让它工作。我认为您不能在同一级别上使用两个省略号。因此,定义类似
的东西会更容易(define-syntax class
(syntax-rules (public private)
((class (public (?var ?val) ...) (private (?var1 ?val1) ...))
(list (list ?var ?val) ... (list ?var1 ?val1) ...))))
但是,如果您必须在同一句法级别上执行所有操作,则可以通过递归应用宏来实现,具体如下:
(define-syntax testclass
(syntax-rules (public private)
((testclass public (var val) . rest)
(testclass ((var val)) public . rest))
((testclass ((var val) ...) public (var1 val1) . rest)
(testclass ((var val) ... (var1 val1)) public . rest))
((testclass lst public private . rest)
(list (quote lst) (quote rest)))))
为了使其更加健壮,您必须为空 public 和私有表达式添加规则。