s48-defenum.scm 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
  2. ;;;
  3. ;;; Port Author: Andrew Whatson
  4. ;;;
  5. ;;; Original Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  6. ;;;
  7. ;;; scheme48-1.9.2/scheme/rts/defenum.scm
  8. ;;;
  9. ;;; define-enumeration macro
  10. ;;;
  11. (define-module (prescheme s48-defenum)
  12. #:use-module (prescheme syntax-utils)
  13. #:export (define-enumeration
  14. enum
  15. enumerand->name
  16. name->enumerand))
  17. (define-syntax define-enumeration
  18. (lambda (x)
  19. (syntax-case x ()
  20. ((_ e-name (e-elems ...))
  21. (with-syntax ((e-vector (syntax-conc #'e-name '-enumeration))
  22. (e-count (syntax-conc #'e-name '-count)))
  23. (let* ((elements #'(e-elems ...))
  24. (count (length elements))
  25. (indexes (iota count)))
  26. #`(begin
  27. (define e-vector #(e-elems ...))
  28. (define e-count #,count)
  29. (define-syntax e-name
  30. (syntax-rules (get e-elems ...)
  31. ((_ get) e-vector)
  32. #,@(map (lambda (elem ix)
  33. #`((_ get #,elem) #,ix))
  34. elements indexes)))
  35. )))))))
  36. (define-syntax components
  37. (syntax-rules (get)
  38. ((_ ?type)
  39. (?type get))))
  40. (define-syntax enum
  41. (syntax-rules (get)
  42. ((_ ?type ?enumerand)
  43. (?type get ?enumerand))))
  44. (define-syntax enumerand->name
  45. (syntax-rules ()
  46. ((enumerand->name ?enumerand ?type)
  47. (vector-ref (components ?type) ?enumerand))))
  48. (define-syntax name->enumerand
  49. (syntax-rules ()
  50. ((name->enumerand ?name ?type)
  51. (lookup-enumerand (components ?type) ?name))))
  52. (define (lookup-enumerand components name)
  53. (let ((len (vector-length components)))
  54. (let loop ((i 0)) ;;vector-posq
  55. (if (>= i len)
  56. #f
  57. (if (eq? name (vector-ref components i))
  58. i
  59. (loop (+ i 1)))))))