home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 44
/
Amiga_Dream_44.iso
/
RiscPc
/
programmation
/
scm4e2.arc
/
!Scm
/
slib
/
mwtest
< prev
next >
Wrap
Text File
|
1994-05-25
|
6KB
|
213 lines
; "mwtest.scm" test macros-that-work
; From: William Clinger
; A short test suite.
; Uses PRETTY-PRINT and EVAL, neither of which is standard Scheme.
; Redefine f and g as desired to fix this.
(require 'pretty-print)
(require 'macros-that-work)
; The value returned by MACWORK:EXPAND is expressed using keywords
; defined in "prefs.sch", which might not be the keywords expected
; by EVAL.
(define begin0 'begin)
(define define0 'define)
(define quote0 'quote)
(define lambda0 'lambda)
(define if0 'if)
(define set!0 'set!)
(define begin2 mw:begin1)
(define define2 mw:define1)
(define quote2 mw:quote1)
(define lambda2 mw:lambda1)
(define if2 mw:if1)
(define set!2 mw:set!1)
(define original-code #f) ; assigned by f, used by g
(define expanded-code #f) ; assigned by f, used by g
(define (f x)
(set! original-code x)
(set! mw:begin1 begin2)
(set! mw:define1 define2)
(set! mw:quote1 quote2)
(set! mw:lambda1 lambda2)
(set! mw:if1 if2)
(set! mw:set!1 set!2)
(set! expanded-code (macwork:expand x))
(pretty-print expanded-code)
)
(define (g answer)
(set! mw:begin1 begin0)
(set! mw:define1 define0)
(set! mw:quote1 quote0)
(set! mw:lambda1 lambda0)
(set! mw:if1 if0)
(set! mw:set!1 set!0)
(if (not (equal? (slib:eval (macwork:expand original-code)) answer))
(begin (newline)
(display "TEST FAILED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
(newline)
(display "Original code was:")
(newline)
(pretty-print original-code)
(newline)
(newline))
#t))
(f '(let ((a 3)) a))
(g 3)
(f '(let ((=> #f))
(cond (#t => 'ok))))
(g 'ok)
; This syntax of set*! matches that of an example in the R4RS.
; That example was put forth as an example of a hygienic macro
; that supposedly couldn't be written using syntax-rules. Hah!
(f '(define-syntax set*!
(syntax-rules
()
((set*! (?var ?val) ...)
(set*!-help (?val ...) () (?var ?val) ...)))))
(f '(define-syntax set*!-help
(syntax-rules
()
((set*!-help () (?temp ...) (?var ?val) ...)
(let ((?temp ?val) ...)
(set! ?var ?temp) ...))
((set*!-help (?var1 ?var2 ...) ?temps ?assignments ...)
(set*!-help (?var2 ...) (temp . ?temps) ?assignments ...)))))
(f '(let ((x 3)
(y 4)
(z 5))
(set*! (x (+ x y z))
(y (- x y z))
(z (* x y z)))
(list x y z)))
(g '(12 -6 60))
(f
'(let ((else #f))
(cond (#f 3)
(else 4)
(#t 5))))
(g '5)
(f '(define-syntax push
(syntax-rules ()
((push item place)
(set! place (cons item place))))))
(f '(let* ((cons (lambda (name)
(case name
((phil) '("three-card monte"))
((dick) '("secret plan to end the war"
"agnew"
"not a crook"))
((jimmy) '("why not the best"))
((ron) '("abolish the draft"
"balance the budget"))
(else '()))))
(scams (cons 'phil)))
(push (car (cons 'jimmy)) scams)
(push (cadr (cons 'ron)) scams)
scams))
(g '("balance the budget" "why not the best" "three-card monte"))
; Tests of quasiquote and the vector extension.
(f '`(list ,(+ 1 2) 4))
(g '(list 3 4))
(f '(let ((name 'a)) `(list ,name ',name)))
(g '(list a (quote a)))
(f '`(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b))
(g '(a 3 4 5 6 b))
(f '`((foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons))))
(g '((foo 7) . cons))
(f '`#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8))
(g '#(10 5 2 4 3 8))
;(f '(let ((who "hoo")
; (are "r")
; (you "u"))
; `#(#(,who ,are ,you)
; #(,@(list you are who))
; #(you are who?))))
;(g '#(#("hoo" "r" "u") #("u" "r" "hoo") #(you are who?)))
; Tests of the ::: escape symbol.
; This syntax of set*! matches the syntax of an example in
; Clinger, "Macros in Scheme". It is a slightly more difficult
; syntax than the syntax in R4RS.
; Note that pattern variables within the scope of the ::: are
; still expanded, so the auxiliary macro's pattern variables
; must be different from those of the outer macro.
(f '(define-syntax set*!
(syntax-rules ()
((set*! i1 e1 more ...)
(letrec-syntax
((set*!-aux
(::: (syntax-rules ()
((set*!-aux ((i1_ e1_ t1) ...))
(let ((t1 e1_) ...)
(set! i1_ t1) ...))
((set*!-aux ((i1_ e1_ t1) ...) i2 e2 more_ ...)
(set*!-aux ((i1_ e1_ t1) ... (i2 e2 newtemp)) more_ ...))))))
(set*!-aux () i1 e1 more ...))))))
(f '(let ((x 3)
(y 4)
(z 5))
(set*! x (+ x y z)
y (- x y z)
z (* x y z))
(list x y z)))
(g '(12 -6 60))
; Tests of the scoping extension.
(f '(define-syntax set! let*
(syntax-rules (car cdr vector-ref)
((set! (car x) y) (set-car! x y))
((set! (cdr x) y) (set-cdr! x y))
((set! (vector-ref x e) y) (vector-set! x e y))
((set! x y) (set! x y)))))
(f '(let* ((days (list 'monday 'wednesday 'friday))
(day1 '(sunday)))
(set! (car days) 'tuesday)
(set! day1 (car days))
day1))
(g 'tuesday)
(f '(define-syntax set! let*
(syntax-rules (string-ref)
((set! (string-ref x e) y) (string-set! x e y))
((set! x y) (set! x y)))))
(f '(let* ((o (make-string 3 #\o))
(v (vector o o o))
(s "woo"))
(set! (string-ref o 0) #\h)
(set! (vector-ref v 0) "boo")
(set! s (string-append (vector-ref v 0)
(vector-ref v 1)
s))
s))
(g '"boohoowoo")