apply-hook.sls 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #!r6rs
  2. ;;; Copyright © 2016 Federico Beffa
  3. ;;;
  4. ;;; This program is free software; you can redistribute it and/or modify it
  5. ;;; under the terms of the GNU General Public License as published by
  6. ;;; the Free Software Foundation; either version 3 of the License, or (at
  7. ;;; your option) any later version.
  8. ;;;
  9. ;;; This program is distributed in the hope that it will be useful, but
  10. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;;; GNU General Public License for more details.
  13. ;;;
  14. ;;; You should have received a copy of the GNU General Public License
  15. ;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Code
  17. (library (mit apply-hook)
  18. (export make-apply-hook apply-hook? apply-hook-procedure set-apply-hook-procedure!
  19. apply-hook-extra set-apply-hook-extra! apply-hook-arity
  20. ;; We export the procedure 'procedure-arity' which is also
  21. ;; exported by the library '(mit arity)'. The difference to
  22. ;; the latter is that this one supports 'apply-hooks'.
  23. ;; Thus, of you make use of 'apply-hooks' you want to use
  24. ;; this one. Otherwise use the other one.
  25. procedure-arity)
  26. (import (rnrs)
  27. (rename (mit arity) (procedure-arity arity:procedure-arity)))
  28. (define-record-type apply-hook-symbol (fields >symbol))
  29. (define-record-type (apply-hook %make-apply-hook %apply-hook?)
  30. (fields (mutable procedure %apply-hook-procedure %set-apply-hook-procedure!)
  31. (mutable extra %apply-hook-extra %set-apply-hook-extra!)))
  32. (define (make-apply-hook proc extra)
  33. ;;(guarantee-procedure proc)
  34. (let ((ahook (%make-apply-hook proc extra)))
  35. (define (dispatch msg . args)
  36. (if (apply-hook-symbol? msg)
  37. (case (apply-hook-symbol->symbol msg)
  38. ((get-hook) ahook) ; used by 'apply-hook?'.
  39. ((get-proc) (%apply-hook-procedure ahook))
  40. ((set-proc!) (apply %set-apply-hook-procedure! ahook args))
  41. ((get-extra) (%apply-hook-extra ahook))
  42. ((set-extra!) (apply %set-apply-hook-extra! ahook args))
  43. ((arity) (arity:procedure-arity (%apply-hook-procedure ahook)))
  44. (else
  45. (error 'make-apply-hook/dispatch "Undefined message symbol" msg)))
  46. (begin
  47. ;; (guarantee-procedure-of-arity (%apply-hook-procedure ahook)
  48. ;; (+ 1 (length args))
  49. ;; 'make-apply-hook/dispatch)
  50. (apply (%apply-hook-procedure ahook) msg args)
  51. ;; (let ((p (%apply-hook-procedure ahook)))
  52. ;; (if (procedure? p) (apply p msg args)))
  53. )))
  54. dispatch))
  55. (define (apply-hook? ah)
  56. (call/cc
  57. (lambda (k)
  58. (with-exception-handler
  59. (lambda (x) (k #f))
  60. (lambda ()
  61. (%apply-hook? (ah (make-apply-hook-symbol 'get-hook))))))))
  62. (define (apply-hook-procedure ah) (ah (make-apply-hook-symbol 'get-proc)))
  63. (define (set-apply-hook-procedure! ah proc)
  64. (guarantee-procedure proc)
  65. (ah (make-apply-hook-symbol 'set-proc!) proc))
  66. (define (apply-hook-extra ah) (ah (make-apply-hook-symbol 'get-extra)))
  67. (define (set-apply-hook-extra! ah extra)
  68. (ah (make-apply-hook-symbol 'set-extra!) extra))
  69. (define (apply-hook-arity ah) (ah (make-apply-hook-symbol 'arity)))
  70. (define (procedure-arity proc)
  71. (guarantee-procedure proc)
  72. (if (apply-hook? proc)
  73. (apply-hook-arity proc)
  74. (arity:procedure-arity proc)))
  75. )