-
Notifications
You must be signed in to change notification settings - Fork 2
/
strategy-list.rkt
110 lines (90 loc) · 2.5 KB
/
strategy-list.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#lang racket/base
#|
|#
(require "strategy.rkt" "util.rkt")
;;;
;;; List access operations.
;;;
;; Implementations of gen:strategic operations for lists. We do not
;; actually include the list type into gen:strategic, but these
;; operations may be useful in implementing gen:strategic operations
;; for user-defined types.
(define* strategic-list-accessors
(make-strategic-data-accessors
(lambda (obj) obj) (lambda (obj lst) lst)
#:visit-all list-visit-all
#:rewrite-all list-rewrite-all
#:rewrite-some list-rewrite-some
#:rewrite-one list-rewrite-one))
;;;
;;; Primitive strategies.
;;;
(module+ test
(require rackunit))
(define-specific-data-strategy* list-all-visitor list-visit-all)
(module+ test
(check-equal?
'(#f #f #t)
(let ()
(define lst null)
((list-all-visitor
(lambda (x)
(set! lst (cons x lst))))
'(#t #f #f))
lst)))
;; This is an `all` for lists, where elements are "subterms".
(define-specific-data-strategy* list-all-rewriter list-rewrite-all)
(module+ test
(check-equal?
(list
((list-all-rewriter number?) '())
((list-all-rewriter number?) '(1 2 3))
((list-all-rewriter number?) '(x 2 y 4)))
'(() (#t #t #t) #f)))
(define-specific-data-strategy* list-some-rewriter list-rewrite-some)
(module+ test
(check-equal?
(list
((list-some-rewriter number?) '())
((list-some-rewriter number?) '(x y z))
((list-some-rewriter number?) '(x 2 y 4)))
'(#f #f (x #t y #t))))
(define-specific-data-strategy* list-one-rewriter list-rewrite-one)
(module+ test
(check-equal?
(list
((list-one-rewriter number?) '())
((list-one-rewriter number?) '(x y z))
((list-one-rewriter number?) '(x 2 y 4)))
'(#f #f (x #t y 4))))
(module+ test
(let ()
(define rw
(with-strategic-data-accessors
strategic-list-accessors
(all-rewriter
(lambda (v)
(add1 v)))))
(define lst '(1 2 3))
(check-equal? (map add1 lst) (rw lst))))
;;;
;;; Strategy combinators.
;;;
(module+ test
(let ()
(define rw
(topdown-rewriter
(lambda (v)
(cond
[(number? v) (add1 v)]
[else v]))
#:rewrite-all (lambda (f ast)
(if (list? ast)
(list-rewrite-all f ast)
ast))))
(define (test lst expect)
(check-equal? (rw lst) expect))
(for ([lst-expect (list
'(() ())
'((1) (2)))])
(apply test lst-expect))))