~ chicken-core (chicken-5) /tests/functor-tests.scm


  1;;;; functor-tests.scm
  2
  3
  4(import chicken.fixnum chicken.port chicken.pretty-print)
  5
  6
  7(include "test.scm")
  8(test-begin "functor tests")
  9
 10;;
 11
 12
 13(include "test-queue")
 14(include "breadth-first")
 15
 16(define (take lst n)
 17  (if (fx<= n 0)
 18      '()
 19      (cons (car lst) (take (cdr lst) (fx- n 1)))))
 20
 21
 22(module queue1 QUEUE
 23  (import (rename scheme
 24		  (null? empty?)
 25		  (car head)
 26		  (cdr dequeue)))
 27  (define empty-queue '())
 28  (define (enqueue q x) (append q (list x)))
 29  ;(define empty? null?)
 30  ;(define head car)
 31  ;(define dequeue cdr) 
 32  )
 33
 34
 35(module queue2 QUEUE
 36  (import (rename scheme (not empty?)) chicken.base)
 37  (define-record entry q x)
 38  (define empty-queue #f)
 39  (define enqueue make-entry)
 40  ;(define empty? not)
 41  (define (head q)
 42    (let ((q2 (entry-q q)))
 43      (if (empty? q2) (entry-x q) (head q2))))
 44  (define (dequeue q) 
 45    (let ((q2 (entry-q q)))
 46      (if (empty? q2) 
 47	  empty-queue 
 48	  (make-entry (dequeue q2) (entry-x q)))) ))
 49
 50
 51(module queue3 QUEUE
 52  (import scheme chicken.base)
 53  (define-record queue heads tails)
 54  (define empty-queue (make-queue '() '()))
 55  (define (norm q)
 56    (if (null? (queue-heads q))
 57	(make-queue (reverse (queue-tails q)) '())
 58	q))
 59  (define (enqueue q x)
 60    (norm (make-queue (queue-heads q) (cons x (queue-tails q)))))
 61  (define (empty? q)
 62    (and (null? (queue-heads q)) (null? (queue-tails q))))
 63  (define (head q) (car (queue-heads q)))
 64  (define (dequeue q)
 65    (norm (make-queue (cdr (queue-heads q)) (queue-tails q)))) )
 66
 67
 68(module test-q1 = (test-queue queue1))
 69(module test-q2 = (test-queue queue2))
 70(module test-q3 = (test-queue queue3))
 71
 72(import (rename test-q1 (list->queue l2q1) (queue->list q2l1)))
 73(import (rename test-q2 (list->queue l2q2) (queue->list q2l2)))
 74(import (rename test-q3 (list->queue l2q3) (queue->list q2l3)))
 75
 76(define (list-tabulate n proc)
 77  (let loop ((i 0))
 78    (if (fx>= i n)
 79	'()
 80	(cons (proc i) (loop (fx+ i 1))))))
 81
 82(define long-list (list-tabulate (cond-expand (csi 500) (else 1000)) identity))
 83
 84(print "Queue representation #1:")
 85(time (q2l1 (l2q1 long-list)))
 86(print "Queue representation #2:")
 87(time (q2l2 (l2q2 long-list)))
 88(print "Queue representation #3:")
 89(time (q2l3 (l2q3 long-list)))
 90
 91(module breadth = (breadth-first queue3))
 92(import breadth)
 93
 94(define (next-char lst) 
 95  (list (cons #\A lst) (cons #\B lst) (cons #\C lst)))
 96
 97(define (show n csq) 
 98  (map list->string (take csq 1)))
 99
100;;XXX shows (""), which looks wrong:
101(pp (show 8 (search next-char '())))	;XXX assert
102
103;; list-style library names
104
105(functor ((double printer) ((P (chicken base)) (print))) (print-twice)
106  (import (scheme) P)
107  (define (print-twice x) (print x) (print x)))
108
109(module (noop printer) *
110  (import (only (scheme) define) (only (chicken base) void))
111  (define print void))
112
113(module (2x print) = ((double printer)))
114
115(module (2x noop) = ((double printer) (noop printer)))
116
117(module (2x write) = (double printer)
118  (import (chicken module))
119  (reexport (rename (scheme) (write print))))
120
121(define output
122  (with-output-to-string
123   (lambda ()
124     (import (2x print))
125     (print-twice #\a)
126     (import (2x noop))
127     (print-twice #\a)
128     (import (2x write))
129     (print-twice #\a))))
130
131(test-equal "double printer" output "a\na\n#\\a#\\a")
132
133;; Test for errors
134
135#+csi
136(begin
137
138(module m1 ())
139
140(test-error 
141 "argument mismatch"
142 (eval '(module m2 = (breadth-first m1))))
143
144(test-error
145 "undefined module"
146 (eval '(module m2 = (breadth-first hunoz))))
147
148(test-error
149 "undefined interface"
150 (eval '(module m2 HUNOZ)))
151
152(test-error
153 "undefined interface in functor"
154 (eval '(functor (f1 (X HUNOZ)) ())))
155
156(test-error
157 "undefined interface in functor result"
158 (eval '(functor (f1 (X ())) HUNOZ)))
159
160)
161
162
163;; Test alternative instantiation syntax:
164
165(functor (frob (X (yibble))) *
166  (import chicken.base X)
167  yibble)
168
169;; XXX This is somewhat iffy: functor instantiation results in a
170;; value!
171(test-equal
172 "alternative functor instantiation syntax"
173 (module yabble = frob (import scheme) (define yibble 99))
174 99)
175
176
177;; Test optional functor arguments
178
179(functor (greet ((X default-writer) (write-greeting))) *
180  (import scheme X)
181  (define (greetings) (write-greeting 'Hello!)))
182
183(module default-writer (write-greeting)
184  (import scheme)
185  (define write-greeting list))
186
187(module writer (write-greeting)
188  (import scheme)
189  (define write-greeting vector))
190
191(module greet1 = (greet writer))
192(module greet2 = (greet))
193
194(test-equal
195 "optional functor argument #1"
196 (module m2 ()
197	 (import greet1)
198	 (greetings))
199 '#(Hello!))
200
201(test-equal
202 "optional functor argument #2"
203 (module m3 ()
204	 (import greet2)
205	 (greetings))
206 '(Hello!))
207
208
209;; Optional functor syntax with builtin ("primitive") modules:
210
211(functor (wrapper ((X scheme) (vector))) *
212  (import (except scheme vector) X)
213  (define (wrap x) (vector x)))
214
215(module default-wrapper (vector)
216  (import scheme))
217
218(module list-wrapper (vector)
219  (import (rename (only scheme list) (list vector))))
220
221(module lwrap = (wrapper list-wrapper))
222(module vwrap = (wrapper))
223
224(test-equal
225 "primitive optional functor argument #1"
226 (module m4 ()
227	 (import lwrap)
228	 (wrap 99))
229 '(99))
230
231(test-equal
232 "primitive optional functor argument #2"
233 (module m5 ()
234	 (import vwrap)
235	 (wrap 99))
236 '#(99))
237
238
239;; Module implementing functor plus more exports did not expose the
240;; additional exports (pointed out by Martin Schneeweis, patch
241;; suggested by megane)
242
243(define-interface iface-a (some-a))
244
245(module iface-a-plus-extra ((interface: iface-a) extra-a)
246  (import scheme (chicken base))
247  (define extra-a 'extra-a)
248  (define some-a 'some-a))
249
250(test-equal
251 "Functor with extra exports"
252 (module m6 ()
253   (import iface-a-plus-extra scheme)
254   (list extra-a some-a))
255 '(extra-a some-a))
256
257
258;;
259
260(test-end)
261
262(test-exit)
Trap