~ubuntu-branches/debian/squeeze/cmucl/squeeze

« back to all changes in this revision

Viewing changes to src/code/sharpm.lisp

  • Committer: Bazaar Package Importer
  • Author(s): Peter Van Eynde
  • Date: 2009-02-18 05:50:05 UTC
  • mfrom: (0.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090218055005-kt6ookdcasemovhl
Tags: 19e-20080501-2
* fix brown bag bug: use cmucl in script, not lisp
* New version should Fixes: #483331 because of asm change

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
;;; Carnegie Mellon University, and has been placed in the public domain.
6
6
;;;
7
7
(ext:file-comment
8
 
  "$Header: /project/cmucl/cvsroot/src/code/sharpm.lisp,v 1.26 2005/11/08 17:12:29 rtoy Exp $")
 
8
  "$Header: /project/cmucl/cvsroot/src/code/sharpm.lisp,v 1.27 2007/06/22 21:45:25 rtoy Exp $")
9
9
;;;
10
10
;;; **********************************************************************
11
11
;;;
243
243
;; substitutes in arrays and structures as well as lists.  The first arg is an
244
244
;; alist of the things to be replaced assoc'd with the things to replace them.
245
245
;;
246
 
(defun circle-subst (old-new-alist tree)
 
246
(defun circle-subst (repl-table tree)
247
247
  (cond ((not (typep tree '(or cons (array t) structure-object
248
248
                            standard-object)))
249
 
         (let ((entry (find tree old-new-alist :key #'second)))
250
 
           (if entry (third entry) tree)))
 
249
         (multiple-value-bind (value presentp)
 
250
             (gethash tree repl-table)
 
251
           (if presentp
 
252
               value
 
253
               tree)))
251
254
        ((null (gethash tree *sharp-equal-circle-table*))
252
255
         (setf (gethash tree *sharp-equal-circle-table*) t)
253
256
         (cond ((typep tree '(or structure-object standard-object))
255
258
                     (end (%instance-length tree)))
256
259
                    ((= i end))
257
260
                  (let* ((old (%instance-ref tree i))
258
 
                         (new (circle-subst old-new-alist old)))
 
261
                         (new (circle-subst repl-table old)))
259
262
                    (unless (eq old new)
260
263
                      (setf (%instance-ref tree i) new)))))
261
264
               ((arrayp tree)
264
267
                  (do ((i start (1+ i)))
265
268
                      ((>= i end))
266
269
                    (let* ((old (aref data i))
267
 
                           (new (circle-subst old-new-alist old)))
 
270
                           (new (circle-subst repl-table old)))
268
271
                      (unless (eq old new)
269
272
                        (setf (aref data i) new))))))
270
273
               (t
271
 
                (let ((a (circle-subst old-new-alist (car tree)))
272
 
                      (d (circle-subst old-new-alist (cdr tree))))
 
274
                (let ((a (circle-subst repl-table (car tree)))
 
275
                      (d (circle-subst repl-table (cdr tree))))
273
276
                  (unless (eq a (car tree))
274
277
                    (rplaca tree a))
275
278
                  (unless (eq d (cdr tree))
277
280
         tree)
278
281
        (t tree)))
279
282
 
 
283
(defun maybe-create-tables ()
 
284
  (unless *sharp-equal-final-table*
 
285
    (setf *sharp-equal-final-table*
 
286
          (make-hash-table :size 40 :rehash-size 4000 :rehash-threshold 0.8 :test 'eql)))
 
287
  (unless *sharp-equal-temp-table*
 
288
    (setf *sharp-equal-temp-table*
 
289
          (make-hash-table :size 40 :rehash-size 4000 :rehash-threshold 0.8 :test 'eql)))
 
290
  (unless *sharp-equal-repl-table*
 
291
    (setf *sharp-equal-repl-table*
 
292
          (make-hash-table :size 40 :rehash-size 4000 :rehash-threshold 0.8 :test 'eq))))
 
293
 
280
294
;;; Sharp-equal works as follows.  When a label is assigned (ie when #= is
281
295
;;; called) we GENSYM a symbol is which is used as an unforgeable tag.
282
296
;;; *SHARP-SHARP-ALIST* maps the integer tag to this gensym.
291
305
;;; for each entry in the *SHARP-SHARP-ALIST, the current object is searched
292
306
;;; and any uses of the gensysm token are replaced with the actual value.
293
307
;;;
294
 
(defvar *sharp-sharp-alist* ())
 
308
 
295
309
;;;
296
310
(defun sharp-equal (stream ignore label)
297
311
  (declare (ignore ignore))
298
312
  (when *read-suppress* (return-from sharp-equal (values)))
299
313
  (unless label
300
314
    (%reader-error stream "Missing label for #=." label))
301
 
  (when (or (assoc label *sharp-sharp-alist*)
302
 
            (assoc label *sharp-equal-alist*))
 
315
  (maybe-create-tables)
 
316
  (when (or (nth-value 1 (gethash label *sharp-equal-final-table*))
 
317
            (nth-value 1 (gethash label *sharp-equal-temp-table*)))
303
318
    (%reader-error stream "Multiply defined label: #~D=" label))
304
 
  (let* ((tag (gensym))
305
 
         (*sharp-sharp-alist* (acons label tag *sharp-sharp-alist*))
306
 
         (obj (read stream t nil t)))
307
 
    (when (eq obj tag)
308
 
      (%reader-error stream "Have to tag something more than just #~D#."
309
 
                     label))
310
 
    (push (list label tag obj) *sharp-equal-alist*)
311
 
    (let ((*sharp-equal-circle-table* (make-hash-table :test #'eq :size 20)))
312
 
      (circle-subst *sharp-equal-alist* obj))))
 
319
  (let* ((tag (gensym)))
 
320
    (setf (gethash label *sharp-equal-temp-table*) tag)
 
321
    (let ((obj (read stream t nil t)))
 
322
      (when (eq obj tag)
 
323
        (%reader-error stream "Have to tag something more than just #~D#."
 
324
                       label))
 
325
      (setf (gethash tag *sharp-equal-repl-table*) obj)
 
326
      (let ((*sharp-equal-circle-table* (make-hash-table :test #'eq :size 20)))
 
327
        (circle-subst *sharp-equal-repl-table* obj))
 
328
      (setf (gethash label *sharp-equal-final-table*) obj))))
313
329
;;;
314
330
(defun sharp-sharp (stream ignore label)
315
331
  (declare (ignore ignore))
317
333
  (unless label
318
334
    (%reader-error stream "Missing label for ##." label))
319
335
 
320
 
  (let ((entry (assoc label *sharp-equal-alist*)))
321
 
    (if entry
322
 
        (third entry)
323
 
        (let ((pair (assoc label *sharp-sharp-alist*)))
324
 
          (unless pair
325
 
            (%reader-error stream "Object is not labelled #~S#" label))
326
 
          (cdr pair)))))
327
 
 
 
336
  (maybe-create-tables)
 
337
  ;; Don't read ANSI "2.4.8.15 Sharpsign Equal-Sign" and worry that it requires
 
338
  ;; you to implement forward references, because forward references are
 
339
  ;; disallowed in "2.4.8.16 Sharpsign Sharpsign".
 
340
  (multiple-value-bind (finalized-object successp)
 
341
      (gethash label *sharp-equal-final-table*)
 
342
    (if successp
 
343
        finalized-object
 
344
        (multiple-value-bind (temporary-tag successp)
 
345
            (gethash label *sharp-equal-temp-table*)
 
346
          (if successp
 
347
              temporary-tag
 
348
              (%reader-error stream "reference to undefined label #~D#" label))))))
328
349
 
329
350
;;;; #+/-
330
351