fluids.scm 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. ;;; Fluids
  2. ;;; Copyright (C) 2024 Igalia, S.L.
  3. ;;;
  4. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  5. ;;; you may not use this file except in compliance with the License.
  6. ;;; You may obtain a copy of the License at
  7. ;;;
  8. ;;; http://www.apache.org/licenses/LICENSE-2.0
  9. ;;;
  10. ;;; Unless required by applicable law or agreed to in writing, software
  11. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  12. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. ;;; See the License for the specific language governing permissions and
  14. ;;; limitations under the License.
  15. ;;; Commentary:
  16. ;;;
  17. ;;; Fluids and dynamic states.
  18. ;;;
  19. ;;; Code:
  20. (library (hoot fluids)
  21. (export make-fluid
  22. fluid-ref
  23. fluid-set!
  24. with-fluid*
  25. with-dynamic-state
  26. with-fluids)
  27. (import (hoot primitives))
  28. (define* (make-fluid #:optional default-value)
  29. (%inline-wasm '(func (param $default (ref eq)) (result (ref eq))
  30. (struct.new $fluid (i32.const 0)
  31. (local.get $default)))
  32. default-value))
  33. (define (fluid-ref x) (%fluid-ref x))
  34. (define (fluid-set! x y) (%fluid-set! x y))
  35. (define (with-fluid* fluid val thunk) (%with-fluid* fluid val thunk))
  36. (define (with-dynamic-state state thunk) (%with-dynamic-state state thunk))
  37. (define-syntax with-fluids
  38. (lambda (stx)
  39. (define (emit-with-fluids bindings body)
  40. (syntax-case bindings ()
  41. (()
  42. body)
  43. (((f v) . bindings)
  44. #`(with-fluid* f v
  45. (lambda ()
  46. #,(emit-with-fluids #'bindings body))))))
  47. (syntax-case stx ()
  48. ((_ ((fluid val) ...) exp exp* ...)
  49. (with-syntax (((fluid-tmp ...) (generate-temporaries #'(fluid ...)))
  50. ((val-tmp ...) (generate-temporaries #'(val ...))))
  51. #`(let ((fluid-tmp fluid) ...)
  52. (let ((val-tmp val) ...)
  53. #,(emit-with-fluids #'((fluid-tmp val-tmp) ...)
  54. #'(let () exp exp* ...))))))))))