source: trunk/source/lib/level-2.lisp @ 12535

Last change on this file since 12535 was 12535, checked in by gz, 10 years ago

Merge r12534

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.2 KB
Line 
1;;;-*-Mode: LISP; Package: CCL -*-
2;;;
3;;;   Copyright (C) 1994-2001 Digitool, Inc
4;;;   This file is part of OpenMCL. 
5;;;
6;;;   OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
7;;;   License , known as the LLGPL and distributed with OpenMCL as the
8;;;   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
9;;;   which is distributed with OpenMCL as the file "LGPL".  Where these
10;;;   conflict, the preamble takes precedence. 
11;;;
12;;;   OpenMCL is referenced in the preamble as the "LIBRARY."
13;;;
14;;;   The LLGPL is also available online at
15;;;   http://opensource.franz.com/preamble.html
16
17;; Level-2.lisp
18
19(in-package "CCL")
20
21(eval-when (eval compile)
22  (require "LEVEL-2")
23  (require "BACKQUOTE")
24  (require "DEFSTRUCT-MACROS"))
25
26
27
28(eval-when (eval compile)
29  (require "LISPEQU"))
30
31
32
33
34
35
36
37
38; This incredibly essential thing is part of ANSI CL; put it in the
39; right package someday.
40; Like maybe when it says something about doc strings, or otherwise
41; becomes useful.
42
43(defun parse-macro (name arglist body &optional env)
44  (values (parse-macro-1 name arglist body env)))
45
46; Return a list containing a special declaration for SYM
47; if SYM is declared special in decls.
48; This is so we can be pedantic about binding &WHOLE/&ENVIRONMENT args
49; that have been scarfed out of a macro-like lambda list.
50; The returned value is supposed to be suitable for splicing ...
51#+not-used
52(defun hoist-special-decls (sym decls)
53  (when sym
54    (dolist (decl decls)
55      (dolist (spec (cdr decl))
56        (when (eq (car spec) 'special)
57          (dolist (s (%cdr spec))
58            (when (eq s sym)
59              (return-from hoist-special-decls `((declare (special ,sym)))))))))))
60
61(defun parse-macro-1 (name arglist body &optional env)
62  (parse-macro-internal name arglist body env nil))
63
64(defun parse-macro-internal (name arglist body env default-initial-value)
65  (unless (verify-lambda-list arglist t t t)
66    (error "Invalid lambda list ~s" arglist))
67  (multiple-value-bind (lambda-list whole environment)
68      (normalize-lambda-list arglist t t)
69    (multiple-value-bind (body local-decs doc)
70        (parse-body body env t)
71      (let ((whole-var (gensym "WHOLE"))
72            (env-var (gensym "ENVIRONMENT")))
73        (multiple-value-bind (bindings binding-decls)
74            (%destructure-lambda-list lambda-list whole-var nil nil
75                                      :cdr-p t
76                                      :whole-p nil
77                                      :use-whole-var t
78                                      :default-initial-value default-initial-value)
79          (when environment
80            (setq bindings (nconc bindings (list `(,environment ,env-var)))))
81          (when whole
82            (setq bindings (nconc bindings (list `(,whole ,whole-var)))))
83          (values
84            `(lambda (,whole-var ,env-var)
85               (declare (ignorable ,whole-var ,env-var))
86               (block ,name
87                 (let* ,(nreverse bindings)
88                   ,@(when binding-decls `((declare ,@binding-decls)))
89                   ,@local-decs
90                   ,@body)))
91            doc))))))
92
93
94(defun %destructure-lambda-list (lambda-list wholeform  lets decls
95                                             &key cdr-p (whole-p t) use-whole-var default-initial-value)
96  (unless (and (listp lambda-list)
97               (verify-lambda-list lambda-list t whole-p))
98    (signal-simple-program-error "Invalid lambda list: ~s" lambda-list))
99  (multiple-value-bind (normalized whole) (normalize-lambda-list
100                                           lambda-list whole-p)
101    (let* ((argstate :required)
102           (allow-other-keys nil)
103           (rest-arg-name nil)
104           (w (if use-whole-var wholeform (or whole (gensym "WHOLE"))))
105           (argptr (gensym "ARGS"))
106           (has-&key nil)
107           (most-recent-binding nil)
108           (keywords ())
109           (first-keyword-init ())
110           (restp nil))
111      (labels ((simple-var (var &optional (initform `,default-initial-value))
112                 (let* ((binding `(,var ,initform)))
113                   (unless (eq argstate :aux)
114                     (setq most-recent-binding binding))
115                   (push  binding lets)
116                   binding))
117               (structured-var (context sub-lambda-list initform)
118                 (let* ((v (gensym (string context))))
119                   (simple-var v initform)
120                   (multiple-value-setq (lets decls)
121                     (%destructure-lambda-list
122                      sub-lambda-list
123                      v
124                      lets
125                      decls
126                      :default-initial-value default-initial-value
127))
128                   v)))
129        (unless use-whole-var
130          (if (atom w)
131            (simple-var w wholeform)
132            (progn
133              (setq w (structured-var "WHOLE" w (if cdr-p `(cdr ,wholeform) wholeform))
134                    cdr-p nil))))
135        (simple-var argptr `(make-destructure-state ,@(if cdr-p `((cdr ,w)) `(,w)) ,w ',lambda-list))
136        (setq most-recent-binding nil)
137        (push `(dynamic-extent ,argptr) decls)
138        (do* ((tail normalized (cdr tail)))
139             ((null tail)
140              (if has-&key
141                (let* ((key-check-form `(check-keywords
142                                         ',(nreverse keywords)
143                                         ,rest-arg-name ,allow-other-keys)))
144                  (if first-keyword-init
145                    (rplaca (cdr first-keyword-init)
146                            `(progn
147                              ,key-check-form
148                              ,(cadr first-keyword-init)))
149                    (let* ((check-var (gensym "CHECK")))
150                      (push `(ignorable ,check-var) decls)
151                      (simple-var check-var key-check-form))))
152                (unless restp
153                  (let* ((checkform `(%check-extra-arguments ,argptr))
154                         (b most-recent-binding)
155                         (b-init (cadr b)))
156                    (if b
157                      (rplaca (cdr b) `(prog1 ,b-init ,checkform))
158                      (let* ((junk (gensym "JUNK")))
159                        (simple-var junk checkform)
160                        (push `(ignorable ,junk) decls))))))
161              (values lets decls))
162          (let* ((var (car tail)))
163            (cond ((or (eq var '&rest) (eq var '&body))
164                   (let* ((r (cadr tail))
165                          (init `(destructure-state.current ,argptr)))
166                     (if (listp r)
167                       (setq rest-arg-name
168                             (structured-var "REST" r init))
169                       (progn
170                         (setq rest-arg-name (gensym "REST"))
171                         (simple-var rest-arg-name init)
172                         (simple-var r rest-arg-name ))))
173                   (setq restp t)
174                   (setq tail (cdr tail)))
175                  ((eq var '&optional) (setq argstate :optional))
176                  ((eq var '&key)
177                   (setq argstate :key)
178                   (setq has-&key t)
179                   (unless restp
180                     (setq restp t
181                           rest-arg-name (gensym "KEYS"))
182                     (push `(ignorable ,rest-arg-name) decls)
183                     (simple-var rest-arg-name
184                                 `(destructure-state.current ,argptr))))
185                  ((eq var '&allow-other-keys)
186                   (setq allow-other-keys t))
187                  ((eq var '&aux)
188                   (setq argstate :aux))
189                  ((listp var)
190                   (case argstate
191                     (:required
192                      (structured-var "REQ" var `(%pop-required-arg-ptr ,argptr)))
193                     (:optional
194                      (let* ((variable (car var))
195                             (initform (if (cdr var)
196                                         (cadr var)
197                                         `,default-initial-value))
198                             (spvar (if (cddr var)
199                                      (caddr var)
200                                      (gensym "OPT-SUPPLIED-P")))
201                             (varinit `(if ,spvar
202                                        (%default-optional-value ,argptr)
203                                        ,initform)))
204                        (simple-var spvar
205                                    `(not (null (destructure-state.current ,argptr))))
206                        (if (listp variable)
207                          (structured-var "OPT" variable varinit)
208                          (simple-var variable varinit))))
209                     (:key
210                      (let* ((explicit-key (consp (car var)))
211                             (variable (if explicit-key
212                                         (cadar var)
213                                         (car var)))
214                             (keyword (if explicit-key
215                                        (caar var)
216                                        (make-keyword variable)))
217                             (initform (if (cdr var)
218                                         (cadr var)
219                                         `,default-initial-value))
220                             (spvar (if (cddr var)
221                                      (caddr var)
222                                      (gensym "KEY-SUPPLIED-P"))))
223                        (push keyword keywords)
224                        (let* ((sp-init (simple-var spvar
225                                                    `(%keyword-present-p
226                                                      ,rest-arg-name
227                                                      ',keyword)))
228                               (var-init `(if ,spvar
229                                           (getf ,rest-arg-name ',keyword)
230                                           ,initform)))
231                          (unless first-keyword-init
232                            (setq first-keyword-init sp-init))
233                          (if (listp variable)
234                            (structured-var "KEY" variable var-init)
235                            (simple-var variable var-init)))))
236                     (:aux
237                      (simple-var (car var) (cadr var)))
238                     (t (error "NYI: ~s" argstate))))
239                  ((symbolp var)
240                   (case argstate
241                     (:required
242                      (simple-var var `(%pop-required-arg-ptr ,argptr)))
243                     (:optional
244                      (simple-var var `(%default-optional-value ,argptr
245                                        ',default-initial-value)))
246                     (:key
247                      (let* ((keyword (make-keyword var)))
248                        (push keyword keywords)
249                        (let* ((init (simple-var
250                                      var
251                                      `(getf ,rest-arg-name
252                                        ',keyword
253                                        ,@(if default-initial-value
254                                             `(',default-initial-value))))))
255                          (unless first-keyword-init
256                            (setq first-keyword-init init)))))
257                     (:aux
258                      (simple-var var)))))))))))
259
260
261
262
263
264
265(defun apply-to-htab-syms (function pkg-vector)
266  (let* ((sym nil)
267         (foundp nil))
268    (dotimes (i (uvsize pkg-vector))
269      (declare (fixnum i))
270      (multiple-value-setq (sym foundp) (%htab-symbol pkg-vector i))
271      (when foundp (funcall function sym)))))
272
273(defun iterate-over-external-symbols (pkg-spec function)
274  (apply-to-htab-syms function (car (pkg.etab (pkg-arg (or pkg-spec *package*))))))
275
276(defun iterate-over-present-symbols (pkg-spec function)
277  (let ((pkg (pkg-arg (or pkg-spec *package*))))
278    (apply-to-htab-syms function (car (pkg.etab pkg)))
279    (apply-to-htab-syms function (car (pkg.itab pkg)))))
280
281(defun iterate-over-accessable-symbols (pkg-spec function)
282  (let* ((pkg (pkg-arg (or pkg-spec *package*)))
283         (used (pkg.used pkg))
284         (shadowed (pkg.shadowed pkg)))
285    (iterate-over-present-symbols pkg function)
286    (when used
287      (if shadowed
288        (flet ((ignore-shadowed-conflicts (var)
289                 (unless (%name-present-in-package-p (symbol-name var) pkg)
290                   (funcall function var))))
291          (declare (dynamic-extent #'ignore-shadowed-conflicts))
292          (dolist (u used) (iterate-over-external-symbols u #'ignore-shadowed-conflicts)))
293        (dolist (u used) (iterate-over-external-symbols u function))))))
294
295(defun iterate-over-all-symbols (function)
296  (dolist (pkg %all-packages%)
297    (iterate-over-present-symbols pkg function)))         
298
299
300
301;;;Eval definitions for things open-coded by the compiler.
302;;;Don't use DEFUN since it should be illegal to DEFUN compiler special forms...
303;;;Of course, these aren't special forms.
304(macrolet ((%eval-redef (name vars &rest body)
305             (when (null body) (setq body `((,name ,@vars))))
306             `(setf (symbol-function ',name)
307                    (qlfun ,name ,vars ,@body))))
308  (declare (optimize (speed 1) (safety 1)))
309  (%eval-redef %ilsl (n x))
310  (%eval-redef %ilsr (n x))
311  (%eval-redef neq (x y))
312  (%eval-redef not (x))
313  (%eval-redef null (x))
314  (%eval-redef rplaca (x y))
315  (%eval-redef rplacd (x y))
316  (%eval-redef set-car (x y))
317  (%eval-redef set-cdr (x y))
318  (%eval-redef int>0-p (x))
319  (%eval-redef %get-byte (ptr &optional (offset 0)) (%get-byte ptr offset))
320  (%eval-redef %get-word (ptr &optional (offset 0)) (%get-word ptr offset))
321  (%eval-redef %get-signed-byte (ptr &optional (offset 0)) (%get-signed-byte ptr offset))
322  (%eval-redef %get-signed-word (ptr &optional (offset 0)) (%get-signed-word ptr offset))
323  (%eval-redef %get-long (ptr &optional (offset 0)) (%get-long ptr offset))
324  (%eval-redef %get-fixnum (ptr &optional (offset 0)) (%get-fixnum ptr offset))
325  (%eval-redef %get-signed-long (ptr &optional (offset 0)) (%get-signed-long ptr offset))
326  (%eval-redef %get-unsigned-long (ptr &optional (offset 0)) (%get-unsigned-long ptr offset))
327  (%eval-redef %get-ptr (ptr &optional (offset 0)) (%get-ptr ptr offset))
328  (%eval-redef %get-full-long (ptr &optional (offset 0)) (%get-full-long ptr offset))
329  (%eval-redef %int-to-ptr (int))
330  (%eval-redef %ptr-to-int (ptr))
331  (%eval-redef %ptr-eql (ptr1 ptr2))
332  (%eval-redef %setf-macptr (ptr1 ptr2))
333  (%eval-redef %null-ptr-p (ptr))
334
335
336  (%eval-redef %iasr (x y))
337
338 
339  (%eval-redef %set-byte (p o &optional (new (prog1 o (setq o 0))))
340               (%set-byte p o new))
341  (%eval-redef %set-unsigned-byte (p o &optional (new (prog1 o (setq o 0))))
342               (%set-unsigned-byte p o new))
343  (%eval-redef %set-word (p o &optional (new (prog1 o (setq o 0))))
344               (%set-word p o new))
345  (%eval-redef %set-unsigned-word (p o &optional (new (prog1 o (setq o 0))))
346               (%set-unsigned-word p o new))
347  (%eval-redef %set-long (p o &optional (new (prog1 o (setq o 0))))
348               (%set-long p o new))
349  (%eval-redef %set-unsigned-long (p o &optional (new (prog1 o (setq o 0))))
350               (%set-unsigned-long p o new))
351  (%eval-redef %set-ptr (p o &optional (new (prog1 o (setq o 0))))
352               (%set-ptr p o new))
353
354 
355  (%eval-redef %word-to-int (word))
356  (%eval-redef %inc-ptr (ptr &optional (by 1)) (%inc-ptr ptr by))
357 
358  (%eval-redef char-code (x))
359  (%eval-redef code-char (x))
360  (%eval-redef 1- (n))
361  (%eval-redef 1+ (n))
362
363  (%eval-redef uvref (x y))
364  (%eval-redef uvset (x y z))
365  (%eval-redef uvsize (x))
366
367  (%eval-redef svref (x y))
368  (%eval-redef svset (x y z))
369 
370 
371 
372  (%eval-redef car (x))
373  (%eval-redef cdr (x))
374  (%eval-redef cons (x y))
375  (%eval-redef endp (x))
376
377  (progn
378    (%eval-redef typecode (x))
379    (%eval-redef lisptag (x))
380    (%eval-redef fulltag (x))
381    (%eval-redef %unbound-marker ())
382    (%eval-redef %slot-unbound-marker ())
383    (%eval-redef %slot-ref (v i))
384    (%eval-redef %alloc-misc (count subtag &optional (initial nil initial-p))
385                 (if initial-p
386                   (%alloc-misc count subtag initial)
387                   (%alloc-misc count subtag)))
388    (%eval-redef %setf-double-float (x y))
389    (%eval-redef %lisp-word-ref (x y))
390    (%eval-redef %temp-cons (x y))
391    (%eval-redef require-fixnum (x))
392    (%eval-redef require-symbol (x))
393    (%eval-redef require-list (x))
394    (%eval-redef require-real (x))
395    (%eval-redef require-simple-string (x))
396    (%eval-redef require-simple-vector (x))
397    (%eval-redef require-character (x))
398    (%eval-redef require-number (x))
399    (%eval-redef require-integer (x))
400    (%eval-redef require-s8 (x))
401    (%eval-redef require-u8 (x))
402    (%eval-redef require-s16 (x))
403    (%eval-redef require-u16 (x))
404    (%eval-redef require-s32 (x))
405    (%eval-redef require-u32 (x))
406    (%eval-redef require-s64 (x))
407    (%eval-redef require-u64 (x))
408    (%eval-redef %reference-external-entry-point (x))
409    )
410 
411  (%eval-redef %get-bit (ptr offset))
412  (%eval-redef %set-bit (ptr offset val))
413  (%eval-redef %get-double-float (ptr &optional (offset 0))
414               (%get-double-float ptr offset))
415  (%eval-redef %get-single-float (ptr &optional (offset 0))
416               (%get-single-float ptr offset))
417  (%eval-redef %set-double-float (p o &optional (new (prog1 o (setq o 0))))
418               (%set-double-float p o new))
419  (%eval-redef %set-single-float (p o &optional (new (prog1 o (setq o 0))))
420               (%set-single-float p o new))
421  (%eval-redef assq (item list))
422)
423
424; In the spirit of eval-redef ...
425
426
427;; pointer hacking stuff
428;
429;
430
431
432
433;;; I'd guess that the majority of bitfields in the world whose width is
434;;; greater than 1 have a width of two.  If that's true, this is probably
435;;; faster than trying to be more clever about it would be.
436(defun %get-bitfield (ptr start-bit width)
437  (declare (fixnum start-bit width))
438  (do* ((bit #+big-endian-target start-bit
439             #+little-endian-target (the fixnum (1- (the fixnum (+ start-bit width))))
440             #+big-endian-target (1+ bit)
441             #+little-endian-target (1- bit))
442        (i 0 (1+ i))
443        (val 0))
444       ((= i width) val)
445    (declare (fixnum val i bit))
446    (setq val (logior (ash val 1) (%get-bit ptr bit)))))
447
448(defun %set-bitfield (ptr start width val)
449  (declare (fixnum val start width))
450  (do* ((v val (ash v -1))
451        (bit #+big-endian-target (1- (+ start width))
452             #+little-endian-target start
453             #+big-endian-target (1- bit)
454             #+little-endian-target (1+ bit))
455        (i 0 (1+ i)))
456       ((= i width) val)
457    (declare (fixnum v bit i))
458    (setf (%get-bit ptr bit) (logand v 1))))
459
460; expands into compiler stuff
461
462(setf (symbol-function '%get-unsigned-byte) (symbol-function '%get-byte))
463(setf (symbol-function '%get-unsigned-word) (symbol-function '%get-word))
464(setf (symbol-function '%get-signed-long) (symbol-function '%get-long))
465
466(defun decompose-record-accessor (accessor &aux ret)
467  (do* ((str (symbol-name accessor) (%substr str (+ i 1) len))
468        (len (length str) (length str))
469        (i (%str-member #\. str) (%str-member #\. str))
470        (field (%substr str 0 (or i len)) (%substr str 0 (or i len))))
471       ((not i) (nreverse (cons (make-keyword field) ret)))
472    (push (make-keyword field) ret)))
473
474
475
476
477(provide 'level-2)
478
479       
480
481
482;; end of level-2.lisp
483
Note: See TracBrowser for help on using the repository browser.