srfi-2.scm 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; The reference implementation is written in some weird Scheme variant.
  3. ; This is an attempt to produce the same result using SYNTAX-RULES.
  4. ; I found the both the specification and the implementation unhelpful.
  5. ; For example, one would think that (AND-LET* ()) -> #T by analogy with
  6. ; (AND) -> #T. The specification doesn't say.
  7. ;
  8. ; The following behaves correctly on the test cases at the end of the
  9. ; reference implementation, except that it doesn't catch the three syntax
  10. ; errors. There is no way for SYNTAX-RULES to distinguish between a
  11. ; constant and a variable, and no easy way to check if a variable is
  12. ; being used twice in the same AND-LET* (and why is that an error? LET*
  13. ; allows it).
  14. (define-syntax and-let*
  15. (syntax-rules ()
  16. ; No body - behave like AND.
  17. ((and-let* ())
  18. #t)
  19. ((and-let* ((var exp)))
  20. exp)
  21. ((and-let* ((exp)))
  22. exp)
  23. ((and-let* (var))
  24. var)
  25. ; Have body - behave like LET* but check for #F values.
  26. ; No clauses so just use the body.
  27. ((and-let* () . body)
  28. (begin . body))
  29. ; (VAR VAL) clause - bind the variable and check for #F.
  30. ((and-let* ((var val) more ...) . body)
  31. (let ((var val))
  32. (if var
  33. (and-let* (more ...) . body)
  34. #f)))
  35. ; Error check to catch illegal (A B ...) clauses.
  36. ((and-let* ((exp junk . more-junk) more ...) . body)
  37. (syntax-violation 'and-let*
  38. "syntax error"
  39. '(and-let* ((exp junk . more-junk) more ...) . body)))
  40. ; (EXP) and VAR - just check the value for #F.
  41. ; There is no way for us to check that VAR is an identifier and not a
  42. ; constant
  43. ((and-let* ((exp) more ...) . body)
  44. (if exp
  45. (and-let* (more ...) . body)
  46. #f))
  47. ((and-let* (var more ...) . body)
  48. (if var
  49. (and-let* (more ...) . body)
  50. #f))))
  51. ;(define-syntax expect
  52. ; (syntax-rules ()
  53. ; ((expect a b)
  54. ; (if (not (equal? a b))
  55. ; (assertion-violation 'expect "test failed" 'a b)))))
  56. ;
  57. ;(expect (and-let* () 1) 1)
  58. ;(expect (and-let* () 1 2) 2)
  59. ;(expect (and-let* () ) #t)
  60. ;
  61. ;(expect (let ((x #f)) (and-let* (x))) #f)
  62. ;(expect (let ((x 1)) (and-let* (x))) 1)
  63. ;(expect (and-let* ((x #f)) ) #f)
  64. ;(expect (and-let* ((x 1)) ) 1)
  65. ;;(must-be-a-syntax-error (and-let* ( #f (x 1))) )
  66. ;(expect (and-let* ( (#f) (x 1)) ) #f)
  67. ;;(must-be-a-syntax-error (and-let* (2 (x 1))) )
  68. ;(expect (and-let* ( (2) (x 1)) ) 1)
  69. ;(expect (and-let* ( (x 1) (2)) ) 2)
  70. ;(expect (let ((x #f)) (and-let* (x) x)) #f)
  71. ;(expect (let ((x "")) (and-let* (x) x)) "")
  72. ;(expect (let ((x "")) (and-let* (x) )) "")
  73. ;(expect (let ((x 1)) (and-let* (x) (+ x 1))) 2)
  74. ;(expect (let ((x #f)) (and-let* (x) (+ x 1))) #f)
  75. ;(expect (let ((x 1)) (and-let* (((positive? x))) (+ x 1))) 2)
  76. ;(expect (let ((x 1)) (and-let* (((positive? x))) )) #t)
  77. ;(expect (let ((x 0)) (and-let* (((positive? x))) (+ x 1))) #f)
  78. ;(expect (let ((x 1)) (and-let* (((positive? x)) (x (+ x 1))) (+ x 1))) 3)
  79. ;;(must-be-a-syntax-error
  80. ;; (let ((x 1)) (and-let* (((positive? x)) (x (+ x 1)) (x (+ x 1))) (+ x 1)))
  81. ;;)
  82. ;
  83. ;(expect (let ((x 1)) (and-let* (x ((positive? x))) (+ x 1))) 2)
  84. ;(expect (let ((x 1)) (and-let* ( ((begin x)) ((positive? x))) (+ x 1))) 2)
  85. ;(expect (let ((x 0)) (and-let* (x ((positive? x))) (+ x 1))) #f)
  86. ;(expect (let ((x #f)) (and-let* (x ((positive? x))) (+ x 1))) #f)
  87. ;(expect (let ((x #f)) (and-let* ( ((begin x)) ((positive? x))) (+ x 1))) #f)
  88. ;
  89. ;(expect (let ((x 1)) (and-let* (x (y (- x 1)) ((positive? y))) (/ x y))) #f)
  90. ;(expect (let ((x 0)) (and-let* (x (y (- x 1)) ((positive? y))) (/ x y))) #f)
  91. ;(expect (let ((x #f)) (and-let* (x (y (- x 1)) ((positive? y))) (/ x y))) #f)
  92. ;(expect (let ((x 3)) (and-let* (x (y (- x 1)) ((positive? y))) (/ x y))) 3/2)