File: comp-package.scm

package info (click to toggle)
scheme48 1.9.2-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 18,232 kB
  • sloc: lisp: 88,907; ansic: 87,519; sh: 3,224; makefile: 771
file content (125 lines) | stat: -rw-r--r-- 3,924 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
; Part of Scheme 48 1.9.  See file COPYING for notices and license.

; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber

; package -> template

(define (compile-package package)
  (let ((template (compile-forms ((get-optimizer
				     (package-optimizer-names package))
				    (expand-package package)
				    package)
				 (package-name package)
				 (package-uid package))))
    (link! template package #t)		; #t means warn about undefined variables
    template))

; First we map down the FORMS+FILES, adding the filenames to ENV and
; scanning the forms.  Then we walk down the list of scanned forms and
; expand all the macros.
;
; All of the reversing in the second step makes it so that we process the
; forms in there original order, to keep any errors or warnings in as
; appropriate an order as possible, and then return them in their original
; order.

(define (expand-package package)
  (let ((env (package->environment package)))
    (call-with-values
     (lambda ()
       (package-source package))
     (lambda (forms+files transforms needs-primitives?)
       (for-each (lambda (name)
		   (define-usual-transform env name))
		 transforms)
       (let ((scanned+envs
	      (map (lambda (forms+file)
		     (let ((filename (car forms+file))
			   (forms (cdr forms+file)))
		       (let ((env (bind-source-file-name filename env)))
			 (cons env
			       (scan-forms forms env)))))
		   (if needs-primitives?
		       `((#f . ,(define-primitives env))
			 . ,forms+files)
		       forms+files))))
	 (reverse 
	  (fold (lambda (scanned+env expanded)
		  (let ((env (car scanned+env)))
		    (fold (lambda (form expanded)
			    (cons (delay (expand-scanned-form form env))
				  expanded))
			  (cdr scanned+env)
			  expanded)))
		scanned+envs
		'())))))))
		       
; NAME is the name of one of the usual Scheme macros (AND, OR, COND, and so
; forth).  This adds the appropriate transform to ENV.

(define (define-usual-transform env name)
  (comp-env-define! env
		    name
		    syntax-type
		    (make-transform/macro (usual-transform name)
					  (extract-package-from-comp-env env)
					  syntax-type
					  `(usual-transform ',name)
					  name)))

; This adds definitions of all operators to ENV and returns a list of forms
; that define the closed-compiled versions of those operators that have such.
; It also adds a definition of ALL-OPERATORS to a vector of all the primitive
; operators, mostly for later use by the debugger to identify which primop
; caused an exception.

(define (define-primitives env)
  (table-walk (lambda (name op)
		(let ((type (operator-type op)))
		  (if (not (eq? (operator-type op) 'leaf))
		      (comp-env-define! env name (operator-type op) op))))
	      operators-table)

  (comp-env-define! env 'all-operators vector-type)
  
  (let ((all-operators-node (expand 'all-operators env))
	(vector-set!-node (make-node operator/literal (get-primop 'vector-set!)))
	(procs '())
	(index 0))

    (define (make-define-primitive-node name env)
      (make-node operator/define
		 `(define ,(expand name env)
		    ,(make-node operator/primitive-procedure
				`(primitive-procedure ,name)))))

    (define (make-register-primitive name index env)
      (make-node operator/call
		 (cons vector-set!-node
		       (list all-operators-node
			     (make-node operator/literal index)
			     (expand name env)))))

    (walk-primops (lambda (name type primop)
		    (comp-env-define! env name type primop)
		    (set! procs
			  (cons (make-define-primitive-node name env)
				(cons
				 (make-register-primitive name index env)
				 procs)))
		    (set! index (+ 1 index))))

    (set! procs
	  (cons
	   (make-node
	    operator/define
	    `(define ,all-operators-node
	       ,(make-node operator/call
			   (cons (make-node operator/literal 
					    (get-primop 'make-vector))
				 (list (make-node operator/literal
						  index))))))
	   procs))

    procs))