source: trunk/ccl/lib/level-2.lisp @ 6208

Last change on this file since 6208 was 6208, checked in by gb, 14 years ago

%GET-BITFIELD and SETF thereof: deal with endianness.

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