vector.scm 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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/vector.scm
  8. ;;;
  9. ;;;----------------------------------------------------------------------------
  10. ;;; STORING NODE TREES IN VECTORS
  11. ;;;----------------------------------------------------------------------------
  12. ;;;
  13. ;;; The use of OTHER and GLOBAL depends on whether NODE->VECTOR or VECTOR->NODE
  14. (define-module (ps-compiler node vector)
  15. #:use-module (prescheme scheme48)
  16. #:use-module (prescheme s48-defrecord)
  17. #:use-module (ps-compiler node node)
  18. #:use-module (ps-compiler node primop)
  19. #:use-module (ps-compiler node variable)
  20. #:use-module (ps-compiler param)
  21. #:use-module (ps-compiler util expand-vec)
  22. #:use-module (ps-compiler util util)
  23. #:export (node->vector
  24. vector->node
  25. vector->leaf-node))
  26. (define-record-type vec
  27. (vector ;; an expanding vector (NODE->VECTOR) or just a vector (VECTOR->NODE)
  28. (index) ;; the index of the next empty slot or the next thing to read
  29. locals ;; vector of local variables (VECTOR->NODE only)
  30. )
  31. ())
  32. (define make-vec vec-maker)
  33. ;; Add value as the next thing in the VEC.
  34. (define (add-datum vec value)
  35. (xvector-set! (vec-vector vec) (vec-index vec) value)
  36. (set-vec-index! vec (+ 1 (vec-index vec))))
  37. ;; Convert a node into a vector
  38. ;;
  39. ;; literal => QUOTE <literal> <rep>
  40. ;; reference => <index of the variable's name in vector> if lexical, or
  41. ;; GLOBAL <variable> if it isn't
  42. ;; lambda => LAMBDA <stuff> #vars <variable names+reps> <call>
  43. ;; call => CALL <source> <primop> <exits> <number of args> <args>
  44. ;; Preserve the node as a vector.
  45. (define (node->vector node)
  46. (let ((vec (make-vec (make-xvector #f) 0 #f)))
  47. (real-node->vector node vec)
  48. (xvector->vector (vec-vector vec))))
  49. ;; The main dispatch
  50. (define (real-node->vector node vec)
  51. (case (node-variant node)
  52. ((literal)
  53. (literal->vector node vec))
  54. ((reference)
  55. (reference->vector node vec))
  56. ((lambda)
  57. (lambda->vector node vec))
  58. ((call)
  59. (add-datum vec 'call)
  60. (call->vector node vec))
  61. (else
  62. (bug "node->vector got funny node ~S" node))))
  63. ;; VARIABLE-FLAGs are used to mark variables with their position in the
  64. ;; vector.
  65. (define (lambda->vector node vec)
  66. (add-datum vec 'lambda)
  67. (add-datum vec (lambda-name node))
  68. (add-datum vec (lambda-type node))
  69. (add-datum vec (lambda-protocol node))
  70. (add-datum vec (lambda-source node))
  71. (add-datum vec (lambda-variable-count node))
  72. (for-each (lambda (var)
  73. (cond ((not var)
  74. (add-datum vec #f))
  75. (else
  76. (set-variable-flag! var (vec-index vec))
  77. (add-datum vec (variable-name var))
  78. (add-datum vec (variable-type var)))))
  79. (lambda-variables node))
  80. (call->vector (lambda-body node) vec)
  81. (for-each (lambda (var)
  82. (if var
  83. (set-variable-flag! var #f)))
  84. (lambda-variables node)))
  85. ;; If VAR is bound locally, then put the index of the variable within the vector
  86. ;; into the vector.
  87. (define (reference->vector node vec)
  88. (let ((var (reference-variable node)))
  89. (cond ((not (variable-binder var))
  90. (add-datum vec 'global)
  91. (add-datum vec var))
  92. ((integer? (variable-flag var))
  93. (add-datum vec (variable-flag var)))
  94. (else
  95. (bug "variable ~S has no vector location" var)))))
  96. (define (literal->vector node vec)
  97. (let ((value (literal-value node)))
  98. (add-datum vec 'quote)
  99. (add-datum vec (literal-value node))
  100. (add-datum vec (literal-type node))))
  101. ;; This counts down so that the continuation will be done after the arguments.
  102. ;; Why does this matter?
  103. (define (call->vector node vec)
  104. (let* ((args (call-args node))
  105. (len (vector-length args)))
  106. (add-datum vec (call-source node))
  107. (add-datum vec (call-primop node))
  108. (add-datum vec (call-exits node))
  109. (add-datum vec len)
  110. (do ((i (- len 1) (- i 1)))
  111. ((< i 0))
  112. (real-node->vector (vector-ref args i) vec))))
  113. ;;----------------------------------------------------------------------------
  114. ;; TURNING VECTORS BACK INTO NODES
  115. ;;----------------------------------------------------------------------------
  116. (define (vector->node vector)
  117. (if (not (vector? vector))
  118. (bug "VECTOR->NODE got funny value ~S~%" vector)
  119. (let ((vec (make-vec vector -1 (make-vector (vector-length vector)))))
  120. (real-vector->node vec))))
  121. (define (vector->leaf-node vector)
  122. (case (vector-ref vector 0)
  123. ((quote global)
  124. (vector->node vector))
  125. (else #f)))
  126. ;; Pop the next thing off of the vector (which is really a (<vector> . <index>)
  127. ;; pair).
  128. (define (get-datum vec)
  129. (let ((i (+ (vec-index vec) 1)))
  130. (set-vec-index! vec i)
  131. (vector-ref (vec-vector vec) i)))
  132. ;; This prevents the (unecessary) resimplification of recreated nodes.
  133. (define (real-vector->node vec)
  134. (let ((node (totally-real-vector->node vec)))
  135. (set-node-simplified?! node #t)
  136. node))
  137. ;; Dispatch on the next thing in VEC.
  138. (define (totally-real-vector->node vec)
  139. (let ((exp (get-datum vec)))
  140. (cond ((integer? exp)
  141. (make-reference-node (vector-ref (vec-locals vec) exp)))
  142. (else
  143. (case exp
  144. ((lambda)
  145. (vector->lambda-node vec))
  146. ((quote)
  147. (let* ((value (get-datum vec))
  148. (rep (get-datum vec)))
  149. (make-literal-node value rep)))
  150. ((global)
  151. (make-reference-node (get-datum vec)))
  152. ((call)
  153. (vector->call-node vec))
  154. ((import) ;; global variable from a separate compilation
  155. (make-reference-node (lookup-imported-variable (get-datum vec))))
  156. (else
  157. (no-op
  158. (bug '"real-vector->node got an unknown code ~S" exp))))))))
  159. (define (vector->lambda-node vec)
  160. (let* ((name (get-datum vec))
  161. (type (get-datum vec))
  162. (protocol (get-datum vec))
  163. (source (get-datum vec))
  164. (count (get-datum vec))
  165. (vars (do ((i 0 (+ i 1))
  166. (v '() (cons (vector->variable vec) v)))
  167. ((>= i count) v)))
  168. (node (make-lambda-node name type (reverse! vars))))
  169. (set-lambda-protocol! node protocol)
  170. (set-lambda-source! node source)
  171. (attach-body node (vector->call-node vec))
  172. (set-node-simplified?! (lambda-body node) #t)
  173. node))
  174. ;; Replace a variable name with a new variable.
  175. (define (vector->variable vec)
  176. (let ((name (get-datum vec)))
  177. (if name
  178. (let ((var (make-variable name (get-datum vec))))
  179. (vector-set! (vec-locals vec) (+ -1 (vec-index vec)) var)
  180. var)
  181. #f)))
  182. (define (vector->call-node vec)
  183. (let* ((source (get-datum vec))
  184. (primop (let ((p (get-datum vec)))
  185. (if (primop? p)
  186. p
  187. (lookup-primop p))))
  188. (exits (get-datum vec))
  189. (count (get-datum vec))
  190. (node (make-call-node primop count exits)))
  191. (do ((i (- count 1) (- i 1)))
  192. ((< i 0))
  193. (attach node i (real-vector->node vec)))
  194. (set-call-source! node source)
  195. node))