1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-11 00:00:49 +02:00
guile/module/slib/scmactst.scm
2001-04-14 11:24:45 +00:00

160 lines
4.1 KiB
Scheme

;;;"scmactst.scm" test syntactic closures macros
;;; From "sc-macro.doc", A Syntactic Closures Macro Facility by Chris Hanson
(define errs '())
(define test
(lambda (expect fun . args)
(write (cons fun args))
(display " ==> ")
((lambda (res)
(write res)
(newline)
(cond ((not (equal? expect res))
(set! errs (cons (list res expect (cons fun args)) errs))
(display " BUT EXPECTED ")
(write expect)
(newline)
#f)
(else #t)))
(if (procedure? fun) (apply fun args) (car args)))))
(require 'syntactic-closures)
(macro:expand
'(define-syntax push
(syntax-rules ()
((push item list)
(set! list (cons item list))))))
(test '(set! foo (cons bar foo)) 'push (macro:expand '(push bar foo)))
(macro:expand
'(define-syntax push1
(transformer
(lambda (exp env)
(let ((item
(make-syntactic-closure env '() (cadr exp)))
(list
(make-syntactic-closure env '() (caddr exp))))
`(set! ,list (cons ,item ,list)))))))
(test '(set! foo (cons bar foo)) 'push1 (macro:expand '(push1 bar foo)))
(macro:expand
'(define-syntax loop
(transformer
(lambda (exp env)
(let ((body (cdr exp)))
`(call-with-current-continuation
(lambda (exit)
(let f ()
,@(map (lambda (exp)
(make-syntactic-closure env '(exit)
exp))
body)
(f)))))))))
(macro:expand
'(define-syntax let1
(transformer
(lambda (exp env)
(let ((id (cadr exp))
(init (caddr exp))
(exp (cadddr exp)))
`((lambda (,id)
,(make-syntactic-closure env (list id) exp))
,(make-syntactic-closure env '() init)))))))
(test 93 'let1 (macro:eval '(let1 a 90 (+ a 3))))
(macro:expand
'(define-syntax loop-until
(syntax-rules
()
((loop-until id init test return step)
(letrec ((loop
(lambda (id)
(if test return (loop step)))))
(loop init))))))
(test (macro:expand '(letrec ((loop (lambda (foo) (if #t 12 (loop 33)))))
(loop 3)))
'loop
(macro:expand '(loop-until foo 3 #t 12 33)))
(macro:expand
'(define-syntax loop-until1
(transformer
(lambda (exp env)
(let ((id (cadr exp))
(init (caddr exp))
(test (cadddr exp))
(return (cadddr (cdr exp)))
(step (cadddr (cddr exp)))
(close
(lambda (exp free)
(make-syntactic-closure env free exp))))
`(letrec ((loop
,(capture-syntactic-environment
(lambda (env)
`(lambda (,id)
(,(make-syntactic-closure env '() `if)
,(close test (list id))
,(close return (list id))
(,(make-syntactic-closure env '()
`loop)
,(close step (list id)))))))))
(loop ,(close init '()))))))))
(test (macro:expand '(letrec ((loop (lambda (foo) (if #t 12 (loop 33)))))
(loop 3)))
'loop1
(macro:expand '(loop-until1 foo 3 #t 12 33)))
(test '#t 'identifier (identifier? 'a))
;;; this needs to setup ENV.
;;;(test '#t 'identifier
;;; (identifier? (macro:expand (make-syntactic-closure env '() 'a))))
(test #f 'identifier (identifier? "a"))
(test #f 'identifier (identifier? #\a))
(test #f 'identifier (identifier? 97))
(test #f 'identifier (identifier? #f))
(test #f 'identifier (identifier? '(a)))
(test #f 'identifier (identifier? '#(a)))
(test '(#t #f)
'syntax
(macro:eval
'(let-syntax
((foo
(transformer
(lambda (form env)
(capture-syntactic-environment
(lambda (transformer-env)
(identifier=? transformer-env 'x env 'x)))))))
(list (foo)
(let ((x 3))
(foo))))))
(test '(#f #t)
'syntax
(macro:eval
'(let-syntax ((bar foo))
(let-syntax
((foo
(transformer
(lambda (form env)
(capture-syntactic-environment
(lambda (transformer-env)
(identifier=? transformer-env 'foo
env (cadr form))))))))
(list (foo foo)
(foo bar))))))
(newline)
(cond ((null? errs) (display "Passed all tests"))
(else (display "errors were:") (newline)
(display "(got expected (call))") (newline)
(for-each (lambda (l) (write l) (newline)) errs)))
(newline)