KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > kawa > functions > ApplyToArgs


1 package gnu.kawa.functions;
2 import gnu.bytecode.*;
3 import gnu.expr.*;
4 import gnu.mapping.*;
5 import gnu.kawa.reflect.Invoke;
6 import gnu.kawa.reflect.ArrayGet;
7
8 /** Implement the standard Scheme function "apply".
9  * This has been generalized so that the last (list argument)
10  * can be any sequence, or any primitive array coercible to Object[]. */

11
12 public class ApplyToArgs extends ProcedureN
13   implements CanInline
14 {
15   public int match1 (Object JavaDoc arg1, CallContext ctx)
16   {
17     if (arg1 instanceof Procedure)
18       return ((Procedure) arg1).match0(ctx);
19     else
20       return super.match1(arg1, ctx);
21   }
22
23   public int match2 (Object JavaDoc arg1, Object JavaDoc arg2, CallContext ctx)
24   {
25     if (arg1 instanceof Procedure)
26       return ((Procedure) arg1).match1(arg2, ctx);
27     else
28       return super.match2(arg1, arg2, ctx);
29   }
30
31   public int match3 (Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, CallContext ctx)
32   {
33     if (arg1 instanceof Procedure)
34       return ((Procedure) arg1).match2(arg2, arg3, ctx);
35     else
36       return super.match3(arg1, arg2, arg3, ctx);
37   }
38
39   public int match4 (Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4,
40                      CallContext ctx)
41   {
42     if (arg1 instanceof Procedure)
43       return ((Procedure) arg1).match3(arg2, arg3, arg4, ctx);
44     else
45       return super.match4(arg1, arg2, arg3, arg4, ctx);
46   }
47
48   public int matchN (Object JavaDoc[] args, CallContext ctx)
49   {
50     int n = args.length;
51     if (n > 0 && args[0] instanceof Procedure)
52       {
53         Procedure proc = (Procedure) args[0];
54         switch (n)
55           {
56           case 1:
57             return proc.match0(ctx);
58           case 2:
59             return proc.match1(args[1], ctx);
60           case 3:
61             return proc.match2(args[1], args[2], ctx);
62           case 4:
63             return proc.match3(args[1], args[2], args[3], ctx);
64           case 5:
65             return proc.match4(args[1], args[2], args[3], args[4], ctx);
66           default:
67             Object JavaDoc[] xargs = new Object JavaDoc[n-1];
68             System.arraycopy(args, 1, xargs, 0, n-1);
69             return proc.matchN(xargs, ctx);
70           }
71       }
72     return super.matchN(args, ctx);
73   }
74
75   public void check1 (Object JavaDoc arg1, CallContext ctx)
76   {
77     if (arg1 instanceof Procedure)
78       ((Procedure) arg1).check0(ctx);
79     else
80       super.check1(arg1, ctx);
81   }
82
83   public void check2 (Object JavaDoc arg1, Object JavaDoc arg2, CallContext ctx)
84   {
85     if (arg1 instanceof Procedure)
86       ((Procedure) arg1).check1(arg2, ctx);
87     else
88       super.check2(arg1, arg2, ctx);
89   }
90
91   public void check3 (Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, CallContext ctx)
92   {
93     if (arg1 instanceof Procedure)
94       ((Procedure) arg1).check2(arg2, arg3, ctx);
95     else
96       super.check3(arg1, arg2, arg3, ctx);
97   }
98
99   public void check4 (Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4,
100                      CallContext ctx)
101   {
102     if (arg1 instanceof Procedure)
103       ((Procedure) arg1).check3(arg2, arg3, arg4, ctx);
104     else
105       super.check4(arg1, arg2, arg3, arg4, ctx);
106   }
107
108   public void checkN (Object JavaDoc[] args, CallContext ctx)
109   {
110     int code = matchN(args, ctx);
111     if (code != 0)
112       {
113         Procedure proc = this;
114         if (args.length > 0 && args[0] instanceof Procedure)
115           {
116             proc = (Procedure) args[0];
117             Object JavaDoc[] xargs = new Object JavaDoc[args.length-1];
118             System.arraycopy(args, 1, xargs, 0, xargs.length);
119             args = xargs;
120           }
121     throw MethodProc.matchFailAsException(code, proc, args);
122       }
123   }
124
125   public ApplyToArgs (String JavaDoc name, Language language)
126   {
127     super(name);
128     this.language = language;
129   }
130
131   Language language;
132
133   public Expression inline (ApplyExp exp, ExpWalker walker)
134   {
135     Expression[] args = exp.getArgs();
136     int nargs = args.length - 1;
137     if (nargs >= 0)
138       {
139         Expression proc = args[0];
140         args[0] = proc;
141         Type ptype = proc.getType();
142         ApplyExp result;
143         Compilation comp = walker.getCompilation();
144         Language language = comp.getLanguage();
145         // This might be more cleanly handled at the type specifier. FIXME
146
if (Invoke.checkKnownClass(ptype, comp) < 0)
147           return exp;
148         ClassType ctype;
149         if (ptype.isSubtype(Compilation.typeProcedure))
150           {
151             Expression[] rargs = new Expression[nargs];
152             System.arraycopy(args, 1, rargs, 0, nargs);
153             result = new ApplyExp(proc, rargs);
154           }
155         else if (ptype.isSubtype(Compilation.typeType)
156                  || language.getTypeFor(proc,false) != null)
157           {
158             result = new ApplyExp(Invoke.make, args);
159           }
160         else if (ptype instanceof ArrayType)
161           {
162             Type elementType = ((ArrayType) ptype).getComponentType();
163             result = new ApplyExp(new ArrayGet(elementType), args);
164           }
165         else if (ptype instanceof ClassType
166                  && (ctype = (ClassType) ptype).isSubclass(typeList)
167                  && nargs == 1)
168           {
169             // We search for a "get(int)" method, rather than just using
170
// typeList.getDeclaredMethod("get", 1) to see if we make a
171
// a virtual call rather than an interface call.
172
Method get = ctype.getMethod("get", new Type[] { Type.int_type });
173             result = new ApplyExp(get, args);
174           }
175         else
176           return exp;
177         result.setLine(exp);
178         return ((InlineCalls) walker).walkApplyOnly(result);
179       }
180     return exp;
181   }
182
183   static final ClassType typeList
184   /* #ifdef JAVA2 */
185   = ClassType.make("java.util.List");
186   /* #else */
187   // = ClassType.make("gnu.lists.Sequence");
188
/* #endif */
189
190   public Object JavaDoc applyN (Object JavaDoc[] args) throws Throwable JavaDoc
191   {
192     Object JavaDoc proc = args[0];
193     Object JavaDoc[] rargs = new Object JavaDoc[args.length-1];
194     System.arraycopy(args, 1, rargs, 0, rargs.length);
195     if (proc instanceof Procedure)
196       {
197         return ((Procedure) proc).applyN(rargs);
198       }
199     if (proc instanceof gnu.bytecode.Type)
200       {
201         return gnu.kawa.reflect.Invoke.make.applyN(args);
202       }
203     if (proc instanceof
204         /* #ifdef JAVA2 */
205         java.util.List JavaDoc
206         /* #else */
207         // gnu.lists.Sequence
208
/* #endif */
209         )
210       {
211         if (args.length != 2)
212           throw new WrongArguments(this, args.length); // FIXME
213
int index = ((Number JavaDoc) rargs[0]).intValue();
214         /* #ifdef JAVA2 */
215         return ((java.util.List JavaDoc) proc).get(index);
216         /* #else */
217         // return ((gnu.lists.Sequence) proc).get(index);
218
/* #endif */
219       }
220     Class JavaDoc pclass = proc.getClass();
221     if (pclass.isArray())
222       {
223         if (args.length != 2)
224           throw new WrongArguments(this, args.length); // FIXME
225
return java.lang.reflect.Array.get(proc, ((Number JavaDoc) rargs[0]).intValue());
226       }
227     throw new WrongType(this, 0, proc, "procedure");
228   }
229 }
230
Popular Tags