001: /*
002: * @(#)reduce.java 1.2 04/12/06
003: *
004: * Copyright (c) 1997-2004 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.lib;
010:
011: import pnuts.lang.*;
012: import pnuts.lang.Runtime;
013: import java.util.*;
014: import java.lang.reflect.Array;
015:
016: public class reduce extends PnutsFunction {
017:
018: public reduce() {
019: super ("reduce");
020: }
021:
022: public boolean defined(int nargs) {
023: return nargs == 2 || nargs == 3;
024: }
025:
026: protected Object exec(Object[] args, final Context context) {
027: int nargs = args.length;
028: Object arg0;
029: Object target;
030: Object initial;
031: if (nargs == 3) {
032: arg0 = args[0];
033: target = args[1];
034: initial = args[2];
035: } else if (nargs == 2) {
036: arg0 = args[0];
037: target = args[1];
038: initial = null;
039: } else {
040: undefined(args, context);
041: return null;
042: }
043:
044: if (!(arg0 instanceof PnutsFunction)) {
045: throw new IllegalArgumentException(String.valueOf(arg0));
046: }
047: final PnutsFunction func = (PnutsFunction) arg0;
048:
049: Object[] fargs = new Object[2];
050: if (target instanceof Iterator) {
051: Iterator it = (Iterator) target;
052: if (nargs == 3) {
053: fargs[0] = initial;
054: } else {
055: if (it.hasNext()) {
056: fargs[0] = it.next();
057: }
058: }
059: while (it.hasNext()) {
060: fargs[1] = it.next();
061: fargs[0] = func.call(fargs, context);
062: }
063: return fargs[0];
064: } else if (target instanceof Enumeration) {
065: Enumeration en = (Enumeration) target;
066: if (nargs == 3) {
067: fargs[0] = initial;
068: } else {
069: if (en.hasMoreElements()) {
070: fargs[0] = en.nextElement();
071: }
072: }
073: while (en.hasMoreElements()) {
074: fargs[1] = en.nextElement();
075: fargs[0] = func.call(fargs, context);
076: }
077: return fargs[0];
078: } else if (target instanceof Collection) {
079: Iterator it = ((Collection) target).iterator();
080: if (nargs == 3) {
081: fargs[0] = initial;
082: } else {
083: if (it.hasNext()) {
084: fargs[0] = it.next();
085: }
086: }
087: while (it.hasNext()) {
088: fargs[1] = it.next();
089: fargs[0] = func.call(fargs, context);
090: }
091: return fargs[0];
092: } else if (target instanceof Object[]) {
093: Object[] array = (Object[]) target;
094: int i = 0;
095: if (nargs == 3) {
096: fargs[0] = initial;
097: } else {
098: if (array.length > 1) {
099: fargs[0] = array[i++];
100: }
101: }
102: for (; i < array.length; i++) {
103: fargs[1] = array[i];
104: fargs[0] = func.call(fargs, context);
105: }
106: return fargs[0];
107: } else if (target instanceof Generator) {
108: final Generator g = (Generator) target;
109: final Object[] fa = fargs;
110: if (nargs == 2) {
111: class F extends PnutsFunction {
112: boolean first = true;
113:
114: protected Object exec(Object[] a, Context ctx) {
115: if (first) {
116: fa[0] = a[0];
117: first = false;
118: } else {
119: fa[1] = a[0];
120: fa[0] = func.call(fa, context);
121: }
122: return null;
123: }
124: }
125: g.apply(new F(), context);
126: } else {
127: fa[0] = initial;
128: class F extends PnutsFunction {
129: protected Object exec(Object[] a, Context ctx) {
130: fa[1] = a[0];
131: fa[0] = func.call(fa, context);
132: return null;
133: }
134: }
135: g.apply(new F(), context);
136: }
137: return fa[0];
138: } else if (Runtime.isArray(target)) {
139: ArrayList lst = new ArrayList();
140: int len = Runtime.getArrayLength(target);
141: int i = 0;
142: if (nargs == 3) {
143: fargs[0] = initial;
144: } else {
145: if (len > 1) {
146: fargs[0] = Array.get(target, i++);
147: }
148: }
149: for (; i < len; i++) {
150: fargs[1] = Array.get(target, i);
151: fargs[0] = func.call(fargs, context);
152: }
153: return fargs[0];
154: } else {
155: throw new IllegalArgumentException();
156: }
157: }
158:
159: public String toString() {
160: return "function reduce( func(a, b), elements { , intialValue} )";
161: }
162: }
|