source: branches/1.1.x/src/org/armedbear/lisp/adjust_array.java

Last change on this file was 13461, checked in by ehuelsmann, 13 years ago

Print expected minimum and maximum argument list lengths in
WrongNumberOfArguments? program errors.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.5 KB
Line 
1/*
2 * adjust_array.java
3 *
4 * Copyright (C) 2004-2007 Peter Graves
5 * $Id: adjust_array.java 13461 2011-08-11 17:01:41Z ehuelsmann $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import static org.armedbear.lisp.Lisp.*;
37
38// ### %adjust-array array new-dimensions element-type initial-element
39// initial-element-p initial-contents initial-contents-p fill-pointer
40// displaced-to displaced-index-offset => new-array
41public final class adjust_array extends Primitive
42{
43    public adjust_array()
44    {
45        super("%adjust-array", PACKAGE_SYS, false);
46    }
47
48    @Override
49    public LispObject execute(LispObject[] args)
50    {
51        if (args.length != 10)
52            return error(new WrongNumberOfArgumentsException(this, 10));
53        AbstractArray array = checkArray(args[0]);
54        LispObject dimensions = args[1];
55        LispObject elementType = args[2];
56        boolean initialElementProvided = args[4] != NIL;
57        boolean initialContentsProvided = args[6] != NIL;
58        LispObject initialElement = initialElementProvided ? args[3] : null;
59        LispObject initialContents = initialContentsProvided ? args[5] : null;
60        LispObject fillPointer = args[7];
61        LispObject displacedTo = args[8];
62        LispObject displacedIndexOffset = args[9];
63        if (initialElementProvided && initialContentsProvided) {
64            return error(new LispError("ADJUST-ARRAY: cannot specify both initial element and initial contents."));
65        }
66        if (elementType != array.getElementType() &&
67            getUpgradedArrayElementType(elementType) != array.getElementType())
68        {
69            return error(new LispError("ADJUST-ARRAY: incompatible element type."));
70        }
71        if (array.getRank() == 0) {
72            return array.adjustArray(new int[0], initialElement, initialContents);
73        }
74        if (!initialElementProvided && array.getElementType() == T)
75            initialElement = Fixnum.ZERO;
76        if (array.getRank() == 1) {
77            final int newSize;
78            if (dimensions instanceof Cons && dimensions.length() == 1)
79                newSize = Fixnum.getValue(dimensions.car());
80            else
81                newSize = Fixnum.getValue(dimensions);
82            if (array instanceof AbstractVector) {
83                AbstractVector v = (AbstractVector) array;
84                AbstractArray v2;
85                if (displacedTo != NIL) {
86                    final int displacement;
87                    if (displacedIndexOffset == NIL)
88                        displacement = 0;
89                    else
90                        displacement = Fixnum.getValue(displacedIndexOffset);
91                    v2 = v.adjustArray(newSize,
92                                        checkArray(displacedTo),
93                                        displacement);
94                } else {
95                    v2 = v.adjustArray(newSize,
96                                        initialElement,
97                                        initialContents);
98                }
99                if (fillPointer != NIL)
100                    v2.setFillPointer(fillPointer);
101                return v2;
102            }
103        }
104        // rank > 1
105        final int rank = dimensions.listp() ? dimensions.length() : 1;
106        int[] dimv = new int[rank];
107        if (dimensions.listp()) {
108            for (int i = 0; i < rank; i++) {
109                LispObject dim = dimensions.car();
110                dimv[i] = Fixnum.getValue(dim);
111                dimensions = dimensions.cdr();
112            }
113        } else
114            dimv[0] = Fixnum.getValue(dimensions);
115
116        if (displacedTo != NIL) {
117            final int displacement;
118            if (displacedIndexOffset == NIL)
119                displacement = 0;
120            else
121                displacement = Fixnum.getValue(displacedIndexOffset);
122            return array.adjustArray(dimv,
123                                     checkArray(displacedTo),
124                                     displacement);
125        } else {
126            return array.adjustArray(dimv,
127                                     initialElement,
128                                     initialContents);
129        }
130    }
131
132    private static final Primitive _ADJUST_ARRAY = new adjust_array();
133}
Note: See TracBrowser for help on using the repository browser.