Hello,

I attach two implementations of srfi-34's "guard" syntax.  (Depending
only of srfi-18; no additional procedures.)

I'd like to ask Elf, or whoever can do so and cares, to update the egg
(since the version there is broken).

However I'm left with a question: which version would one prefer?  So
far I've got (from watching the mailing list) the feeling that
define-macro and define-syntax don't play well together.

Also I'm unsure whether all programs using define-syntax macros need to
require syntax-case, do they?  If so, would there be trouble with
define-macro in those files?

If it was better to have both versions available, the define-macro
version for compatibility and define-syntax for the upcoming hygienic
chicken, then: how should this be handled?  Two eggs?

Best regards

/Jörg
(define-macro (guard . form)
  (let* ((clause (or (and (pair? form) (car form))
                     (error "guard: syntax error in" form)))
         (body (cdr form))
	 (condition (gensym))
	 (handler-k (gensym))
	 (return (gensym))
	 (oldh (gensym)))
    `((call-with-current-continuation
       (lambda (,return)
	 (let ((,oldh (current-exception-handler)))
	   (with-exception-handler
	    (lambda (,condition)
	      (with-exception-handler
	       ,oldh
	       (call-with-current-continuation
		(lambda (,handler-k)
		  (,return (lambda ()
			    ((lambda (,(car clause))
			       ,(let loop ((clauses (cdr clause)))
				  (if (null? clauses)
				      `(raise ,(car clause))
				      (let ((c (car clauses)))
					(cond
					 ((eq? 'else (car c))
					  (if (null? (cdr c))
					      '#f
					      (if (null? (cddr c))
						  (cadr c)
						  `(begin . ,(cdr c)))))
					 ((and (pair? c) (pair? (cdr c)) (eq? '=> (cadr c)))
					  (let ((v (gensym)))
					    `(let ((,v ,(car c)))
					       (if ,v (,(caddr c)) ,(loop (cdr clauses))))))
					 ((and (pair? c) (null? (cdr c)))
					  (let ((v (gensym)))
					    `(let ((,v ,(car c)))
					       (if ,v ,v ,(loop (cdr clauses))))))
					 ((pair? c)
					  `(if ,(car c)
					       ,(if (null? (cddr c))
						    (cadr c)
						    `(begin . ,(cdr c)))
					       ,(loop (cdr clauses))))
					 (else (error "guard syntax error in ~a" c)))))))
			     ,condition)))))))
	    (lambda ()
	      (##sys#call-with-values
	       (lambda ()
		 ,(if (and (pair? body) (null? (cdr body)))
		      (car body) `(begin . ,body) ))
	       (lambda args
		 (,return (lambda () (##sys#apply ##sys#values args)))) ) ) )) ) ))))
(define-syntax guard
  (syntax-rules ()
    ((guard (var clause ...) e1 e2 ...)
     ((call-with-current-continuation
       (lambda (guard-k)
         (let ((oldh (current-exception-handler)))
	   (with-exception-handler
	    (lambda (condition)
	      (with-exception-handler
	       oldh
	       (call-with-current-continuation
		(lambda (handler-k)
		  (guard-k
		   (lambda ()
		     (let ((var condition))      ; clauses may SET! var
		       (guard-aux (handler-k (lambda ()
					       (raise condition)))
				  clause ...))))))))
	    (lambda ()
	      (call-with-values
		  (lambda () e1 e2 ...)
		(lambda args
		  (guard-k (lambda ()
			     (apply values args))))))))))))))


(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))
     test)
    ((guard-aux reraise (test) clause1 clause2 ...)
     (let ((temp test))
       (if temp
           temp
           (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 ...)))))
_______________________________________________
Chicken-users mailing list
Chicken-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/chicken-users

Reply via email to