File: scan-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 (148 lines) | stat: -rw-r--r-- 4,635 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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
; Part of Scheme 48 1.9.  See file COPYING for notices and license.

; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber

; Scanning structures and processing package clauses.

; Utility for compile-structures (link/link.scm) and
; ensure-loaded (env/load-package.scm).
;
; Returns a list of all packages reachable from STRUCTS that answer true to
; INCLUDE-THIS-PACKAGE?.

(define (collect-packages structs include-this-package?)
  (let ((package-seen '())
	(structure-seen '())
	(packages '()))
    (letrec ((recur
	      (lambda (structure visited)
		(if (memq (structure-package structure) visited)
		    (warning 'collect-packages "cycle in structures dependencies"
			     structure visited))
		(if (not (memq structure structure-seen))
		    (begin
		      (set! structure-seen (cons structure structure-seen))
		      (let ((package (structure-package structure)))
			(if (not (memq package package-seen))
			    (begin
			      (set! package-seen (cons package package-seen))
			      (if (include-this-package? package)
				  (let ((visited (cons package visited)))
				    (for-each (lambda (struct)
						(recur struct visited))
					      (package-opens package))
				    (for-each (lambda (name+struct)
						(recur (cdr name+struct) visited))
					      (package-accesses package))
				    (set! packages (cons package packages))))))))))))
      (for-each (lambda (struct)
		  (recur struct '()))
		structs)
      (reverse packages))))

; Walk through PACKAGE's clauses to find the source code.  The relevant
; clauses are:
;   (files name ...)
;   (begin form ...)
;   (define-all-operators)
;   (usual-transforms name ...)
;
; Returns a list of pairs (file . (node1 node2 ...)), a list of names
; of standard transforms, and a boolean value which is true if the package
; is to include definitions of all primitives.

(define (package-source package)
  (let* ((config-file (package-file-name package))
	 (dir (if config-file
		  (file-name-directory config-file)
		  #f)))
    (call-with-values
	(lambda ()
	  (fold->3 (lambda (clause stuff transforms primitives?)
		     (case (car clause)
		       ((files)
			(values (read-files (cdr clause) stuff dir package)
				transforms
				primitives?))
		       ((begin)
			(values (cons (cons config-file (cdr clause))
				      stuff)
				transforms
				primitives?))
		       ((integrate)
			(set-package-integrate?! package
						 (or (null? (cdr clause))
						     (cadr clause)))
			(values stuff transforms primitives?))
		       ((optimize)
			(values stuff transforms primitives?))
		       ((define-all-operators)
			(values stuff transforms #t))
		       ((usual-transforms)
			(values stuff
				(append (reverse (cdr clause)) transforms)
				primitives?))
		       ((reader)
			(let ((r (force (comp-env-macro-eval (package->environment package)))))
			  (set-package-reader! package ((car r) (cadr clause) (cdr r))))
			(values stuff transforms primitives?))
		       (else
			(assertion-violation 'package-source
					     "unrecognized define-structure keyword"
					     clause))))
		   (package-clauses package)
		   '() '() #f))
      (lambda (stuff transforms primitives?)
	(values (reverse stuff)
		(reverse transforms)
		primitives?)))))

; Also prints out the filenames (courtesy of READ-FORMS).

(define (read-files all-files stuff dir package)
  (force-output (current-output-port))		; just to be nice
  (fold (lambda (filespec stuff)
	  (let ((file (namestring filespec
				  dir
				  *scheme-file-type*)))
	    (display #\space (current-noise-port))
	    (cons (cons file (read-forms file package #f))
		  stuff)))
	all-files
	stuff))

(define (package-optimizer-names package)
  (if (package-integrate? package)
      (let ((opts (apply append
			 (map cdr (filter (lambda (clause)
					    (eq? (car clause) 'optimize))
					  (package-clauses package))))))
	(reduce (lambda (name opts)
		  (if (memq name opts)
		      opts
		      (cons name opts)))
		opts
		'()))
      '()))

(define (check-structure structure)
  (let ((undefined '()))
    (for-each-export
         (lambda (name want-type binding)
	   (if (binding? binding)
	       (let ((have-type (binding-type binding)))
		 (if (not (compatible-types? have-type want-type))
		     (warning 'check-structure
			      "Type in interface doesn't match binding"
			      name
			      `(binding: ,(type->sexp have-type #t))
			      `(interface: ,(type->sexp want-type #t))
			      structure)))
	       (set! undefined (cons name undefined))))
	 structure)
    (if (not (null? undefined))
	(warning 'check-structure
		 "Structure has undefined exports"
		 structure
		 undefined))))