diff --git a/macro-testing.scm b/macro-testing.scm new file mode 100644 index 00000000..26ff9404 --- /dev/null +++ b/macro-testing.scm @@ -0,0 +1,63 @@ +(import (scheme base) (scheme write)) + +;(call-with-values (lambda () (values 1 2)) (lambda (x y) (write `(,x ,y)))) +(define-syntax letrec* + (syntax-rules () + ((letrec* ((var val) ...) . body) + (let () (define var val) ... . body)))) + +(define-syntax guard + (syntax-rules () + ((guard (var clause ...) e1 e2 ...) + ((call-with-current-continuation + (lambda (guard-k) + (with-exception-handler + (lambda (condition) + ((call-with-current-continuation + (lambda (handler-k) + (guard-k + (lambda () + (let ((var condition)) ; clauses may SET! var + (guard-aux (handler-k (lambda () + (raise-continuable condition))) + clause ...)))))))) + (lambda () + (let ((res (begin e1 e2 ...))) + (guard-k (lambda () res))))))))))) + +(define-syntax guard-aux + (syntax-rules (else =>) + ((guard-aux reraise (else result1 result2 ...)) + (begin result1 result2 ...)) + ((guard-aux reraise (test => result)) + (let ((temp test)) + (if temp (result temp) reraise))) + ((guard-aux reraise (test => result) clause1 clause2 ...) + (let ((temp test)) + (if temp (result temp) (guard-aux reraise clause1 clause2 ...)))) + ((guard-aux reraise (test)) + (or test reraise)) + ((guard-aux reraise (test) clause1 clause2 ...) + (or test (guard-aux reraise clause1 clause2 ...))) + ((guard-aux reraise (test result1 result2 ...)) + (if test (begin result1 result2 ...) reraise)) + ((guard-aux reraise (test result1 result2 ...) clause1 clause2 ...) + (if test + (begin result1 result2 ...) + (guard-aux reraise clause1 clause2 ...))))) + +(write + (letrec* ((x 1)) x)) + +(write + (guard (condition + ((assq 'a condition) => cdr) + ((assq 'b condition))) + (raise (list (cons 'a 42))))) ;=> 42 + +(write + (guard (condition + ((assq 'a condition) => cdr) + ((assq 'b condition))) + (raise (list (cons 'b 23))))) ;=> (b . 23) +