variable.scm 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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
  6. ;;;
  7. ;;; scheme48-1.9.2/ps-compiler/node/node.scm
  8. ;;;
  9. ;;; This file contains the definitions of the node tree data structure.
  10. (define-module (ps-compiler node variable)
  11. #:use-module (prescheme scheme48)
  12. #:use-module (prescheme s48-defrecord)
  13. #:use-module (prescheme record-discloser)
  14. #:use-module (ps-compiler node node)
  15. #:use-module (ps-compiler util util)
  16. #:replace (variable? make-variable)
  17. #:export (global-variable? make-global-variable
  18. variable-name set-variable-name!
  19. variable-id
  20. variable-type set-variable-type!
  21. variable-binder set-variable-binder!
  22. variable-refs set-variable-refs!
  23. variable-flag set-variable-flag!
  24. variable-flags set-variable-flags!
  25. variable-generate set-variable-generate!
  26. new-variable-id
  27. erase-variable
  28. reset-node-id node-hash node-unhash
  29. variable-index copy-variable used? unused?
  30. variable-flag-accessor variable-flag-setter variable-flag-remover
  31. variable-known-value
  32. add-variable-known-value!
  33. remove-variable-known-value!
  34. variable-simplifier
  35. add-variable-simplifier!
  36. remove-variable-simplifier!
  37. note-known-global-lambda!
  38. variable-known-lambda))
  39. ;;;---------------------------------------------------------------------------
  40. ;;; Records to represent variables.
  41. (define-record-type variable
  42. ((name) ;; Source code name for variable (used for debugging only)
  43. (id) ;; Unique numeric identifier (used for debugging only)
  44. (type) ;; Type for variable's value
  45. )
  46. (binder ;; LAMBDA node which binds this variable
  47. (refs '()) ;; List of leaf nodes n for which (REFERENCE-VARIABLE n) = var.
  48. (flag #f) ;; Useful slot, used by shapes, COPY-NODE, NODE->VECTOR, etc.
  49. ;; all users must leave this is #F
  50. (flags '()) ;; For various annotations, e.g. IGNORABLE
  51. (generate #f) ;; For whatever code generation wants
  52. ))
  53. (define-record-discloser type/variable
  54. (lambda (var)
  55. (node-hash var)
  56. (list 'variable (variable-name var) (variable-id var))))
  57. (define (make-variable name type)
  58. (variable-maker name (new-variable-id) type))
  59. (define (make-global-variable name type)
  60. (let ((var (make-variable name type)))
  61. (set-variable-binder! var #f)
  62. var))
  63. (define (global-variable? var)
  64. (not (variable-binder var)))
  65. ;; Every variable has a unique numeric identifier that is used for printing.
  66. (define *variable-id* 0)
  67. (define (new-variable-id)
  68. (let ((id *variable-id*))
  69. (set! *variable-id* (+ 1 *variable-id*))
  70. id))
  71. (define (erase-variable var)
  72. (cond ((eq? (variable-id var) '<erased>)
  73. (bug "variable ~S already erased" var))
  74. (else
  75. (set-variable-id! var '<erased>))))
  76. (define *node-hash-table* #f)
  77. (define (reset-node-id)
  78. (set! *variable-id* 0)
  79. (set! *node-hash-table* (make-table)))
  80. (define (node-hash var-or-lambda)
  81. (let ((id (if (variable? var-or-lambda)
  82. (variable-id var-or-lambda)
  83. (lambda-id var-or-lambda))))
  84. (table-set! *node-hash-table* id var-or-lambda)))
  85. (define (node-unhash n)
  86. (table-ref *node-hash-table* n))
  87. ;; The index of VAR in the variables bound by its binder.
  88. (define (variable-index var)
  89. (let ((binder (variable-binder var)))
  90. (if (not binder)
  91. (bug "VARIABLE-INDEX called on global variable ~S" var)
  92. (do ((i 0 (+ i 1))
  93. (vs (lambda-variables binder) (cdr vs)))
  94. ((eq? (car vs) var)
  95. i)))))
  96. ;; Copy an old variable.
  97. (define (copy-variable old)
  98. (let ((var (make-variable (variable-name old) (variable-type old))))
  99. (set-variable-flags! var (variable-flags old))
  100. var))
  101. ;; An unused variable is either #F or a variable with no references.
  102. (define (used? var)
  103. (and var
  104. (not (null? (variable-refs var)))))
  105. (define (unused? var)
  106. (not (used? var)))
  107. ;; known values for top-level variables
  108. (define (variable-flag-accessor flag)
  109. (lambda (var)
  110. (let ((p (flag-assq flag (variable-flags var))))
  111. (if p (cdr p) #f))))
  112. (define (variable-flag-setter flag)
  113. (lambda (var value)
  114. (set-variable-flags! var
  115. (cons (cons flag value)
  116. (variable-flags var)))))
  117. (define (variable-flag-remover flag)
  118. (lambda (var)
  119. (set-variable-flags! var (filter (lambda (x)
  120. (or (not (pair? x))
  121. (not (eq? (car x) flag))))
  122. (variable-flags var)))))
  123. (define variable-known-value (variable-flag-accessor 'known-value))
  124. (define add-variable-known-value! (variable-flag-setter 'known-value))
  125. (define remove-variable-known-value! (variable-flag-remover 'known-value))
  126. (define variable-simplifier (variable-flag-accessor 'simplifier))
  127. (define add-variable-simplifier! (variable-flag-setter 'simplifier))
  128. (define remove-variable-simplifier! (variable-flag-remover 'simplifier))
  129. (define variable-known-lambda (variable-flag-accessor 'known-lambda))
  130. (define note-known-global-lambda! (variable-flag-setter 'known-lambda))