comp-package.scm 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; package -> template
  4. (define (compile-package package)
  5. (let ((template (compile-forms ((get-optimizer
  6. (package-optimizer-names package))
  7. (expand-package package)
  8. package)
  9. (package-name package)
  10. (package-uid package))))
  11. (link! template package #t) ; #t means warn about undefined variables
  12. template))
  13. ; First we map down the FORMS+FILES, adding the filenames to ENV and
  14. ; scanning the forms. Then we walk down the list of scanned forms and
  15. ; expand all the macros.
  16. ;
  17. ; All of the reversing in the second step makes it so that we process the
  18. ; forms in there original order, to keep any errors or warnings in as
  19. ; appropriate an order as possible, and then return them in their original
  20. ; order.
  21. (define (expand-package package)
  22. (let ((env (package->environment package)))
  23. (call-with-values
  24. (lambda ()
  25. (package-source package))
  26. (lambda (forms+files transforms needs-primitives?)
  27. (for-each (lambda (name)
  28. (define-usual-transform env name))
  29. transforms)
  30. (let ((scanned+envs
  31. (map (lambda (forms+file)
  32. (let ((filename (car forms+file))
  33. (forms (cdr forms+file)))
  34. (let ((env (bind-source-file-name filename env)))
  35. (cons env
  36. (scan-forms forms env)))))
  37. (if needs-primitives?
  38. `((#f . ,(define-primitives env))
  39. . ,forms+files)
  40. forms+files))))
  41. (reverse
  42. (fold (lambda (scanned+env expanded)
  43. (let ((env (car scanned+env)))
  44. (fold (lambda (form expanded)
  45. (cons (delay (expand-scanned-form form env))
  46. expanded))
  47. (cdr scanned+env)
  48. expanded)))
  49. scanned+envs
  50. '())))))))
  51. ; NAME is the name of one of the usual Scheme macros (AND, OR, COND, and so
  52. ; forth). This adds the appropriate transform to ENV.
  53. (define (define-usual-transform env name)
  54. (comp-env-define! env
  55. name
  56. syntax-type
  57. (make-transform/macro (usual-transform name)
  58. (extract-package-from-comp-env env)
  59. syntax-type
  60. `(usual-transform ',name)
  61. name)))
  62. ; This adds definitions of all operators to ENV and returns a list of forms
  63. ; that define the closed-compiled versions of those operators that have such.
  64. ; It also adds a definition of ALL-OPERATORS to a vector of all the primitive
  65. ; operators, mostly for later use by the debugger to identify which primop
  66. ; caused an exception.
  67. (define (define-primitives env)
  68. (table-walk (lambda (name op)
  69. (let ((type (operator-type op)))
  70. (if (not (eq? (operator-type op) 'leaf))
  71. (comp-env-define! env name (operator-type op) op))))
  72. operators-table)
  73. (comp-env-define! env 'all-operators vector-type)
  74. (let ((all-operators-node (expand 'all-operators env))
  75. (vector-set!-node (make-node operator/literal (get-primop 'vector-set!)))
  76. (procs '())
  77. (index 0))
  78. (define (make-define-primitive-node name env)
  79. (make-node operator/define
  80. `(define ,(expand name env)
  81. ,(make-node operator/primitive-procedure
  82. `(primitive-procedure ,name)))))
  83. (define (make-register-primitive name index env)
  84. (make-node operator/call
  85. (cons vector-set!-node
  86. (list all-operators-node
  87. (make-node operator/literal index)
  88. (expand name env)))))
  89. (walk-primops (lambda (name type primop)
  90. (comp-env-define! env name type primop)
  91. (set! procs
  92. (cons (make-define-primitive-node name env)
  93. (cons
  94. (make-register-primitive name index env)
  95. procs)))
  96. (set! index (+ 1 index))))
  97. (set! procs
  98. (cons
  99. (make-node
  100. operator/define
  101. `(define ,all-operators-node
  102. ,(make-node operator/call
  103. (cons (make-node operator/literal
  104. (get-primop 'make-vector))
  105. (list (make-node operator/literal
  106. index))))))
  107. procs))
  108. procs))