procedures.scm 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. ;;; Procedures on procedures
  2. ;;; Copyright (C) 2023, 2024, 2025 Igalia, S.L.
  3. ;;; Copyright (C) 2023 Robin Templeton <robin@spritely.institute>
  4. ;;;
  5. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  6. ;;; you may not use this file except in compliance with the License.
  7. ;;; You may obtain a copy of the License at
  8. ;;;
  9. ;;; http://www.apache.org/licenses/LICENSE-2.0
  10. ;;;
  11. ;;; Unless required by applicable law or agreed to in writing, software
  12. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  13. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ;;; See the License for the specific language governing permissions and
  15. ;;; limitations under the License.
  16. ;;; Commentary:
  17. ;;;
  18. ;;; procedure?
  19. ;;;
  20. ;;; Code:
  21. (library (hoot procedures)
  22. (export procedure?
  23. procedure-name
  24. procedure-property
  25. set-procedure-property!)
  26. (import (rename (only (hoot primitives)
  27. %procedure?
  28. procedure-property
  29. %struct?
  30. %struct-vtable
  31. %vector-length
  32. %vector-ref)
  33. (procedure-property guile:procedure-property))
  34. (hoot cond-expand)
  35. (hoot errors)
  36. (hoot inline-wasm)
  37. (hoot syntax)
  38. (hoot symbols))
  39. (define (applicable-record? x)
  40. (and (%struct? x)
  41. (%inline-wasm
  42. '(func (param $x (ref $struct)) (result (ref eq))
  43. (struct.get $vtable $applicable?
  44. (struct.get $struct $vtable (local.get $x))))
  45. x)))
  46. (define (procedure? x)
  47. (or (%procedure? x) (applicable-record? x)))
  48. (cond-expand
  49. (guile-vm
  50. (define (procedure-property proc prop)
  51. (check-type proc procedure? 'procedure-property)
  52. (guile:procedure-property proc prop)))
  53. (hoot
  54. (define (%procedure-name proc)
  55. (cond
  56. ((%procedure? proc)
  57. (%inline-wasm
  58. '(func (param $proc (ref $proc)) (result (ref eq))
  59. (local $maybe-string (ref null string))
  60. (call $code-name (struct.get $proc $func (local.get $proc)))
  61. (local.set $maybe-string)
  62. (if (ref eq)
  63. (ref.is_null (local.get $maybe-string))
  64. (then (ref.i31 (i32.const 1)))
  65. (else
  66. (call $string->symbol
  67. (struct.new $string (i32.const 0)
  68. (ref.as_non_null
  69. (local.get $maybe-string)))))))
  70. proc))
  71. ((applicable-record? proc)
  72. (procedure-name
  73. (%inline-wasm
  74. '(func (param $struct (ref $struct/1)) (result (ref eq))
  75. (struct.get $struct/1 $field0
  76. (local.get $struct)))
  77. proc)))
  78. (else
  79. (raise (make-type-error proc 'procedure-name 'procedure?)))))
  80. (define (procedure-property proc prop)
  81. (check-type proc procedure? 'procedure-property)
  82. ;; FIXME: Wire up to (call $code-properties).
  83. (case prop
  84. ((name) (%procedure-name proc))
  85. (else #f)))))
  86. (define (procedure-name proc)
  87. (check-type proc procedure? 'procedure-name)
  88. (procedure-property proc 'name))
  89. (define (set-procedure-property! proc name val)
  90. (check-type proc procedure? 'set-procedure-property!)
  91. (check-type name symbol? 'set-procedure-property!)
  92. (raise (make-unimplemented-error 'set-procedure-property!))))