001: /*
002: * $Id: AnyTuple.java,v 1.11 2002/09/16 08:05:02 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.core;
011:
012: import java.io.IOException;
013: import java.io.OutputStream;
014: import java.io.Writer;
015: import java.util.ArrayList;
016: import java.util.Comparator;
017: import anvil.core.runtime.AnyFunction;
018: import anvil.script.Context;
019: import anvil.script.Function;
020: import anvil.java.util.BindingEnumeration;
021:
022: /// @class tuple
023: /// Tuple is an immutable sequence of values.
024: ///
025:
026: /**
027: * class AnyTuple
028: *
029: * @author: Jani Lehtimäki
030: */
031: public final class AnyTuple extends AnyList {
032:
033: /// @constructor tuple
034: /// Constructs tuple. Same as builtin <code>(elements, ...)</code> constructor.
035: /// @synopsis tuple(object element, ...)
036: public static final Any newInstance(Any[] list) {
037: return new AnyTuple(list);
038: }
039:
040: transient public static final anvil.script.compiler.NativeClass __class__ = new anvil.script.compiler.NativeClass(
041: "tuple", AnyTuple.class,
042: AnySequence.__class__,
043: //DOC{{
044: ""
045: + " @class tuple\n"
046: + " Tuple is an immutable sequence of values.\n"
047: + "\n"
048: + " @constructor tuple\n"
049: + " Constructs tuple. Same as builtin <code>(elements, ...)</code> constructor.\n"
050: + " @synopsis tuple(object element, ...)\n"
051: //}}DOC
052: );
053:
054: public AnyTuple() {
055: super ();
056: }
057:
058: public AnyTuple(Any[] array) {
059: super (array);
060: }
061:
062: public AnySequence getSlice(int start, int length) {
063: Any[] b = new Any[length];
064: System.arraycopy(_array, start, b, 0, length);
065: return new AnyTuple(b);
066: }
067:
068: public AnySequence createSequence(Any element) {
069: return new AnyTuple(new Any[] { element });
070: }
071:
072: public AnySequence createEmptySequence() {
073: return new AnyTuple(ARRAY0);
074: }
075:
076: public AnySequence clear() {
077: return new AnyTuple(new Any[0]);
078: }
079:
080: public AnySequence setSize(int size) {
081: Any[] newarray = new Any[size];
082: if (size > 0) {
083: System.arraycopy(_array, 0, newarray, 0, size);
084: }
085: return new AnyTuple(newarray);
086: }
087:
088: public AnySequence deleteSlice(int start, int length) {
089: Any[] array = _array;
090: int size = _size;
091: Any[] newarray = new Any[size - length];
092: if (start > 0) {
093: System.arraycopy(array, 0, newarray, 0, start);
094: }
095: if (start + length < size) {
096: System.arraycopy(array, start + length, newarray, start,
097: size - (start + length));
098: }
099: return new AnyTuple(newarray);
100: }
101:
102: public AnySequence setSlice(int start, int length, Any element) {
103: Any[] array = _array;
104: int size = _size;
105: Any[] newarray = new Any[size - length + 1];
106: if (start > 0) {
107: System.arraycopy(array, 0, newarray, 0, start);
108: }
109: newarray[start] = element;
110: if (start + length < size) {
111: System.arraycopy(array, start + length, newarray,
112: start + 1, size - (start + length));
113: }
114: return new AnyTuple(newarray);
115: }
116:
117: public AnySequence setSlice(int start, int length,
118: AnySequence sequence) {
119: Any[] seq = sequence.toList();
120: int seq_length = sequence.getSize();
121: Any[] array = _array;
122: int size = _size;
123: Any[] newarray = new Any[size - length + seq_length];
124: if (start > 0) {
125: System.arraycopy(array, 0, newarray, 0, start);
126: }
127: if (seq_length > 0) {
128: System.arraycopy(seq, 0, newarray, start, seq_length);
129: }
130: if (start + length < size) {
131: System.arraycopy(array, start + length, newarray, start
132: + seq_length, size - (start + length));
133: }
134: return new AnyTuple(newarray);
135: }
136:
137: public AnySequence append(AnySequence sequence) {
138: Any[] seq = sequence.toList();
139: int seq_length = sequence.getSize();
140: Any[] array = _array;
141: int size = _size;
142: Any[] newarray = new Any[size + seq_length];
143: System.arraycopy(array, 0, newarray, 0, size);
144: System.arraycopy(seq, 0, newarray, size, seq_length);
145: return new AnyTuple(newarray);
146: }
147:
148: public AnySequence append(Any element) {
149: Any[] array = _array;
150: int size = _size;
151: Any[] newarray = new Any[size + 1];
152: System.arraycopy(array, 0, newarray, 0, size);
153: newarray[size] = element;
154: return new AnyTuple(newarray);
155: }
156:
157: public AnySequence crop(int start, int length) {
158: Any[] newarray = new Any[length];
159: if (length > 0) {
160: System.arraycopy(_array, start, newarray, 0, length);
161: }
162: return new AnyTuple(newarray);
163: }
164:
165: public AnySequence reverse(int start, int length) {
166: Any[] newarray = new Any[length];
167: for (int i = 0; i < length; i++) {
168: newarray[length - i - 1] = _array[start + i];
169: }
170: return new AnyTuple(newarray);
171: }
172:
173: public AnySequence sort(int start, int length, Comparator comparator) {
174: Any[] newarray = new Any[_size];
175: System.arraycopy(_array, 0, newarray, 0, _size);
176: if (comparator != null) {
177: java.util.Arrays.sort(newarray, start, start + length,
178: comparator);
179: } else {
180: java.util.Arrays.sort(newarray, start, start + length);
181: }
182: return new AnyTuple(newarray);
183: }
184:
185: public AnySequence swap(int index1, int index2) {
186: Any[] newarray = new Any[_size];
187: System.arraycopy(_array, 0, newarray, 0, _size);
188: Any any = newarray[index1];
189: newarray[index1] = newarray[index2];
190: newarray[index2] = any;
191: return new AnyTuple(newarray);
192: }
193:
194: public AnySequence fill(Any fill, int start, int length) {
195: Any[] newarray = new Any[_size];
196: System.arraycopy(_array, 0, newarray, 0, _size);
197: java.util.Arrays.fill(newarray, start, start + length, fill);
198: return new AnyTuple(newarray);
199: }
200:
201: public anvil.script.ClassType classOf() {
202: return __class__;
203: }
204:
205: public int typeOf() {
206: return IS_TUPLE;
207: }
208:
209: public boolean isMutable() {
210: Any[] array = _array;
211: int n = _size;
212: for (int i = 0; i < n; i++) {
213: if (array[i].isMutable()) {
214: return true;
215: }
216: }
217: return false;
218: }
219:
220: public boolean isTuple() {
221: return true;
222: }
223:
224: public int hashCode() {
225: Any[] array = _array;
226: int n = _size;
227: int h = 0;
228: for (int i = 0; i < n; i++) {
229: h += (i + 1) * array[i].hashCode();
230: }
231: return h;
232: }
233:
234: public String toString() {
235: StringBuffer buffer = new StringBuffer();
236: buffer.append('(');
237: int n = _size;
238: for (int i = 0; i < n; i++) {
239: if (i > 0) {
240: buffer.append(',');
241: buffer.append(' ');
242: }
243: buffer.append(_array[i].toString());
244: }
245: buffer.append(')');
246: return buffer.toString();
247: }
248:
249: public Writer toAnvil(Writer writer) throws IOException {
250: Any[] array = _array;
251: final int n = _size;
252: writer.write("(");
253: for (int i = 0; i < n; i++) {
254: if (i > 0) {
255: writer.write(',');
256: writer.write(' ');
257: }
258: array[i].toAnvil(writer);
259: }
260: writer.write(')');
261: return writer;
262: }
263:
264: public Writer toJava(Writer writer) throws IOException {
265: Any[] array = _array;
266: final int n = _size;
267: writer.write("new anvil.core.AnyTuple(new Any[]{");
268: for (int i = 0; i < n; i++) {
269: if (i > 0) {
270: writer.write(',');
271: writer.write(' ');
272: }
273: array[i].toJava(writer);
274: }
275: writer.write('}');
276: writer.write(')');
277: return writer;
278: }
279:
280: public anvil.codec.Code toCode(anvil.codec.Code code) {
281: anvil.codec.ConstantPool pool = code.getPool();
282: int clazz = pool.addClass("anvil/core/AnyTuple");
283: code.anew(clazz);
284: code.dup();
285: Any[] array = _array;
286: final int n = _size;
287: code.iconst(n);
288: code.anewarray(pool.addClass("anvil/core/Any"));
289: for (int i = 0; i < n; i++) {
290: code.dup();
291: code.iconst(i);
292: _array[i].toCode(code);
293: code.aastore();
294: }
295: code.invokespecial(pool.addMethodRef(clazz, "<init>",
296: "([Lanvil/core/Any;)V"));
297: return code;
298: }
299:
300: public Object clone() {
301: return this ;
302: }
303:
304: public Any copy() {
305: int length = _size;
306: if (length == 0) {
307: return this ;
308: }
309: Any[] array = new Any[length];
310: for (int i = 0; i < length; i++) {
311: array[i] = _array[i].copy();
312: }
313: return new AnyTuple(array);
314: }
315:
316: public void serialize(Serializer serializer) throws IOException {
317: if (serializer.register(this )) {
318: return;
319: }
320: Any[] array = _array;
321: final int n = _size;
322: serializer.write('l');
323: serializer.write(n);
324: serializer.write(':');
325: for (int i = 0; i < n; i++) {
326: _array[i].serialize(serializer);
327: }
328: }
329:
330: public static AnyList unserialize(Unserializer unserializer)
331: throws UnserializationException {
332: int length = (int) unserializer.getLong();
333: if (length < 0) {
334: throw new UnserializationException();
335: }
336: AnyTuple list = new AnyTuple();
337: unserializer.register(list);
338: if (length > 0) {
339: Any[] array = new Any[length];
340: for (int i = 0; i < length; i++) {
341: array[i] = unserializer.unserialize();
342: }
343: list._array = array;
344: list._size = length;
345: }
346: return list;
347: }
348:
349: public boolean deleteReference(Context context, Any index) {
350: throw context.ReferenceError("Tuple is immutable");
351: }
352:
353: public Any setReference(Context context, Any index, Any value) {
354: throw context.ReferenceError("Tuple is immutable");
355: }
356:
357: public Any setReference(Context context, Any value) {
358: throw context.ReferenceError("Tuple is immutable");
359: }
360:
361: public Any m_set(Context context) {
362: throw context.TypeError("tuple is immutable");
363: }
364:
365: }
|