1 | ;;; compiler-pass1.lisp |
---|
2 | ;;; |
---|
3 | ;;; Copyright (C) 2003-2008 Peter Graves |
---|
4 | ;;; $Id: compiler-pass1.lisp 11789 2009-04-27 21:10:24Z vvoutilainen $ |
---|
5 | ;;; |
---|
6 | ;;; This program is free software; you can redistribute it and/or |
---|
7 | ;;; modify it under the terms of the GNU General Public License |
---|
8 | ;;; as published by the Free Software Foundation; either version 2 |
---|
9 | ;;; of the License, or (at your option) any later version. |
---|
10 | ;;; |
---|
11 | ;;; This program is distributed in the hope that it will be useful, |
---|
12 | ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | ;;; GNU General Public License for more details. |
---|
15 | ;;; |
---|
16 | ;;; You should have received a copy of the GNU General Public License |
---|
17 | ;;; along with this program; if not, write to the Free Software |
---|
18 | ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
---|
19 | ;;; |
---|
20 | ;;; As a special exception, the copyright holders of this library give you |
---|
21 | ;;; permission to link this library with independent modules to produce an |
---|
22 | ;;; executable, regardless of the license terms of these independent |
---|
23 | ;;; modules, and to copy and distribute the resulting executable under |
---|
24 | ;;; terms of your choice, provided that you also meet, for each linked |
---|
25 | ;;; independent module, the terms and conditions of the license of that |
---|
26 | ;;; module. An independent module is a module which is not derived from |
---|
27 | ;;; or based on this library. If you modify this library, you may extend |
---|
28 | ;;; this exception to your version of the library, but you are not |
---|
29 | ;;; obligated to do so. If you do not wish to do so, delete this |
---|
30 | ;;; exception statement from your version. |
---|
31 | |
---|
32 | (in-package "JVM") |
---|
33 | |
---|
34 | (eval-when (:compile-toplevel :load-toplevel :execute) |
---|
35 | (require "LOOP") |
---|
36 | (require "FORMAT") |
---|
37 | (require "CLOS") |
---|
38 | (require "PRINT-OBJECT") |
---|
39 | (require "COMPILER-TYPES") |
---|
40 | (require "KNOWN-FUNCTIONS") |
---|
41 | (require "KNOWN-SYMBOLS") |
---|
42 | (require "DUMP-FORM") |
---|
43 | (require "OPCODES") |
---|
44 | (require "JAVA")) |
---|
45 | |
---|
46 | |
---|
47 | (eval-when (:compile-toplevel :load-toplevel :execute) |
---|
48 | (defun generate-inline-expansion (block-name lambda-list body) |
---|
49 | (cond ((intersection lambda-list '(&optional &rest &key &allow-other-keys &aux) :test 'eq) |
---|
50 | nil) |
---|
51 | (t |
---|
52 | (setf body (copy-tree body)) |
---|
53 | (list 'LAMBDA lambda-list (precompile-form (list* 'BLOCK block-name body) t))))) |
---|
54 | ) ; EVAL-WHEN |
---|
55 | |
---|
56 | ;;; Pass 1. |
---|
57 | |
---|
58 | |
---|
59 | ;; Returns a list of declared free specials, if any are found. |
---|
60 | (declaim (ftype (function (list list) list) process-declarations-for-vars)) |
---|
61 | (defun process-declarations-for-vars (body variables) |
---|
62 | (let ((free-specials '())) |
---|
63 | (dolist (subform body) |
---|
64 | (unless (and (consp subform) (eq (%car subform) 'DECLARE)) |
---|
65 | (return)) |
---|
66 | (let ((decls (%cdr subform))) |
---|
67 | (dolist (decl decls) |
---|
68 | (case (car decl) |
---|
69 | ((DYNAMIC-EXTENT FTYPE INLINE NOTINLINE OPTIMIZE) |
---|
70 | ;; Nothing to do here. |
---|
71 | ) |
---|
72 | ((IGNORE IGNORABLE) |
---|
73 | (process-ignore/ignorable (%car decl) (%cdr decl) variables)) |
---|
74 | (SPECIAL |
---|
75 | (dolist (name (%cdr decl)) |
---|
76 | (let ((variable (find-variable name variables))) |
---|
77 | (cond ((and variable |
---|
78 | ;; see comment below (and DO-ALL-SYMBOLS.11) |
---|
79 | (eq (variable-compiland variable) *current-compiland*)) |
---|
80 | (setf (variable-special-p variable) t)) |
---|
81 | (t |
---|
82 | (dformat t "adding free special ~S~%" name) |
---|
83 | (push (make-variable :name name :special-p t) free-specials)))))) |
---|
84 | (TYPE |
---|
85 | (dolist (name (cddr decl)) |
---|
86 | (let ((variable (find-variable name variables))) |
---|
87 | (when (and variable |
---|
88 | ;; Don't apply a declaration in a local function to |
---|
89 | ;; a variable defined in its parent. For an example, |
---|
90 | ;; see CREATE-GREEDY-NO-ZERO-MATCHER in cl-ppcre. |
---|
91 | ;; FIXME suboptimal, since we ignore the declaration |
---|
92 | (eq (variable-compiland variable) *current-compiland*)) |
---|
93 | (setf (variable-declared-type variable) |
---|
94 | (make-compiler-type (cadr decl))))))) |
---|
95 | (t |
---|
96 | (dolist (name (cdr decl)) |
---|
97 | (let ((variable (find-variable name variables))) |
---|
98 | (when variable |
---|
99 | (setf (variable-declared-type variable) |
---|
100 | (make-compiler-type (%car decl))))))))))) |
---|
101 | free-specials)) |
---|
102 | |
---|
103 | (defun check-name (name) |
---|
104 | ;; FIXME Currently this error is signalled by the precompiler. |
---|
105 | (unless (symbolp name) |
---|
106 | (compiler-error "The variable ~S is not a symbol." name)) |
---|
107 | (when (constantp name) |
---|
108 | (compiler-error "The name of the variable ~S is already in use to name a constant." name)) |
---|
109 | name) |
---|
110 | |
---|
111 | (declaim (ftype (function (t) t) p1-body)) |
---|
112 | (defun p1-body (body) |
---|
113 | (declare (optimize speed)) |
---|
114 | (let ((tail body)) |
---|
115 | (loop |
---|
116 | (when (endp tail) |
---|
117 | (return)) |
---|
118 | (setf (car tail) (p1 (%car tail))) |
---|
119 | (setf tail (%cdr tail)))) |
---|
120 | body) |
---|
121 | |
---|
122 | (defknown p1-default (t) t) |
---|
123 | (declaim (inline p1-default)) |
---|
124 | (defun p1-default (form) |
---|
125 | (setf (cdr form) (p1-body (cdr form))) |
---|
126 | form) |
---|
127 | |
---|
128 | (defknown p1-if (t) t) |
---|
129 | (defun p1-if (form) |
---|
130 | (let ((test (cadr form))) |
---|
131 | (cond ((unsafe-p test) |
---|
132 | (cond ((and (consp test) |
---|
133 | (memq (%car test) '(GO RETURN-FROM THROW))) |
---|
134 | (p1 test)) |
---|
135 | (t |
---|
136 | (let* ((var (gensym)) |
---|
137 | (new-form |
---|
138 | `(let ((,var ,test)) |
---|
139 | (if ,var ,(third form) ,(fourth form))))) |
---|
140 | (p1 new-form))))) |
---|
141 | (t |
---|
142 | (p1-default form))))) |
---|
143 | |
---|
144 | |
---|
145 | (defmacro p1-let/let*-vars |
---|
146 | (varlist variables-var var body1 body2) |
---|
147 | (let ((varspec (gensym)) |
---|
148 | (initform (gensym)) |
---|
149 | (name (gensym))) |
---|
150 | `(let ((,variables-var ())) |
---|
151 | (dolist (,varspec ,varlist) |
---|
152 | (cond ((consp ,varspec) |
---|
153 | ;; FIXME Currently this error is signalled by the precompiler. |
---|
154 | (unless (= (length ,varspec) 2) |
---|
155 | (compiler-error "The LET/LET* binding specification ~S is invalid." |
---|
156 | ,varspec)) |
---|
157 | (let* ((,name (%car ,varspec)) |
---|
158 | (,initform (p1 (%cadr ,varspec))) |
---|
159 | (,var (make-variable :name (check-name ,name) :initform ,initform))) |
---|
160 | (push ,var ,variables-var) |
---|
161 | ,@body1)) |
---|
162 | (t |
---|
163 | (let ((,var (make-variable :name (check-name ,varspec)))) |
---|
164 | (push ,var ,variables-var) |
---|
165 | ,@body1)))) |
---|
166 | ,@body2))) |
---|
167 | |
---|
168 | (defknown p1-let-vars (t) t) |
---|
169 | (defun p1-let-vars (varlist) |
---|
170 | (p1-let/let*-vars |
---|
171 | varlist vars var |
---|
172 | () |
---|
173 | ((setf vars (nreverse vars)) |
---|
174 | (dolist (variable vars) |
---|
175 | (push variable *visible-variables*) |
---|
176 | (push variable *all-variables*)) |
---|
177 | vars))) |
---|
178 | |
---|
179 | (defknown p1-let*-vars (t) t) |
---|
180 | (defun p1-let*-vars (varlist) |
---|
181 | (p1-let/let*-vars |
---|
182 | varlist vars var |
---|
183 | ((push var *visible-variables*) |
---|
184 | (push var *all-variables*)) |
---|
185 | ((nreverse vars)))) |
---|
186 | |
---|
187 | (defun p1-let/let* (form) |
---|
188 | (declare (type cons form)) |
---|
189 | (let* ((*visible-variables* *visible-variables*) |
---|
190 | (block (make-block-node '(LET))) |
---|
191 | (*blocks* (cons block *blocks*)) |
---|
192 | (op (%car form)) |
---|
193 | (varlist (cadr form)) |
---|
194 | (body (cddr form))) |
---|
195 | (aver (or (eq op 'LET) (eq op 'LET*))) |
---|
196 | (when (eq op 'LET) |
---|
197 | ;; Convert to LET* if possible. |
---|
198 | (if (null (cdr varlist)) |
---|
199 | (setf op 'LET*) |
---|
200 | (dolist (varspec varlist (setf op 'LET*)) |
---|
201 | (or (atom varspec) |
---|
202 | (constantp (cadr varspec)) |
---|
203 | (eq (car varspec) (cadr varspec)) |
---|
204 | (return))))) |
---|
205 | (let ((vars (if (eq op 'LET) |
---|
206 | (p1-let-vars varlist) |
---|
207 | (p1-let*-vars varlist)))) |
---|
208 | ;; Check for globally declared specials. |
---|
209 | (dolist (variable vars) |
---|
210 | (when (special-variable-p (variable-name variable)) |
---|
211 | (setf (variable-special-p variable) t))) |
---|
212 | ;; For processing declarations, we want to walk the variable list from |
---|
213 | ;; last to first, since declarations apply to the last-defined variable |
---|
214 | ;; with the specified name. |
---|
215 | (setf (block-free-specials block) (process-declarations-for-vars body (reverse vars))) |
---|
216 | (setf (block-vars block) vars) |
---|
217 | ;; Make free specials visible. |
---|
218 | (dolist (variable (block-free-specials block)) |
---|
219 | (push variable *visible-variables*))) |
---|
220 | (setf body (p1-body body)) |
---|
221 | (setf (block-form block) (list* op varlist body)) |
---|
222 | block)) |
---|
223 | |
---|
224 | (defun p1-locally (form) |
---|
225 | (let ((*visible-variables* *visible-variables*) |
---|
226 | (specials (process-special-declarations (cdr form)))) |
---|
227 | (dolist (name specials) |
---|
228 | ;; (format t "p1-locally ~S is special~%" name) |
---|
229 | (push (make-variable :name name :special-p t) *visible-variables*)) |
---|
230 | (setf (cdr form) (p1-body (cdr form))) |
---|
231 | form)) |
---|
232 | |
---|
233 | (defknown p1-m-v-b (t) t) |
---|
234 | (defun p1-m-v-b (form) |
---|
235 | (when (= (length (cadr form)) 1) |
---|
236 | (let ((new-form `(let* ((,(caadr form) ,(caddr form))) ,@(cdddr form)))) |
---|
237 | (return-from p1-m-v-b (p1-let/let* new-form)))) |
---|
238 | (let* ((*visible-variables* *visible-variables*) |
---|
239 | (block (make-block-node '(MULTIPLE-VALUE-BIND))) |
---|
240 | (*blocks* (cons block *blocks*)) |
---|
241 | (varlist (cadr form)) |
---|
242 | (values-form (caddr form)) |
---|
243 | (body (cdddr form))) |
---|
244 | ;; Process the values-form first. ("The scopes of the name binding and |
---|
245 | ;; declarations do not include the values-form.") |
---|
246 | (setf values-form (p1 values-form)) |
---|
247 | (let ((vars ())) |
---|
248 | (dolist (symbol varlist) |
---|
249 | (let ((var (make-variable :name symbol))) |
---|
250 | (push var vars) |
---|
251 | (push var *visible-variables*) |
---|
252 | (push var *all-variables*))) |
---|
253 | ;; Check for globally declared specials. |
---|
254 | (dolist (variable vars) |
---|
255 | (when (special-variable-p (variable-name variable)) |
---|
256 | (setf (variable-special-p variable) t))) |
---|
257 | (setf (block-free-specials block) (process-declarations-for-vars body vars)) |
---|
258 | (setf (block-vars block) (nreverse vars))) |
---|
259 | (setf body (p1-body body)) |
---|
260 | (setf (block-form block) (list* 'MULTIPLE-VALUE-BIND varlist values-form body)) |
---|
261 | block)) |
---|
262 | |
---|
263 | (defun p1-block (form) |
---|
264 | (let* ((block (make-block-node (cadr form))) |
---|
265 | (*blocks* (cons block *blocks*))) |
---|
266 | (setf (cddr form) (p1-body (cddr form))) |
---|
267 | (setf (block-form block) form) |
---|
268 | block)) |
---|
269 | |
---|
270 | (defun p1-catch (form) |
---|
271 | (let* ((tag (p1 (cadr form))) |
---|
272 | (body (cddr form)) |
---|
273 | (result '())) |
---|
274 | (dolist (subform body) |
---|
275 | (let ((op (and (consp subform) (%car subform)))) |
---|
276 | (push (p1 subform) result) |
---|
277 | (when (memq op '(GO RETURN-FROM THROW)) |
---|
278 | (return)))) |
---|
279 | (setf result (nreverse result)) |
---|
280 | (when (and (null (cdr result)) |
---|
281 | (consp (car result)) |
---|
282 | (eq (caar result) 'GO)) |
---|
283 | (return-from p1-catch (car result))) |
---|
284 | (push tag result) |
---|
285 | (push 'CATCH result) |
---|
286 | (let ((block (make-block-node '(CATCH)))) |
---|
287 | (setf (block-form block) result) |
---|
288 | block))) |
---|
289 | |
---|
290 | (defun p1-unwind-protect (form) |
---|
291 | (if (= (length form) 2) |
---|
292 | (p1 (second form)) ; No cleanup forms: (unwind-protect (...)) => (...) |
---|
293 | (let* ((block (make-block-node '(UNWIND-PROTECT))) |
---|
294 | (*blocks* (cons block *blocks*))) |
---|
295 | (setf (block-form block) (p1-default form)) |
---|
296 | block))) |
---|
297 | |
---|
298 | (defknown p1-return-from (t) t) |
---|
299 | (defun p1-return-from (form) |
---|
300 | (let* ((name (second form)) |
---|
301 | (block (find-block name))) |
---|
302 | (when (null block) |
---|
303 | (compiler-error "RETURN-FROM ~S: no block named ~S is currently visible." |
---|
304 | name name)) |
---|
305 | (dformat t "p1-return-from block = ~S~%" (block-name block)) |
---|
306 | (setf (block-return-p block) t) |
---|
307 | (cond ((eq (block-compiland block) *current-compiland*) |
---|
308 | ;; Local case. If the RETURN is nested inside an UNWIND-PROTECT |
---|
309 | ;; which is inside the block we're returning from, we'll do a non- |
---|
310 | ;; local return anyway so that UNWIND-PROTECT can catch it and run |
---|
311 | ;; its cleanup forms. |
---|
312 | (dformat t "*blocks* = ~S~%" (mapcar #'block-name *blocks*)) |
---|
313 | (let ((protected |
---|
314 | (dolist (enclosing-block *blocks*) |
---|
315 | (when (eq enclosing-block block) |
---|
316 | (return nil)) |
---|
317 | (when (equal (block-name enclosing-block) '(UNWIND-PROTECT)) |
---|
318 | (return t))))) |
---|
319 | (dformat t "p1-return-from protected = ~S~%" protected) |
---|
320 | (when protected |
---|
321 | (setf (block-non-local-return-p block) t)))) |
---|
322 | (t |
---|
323 | (setf (block-non-local-return-p block) t))) |
---|
324 | (when (block-non-local-return-p block) |
---|
325 | (dformat t "non-local return from block ~S~%" (block-name block)))) |
---|
326 | (list* 'RETURN-FROM (cadr form) (mapcar #'p1 (cddr form)))) |
---|
327 | |
---|
328 | (defun p1-tagbody (form) |
---|
329 | (let* ((block (make-block-node '(TAGBODY))) |
---|
330 | (*blocks* (cons block *blocks*)) |
---|
331 | (*visible-tags* *visible-tags*) |
---|
332 | (body (cdr form))) |
---|
333 | ;; Make all the tags visible before processing the body forms. |
---|
334 | (dolist (subform body) |
---|
335 | (when (or (symbolp subform) (integerp subform)) |
---|
336 | (let* ((tag (make-tag :name subform :label (gensym) :block block))) |
---|
337 | (push tag *visible-tags*)))) |
---|
338 | (let ((new-body '()) |
---|
339 | (live t)) |
---|
340 | (dolist (subform body) |
---|
341 | (cond ((or (symbolp subform) (integerp subform)) |
---|
342 | (push subform new-body) |
---|
343 | (setf live t)) |
---|
344 | ((not live) |
---|
345 | ;; Nothing to do. |
---|
346 | ) |
---|
347 | (t |
---|
348 | (when (and (consp subform) |
---|
349 | (memq (%car subform) '(GO RETURN-FROM THROW))) |
---|
350 | ;; Subsequent subforms are unreachable until we see another |
---|
351 | ;; tag. |
---|
352 | (setf live nil)) |
---|
353 | (push (p1 subform) new-body)))) |
---|
354 | (setf (block-form block) (list* 'TAGBODY (nreverse new-body)))) |
---|
355 | block)) |
---|
356 | |
---|
357 | (defknown p1-go (t) t) |
---|
358 | (defun p1-go (form) |
---|
359 | (let* ((name (cadr form)) |
---|
360 | (tag (find-tag name))) |
---|
361 | (unless tag |
---|
362 | (error "p1-go: tag not found: ~S" name)) |
---|
363 | (let ((tag-block (tag-block tag))) |
---|
364 | (cond ((eq (tag-compiland tag) *current-compiland*) |
---|
365 | ;; Does the GO leave an enclosing UNWIND-PROTECT? |
---|
366 | (let ((protected |
---|
367 | (dolist (enclosing-block *blocks*) |
---|
368 | (when (eq enclosing-block tag-block) |
---|
369 | (return nil)) |
---|
370 | (when (equal (block-name enclosing-block) '(UNWIND-PROTECT)) |
---|
371 | (return t))))) |
---|
372 | (when protected |
---|
373 | (setf (block-non-local-go-p tag-block) t)))) |
---|
374 | (t |
---|
375 | (setf (block-non-local-go-p tag-block) t))))) |
---|
376 | form) |
---|
377 | |
---|
378 | (defun validate-name-and-lambda-list (name lambda-list context) |
---|
379 | (unless (or (symbolp name) (setf-function-name-p name)) |
---|
380 | (compiler-error "~S is not a valid function name." name)) |
---|
381 | (when (or (memq '&optional lambda-list) |
---|
382 | (memq '&key lambda-list)) |
---|
383 | (let ((state nil)) |
---|
384 | (dolist (arg lambda-list) |
---|
385 | (cond ((memq arg lambda-list-keywords) |
---|
386 | (setf state arg)) |
---|
387 | ((memq state '(&optional &key)) |
---|
388 | (when (and (consp arg) (not (constantp (second arg)))) |
---|
389 | (compiler-unsupported |
---|
390 | "~A: can't handle ~A argument with non-constant initform." |
---|
391 | context |
---|
392 | (if (eq state '&optional) "optional" "keyword"))))))))) |
---|
393 | |
---|
394 | (defmacro with-local-functions-for-flet/labels |
---|
395 | (form local-functions-var lambda-name lambda-list-var name-var body-var body1 body2) |
---|
396 | `(progn (incf (compiland-children *current-compiland*) (length (cadr ,form))) |
---|
397 | (let ((*visible-variables* *visible-variables*) |
---|
398 | (*local-functions* *local-functions*) |
---|
399 | (*current-compiland* *current-compiland*) |
---|
400 | (,local-functions-var '())) |
---|
401 | (dolist (definition (cadr ,form)) |
---|
402 | (let ((,name-var (car definition)) |
---|
403 | (,lambda-list-var (cadr definition))) |
---|
404 | (validate-name-and-lambda-list ,name-var ,lambda-list-var ,lambda-name) |
---|
405 | |
---|
406 | (let* ((,body-var (cddr definition)) |
---|
407 | (compiland (make-compiland :name ,name-var |
---|
408 | :parent *current-compiland*))) |
---|
409 | ,@body1))) |
---|
410 | (setf ,local-functions-var (nreverse ,local-functions-var)) |
---|
411 | ;; Make the local functions visible. |
---|
412 | (dolist (local-function ,local-functions-var) |
---|
413 | (push local-function *local-functions*) |
---|
414 | (let ((variable (local-function-variable local-function))) |
---|
415 | (when variable |
---|
416 | (push variable *visible-variables*)))) |
---|
417 | ,@body2))) |
---|
418 | |
---|
419 | (defun p1-flet (form) |
---|
420 | (with-local-functions-for-flet/labels |
---|
421 | form local-functions 'FLET lambda-list name body |
---|
422 | ((let ((local-function (make-local-function :name name |
---|
423 | :compiland compiland))) |
---|
424 | (multiple-value-bind (body decls) (parse-body body) |
---|
425 | (let* ((block-name (fdefinition-block-name name)) |
---|
426 | (lambda-expression |
---|
427 | `(lambda ,lambda-list ,@decls (block ,block-name ,@body))) |
---|
428 | (*visible-variables* *visible-variables*) |
---|
429 | (*local-functions* *local-functions*) |
---|
430 | (*current-compiland* compiland)) |
---|
431 | (setf (compiland-lambda-expression compiland) lambda-expression) |
---|
432 | (setf (local-function-inline-expansion local-function) |
---|
433 | (generate-inline-expansion block-name lambda-list body)) |
---|
434 | (p1-compiland compiland))) |
---|
435 | (when *closure-variables* |
---|
436 | (let ((variable (make-variable :name (gensym)))) |
---|
437 | (setf (local-function-variable local-function) variable) |
---|
438 | (push variable *all-variables*))) |
---|
439 | (push local-function local-functions))) |
---|
440 | ((with-saved-compiler-policy |
---|
441 | (process-optimization-declarations (cddr form)) |
---|
442 | (list* (car form) local-functions (p1-body (cddr form))))))) |
---|
443 | |
---|
444 | |
---|
445 | (defun p1-labels (form) |
---|
446 | (with-local-functions-for-flet/labels |
---|
447 | form local-functions 'LABELS lambda-list name body |
---|
448 | ((let* ((variable (make-variable :name (gensym))) |
---|
449 | (local-function (make-local-function :name name |
---|
450 | :compiland compiland |
---|
451 | :variable variable))) |
---|
452 | (multiple-value-bind (body decls) (parse-body body) |
---|
453 | (setf (compiland-lambda-expression compiland) |
---|
454 | `(lambda ,lambda-list ,@decls (block ,name ,@body)))) |
---|
455 | (push variable *all-variables*) |
---|
456 | (push local-function local-functions))) |
---|
457 | ((dolist (local-function local-functions) |
---|
458 | (let ((*visible-variables* *visible-variables*) |
---|
459 | (*current-compiland* (local-function-compiland local-function))) |
---|
460 | (p1-compiland (local-function-compiland local-function)))) |
---|
461 | (list* (car form) local-functions (p1-body (cddr form)))))) |
---|
462 | |
---|
463 | (defknown p1-funcall (t) t) |
---|
464 | (defun p1-funcall (form) |
---|
465 | (unless (> (length form) 1) |
---|
466 | (compiler-warn "Wrong number of arguments for ~A." (car form)) |
---|
467 | (return-from p1-funcall form)) |
---|
468 | (let ((function-form (%cadr form))) |
---|
469 | (when (and (consp function-form) |
---|
470 | (eq (%car function-form) 'FUNCTION)) |
---|
471 | (let ((name (%cadr function-form))) |
---|
472 | ;; (format t "p1-funcall name = ~S~%" name) |
---|
473 | (let ((source-transform (source-transform name))) |
---|
474 | (when source-transform |
---|
475 | ;; (format t "found source transform for ~S~%" name) |
---|
476 | ;; (format t "old form = ~S~%" form) |
---|
477 | ;; (let ((new-form (expand-source-transform form))) |
---|
478 | ;; (when (neq new-form form) |
---|
479 | ;; (format t "new form = ~S~%" new-form) |
---|
480 | ;; (return-from p1-funcall (p1 new-form)))) |
---|
481 | (let ((new-form (expand-source-transform (list* name (cddr form))))) |
---|
482 | ;; (format t "new form = ~S~%" new-form) |
---|
483 | (return-from p1-funcall (p1 new-form))) |
---|
484 | ))))) |
---|
485 | ;; Otherwise... |
---|
486 | (p1-function-call form)) |
---|
487 | |
---|
488 | (defun p1-function (form) |
---|
489 | (let ((form (copy-tree form)) |
---|
490 | local-function) |
---|
491 | (cond ((and (consp (cadr form)) |
---|
492 | (or (eq (caadr form) 'LAMBDA) |
---|
493 | (eq (caadr form) 'NAMED-LAMBDA))) |
---|
494 | (let* ((named-lambda-p (eq (caadr form) 'NAMED-LAMBDA)) |
---|
495 | (named-lambda-form (when named-lambda-p |
---|
496 | (cadr form))) |
---|
497 | (name (when named-lambda-p |
---|
498 | (cadr named-lambda-form))) |
---|
499 | (lambda-form (if named-lambda-p |
---|
500 | (cons 'LAMBDA (cddr named-lambda-form)) |
---|
501 | (cadr form))) |
---|
502 | (lambda-list (cadr lambda-form)) |
---|
503 | (body (cddr lambda-form)) |
---|
504 | (compiland (make-compiland :name (if named-lambda-p |
---|
505 | name (gensym "ANONYMOUS-LAMBDA-")) |
---|
506 | :lambda-expression lambda-form |
---|
507 | :parent *current-compiland*))) |
---|
508 | (when *current-compiland* |
---|
509 | (incf (compiland-children *current-compiland*))) |
---|
510 | (multiple-value-bind (body decls) |
---|
511 | (parse-body body) |
---|
512 | (setf (compiland-lambda-expression compiland) |
---|
513 | (if named-lambda-p |
---|
514 | `(lambda ,lambda-list ,@decls (block nil ,@body)) |
---|
515 | `(lambda ,lambda-list ,@decls ,@body))) |
---|
516 | (let ((*visible-variables* *visible-variables*) |
---|
517 | (*current-compiland* compiland)) |
---|
518 | (p1-compiland compiland))) |
---|
519 | (list 'FUNCTION compiland))) |
---|
520 | ((setf local-function (find-local-function (cadr form))) |
---|
521 | (dformat t "p1-function local function ~S~%" (cadr form)) |
---|
522 | (let ((variable (local-function-variable local-function))) |
---|
523 | (when variable |
---|
524 | (dformat t "p1-function ~S used non-locally~%" (variable-name variable)) |
---|
525 | (setf (variable-used-non-locally-p variable) t))) |
---|
526 | form) |
---|
527 | (t |
---|
528 | form)))) |
---|
529 | |
---|
530 | (defun p1-lambda (form) |
---|
531 | (let* ((lambda-list (cadr form)) |
---|
532 | (body (cddr form)) |
---|
533 | (auxvars (memq '&AUX lambda-list))) |
---|
534 | (when (or (memq '&optional lambda-list) |
---|
535 | (memq '&key lambda-list)) |
---|
536 | (let ((state nil)) |
---|
537 | (dolist (arg lambda-list) |
---|
538 | (cond ((memq arg lambda-list-keywords) |
---|
539 | (setf state arg)) |
---|
540 | ((memq state '(&optional &key)) |
---|
541 | (when (and (consp arg) |
---|
542 | (not (constantp (second arg)))) |
---|
543 | (compiler-unsupported |
---|
544 | "P1-LAMBDA: can't handle optional argument with non-constant initform."))))))) |
---|
545 | (when auxvars |
---|
546 | (setf lambda-list (subseq lambda-list 0 (position '&AUX lambda-list))) |
---|
547 | (setf body (list (append (list 'LET* (cdr auxvars)) body)))) |
---|
548 | (p1-function (list 'FUNCTION (list* 'LAMBDA lambda-list body))))) |
---|
549 | |
---|
550 | (defun p1-eval-when (form) |
---|
551 | (list* (car form) (cadr form) (mapcar #'p1 (cddr form)))) |
---|
552 | |
---|
553 | (defknown p1-progv (t) t) |
---|
554 | (defun p1-progv (form) |
---|
555 | ;; We've already checked argument count in PRECOMPILE-PROGV. |
---|
556 | (let ((new-form (rewrite-progv form))) |
---|
557 | (when (neq new-form form) |
---|
558 | (return-from p1-progv (p1 new-form)))) |
---|
559 | (let ((symbols-form (cadr form)) |
---|
560 | (values-form (caddr form)) |
---|
561 | (body (cdddr form))) |
---|
562 | `(progv ,(p1 symbols-form) ,(p1 values-form) ,@(p1-body body)))) |
---|
563 | |
---|
564 | (defknown rewrite-progv (t) t) |
---|
565 | (defun rewrite-progv (form) |
---|
566 | (let ((symbols-form (cadr form)) |
---|
567 | (values-form (caddr form)) |
---|
568 | (body (cdddr form))) |
---|
569 | (cond ((or (unsafe-p symbols-form) (unsafe-p values-form)) |
---|
570 | (let ((g1 (gensym)) |
---|
571 | (g2 (gensym))) |
---|
572 | `(let ((,g1 ,symbols-form) |
---|
573 | (,g2 ,values-form)) |
---|
574 | (progv ,g1 ,g2 ,@body)))) |
---|
575 | (t |
---|
576 | form)))) |
---|
577 | |
---|
578 | (defun p1-quote (form) |
---|
579 | (unless (= (length form) 2) |
---|
580 | (compiler-error "Wrong number of arguments for special operator ~A (expected 1, but received ~D)." |
---|
581 | 'QUOTE |
---|
582 | (1- (length form)))) |
---|
583 | (let ((arg (%cadr form))) |
---|
584 | (if (or (numberp arg) (characterp arg)) |
---|
585 | arg |
---|
586 | form))) |
---|
587 | |
---|
588 | (defun p1-setq (form) |
---|
589 | (unless (= (length form) 3) |
---|
590 | (error "Too many arguments for SETQ.")) |
---|
591 | (let ((arg1 (%cadr form)) |
---|
592 | (arg2 (%caddr form))) |
---|
593 | (let ((variable (find-visible-variable arg1))) |
---|
594 | (if variable |
---|
595 | (progn |
---|
596 | (when (variable-ignore-p variable) |
---|
597 | (compiler-style-warn |
---|
598 | "Variable ~S is assigned even though it was declared to be ignored." |
---|
599 | (variable-name variable))) |
---|
600 | (incf (variable-writes variable)) |
---|
601 | (cond ((eq (variable-compiland variable) *current-compiland*) |
---|
602 | (dformat t "p1-setq: write ~S~%" arg1)) |
---|
603 | (t |
---|
604 | (dformat t "p1-setq: non-local write ~S~%" arg1) |
---|
605 | (setf (variable-used-non-locally-p variable) t)))) |
---|
606 | (dformat t "p1-setq: unknown variable ~S~%" arg1))) |
---|
607 | (list 'SETQ arg1 (p1 arg2)))) |
---|
608 | |
---|
609 | (defun p1-the (form) |
---|
610 | (unless (= (length form) 3) |
---|
611 | (compiler-error "Wrong number of arguments for special operator ~A (expected 2, but received ~D)." |
---|
612 | 'THE |
---|
613 | (1- (length form)))) |
---|
614 | (let ((type (%cadr form)) |
---|
615 | (expr (%caddr form))) |
---|
616 | (cond ((and (listp type) (eq (car type) 'VALUES)) |
---|
617 | ;; FIXME |
---|
618 | (p1 expr)) |
---|
619 | ((= *safety* 3) |
---|
620 | (let* ((sym (gensym)) |
---|
621 | (new-expr `(let ((,sym ,expr)) |
---|
622 | (require-type ,sym ',type) |
---|
623 | ,sym))) |
---|
624 | (p1 new-expr))) |
---|
625 | (t |
---|
626 | (list 'THE type (p1 expr)))))) |
---|
627 | |
---|
628 | (defun p1-truly-the (form) |
---|
629 | (unless (= (length form) 3) |
---|
630 | (compiler-error "Wrong number of arguments for special operator ~A (expected 2, but received ~D)." |
---|
631 | 'TRULY-THE |
---|
632 | (1- (length form)))) |
---|
633 | (list 'TRULY-THE (%cadr form) (p1 (%caddr form)))) |
---|
634 | |
---|
635 | (defknown unsafe-p (t) t) |
---|
636 | (defun unsafe-p (args) |
---|
637 | (cond ((node-p args) |
---|
638 | (unsafe-p (node-form args))) |
---|
639 | ((atom args) |
---|
640 | nil) |
---|
641 | (t |
---|
642 | (case (%car args) |
---|
643 | (QUOTE |
---|
644 | nil) |
---|
645 | (LAMBDA |
---|
646 | nil) |
---|
647 | ((RETURN-FROM GO CATCH THROW UNWIND-PROTECT BLOCK) |
---|
648 | t) |
---|
649 | (t |
---|
650 | (dolist (arg args) |
---|
651 | (when (unsafe-p arg) |
---|
652 | (return t)))))))) |
---|
653 | |
---|
654 | (defknown rewrite-throw (t) t) |
---|
655 | (defun rewrite-throw (form) |
---|
656 | (let ((args (cdr form))) |
---|
657 | (if (unsafe-p args) |
---|
658 | (let ((syms ()) |
---|
659 | (lets ())) |
---|
660 | ;; Tag. |
---|
661 | (let ((arg (first args))) |
---|
662 | (if (constantp arg) |
---|
663 | (push arg syms) |
---|
664 | (let ((sym (gensym))) |
---|
665 | (push sym syms) |
---|
666 | (push (list sym arg) lets)))) |
---|
667 | ;; Result. "If the result-form produces multiple values, then all the |
---|
668 | ;; values are saved." |
---|
669 | (let ((arg (second args))) |
---|
670 | (if (constantp arg) |
---|
671 | (push arg syms) |
---|
672 | (let ((sym (gensym))) |
---|
673 | (cond ((single-valued-p arg) |
---|
674 | (push sym syms) |
---|
675 | (push (list sym arg) lets)) |
---|
676 | (t |
---|
677 | (push (list 'VALUES-LIST sym) syms) |
---|
678 | (push (list sym (list 'MULTIPLE-VALUE-LIST arg)) lets)))))) |
---|
679 | (list 'LET* (nreverse lets) (list* 'THROW (nreverse syms)))) |
---|
680 | form))) |
---|
681 | |
---|
682 | (defknown p1-throw (t) t) |
---|
683 | (defun p1-throw (form) |
---|
684 | (let ((new-form (rewrite-throw form))) |
---|
685 | (when (neq new-form form) |
---|
686 | (return-from p1-throw (p1 new-form)))) |
---|
687 | (list* 'THROW (mapcar #'p1 (cdr form)))) |
---|
688 | |
---|
689 | (defknown rewrite-function-call (t) t) |
---|
690 | (defun rewrite-function-call (form) |
---|
691 | (let ((args (cdr form))) |
---|
692 | (if (unsafe-p args) |
---|
693 | (let ((arg1 (car args))) |
---|
694 | (cond ((and (consp arg1) (eq (car arg1) 'GO)) |
---|
695 | arg1) |
---|
696 | (t |
---|
697 | (let ((syms ()) |
---|
698 | (lets ())) |
---|
699 | ;; Preserve the order of evaluation of the arguments! |
---|
700 | (dolist (arg args) |
---|
701 | (cond ((constantp arg) |
---|
702 | (push arg syms)) |
---|
703 | ((and (consp arg) (eq (car arg) 'GO)) |
---|
704 | (return-from rewrite-function-call |
---|
705 | (list 'LET* (nreverse lets) arg))) |
---|
706 | (t |
---|
707 | (let ((sym (gensym))) |
---|
708 | (push sym syms) |
---|
709 | (push (list sym arg) lets))))) |
---|
710 | (list 'LET* (nreverse lets) (list* (car form) (nreverse syms))))))) |
---|
711 | form))) |
---|
712 | |
---|
713 | (defknown p1-function-call (t) t) |
---|
714 | (defun p1-function-call (form) |
---|
715 | (let ((new-form (rewrite-function-call form))) |
---|
716 | (when (neq new-form form) |
---|
717 | ;; (let ((*print-structure* nil)) |
---|
718 | ;; (format t "old form = ~S~%" form) |
---|
719 | ;; (format t "new form = ~S~%" new-form)) |
---|
720 | (return-from p1-function-call (p1 new-form)))) |
---|
721 | (let* ((op (car form)) |
---|
722 | (local-function (find-local-function op))) |
---|
723 | (cond (local-function |
---|
724 | ;; (format t "p1 local call to ~S~%" op) |
---|
725 | ;; (format t "inline-p = ~S~%" (inline-p op)) |
---|
726 | |
---|
727 | (when (and *enable-inline-expansion* (inline-p op)) |
---|
728 | (let ((expansion (local-function-inline-expansion local-function))) |
---|
729 | (when expansion |
---|
730 | (let ((explain *explain*)) |
---|
731 | (when (and explain (memq :calls explain)) |
---|
732 | (format t "; inlining call to local function ~S~%" op))) |
---|
733 | (return-from p1-function-call (p1 (expand-inline form expansion)))))) |
---|
734 | |
---|
735 | ;; FIXME |
---|
736 | (dformat t "local function assumed not single-valued~%") |
---|
737 | (setf (compiland-%single-valued-p *current-compiland*) nil) |
---|
738 | |
---|
739 | (let ((variable (local-function-variable local-function))) |
---|
740 | (when variable |
---|
741 | (dformat t "p1 ~S used non-locally~%" (variable-name variable)) |
---|
742 | (setf (variable-used-non-locally-p variable) t)))) |
---|
743 | (t |
---|
744 | ;; Not a local function call. |
---|
745 | (dformat t "p1 non-local call to ~S~%" op) |
---|
746 | (unless (single-valued-p form) |
---|
747 | ;; (format t "not single-valued op = ~S~%" op) |
---|
748 | (setf (compiland-%single-valued-p *current-compiland*) nil))))) |
---|
749 | (p1-default form)) |
---|
750 | |
---|
751 | (defknown p1 (t) t) |
---|
752 | (defun p1 (form) |
---|
753 | (cond ((symbolp form) |
---|
754 | (let (value) |
---|
755 | (cond ((null form) |
---|
756 | form) |
---|
757 | ((eq form t) |
---|
758 | form) |
---|
759 | ((keywordp form) |
---|
760 | form) |
---|
761 | ((and (constantp form) |
---|
762 | (progn |
---|
763 | (setf value (symbol-value form)) |
---|
764 | (or (numberp value) |
---|
765 | (stringp value) |
---|
766 | (pathnamep value)))) |
---|
767 | (setf form value)) |
---|
768 | (t |
---|
769 | (let ((variable (find-visible-variable form))) |
---|
770 | (when (null variable) |
---|
771 | (unless (or (special-variable-p form) |
---|
772 | (memq form *undefined-variables*)) |
---|
773 | (compiler-style-warn "Undefined variable: ~S" form) |
---|
774 | (push form *undefined-variables*)) |
---|
775 | (setf variable (make-variable :name form :special-p t)) |
---|
776 | (push variable *visible-variables*)) |
---|
777 | (let ((ref (make-var-ref variable))) |
---|
778 | (unless (variable-special-p variable) |
---|
779 | (when (variable-ignore-p variable) |
---|
780 | (compiler-style-warn |
---|
781 | "Variable ~S is read even though it was declared to be ignored." |
---|
782 | (variable-name variable))) |
---|
783 | (push ref (variable-references variable)) |
---|
784 | (incf (variable-reads variable)) |
---|
785 | (cond ((eq (variable-compiland variable) *current-compiland*) |
---|
786 | (dformat t "p1: read ~S~%" form)) |
---|
787 | (t |
---|
788 | (dformat t "p1: non-local read ~S variable-compiland = ~S current compiland = ~S~%" |
---|
789 | form |
---|
790 | (compiland-name (variable-compiland variable)) |
---|
791 | (compiland-name *current-compiland*)) |
---|
792 | (setf (variable-used-non-locally-p variable) t)))) |
---|
793 | (setf form ref))) |
---|
794 | form)))) |
---|
795 | ((atom form) |
---|
796 | form) |
---|
797 | (t |
---|
798 | (let ((op (%car form)) |
---|
799 | handler) |
---|
800 | (cond ((symbolp op) |
---|
801 | (when (compiler-macro-function op) |
---|
802 | (unless (notinline-p op) |
---|
803 | (multiple-value-bind (expansion expanded-p) |
---|
804 | (compiler-macroexpand form) |
---|
805 | ;; Fall through if no change... |
---|
806 | (when expanded-p |
---|
807 | (return-from p1 (p1 expansion)))))) |
---|
808 | (cond ((setf handler (get op 'p1-handler)) |
---|
809 | (funcall handler form)) |
---|
810 | ((macro-function op *compile-file-environment*) |
---|
811 | (p1 (macroexpand form *compile-file-environment*))) |
---|
812 | ((special-operator-p op) |
---|
813 | (compiler-unsupported "P1: unsupported special operator ~S" op)) |
---|
814 | (t |
---|
815 | (p1-function-call form)))) |
---|
816 | ((and (consp op) (eq (%car op) 'LAMBDA)) |
---|
817 | (p1 (list* 'FUNCALL form))) |
---|
818 | (t |
---|
819 | form)))))) |
---|
820 | |
---|
821 | (defun install-p1-handler (symbol handler) |
---|
822 | (setf (get symbol 'p1-handler) handler)) |
---|
823 | |
---|
824 | (defun initialize-p1-handlers () |
---|
825 | (dolist (pair '((AND p1-default) |
---|
826 | (BLOCK p1-block) |
---|
827 | (CATCH p1-catch) |
---|
828 | (DECLARE identity) |
---|
829 | (EVAL-WHEN p1-eval-when) |
---|
830 | (FLET p1-flet) |
---|
831 | (FUNCALL p1-funcall) |
---|
832 | (FUNCTION p1-function) |
---|
833 | (GO p1-go) |
---|
834 | (IF p1-if) |
---|
835 | (LABELS p1-labels) |
---|
836 | (LAMBDA p1-lambda) |
---|
837 | (LET p1-let/let*) |
---|
838 | (LET* p1-let/let*) |
---|
839 | (LOAD-TIME-VALUE identity) |
---|
840 | (LOCALLY p1-locally) |
---|
841 | (MULTIPLE-VALUE-BIND p1-m-v-b) |
---|
842 | (MULTIPLE-VALUE-CALL p1-default) |
---|
843 | (MULTIPLE-VALUE-LIST p1-default) |
---|
844 | (MULTIPLE-VALUE-PROG1 p1-default) |
---|
845 | (OR p1-default) |
---|
846 | (PROGN p1-default) |
---|
847 | (PROGV p1-progv) |
---|
848 | (QUOTE p1-quote) |
---|
849 | (RETURN-FROM p1-return-from) |
---|
850 | (SETQ p1-setq) |
---|
851 | (SYMBOL-MACROLET identity) |
---|
852 | (TAGBODY p1-tagbody) |
---|
853 | (THE p1-the) |
---|
854 | (THROW p1-throw) |
---|
855 | (TRULY-THE p1-truly-the) |
---|
856 | (UNWIND-PROTECT p1-unwind-protect))) |
---|
857 | (install-p1-handler (%car pair) (%cadr pair)))) |
---|
858 | |
---|
859 | (initialize-p1-handlers) |
---|
860 | |
---|
861 | (defun invoke-compile-xep (xep-lambda-expression compiland) |
---|
862 | (let ((xep-compiland |
---|
863 | (make-compiland :lambda-expression |
---|
864 | (precompile-form xep-lambda-expression t) |
---|
865 | :class-file (compiland-class-file compiland)))) |
---|
866 | (compile-xep xep-compiland))) |
---|
867 | |
---|
868 | (defun p1-compiland (compiland) |
---|
869 | ;; (format t "p1-compiland name = ~S~%" (compiland-name compiland)) |
---|
870 | (let ((form (compiland-lambda-expression compiland))) |
---|
871 | (aver (eq (car form) 'LAMBDA)) |
---|
872 | (process-optimization-declarations (cddr form)) |
---|
873 | |
---|
874 | (let* ((lambda-list (cadr form)) |
---|
875 | (body (cddr form)) |
---|
876 | (auxvars (memq '&AUX lambda-list))) |
---|
877 | (when auxvars |
---|
878 | (setf lambda-list (subseq lambda-list 0 (position '&AUX lambda-list))) |
---|
879 | (setf body (list (append (list 'LET* (cdr auxvars)) body)))) |
---|
880 | |
---|
881 | (when (and (null (compiland-parent compiland)) |
---|
882 | ;; FIXME support SETF functions! |
---|
883 | (symbolp (compiland-name compiland))) |
---|
884 | (when (memq '&OPTIONAL lambda-list) |
---|
885 | (unless (or (memq '&KEY lambda-list) (memq '&REST lambda-list)) |
---|
886 | (let ((required-args (subseq lambda-list 0 (position '&OPTIONAL lambda-list))) |
---|
887 | (optional-args (cdr (memq '&OPTIONAL lambda-list)))) |
---|
888 | (dformat t "optional-args = ~S~%" optional-args) |
---|
889 | (when (= (length optional-args) 1) |
---|
890 | (let* ((optional-arg (car optional-args)) |
---|
891 | (name (if (consp optional-arg) (%car optional-arg) optional-arg)) |
---|
892 | (initform (if (consp optional-arg) (cadr optional-arg) nil)) |
---|
893 | (supplied-p-var (and (consp optional-arg) |
---|
894 | (= (length optional-arg) 3) |
---|
895 | (third optional-arg))) |
---|
896 | (all-args |
---|
897 | (append required-args (list name) |
---|
898 | (when supplied-p-var (list supplied-p-var))))) |
---|
899 | (when (<= (length all-args) call-registers-limit) |
---|
900 | (dformat t "optional-arg = ~S~%" optional-arg) |
---|
901 | (dformat t "supplied-p-var = ~S~%" supplied-p-var) |
---|
902 | (dformat t "required-args = ~S~%" required-args) |
---|
903 | (dformat t "all-args = ~S~%" all-args) |
---|
904 | (cond (supplied-p-var |
---|
905 | (let ((xep-lambda-expression |
---|
906 | `(lambda ,required-args |
---|
907 | (let* ((,name ,initform) |
---|
908 | (,supplied-p-var nil)) |
---|
909 | (%call-internal ,@all-args))))) |
---|
910 | (dformat t "xep-lambda-expression = ~S~%" xep-lambda-expression) |
---|
911 | (invoke-compile-xep xep-lambda-expression compiland)) |
---|
912 | (let ((xep-lambda-expression |
---|
913 | `(lambda ,(append required-args (list name)) |
---|
914 | (let* ((,supplied-p-var t)) |
---|
915 | (%call-internal ,@all-args))))) |
---|
916 | (dformat t "xep-lambda-expression = ~S~%" xep-lambda-expression) |
---|
917 | (invoke-compile-xep xep-lambda-expression compiland)) |
---|
918 | (setf lambda-list all-args) |
---|
919 | (setf (compiland-kind compiland) :internal)) |
---|
920 | (t |
---|
921 | (let ((xep-lambda-expression |
---|
922 | `(lambda ,required-args |
---|
923 | (let* ((,name ,initform)) |
---|
924 | (,(compiland-name compiland) ,@all-args))))) |
---|
925 | (dformat t "xep-lambda-expression = ~S~%" xep-lambda-expression) |
---|
926 | (invoke-compile-xep xep-lambda-expression compiland)) |
---|
927 | (setf lambda-list all-args)))))))))) |
---|
928 | |
---|
929 | (let* ((closure (make-closure `(lambda ,lambda-list nil) nil)) |
---|
930 | (syms (sys::varlist closure)) |
---|
931 | (vars nil)) |
---|
932 | (dolist (sym syms) |
---|
933 | (let ((var (make-variable :name sym |
---|
934 | :special-p (special-variable-p sym)))) |
---|
935 | (push var vars) |
---|
936 | (push var *all-variables*))) |
---|
937 | (setf (compiland-arg-vars compiland) (nreverse vars)) |
---|
938 | (let ((*visible-variables* *visible-variables*)) |
---|
939 | (dolist (var (compiland-arg-vars compiland)) |
---|
940 | (push var *visible-variables*)) |
---|
941 | (let ((free-specials (process-declarations-for-vars body *visible-variables*))) |
---|
942 | (dolist (var free-specials) |
---|
943 | (push var *visible-variables*))) |
---|
944 | (setf (compiland-p1-result compiland) |
---|
945 | (list* 'LAMBDA lambda-list (p1-body body)))))))) |
---|
946 | |
---|
947 | (provide "COMPILER-PASS1") |
---|