001: /*
002: * max.java
003: *
004: * Copyright (c) 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package org.pnuts.math;
010:
011: import pnuts.lang.PnutsFunction;
012: import pnuts.lang.Context;
013: import pnuts.lang.Runtime;
014: import java.util.Collection;
015: import java.util.Iterator;
016: import java.lang.reflect.Array;
017: import java.util.Collections;
018: import java.util.Comparator;
019: import java.util.List;
020:
021: public class max extends PnutsFunction {
022:
023: public max() {
024: super ("max");
025: }
026:
027: public boolean defined(int nargs) {
028: return nargs == 1 || nargs == 2;
029: }
030:
031: protected Object exec(Object[] args, final Context context) {
032: int nargs = args.length;
033: Object arg0 = args[0];
034: int type0 = 0;
035: if (nargs == 1 || nargs == 2) {
036: if (arg0 instanceof Collection) {
037: type0 = 1;
038: } else if (arg0 instanceof int[]) {
039: type0 = 2;
040: } else if (arg0 instanceof long[]) {
041: type0 = 3;
042: } else if (arg0 instanceof short[]) {
043: type0 = 4;
044: } else if (arg0 instanceof byte[]) {
045: type0 = 5;
046: } else if (arg0 instanceof double[]) {
047: type0 = 6;
048: } else if (arg0 instanceof float[]) {
049: type0 = 7;
050: } else if (arg0 instanceof Object[]) {
051: type0 = 8;
052: }
053: }
054: if (nargs == 1) {
055: Object arg = args[0];
056: if (type0 == 0) {
057: throw new IllegalArgumentException(String.valueOf(arg0));
058: } else if (type0 == 1) {
059: Iterator it = ((Collection) arg).iterator();
060: Object max = null;
061: if (it.hasNext()) {
062: max = it.next();
063: }
064: while (it.hasNext()) {
065: Object next = it.next();
066: if (Runtime.lt(max, next)) {
067: max = next;
068: }
069: }
070: return max;
071: } else {
072: Object max = null;
073: int len = Array.getLength(arg);
074: if (len > 0) {
075: max = Array.get(arg, 0);
076: }
077: for (int i = 1; i < len; i++) {
078: Object next = Array.get(arg, i);
079: if (Runtime.lt(max, next)) {
080: max = next;
081: }
082: }
083: return max;
084: }
085: } else if (nargs == 2) {
086: Object arg1 = args[1];
087: if (type0 == 0) {
088: if (Runtime.lt(arg0, arg1)) {
089: return arg1;
090: } else {
091: return arg0;
092: }
093: }
094: int type1 = 0;
095: if (arg1 instanceof PnutsFunction) {
096: type1 = 1;
097: } else if (arg1 instanceof Comparator) {
098: type1 = 2;
099: } else if (arg1 == null) {
100: type1 = 3;
101: } else {
102: throw new IllegalArgumentException(String.valueOf(arg1));
103: }
104: Comparator comp = null;
105: if (type1 == 3) { // default comparator
106: switch (type0) {
107: case 1: // Collection
108: return Collections.max((Collection) arg0);
109: case 2: { // int[]
110: int[] array = (int[]) arg0;
111: if (array.length < 1) {
112: return null;
113: }
114: int m = array[0];
115: for (int i = 1; i < array.length; i++) {
116: int j = array[i];
117: if (j > m) {
118: m = j;
119: }
120: }
121: return new Integer(m);
122: }
123: case 3: { // long[]
124: long[] array = (long[]) arg0;
125: if (array.length < 1) {
126: return null;
127: }
128: long m = array[0];
129: for (int i = 1; i < array.length; i++) {
130: long j = array[i];
131: if (j > m) {
132: m = j;
133: }
134: }
135: return new Long(m);
136: }
137: case 4: { // short[]
138: short[] array = (short[]) arg0;
139: if (array.length < 1) {
140: return null;
141: }
142: short m = array[0];
143: for (int i = 1; i < array.length; i++) {
144: short j = array[i];
145: if (j > m) {
146: m = j;
147: }
148: }
149: return new Short(m);
150: }
151: case 5: { // byte[]
152: byte[] array = (byte[]) arg0;
153: if (array.length < 1) {
154: return null;
155: }
156: byte m = array[0];
157: for (int i = 1; i < array.length; i++) {
158: byte j = array[i];
159: if (j > m) {
160: m = j;
161: }
162: }
163: return new Byte(m);
164: }
165: case 6: { // double[]
166: double[] array = (double[]) arg0;
167: if (array.length < 1) {
168: return null;
169: }
170: double m = array[0];
171: for (int i = 1; i < array.length; i++) {
172: double j = array[i];
173: if (j > m) {
174: m = j;
175: }
176: }
177: return new Double(m);
178: }
179: case 7: { // float[]
180: float[] array = (float[]) arg0;
181: if (array.length < 1) {
182: return null;
183: }
184: float m = array[0];
185: for (int i = 1; i < array.length; i++) {
186: float j = array[i];
187: if (j > m) {
188: m = j;
189: }
190: }
191: return new Float(m);
192: }
193: case 8: { // Object[]
194: Object[] array = (Object[]) arg0;
195: int len = array.length;
196: if (len < 1) {
197: return null;
198: }
199: Object m = array[0];
200: Comparable c;
201: if (m instanceof Comparable) {
202: c = (Comparable) m;
203: } else {
204: return null;
205: }
206: for (int i = 1; i < len; i++) {
207: Object j = array[i];
208: if (c.compareTo(j) < 0) {
209: if (j instanceof Comparable) {
210: c = (Comparable) j;
211: }
212: }
213: }
214: return c;
215: }
216: default:
217: throw new IllegalArgumentException(String
218: .valueOf(arg0));
219: }
220: } else if (type1 == 1) {
221: final PnutsFunction func = (PnutsFunction) arg1;
222: comp = new Comparator() {
223: public int compare(Object obj1, Object obj2) {
224: Object o1 = func.call(new Object[] { obj1 },
225: context);
226: Object o2 = func.call(new Object[] { obj2 },
227: context);
228: return Runtime.compareTo(o1, o2);
229: }
230: };
231: } else if (type1 == 2) {
232: comp = (Comparator) arg1;
233: }
234: switch (type0) {
235: case 1: // Collection
236: return Collections.max((Collection) arg0, comp);
237: case 2: { // int[]
238: int[] array = (int[]) arg0;
239: if (array.length < 1) {
240: return null;
241: }
242: Integer m = new Integer(array[0]);
243: for (int i = 1; i < array.length; i++) {
244: Integer j = new Integer(array[i]);
245: if (comp.compare(j, m) > 0) {
246: m = j;
247: }
248: }
249: return m;
250: }
251: case 3: { // long[]
252: long[] array = (long[]) arg0;
253: if (array.length < 1) {
254: return null;
255: }
256: Long m = new Long(array[0]);
257: for (int i = 1; i < array.length; i++) {
258: Long j = new Long(array[i]);
259: if (comp.compare(j, m) > 0) {
260: m = j;
261: }
262: }
263: return m;
264: }
265: case 4: { // short[]
266: short[] array = (short[]) arg0;
267: if (array.length < 1) {
268: return null;
269: }
270: Short m = new Short(array[0]);
271: for (int i = 1; i < array.length; i++) {
272: Short j = new Short(array[i]);
273: if (comp.compare(j, m) > 0) {
274: m = j;
275: }
276: }
277: return m;
278: }
279: case 5: { // byte[]
280: byte[] array = (byte[]) arg0;
281: if (array.length < 1) {
282: return null;
283: }
284: Byte m = new Byte(array[0]);
285: for (int i = 1; i < array.length; i++) {
286: Byte j = new Byte(array[i]);
287: if (comp.compare(j, m) > 0) {
288: m = j;
289: }
290: }
291: return m;
292: }
293: case 6: { // double[]
294: double[] array = (double[]) arg0;
295: if (array.length < 1) {
296: return null;
297: }
298: Double m = new Double(array[0]);
299: for (int i = 1; i < array.length; i++) {
300: Double j = new Double(array[i]);
301: if (comp.compare(j, m) > 0) {
302: m = j;
303: }
304: }
305: return m;
306: }
307: case 7: { // float[]
308: float[] array = (float[]) arg0;
309: if (array.length < 1) {
310: return null;
311: }
312: Float m = new Float(array[0]);
313: for (int i = 1; i < array.length; i++) {
314: Float j = new Float(array[i]);
315: if (comp.compare(j, m) > 0) {
316: m = j;
317: }
318: }
319: return m;
320: }
321: case 8: { // Object[]
322: Object[] array = (Object[]) arg0;
323: int len = array.length;
324: if (len < 1) {
325: return null;
326: }
327: Object m = array[0];
328: for (int i = 1; i < len; i++) {
329: Object j = array[i];
330: if (comp.compare(j, m) > 0) {
331: m = j;
332: }
333: }
334: return m;
335: }
336: default:
337: throw new IllegalArgumentException(String.valueOf(arg0));
338: }
339: } else {
340: undefined(args, context);
341: return null;
342: }
343: }
344:
345: public String toString() {
346: return "fuction max(arg1, arg2) or (collection/array {, comparator | f(arg) })";
347: }
348: }
|