srfi-61.scm 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. ; SRFI 61 reference implementation
  2. ; Copyright (C) 2004 Taylor Campbell. All rights reserved.
  3. ;
  4. ; This document and translations of it may be copied and furnished to others, and
  5. ; derivative works that comment on or otherwise explain it or assist in its
  6. ; implementation may be prepared, copied, published and distributed, in whole or
  7. ; in part, without restriction of any kind, provided that the above copyright notice
  8. ; and this paragraph are included on all such copies and derivative works. However,
  9. ; this document itself may not be modified in any way, such as by removing this
  10. ; copyright notice or references to the Scheme Request for Implementation process or
  11. ; editors, except as needed for the purpose of developing SRFIs in which case the
  12. ; procedures for copyrights defined in the SRFI process must be followed, or as
  13. ; required to translate it into languages other than English.
  14. ;
  15. ; The limited permissions granted above are perpetual and will not be revoked by the
  16. ; authors or their successors or assigns.
  17. ;
  18. ; This document and the information contained herein is provided on an "AS IS" basis
  19. ; and THE AUTHORS AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
  20. ; INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
  21. ; WILL NOT INFRINGE ON ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
  22. ; FITNESS FOR A PARTICULAR PURPOSE.
  23. (define-syntax cond
  24. (syntax-rules (=> ELSE)
  25. ((COND (ELSE else1 else2 ...))
  26. ;; The (IF #T (BEGIN ...)) wrapper ensures that there may be no
  27. ;; internal definitions in the body of the clause. R5RS mandates
  28. ;; this in text (by referring to each subform of the clauses as
  29. ;; <expression>) but not in its reference implementation of COND,
  30. ;; which just expands to (BEGIN ...) with no (IF #T ...) wrapper.
  31. (IF #T (BEGIN else1 else2 ...)))
  32. ((COND (test => receiver) more-clause ...)
  33. (LET ((T test))
  34. (COND/MAYBE-MORE T
  35. (receiver T)
  36. more-clause ...)))
  37. ((COND (generator guard => receiver) more-clause ...)
  38. (CALL-WITH-VALUES (LAMBDA () generator)
  39. (LAMBDA T
  40. (COND/MAYBE-MORE (APPLY guard T)
  41. (APPLY receiver T)
  42. more-clause ...))))
  43. ((COND (test) more-clause ...)
  44. (LET ((T test))
  45. (COND/MAYBE-MORE T T more-clause ...)))
  46. ((COND (test body1 body2 ...) more-clause ...)
  47. (COND/MAYBE-MORE test
  48. (BEGIN body1 body2 ...)
  49. more-clause ...))))
  50. (define-syntax cond/maybe-more
  51. (syntax-rules ()
  52. ((COND/MAYBE-MORE test consequent)
  53. (IF test
  54. consequent))
  55. ((COND/MAYBE-MORE test consequent clause ...)
  56. (IF test
  57. consequent
  58. (COND clause ...)))))