KickJava   Java API By Example, From Geeks To Geeks.

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


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 /** Implements Kawa extension function "setter", as in SRFI-17. */
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 JavaDoc setter (Procedure arg)
17   {
18     return arg.getSetter();
19   }
20
21   public Object JavaDoc apply1 (Object JavaDoc arg)
22   {
23     if (! (arg instanceof Procedure))
24       {
25         /* #ifdef JAVA2 */
26         if (arg instanceof java.util.List JavaDoc)
27           return new SetList((java.util.List JavaDoc) arg);
28         /* #else */
29         // if (arg instanceof gnu.lists.Sequence)
30
// return new SetList((gnu.lists.Sequence) arg);
31
/* #endif */
32         Class JavaDoc cl = arg.getClass();
33         if (cl.isArray())
34           return new SetArray(arg, Language.getDefaultLanguage()/*FIXME*/);
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 JavaDoc value = ((QuoteExp) arg).getValue();
68             if (value instanceof Procedure)
69               {
70                 Object JavaDoc setter = ((Procedure) value).getSetter();
71                 if (setter instanceof Procedure)
72                   {
73                     if (setter instanceof java.io.Externalizable JavaDoc)
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 JavaDoc arg1, Object JavaDoc value) throws Throwable JavaDoc
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 JavaDoc array;
101   Type elementType;
102   public SetArray (Object JavaDoc array, Language language)
103   {
104     Class JavaDoc elementClass = array.getClass().getComponentType();
105     elementType = language.getTypeFor(elementClass);
106     this.array = array;
107   }
108
109   public Object JavaDoc apply2 (Object JavaDoc index, Object JavaDoc value)
110   {
111     value = elementType.coerceFromObject(value);
112     java.lang.reflect.Array.set(array,
113                                 ((Number JavaDoc) index).intValue(),
114                                 value);
115     return Values.empty;
116   }
117 }
118
119 class SetList extends Procedure2
120 {
121   /* #ifdef JAVA2 */
122   java.util.List JavaDoc list;
123   public SetList (java.util.List JavaDoc list)
124   {
125     this.list = list;
126   }
127   /* #else */
128   // gnu.lists.Sequence list;
129
// public SetList (gnu.lists.Sequence list)
130
// {
131
// this.list = list;
132
// }
133
/* #endif */
134   Type elementType;
135
136   public Object JavaDoc apply2 (Object JavaDoc index, Object JavaDoc value)
137   {
138     list.set(((Number JavaDoc) 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