srfi-61.scm 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. ; SRFI 61 reference implementation
  2. ; Copyright (C) 2004 Taylor Campbell. All rights reserved.
  3. ;
  4. ; Permission is hereby granted, free of charge, to any person
  5. ; obtaining a copy of this software and associated documentation files
  6. ; (the "Software"), to deal in the Software without restriction,
  7. ; including without limitation the rights to use, copy, modify, merge,
  8. ; publish, distribute, sublicense, and/or sell copies of the Software,
  9. ; and to permit persons to whom the Software is furnished to do so,
  10. ; subject to the following conditions:
  11. ;
  12. ; The above copyright notice and this permission notice shall be
  13. ; included in all copies or substantial portions of the Software.
  14. ;
  15. ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. ; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. ; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. ; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19. ; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20. ; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. ; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. ; SOFTWARE.
  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 ...)))))