parameters.scm 2.9 KB

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