source: trunk/abcl/src/org/armedbear/lisp/make-sequence.lisp @ 11490

Last change on this file since 11490 was 11391, checked in by vvoutilainen, 16 years ago

ABCL license is GPL + Classpath exception. This was intended
by Peter Graves, the original author. For reference, see
http://sourceforge.net/mailarchive/forum.php?thread_name=20040721115302.839%40prufrock&forum_name=armedbear-j-announce

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.4 KB
Line 
1;;; make-sequence.lisp
2;;;
3;;; Copyright (C) 2003-2005 Peter Graves
4;;; $Id: make-sequence.lisp 11391 2008-11-15 22:38:34Z 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 #:system)
33
34;;; Adapted from ECL.
35
36(defun size-mismatch-error (type size)
37  (error 'simple-type-error
38         :format-control "The requested length (~D) does not match the specified type ~A."
39         :format-arguments (list size type)))
40
41(defun make-sequence (type size &key (initial-element nil iesp))
42  (let (element-type sequence)
43    (setf type (normalize-type type))
44    (cond ((atom type)
45           (when (classp type)
46             (setf type (%class-name type)))
47           (cond ((memq type '(LIST CONS))
48                  (when (zerop size)
49                    (if (eq type 'CONS)
50                        (size-mismatch-error type size)
51                        (return-from make-sequence nil)))
52                  (return-from make-sequence
53                               (if iesp
54                                   (make-list size :initial-element initial-element)
55                                   (make-list size))))
56                 ((memq type '(STRING SIMPLE-STRING BASE-STRING SIMPLE-BASE-STRING))
57                  (return-from make-sequence
58                               (if iesp
59                                   (make-string size :initial-element initial-element)
60                                   (make-string size))))
61                 ((eq type 'NULL)
62                  (if (zerop size)
63                      (return-from make-sequence nil)
64                      (size-mismatch-error type size)))
65                 (t
66                  (setq element-type
67                        (cond ((memq type '(BIT-VECTOR SIMPLE-BIT-VECTOR)) 'BIT)
68                              ((memq type '(VECTOR SIMPLE-VECTOR)) t)
69                              (t
70                               (error 'simple-type-error
71                                      :format-control "~S is not a sequence type."
72                                      :format-arguments (list type))))))))
73          (t
74           (let ((name (%car type))
75                 (args (%cdr type)))
76             (when (eq name 'LIST)
77               (return-from make-sequence
78                            (if iesp
79                                (make-list size :initial-element initial-element)
80                                (make-list size))))
81             (when (eq name 'CONS)
82               (unless (plusp size)
83                 (size-mismatch-error name size))
84               (return-from make-sequence
85                            (if iesp
86                                (make-list size :initial-element initial-element)
87                                (make-list size))))
88             (unless (memq name '(ARRAY SIMPLE-ARRAY VECTOR SIMPLE-VECTOR
89                                  BIT-VECTOR SIMPLE-BIT-VECTOR STRING SIMPLE-STRING
90                                  BASE-STRING SIMPLE-BASE-STRING))
91               (error 'simple-type-error
92                      :format-control "~S is not a sequence type."
93                      :format-arguments (list type)))
94             (let ((len nil))
95               (cond ((memq name '(STRING SIMPLE-STRING BASE-STRING SIMPLE-BASE-STRING))
96                      (setf element-type 'character
97                            len (car args)))
98                     ((memq name '(ARRAY SIMPLE-ARRAY))
99                      (setf element-type (or (car args) t)
100                            len (if (consp (cadr args)) (caadr args) '*)))
101                     ((memq name '(BIT-VECTOR SIMPLE-BIT-VECTOR))
102                      (setf element-type 'bit
103                            len (car args)))
104                     (t
105                      (setf element-type (or (car args) t)
106                            len (cadr args))))
107               (unless (or (null len) (eq len '*) (equal len '(*)))
108                 (when (/= size len)
109                   (size-mismatch-error type size)))))))
110    (setq sequence
111          (if iesp
112              (make-array size :element-type element-type :initial-element initial-element)
113              (make-array size :element-type element-type)))
114    sequence))
Note: See TracBrowser for help on using the repository browser.