~ chicken-core (chicken-5) /tests/functor-tests.scm
Trap1;;;; functor-tests.scm234(import chicken.fixnum chicken.port chicken.pretty-print)567(include "test.scm")8(test-begin "functor tests")910;;111213(include "test-queue")14(include "breadth-first")1516(define (take lst n)17 (if (fx<= n 0)18 '()19 (cons (car lst) (take (cdr lst) (fx- n 1)))))202122(module queue1 QUEUE23 (import (rename scheme24 (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 )333435(module queue2 QUEUE36 (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-queue48 (make-entry (dequeue q2) (entry-x q)))) ))495051(module queue3 QUEUE52 (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)))) )666768(module test-q1 = (test-queue queue1))69(module test-q2 = (test-queue queue2))70(module test-q3 = (test-queue queue3))7172(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)))7576(define (list-tabulate n proc)77 (let loop ((i 0))78 (if (fx>= i n)79 '()80 (cons (proc i) (loop (fx+ i 1))))))8182(define long-list (list-tabulate (cond-expand (csi 500) (else 1000)) identity))8384(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)))9091(module breadth = (breadth-first queue3))92(import breadth)9394(define (next-char lst)95 (list (cons #\A lst) (cons #\B lst) (cons #\C lst)))9697(define (show n csq)98 (map list->string (take csq 1)))99100;;XXX shows (""), which looks wrong:101(pp (show 8 (search next-char '()))) ;XXX assert102103;; list-style library names104105(functor ((double printer) ((P (chicken base)) (print))) (print-twice)106 (import (scheme) P)107 (define (print-twice x) (print x) (print x)))108109(module (noop printer) *110 (import (only (scheme) define) (only (chicken base) void))111 (define print void))112113(module (2x print) = ((double printer)))114115(module (2x noop) = ((double printer) (noop printer)))116117(module (2x write) = (double printer)118 (import (chicken module))119 (reexport (rename (scheme) (write print))))120121(define output122 (with-output-to-string123 (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))))130131(test-equal "double printer" output "a\na\n#\\a#\\a")132133;; Test for errors134135#+csi136(begin137138(module m1 ())139140(test-error141 "argument mismatch"142 (eval '(module m2 = (breadth-first m1))))143144(test-error145 "undefined module"146 (eval '(module m2 = (breadth-first hunoz))))147148(test-error149 "undefined interface"150 (eval '(module m2 HUNOZ)))151152(test-error153 "undefined interface in functor"154 (eval '(functor (f1 (X HUNOZ)) ())))155156(test-error157 "undefined interface in functor result"158 (eval '(functor (f1 (X ())) HUNOZ)))159160)161162163;; Test alternative instantiation syntax:164165(functor (frob (X (yibble))) *166 (import chicken.base X)167 yibble)168169;; XXX This is somewhat iffy: functor instantiation results in a170;; value!171(test-equal172 "alternative functor instantiation syntax"173 (module yabble = frob (import scheme) (define yibble 99))174 99)175176177;; Test optional functor arguments178179(functor (greet ((X default-writer) (write-greeting))) *180 (import scheme X)181 (define (greetings) (write-greeting 'Hello!)))182183(module default-writer (write-greeting)184 (import scheme)185 (define write-greeting list))186187(module writer (write-greeting)188 (import scheme)189 (define write-greeting vector))190191(module greet1 = (greet writer))192(module greet2 = (greet))193194(test-equal195 "optional functor argument #1"196 (module m2 ()197 (import greet1)198 (greetings))199 '#(Hello!))200201(test-equal202 "optional functor argument #2"203 (module m3 ()204 (import greet2)205 (greetings))206 '(Hello!))207208209;; Optional functor syntax with builtin ("primitive") modules:210211(functor (wrapper ((X scheme) (vector))) *212 (import (except scheme vector) X)213 (define (wrap x) (vector x)))214215(module default-wrapper (vector)216 (import scheme))217218(module list-wrapper (vector)219 (import (rename (only scheme list) (list vector))))220221(module lwrap = (wrapper list-wrapper))222(module vwrap = (wrapper))223224(test-equal225 "primitive optional functor argument #1"226 (module m4 ()227 (import lwrap)228 (wrap 99))229 '(99))230231(test-equal232 "primitive optional functor argument #2"233 (module m5 ()234 (import vwrap)235 (wrap 99))236 '#(99))237238239;; Module implementing functor plus more exports did not expose the240;; additional exports (pointed out by Martin Schneeweis, patch241;; suggested by megane)242243(define-interface iface-a (some-a))244245(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))249250(test-equal251 "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))256257258;;259260(test-end)261262(test-exit)