name.scm 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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/bcomp/name.scm
  8. ;;;
  9. ;;; Names (symbols) and generated names.
  10. (define-module (prescheme bcomp name)
  11. #:use-module (srfi srfi-9)
  12. #:use-module (srfi srfi-69)
  13. #:use-module (prescheme scheme48)
  14. #:use-module (prescheme record-discloser)
  15. #:export (name?
  16. name->symbol
  17. make-name-generator
  18. make-generated
  19. generate-name ;;qualified->name in opt/inline.scm
  20. generated?
  21. generated-name
  22. generated-token
  23. generated-env
  24. generated-parent-name
  25. generated-uid
  26. make-name-table
  27. make-qualified
  28. qualified?
  29. qualified-parent-name
  30. qualified-symbol
  31. qualified-uid
  32. desyntaxify))
  33. (define (name? thing)
  34. (or (symbol? thing)
  35. (generated? thing)))
  36. ;; Generated names
  37. ;; Generated names make lexically-scoped macros work. They're the same
  38. ;; as what Alan Bawden and Chris Hanson call "aliases". The parent
  39. ;; field is always another name (perhaps generated). The parent chain
  40. ;; provides an access path to the name's binding, should one ever be
  41. ;; needed. That is: If name M is bound to a transform T that generates
  42. ;; name G as an alias for name N, then M is (generated-parent-name G),
  43. ;; so we can get the binding of G by accessing the binding of N in T's
  44. ;; environment of closure, and we get T by looking up M in the
  45. ;; environment in which M is *used*.
  46. (define-record-type :generated
  47. (make-generated name token env parent-name)
  48. generated?
  49. (name generated-name)
  50. (token generated-token)
  51. (env generated-env)
  52. (parent-name generated-parent-name))
  53. (define-record-discloser :generated
  54. (lambda (name)
  55. (list 'generated (generated-name name) (generated-uid name))))
  56. (define (generate-name name env parent-name) ;;for opt/inline.scm
  57. (make-generated name (cons #f #f) env parent-name))
  58. (define (generated-uid generated-name)
  59. (let ((token (generated-token generated-name)))
  60. (or (car token)
  61. (let ((uid *generated-uid*))
  62. (set! *generated-uid* (+ *generated-uid* 1))
  63. (set-car! token uid)
  64. uid))))
  65. (define *generated-uid* 0)
  66. (define (name->symbol name)
  67. (if (symbol? name)
  68. name
  69. (string->symbol (string-append (symbol->string
  70. (name->symbol (generated-name name)))
  71. "##"
  72. (number->string (generated-uid name))))))
  73. (define (name-hash name bound)
  74. (cond ((symbol? name)
  75. (string-hash (symbol->string name) bound))
  76. ((generated? name)
  77. (name-hash (generated-name name) bound))
  78. (else
  79. (assertion-violation 'name-hash "invalid name" name))))
  80. (define make-name-table
  81. (make-hash-table eq? name-hash))
  82. ;; Used by QUOTE to turn generated names back into symbols
  83. (define (desyntaxify thing0)
  84. (let desyntaxify ((thing thing0))
  85. (cond ((or (boolean? thing) (null? thing) (number? thing)
  86. (symbol? thing) (char? thing))
  87. thing)
  88. ((string? thing)
  89. (make-immutable! thing))
  90. ((generated? thing)
  91. (desyntaxify (generated-name thing)))
  92. ((pair? thing)
  93. (make-immutable!
  94. (cons (desyntaxify (car thing))
  95. (desyntaxify (cdr thing)))))
  96. ((vector? thing)
  97. (make-immutable!
  98. (let ((new (make-vector (vector-length thing) #f)))
  99. (let loop ((i 0))
  100. (if (>= i (vector-length thing))
  101. new
  102. (begin
  103. (vector-set! new i (desyntaxify (vector-ref thing i)))
  104. (loop (+ i 1))))))))
  105. (else
  106. (syntax-violation 'quote "invalid datum in quotation" thing)))))
  107. ;;----------------
  108. ;; Qualified names
  109. ;;
  110. ;; A qualified name is a generated name that has been translated into a path.
  111. ;; For example, if syntax A introduces a reference to procedure B, then the
  112. ;; reference to B, as a qualified name, will be #(>> A B). If B refers to
  113. ;; C and is substituted in-line, then the reference to C is #(>> #(>> A B) C).
  114. ;; The binding for C can be located by going to the structure which supplies A,
  115. ;; finding where it gets B from, and then looking up C there.
  116. ;; These can't be records because they are included in linked images.
  117. (define (make-qualified transform-name sym uid)
  118. (vector '>> transform-name sym uid))
  119. (define (qualified? thing)
  120. (and (vector? thing)
  121. (= (vector-length thing) 4)
  122. (eq? (vector-ref thing 0) '>>)))
  123. (define (qualified-parent-name q) (vector-ref q 1))
  124. (define (qualified-symbol q) (vector-ref q 2))
  125. (define (qualified-uid q) (vector-ref q 3))