parameters.scm 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. ;;; Parameters
  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. ;;; Parameters.
  18. ;;;
  19. ;;; Code:
  20. (library (hoot parameters)
  21. (export make-parameter parameter? parameterize)
  22. (import (hoot primitives)
  23. (hoot cond-expand)
  24. (hoot fluids)
  25. (hoot errors))
  26. (cond-expand
  27. (guile-vm
  28. (define make-parameter guile:make-parameter)
  29. (define parameter? guile:parameter?)
  30. (define parameter-fluid guile:parameter-fluid)
  31. (define parameter-convert guile:parameter-converter))
  32. (else
  33. (define* (make-parameter init #:optional (conv (lambda (x) x)))
  34. (let ((fluid (make-fluid (conv init))))
  35. (%inline-wasm
  36. '(func (param $fluid (ref eq))
  37. (param $convert (ref eq))
  38. (result (ref eq))
  39. (struct.new $parameter
  40. (i32.const 0)
  41. (ref.func $parameter)
  42. (ref.cast $fluid (local.get $fluid))
  43. (ref.cast $proc (local.get $convert))))
  44. fluid conv)))
  45. (define (parameter? x)
  46. (%inline-wasm
  47. '(func (param $x (ref eq)) (result (ref eq))
  48. (if (ref eq)
  49. (ref.test $parameter (local.get $x))
  50. (then (ref.i31 (i32.const 17)))
  51. (else (ref.i31 (i32.const 1)))))
  52. x))
  53. (define (parameter-fluid x)
  54. (%inline-wasm
  55. '(func (param $param (ref $parameter)) (result (ref eq))
  56. (struct.get $parameter $fluid (local.get $param)))
  57. x))
  58. (define (parameter-convert x)
  59. (%inline-wasm
  60. '(func (param $param (ref $parameter)) (result (ref eq))
  61. (struct.get $parameter $convert (local.get $param)))
  62. x))))
  63. (define-syntax parameterize
  64. (lambda (x)
  65. (syntax-case x ()
  66. ((_ ((parameter value) ...) body body* ...)
  67. (with-syntax (((p ...) (generate-temporaries #'(parameter ...))))
  68. #'(let ((p parameter) ...)
  69. (check-type p parameter? 'parameterize)
  70. ...
  71. (with-fluids (((parameter-fluid p) ((parameter-convert p) value))
  72. ...)
  73. body body* ...))))))))