parameters.scm 2.4 KB

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