2016-04-14 4 views
-1

Full sourceMakromusterabgleich nicht

So habe ich ein Makro-Objekte für die Herstellung, und es wird verwendet, wie:

(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 

ich ein anderes Muster für mit öffentlichen und privaten Mitglieder hinzugefügt,

(define ob 
    (class private 
     (a 10) (b 20) 
     public 
     (get-a (lambda (x) a)) 
     (set-a! (lambda (x) (set! a x))))) 

und das funktioniert, aber aus irgendeinem Grund, wird es nicht mit diesem Muster übereinstimmen:

(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!")))))) 

Die Fehlermeldung für den Versuch, OB2 zu verwenden ist in der Quelle

Antwort

2

Soweit ich verstehe, das erste Beispiel soll nicht funktionieren, und in der Tat, konnte ich es nicht zu arbeiten. Ich glaube nicht, dass Sie zwei Ellipsen auf derselben Ebene verwenden können. Daher wäre es einfacher, so etwas wie jedoch

(define-syntax class 
    (syntax-rules (public private) 
    ((class (public (?var ?val) ...) (private (?var1 ?val1) ...)) 
    (list (list ?var ?val) ... (list ?var1 ?val1) ...)))) 

definieren, wenn Sie sie alle auf der gleichen syntaktischen Ebene zu tun haben, können Sie dies tun, indem Sie das Makro rekursiv anwenden, entlang der folgenden Zeilen:

(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))))) 

Um dies robuster zu machen, müssen Sie Regeln für leere öffentliche und private Ausdrücke hinzufügen.

+0

Mit welcher Implementierung arbeiten Sie? Ich benutze Huhn und arbeitete an diesem Problem auf der IRC dafür, wir hatten definitiv kein Problem mit zwei Ellipsen zu verwenden, und andere waren in der Lage, das erste Beispiel – Anandamide

+0

I.E. Ich habe mit den Implementierungsdesignern gesprochen und sie sagen, dass es syntaktisch korrekt ist. – Anandamide

+0

und dass sein auch in r5rs definiert Verhalten – Anandamide