diff --git a/main.rkt b/main.rkt index 46a4d1e..e4bd1b4 100644 --- a/main.rkt +++ b/main.rkt @@ -19,8 +19,12 @@ (~and fields ([field:id (~literal :) type] ...)) (~or (~optional (~and transparent #:transparent)) - (~optional (~seq #:property (~literal prop:custom-write) custom-write:expr)) - (~optional (~seq #:property (~literal prop:equal+hash) equal+hash:expr))) + (~optional (~seq #:property + (~literal prop:custom-write) + custom-write:expr)) + (~optional (~seq #:property + (~literal prop:equal+hash) + equal+hash:expr))) ...) (define poly? (and (attribute polymorphic) (not (stx-null? #'(T ...))))) @@ -46,10 +50,50 @@ #`(begin #,@(when-attr custom-write - (: printer #,(maybe-∀ #'(→ ins Output-Port (U #t #f 0 1) Any))) - (define printer custom-write)) - #,@(if (attribute equal+hash) - (let () + (define-type PrinterType + #,(maybe-∀ #'(→ ins Output-Port (U #t #f 0 1) Any))) + (: printer PrinterType) + (: printer-implementation PrinterType) + (define (printer self port mode) + (printer-implementation self port mode))) + + #,@(when-attr equal+hash + (define-type ComparerType-Equal + #,(maybe-∀2 + #'(→ ins ins2 (→ Any Any Boolean) Any))) + (define-type ComparerType-Hash1 + #,(maybe-∀ + #'(→ ins (→ Any Fixnum) Fixnum))) + (define-type ComparerType-Hash2 + #,(maybe-∀ + #'(→ ins (→ Any Fixnum) Fixnum))) + (define-type ComparerType + (List ComparerType-Equal + ComparerType-Hash1 + ComparerType-Hash2)) + (: eq+h ComparerType) + (: eq+h-implementation (→ ComparerType)) + (define eq+h + (list (ann (λ (a b r) ((car (eq+h-implementation)) a b r)) + ComparerType-Equal) + (ann (λ (a r) ((cadr (eq+h-implementation)) a r)) + ComparerType-Hash1) + (ann (λ (a r) ((caddr (eq+h-implementation)) a r)) + ComparerType-Hash2)))) + + (struct #,@(when-attr polymorphic (T ...)) + name + #,@(when-attr parent parent) + fields + #,@(when-attr transparent #:transparent) + #,@(when-attr custom-write #:property prop:custom-write printer) + #,@(when-attr equal+hash #:property prop:equal+hash eq+h)) + + #,@(when-attr custom-write + (define printer-implementation custom-write)) + + #,@(when-attr equal+hash + #,(let () (define/with-syntax equal+hash-ann (syntax-parse #'equal+hash [((~and list (~literal list)) equal? hash1 hash2) @@ -63,20 +107,5 @@ #,(maybe-∀ #'(→ ins (→ Any Fixnum) Fixnum))))] [expr:expr #'expr])) - #`((: eq+h (List #,(maybe-∀2 - #'(→ ins ins2 (→ Any Any Boolean) Any)) - #,(maybe-∀ - #'(→ ins (→ Any Fixnum) Fixnum)) - #,(maybe-∀ - #'(→ ins (→ Any Fixnum) Fixnum)))) - (define eq+h equal+hash-ann))) - #'()) - - (struct #,@(when-attr polymorphic (T ...)) - name - #,@(when-attr parent parent) - fields - #,@(when-attr transparent #:transparent) - #,@(when-attr custom-write #:property prop:custom-write printer) - #,@(when-attr equal+hash #:property prop:equal+hash eq+h)))])) + #`(define eq+h-implementation (λ () equal+hash-ann)))))]))