/batch/merge.rkt

http://github.com/jeapostrophe/compiler · Racket · 164 lines · 153 code · 9 blank · 2 comment · 14 complexity · b3dcde270f5832206037da6e87ab3221 MD5 · raw file

  1. #lang racket
  2. (require compiler/zo-parse
  3. "util.rkt"
  4. "mpi.rkt"
  5. "nodep.rkt"
  6. "update-toplevels.rkt")
  7. (define MODULE-TOPLEVEL-OFFSETS (make-hash))
  8. (define (merge-compilation-top top)
  9. (match top
  10. [(struct compilation-top (max-let-depth prefix form))
  11. (define-values (new-max-let-depth new-prefix gen-new-forms)
  12. (merge-form max-let-depth prefix form))
  13. (define total-tls (length (prefix-toplevels new-prefix)))
  14. (define total-stxs (length (prefix-stxs new-prefix)))
  15. (define total-lifts (prefix-num-lifts new-prefix))
  16. (eprintf "max-let-depth ~S to ~S~n" max-let-depth new-max-let-depth)
  17. (eprintf "total toplevels ~S~n" total-tls)
  18. (eprintf "total stxs ~S~n" total-stxs)
  19. (eprintf "num-lifts ~S~n" total-lifts)
  20. (make-compilation-top
  21. new-max-let-depth new-prefix
  22. (make-splice (gen-new-forms new-prefix)))]
  23. [else (error 'merge "unrecognized: ~e" top)]))
  24. (define (merge-forms max-let-depth prefix forms)
  25. (if (empty? forms)
  26. (values max-let-depth prefix (lambda _ empty))
  27. (let*-values ([(fmax-let-depth fprefix gen-fform) (merge-form max-let-depth prefix (first forms))]
  28. [(rmax-let-depth rprefix gen-rforms) (merge-forms fmax-let-depth fprefix (rest forms))])
  29. (values rmax-let-depth
  30. rprefix
  31. (lambda args
  32. (append (apply gen-fform args)
  33. (apply gen-rforms args)))))))
  34. (define (merge-form max-let-depth prefix form)
  35. (match form
  36. [(? mod?)
  37. (merge-module max-let-depth prefix form)]
  38. [(struct seq (forms))
  39. (merge-forms max-let-depth prefix forms)]
  40. [(struct splice (forms))
  41. (merge-forms max-let-depth prefix forms)]
  42. [else
  43. (values max-let-depth prefix (lambda _ (list form)))]))
  44. (define (merge-prefix root-prefix mod-prefix)
  45. (match root-prefix
  46. [(struct prefix (root-num-lifts root-toplevels root-stxs))
  47. (match mod-prefix
  48. [(struct prefix (mod-num-lifts mod-toplevels mod-stxs))
  49. (make-prefix (+ root-num-lifts mod-num-lifts)
  50. (append root-toplevels mod-toplevels)
  51. (append root-stxs mod-stxs))])]))
  52. (define (compute-new-modvar mv rw)
  53. (match mv
  54. [(struct module-variable (modidx sym pos phase))
  55. (match rw
  56. [(struct modvar-rewrite (self-modidx provide->toplevel))
  57. (eprintf "Rewriting ~a of ~S~n" pos (mpi->path* modidx))
  58. (+ (hash-ref MODULE-TOPLEVEL-OFFSETS self-modidx
  59. (lambda ()
  60. (error 'compute-new-modvar "toplevel offset not yet computed: ~S" self-modidx)))
  61. (provide->toplevel sym pos))])]))
  62. (define (filter-rewritable-module-variable? toplevel-offset mod-toplevels)
  63. (define-values
  64. (i new-toplevels remap)
  65. (for/fold ([i 0]
  66. [new-toplevels empty]
  67. [remap empty])
  68. ([tl (in-list mod-toplevels)])
  69. (match tl
  70. [(and mv (struct module-variable (modidx sym pos phase)))
  71. (define rw (get-modvar-rewrite modidx))
  72. (unless (or (not phase) (zero? phase))
  73. (error 'eliminate-module-variables "Non-zero phases not supported: ~S" mv))
  74. (cond
  75. ; Primitive module like #%paramz
  76. [(symbol? rw)
  77. (eprintf "~S from ~S~n" sym rw)
  78. (values (add1 i)
  79. (list* tl new-toplevels)
  80. (list* (+ i toplevel-offset) remap))]
  81. [(module-path-index? rw)
  82. (values (add1 i)
  83. (list* tl new-toplevels)
  84. (list* (+ i toplevel-offset) remap))]
  85. [(modvar-rewrite? rw)
  86. (values i
  87. new-toplevels
  88. (list* (compute-new-modvar mv rw) remap))]
  89. [else
  90. (error 'filter-rewritable-module-variable? "Unsupported module-rewrite: ~S" rw)])]
  91. [tl
  92. (values (add1 i)
  93. (list* tl new-toplevels)
  94. (list* (+ i toplevel-offset) remap))])))
  95. (values (reverse new-toplevels)
  96. (reverse remap)))
  97. (define (merge-module max-let-depth top-prefix mod-form)
  98. (match mod-form
  99. [(struct mod (name srcname self-modidx mod-prefix provides requires body syntax-body unexported mod-max-let-depth dummy lang-info internal-context))
  100. (define toplevel-offset (length (prefix-toplevels top-prefix)))
  101. (define topsyntax-offset (length (prefix-stxs top-prefix)))
  102. (define lift-offset (prefix-num-lifts top-prefix))
  103. (define mod-toplevels (prefix-toplevels mod-prefix))
  104. (define-values (new-mod-toplevels toplevel-remap) (filter-rewritable-module-variable? toplevel-offset mod-toplevels))
  105. (define num-mod-toplevels
  106. (length toplevel-remap))
  107. (define mod-stxs
  108. (length (prefix-stxs mod-prefix)))
  109. (define mod-num-lifts
  110. (prefix-num-lifts mod-prefix))
  111. (define new-mod-prefix
  112. (struct-copy prefix mod-prefix
  113. [toplevels new-mod-toplevels]))
  114. (hash-set! MODULE-TOPLEVEL-OFFSETS self-modidx toplevel-offset)
  115. (unless (= (length toplevel-remap)
  116. (length mod-toplevels))
  117. (error 'merge-module "Not remapping everything: ~S ~S~n"
  118. mod-toplevels toplevel-remap))
  119. (eprintf "[~S] Incrementing toplevels by ~a~n"
  120. name
  121. toplevel-offset)
  122. (eprintf "[~S] Incrementing lifts by ~a~n"
  123. name
  124. lift-offset)
  125. (eprintf "[~S] Filtered mod-vars from ~a to ~a~n"
  126. name
  127. (length mod-toplevels)
  128. (length new-mod-toplevels))
  129. (values (max max-let-depth mod-max-let-depth)
  130. (merge-prefix top-prefix new-mod-prefix)
  131. (lambda (top-prefix)
  132. (define top-lift-start (prefix-lift-start top-prefix))
  133. (define mod-lift-start (prefix-lift-start mod-prefix))
  134. (define total-lifts (prefix-num-lifts top-prefix))
  135. (define max-toplevel (+ top-lift-start total-lifts))
  136. (define update
  137. (update-toplevels
  138. (lambda (n)
  139. (cond
  140. [(mod-lift-start . <= . n)
  141. ; This is a lift
  142. (local [(define which-lift (- n mod-lift-start))
  143. (define lift-tl (+ top-lift-start lift-offset which-lift))]
  144. (when (lift-tl . >= . max-toplevel)
  145. (error 'merge-module "[~S] lift error: orig(~a) which(~a) max(~a) lifts(~a) now(~a)"
  146. name n which-lift num-mod-toplevels mod-num-lifts lift-tl))
  147. lift-tl)]
  148. [else
  149. (list-ref toplevel-remap n)]))
  150. (lambda (n)
  151. (+ n topsyntax-offset))
  152. (prefix-syntax-start top-prefix)))
  153. (map update body)))]))
  154. (provide/contract
  155. [merge-compilation-top (compilation-top? . -> . compilation-top?)])