vector.scm 6.5 KB

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