1 package gnu.kawa.functions; 2 import gnu.bytecode.*; 3 import gnu.mapping.*; 4 import gnu.expr.*; 5 import gnu.mapping.Procedure; 6 import gnu.kawa.reflect.Invoke; 7 import gnu.kawa.reflect.ArraySet; 8 9 10 11 public class Setter extends Procedure1 implements CanInline, HasSetter 12 { 13 public static final Setter setter = new Setter(); 14 static { setter.setName("setter"); } 15 16 public static Object setter (Procedure arg) 17 { 18 return arg.getSetter(); 19 } 20 21 public Object apply1 (Object arg) 22 { 23 if (! (arg instanceof Procedure)) 24 { 25 26 if (arg instanceof java.util.List ) 27 return new SetList((java.util.List ) arg); 28 29 32 Class cl = arg.getClass(); 33 if (cl.isArray()) 34 return new SetArray(arg, Language.getDefaultLanguage()); 35 } 36 return ((Procedure)arg).getSetter(); 37 } 38 39 public Expression inline (ApplyExp exp, ExpWalker walker) 40 { 41 Expression[] args = exp.getArgs(); 42 if (args.length == 1) 43 { 44 Expression arg = args[0]; 45 Type argType = arg.getType(); 46 ClassType ctype; 47 if (argType instanceof ArrayType) 48 { 49 return new SetArrayExp(arg, (ArrayType) argType); 50 } 51 if (argType instanceof ClassType 52 && (ctype = (ClassType) argType).isSubclass(ApplyToArgs.typeList)) 53 { 54 if (exp instanceof SetListExp) 55 return exp; 56 else 57 return new SetListExp(exp.getFunction(), args); 58 } 59 if (arg instanceof ReferenceExp) 60 { 61 Declaration decl = ((ReferenceExp) arg).getBinding(); 62 if (decl != null) 63 arg = decl.getValue(); 64 } 65 if (arg instanceof QuoteExp) 66 { 67 Object value = ((QuoteExp) arg).getValue(); 68 if (value instanceof Procedure) 69 { 70 Object setter = ((Procedure) value).getSetter(); 71 if (setter instanceof Procedure) 72 { 73 if (setter instanceof java.io.Externalizable ) 74 return new QuoteExp(setter); 75 Declaration decl 76 = Declaration.getDeclaration((Procedure) setter); 77 if (decl != null) 78 return new ReferenceExp(decl); 79 } 80 } 81 } 82 } 83 return exp; 84 } 85 86 public void set1(Object arg1, Object value) throws Throwable 87 { 88 ((Procedure) arg1).setSetter((Procedure) value); 89 } 90 91 static final ClassType setterType = ClassType.make("gnu.kawa.functions.Setter"); 92 static final Field setterField = setterType.getDeclaredField("setter"); 93 public static final Declaration setterDecl = new Declaration("setter", setterField); 94 static { setterDecl.noteValue(new QuoteExp(Setter.setter)); } 95 96 } 97 98 class SetArray extends Procedure2 99 { 100 Object array; 101 Type elementType; 102 public SetArray (Object array, Language language) 103 { 104 Class elementClass = array.getClass().getComponentType(); 105 elementType = language.getTypeFor(elementClass); 106 this.array = array; 107 } 108 109 public Object apply2 (Object index, Object value) 110 { 111 value = elementType.coerceFromObject(value); 112 java.lang.reflect.Array.set(array, 113 ((Number ) index).intValue(), 114 value); 115 return Values.empty; 116 } 117 } 118 119 class SetList extends Procedure2 120 { 121 122 java.util.List list; 123 public SetList (java.util.List list) 124 { 125 this.list = list; 126 } 127 128 134 Type elementType; 135 136 public Object apply2 (Object index, Object value) 137 { 138 list.set(((Number ) index).intValue(), value); 139 return Values.empty; 140 } 141 } 142 143 class SetArrayExp extends ApplyExp 144 { 145 public static final ClassType typeSetArray 146 = ClassType.make("gnu.kawa.functions.SetArray"); 147 148 Type elementType; 149 150 public SetArrayExp (Expression array, ArrayType arrayType) 151 { 152 super(Invoke.make, new Expression[] { new QuoteExp(typeSetArray), array }); 153 elementType = arrayType.getComponentType(); 154 } 155 156 public Expression inline (ApplyExp exp, InlineCalls walker, Declaration decl) 157 { 158 Expression[] args = exp.getArgs(); 159 if (args.length == 2) 160 { 161 Expression array = this.getArgs()[1]; 162 Expression[] xargs = new Expression[3]; 163 xargs[0] = array; 164 xargs[1] = args[0]; 165 xargs[2] = args[1]; 166 ArraySet arrSetter = new ArraySet(elementType); 167 return walker.walkApplyOnly(new ApplyExp(arrSetter, xargs)); 168 } 169 return exp; 170 } 171 } 172 173 class SetListExp extends ApplyExp 174 { 175 public SetListExp (Expression func, Expression[] args) 176 { 177 super(func, args); 178 } 179 180 public Expression inline (ApplyExp exp, InlineCalls walker, Declaration decl) 181 { 182 Expression[] args = exp.getArgs(); 183 if (args.length == 2) 184 { 185 Expression[] xargs = new Expression[4]; 186 xargs[0] = this.getArgs()[0]; 187 xargs[1] = QuoteExp.getInstance("set"); 188 xargs[2] = Convert.makeCoercion(args[0], Type.int_type); 189 xargs[3] = args[1]; 190 Expression set 191 = walker.walkApplyOnly(new ApplyExp(Invoke.invoke, xargs)); 192 return Convert.makeCoercion(set, Type.void_type); 193 } 194 return exp; 195 } 196 } 197 198 | Popular Tags |