Add vector signatures, and `vector-of' to the HtDP signature syntax.
This commit is contained in:
parent
3751452530
commit
fa854f62fc
|
@ -25,6 +25,7 @@
|
||||||
make-predicate-signature
|
make-predicate-signature
|
||||||
make-type-variable-signature
|
make-type-variable-signature
|
||||||
make-list-signature
|
make-list-signature
|
||||||
|
make-vector-signature
|
||||||
make-mixed-signature
|
make-mixed-signature
|
||||||
make-combined-signature
|
make-combined-signature
|
||||||
make-case-signature
|
make-case-signature
|
||||||
|
@ -177,6 +178,52 @@
|
||||||
(apply proc arbitraries)
|
(apply proc arbitraries)
|
||||||
#f)))
|
#f)))
|
||||||
|
|
||||||
|
(define vectors-table (make-weak-hasheq)) ; #### ought to do ephemerons, too
|
||||||
|
|
||||||
|
(define (make-vector-signature name arg-signature syntax)
|
||||||
|
(make-signature
|
||||||
|
name
|
||||||
|
(lambda (self obj)
|
||||||
|
|
||||||
|
(define (check old-sigs)
|
||||||
|
(let ((old-sigs (cons arg-signature old-sigs)))
|
||||||
|
(hash-set! vectors-table obj old-sigs)
|
||||||
|
(let* ((orig (vector->list obj))
|
||||||
|
(els (map (lambda (x)
|
||||||
|
(apply-signature arg-signature x))
|
||||||
|
orig)))
|
||||||
|
(if (andmap eq? orig els)
|
||||||
|
obj
|
||||||
|
(let ((new (list->vector els)))
|
||||||
|
(hash-set! vectors-table obj new old-sigs)
|
||||||
|
obj)))))
|
||||||
|
|
||||||
|
(cond
|
||||||
|
((not (vector? obj))
|
||||||
|
(signature-violation obj self #f #f)
|
||||||
|
obj)
|
||||||
|
((hash-ref vectors-table obj #f)
|
||||||
|
=> (lambda (old-sigs)
|
||||||
|
(if (ormap (lambda (old-sig)
|
||||||
|
(signature<=? old-sig arg-signature))
|
||||||
|
old-sigs)
|
||||||
|
obj
|
||||||
|
(check old-sigs))))
|
||||||
|
(else
|
||||||
|
(check '()))))
|
||||||
|
syntax
|
||||||
|
#:arbitrary-promise
|
||||||
|
(delay
|
||||||
|
(lift->arbitrary arbitrary-vector arg-signature))
|
||||||
|
#:info-promise
|
||||||
|
(delay (make-vector-info arg-signature))
|
||||||
|
#:=?-proc
|
||||||
|
(lambda (this-info other-info)
|
||||||
|
(and (vector-info? other-info)
|
||||||
|
(signature=? arg-signature (vector-info-arg-signature other-info))))))
|
||||||
|
|
||||||
|
(define-struct vector-info (arg-signature) #:transparent)
|
||||||
|
|
||||||
(define (make-mixed-signature name alternative-signatures syntax)
|
(define (make-mixed-signature name alternative-signatures syntax)
|
||||||
(letrec ((alternative-signatures-promise
|
(letrec ((alternative-signatures-promise
|
||||||
(delay
|
(delay
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
(provide :
|
(provide :
|
||||||
signature signature/arbitrary
|
signature signature/arbitrary
|
||||||
define/signature define-values/signature
|
define/signature define-values/signature
|
||||||
-> mixed one-of predicate combined property list-of)
|
-> mixed one-of predicate combined property list-of vector-of)
|
||||||
|
|
||||||
(require deinprogramm/signature/signature
|
(require deinprogramm/signature/signature
|
||||||
deinprogramm/signature/signature-english
|
deinprogramm/signature/signature-english
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
(define-for-syntax (parse-signature name stx)
|
(define-for-syntax (parse-signature name stx)
|
||||||
(syntax-case* stx
|
(syntax-case* stx
|
||||||
(mixed one-of predicate list-of -> combined property reference at signature)
|
(mixed one-of predicate list-of vector-of -> combined property reference at signature)
|
||||||
module-or-top-identifier=?
|
module-or-top-identifier=?
|
||||||
((mixed ?signature ...)
|
((mixed ?signature ...)
|
||||||
(with-syntax ((?stx (phase-lift stx))
|
(with-syntax ((?stx (phase-lift stx))
|
||||||
|
@ -63,6 +63,15 @@
|
||||||
(raise-syntax-error #f
|
(raise-syntax-error #f
|
||||||
"list-of signature accepts only a single operand"
|
"list-of signature accepts only a single operand"
|
||||||
(syntax ?signature1)))
|
(syntax ?signature1)))
|
||||||
|
((vector-of ?signature)
|
||||||
|
(with-syntax ((?stx (phase-lift stx))
|
||||||
|
(?name name)
|
||||||
|
(?signature-expr (parse-signature #f #'?signature)))
|
||||||
|
#'(make-vector-signature '?name ?signature-expr ?stx)))
|
||||||
|
((vector-of ?signature1 ?rest ...)
|
||||||
|
(raise-syntax-error #f
|
||||||
|
"vector-of signature accepts only a single operand"
|
||||||
|
(syntax ?signature1)))
|
||||||
((?arg-signature ... -> ?return-signature)
|
((?arg-signature ... -> ?return-signature)
|
||||||
(with-syntax ((?stx (phase-lift stx))
|
(with-syntax ((?stx (phase-lift stx))
|
||||||
(?name name)
|
(?name name)
|
||||||
|
@ -249,3 +258,4 @@
|
||||||
(define-syntax combined within-signature-syntax-transformer)
|
(define-syntax combined within-signature-syntax-transformer)
|
||||||
(define-syntax property within-signature-syntax-transformer)
|
(define-syntax property within-signature-syntax-transformer)
|
||||||
(define-syntax list-of within-signature-syntax-transformer)
|
(define-syntax list-of within-signature-syntax-transformer)
|
||||||
|
(define-syntax vector-of within-signature-syntax-transformer)
|
||||||
|
|
|
@ -86,6 +86,38 @@
|
||||||
(check-equal? (say-no (proc no2)) 'no))
|
(check-equal? (say-no (proc no2)) 'no))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(test-case
|
||||||
|
"vector"
|
||||||
|
(define integer-vector (make-vector-signature 'integer-list integer #f))
|
||||||
|
(check-equal? (say-no (apply-signature integer-vector '#(1 2 3)))
|
||||||
|
'#(1 2 3))
|
||||||
|
(check-equal? (say-no (apply-signature integer-vector '#f))
|
||||||
|
'no)
|
||||||
|
(check-eq? (failed-signature (apply-signature integer-vector '#(1 #f 3)))
|
||||||
|
integer))
|
||||||
|
|
||||||
|
(test-case
|
||||||
|
"vector/cached"
|
||||||
|
(let ((count 0))
|
||||||
|
(define counting-integer
|
||||||
|
(make-predicate-signature 'counting-integer
|
||||||
|
(lambda (obj)
|
||||||
|
(set! count (+ 1 count))
|
||||||
|
(integer? obj))
|
||||||
|
'integer-marker))
|
||||||
|
|
||||||
|
(define integer-vector (make-vector-signature 'integer-list counting-integer #f))
|
||||||
|
|
||||||
|
(define v1 '#(1 2 3))
|
||||||
|
|
||||||
|
(check-eq? (say-no (apply-signature integer-vector v1))
|
||||||
|
v1)
|
||||||
|
(check-equal? count 3)
|
||||||
|
(check-eq? (say-no (apply-signature integer-vector v1))
|
||||||
|
v1)
|
||||||
|
(check-equal? count 3)))
|
||||||
|
|
||||||
|
|
||||||
(test-case
|
(test-case
|
||||||
"mixed"
|
"mixed"
|
||||||
(define int-or-bool (make-mixed-signature 'int-or-bool
|
(define int-or-bool (make-mixed-signature 'int-or-bool
|
||||||
|
|
Loading…
Reference in New Issue
Block a user