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 11 12 public class ApplyToArgs extends ProcedureN 13 implements CanInline 14 { 15 public int match1 (Object 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 arg1, Object 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 arg1, Object arg2, Object 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 arg1, Object arg2, Object arg3, Object 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 [] 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 [] xargs = new Object [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 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 arg1, Object 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 arg1, Object arg2, Object 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 arg1, Object arg2, Object arg3, Object 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 [] 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 [] xargs = new Object [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 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 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 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 185 = ClassType.make("java.util.List"); 186 187 189 190 public Object applyN (Object [] args) throws Throwable 191 { 192 Object proc = args[0]; 193 Object [] rargs = new Object [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 205 java.util.List 206 207 209 ) 210 { 211 if (args.length != 2) 212 throw new WrongArguments(this, args.length); int index = ((Number ) rargs[0]).intValue(); 214 215 return ((java.util.List ) proc).get(index); 216 217 219 } 220 Class pclass = proc.getClass(); 221 if (pclass.isArray()) 222 { 223 if (args.length != 2) 224 throw new WrongArguments(this, args.length); return java.lang.reflect.Array.get(proc, ((Number ) rargs[0]).intValue()); 226 } 227 throw new WrongType(this, 0, proc, "procedure"); 228 } 229 } 230 | Popular Tags |