01: package gnu.kawa.functions;
02:
03: import gnu.bytecode.*;
04: import gnu.mapping.*;
05: import gnu.kawa.reflect.*;
06: import gnu.expr.*;
07:
08: /** Procedure to get the value of a named component of an object. */
09:
10: public class SetNamedPart extends Procedure3 implements HasSetter,
11: CanInline {
12: public static final SetNamedPart setNamedPart = new SetNamedPart();
13: static {
14: setNamedPart.setName("setNamedPart");
15: }
16:
17: public Expression inline(ApplyExp exp, ExpWalker walker) {
18: Expression[] args = exp.getArgs();
19: if (args.length != 3 || !(args[1] instanceof QuoteExp))
20: return exp;
21: Expression context = args[0];
22: String mname = ((QuoteExp) args[1]).getValue().toString();
23: Type type = context.getType();
24: Compilation comp = walker.getCompilation();
25: Language language = comp.getLanguage();
26: Type typeval = language.getTypeFor(context);
27: ClassType caller = comp == null ? null
28: : comp.curClass != null ? comp.curClass
29: : comp.mainClass;
30: if (typeval instanceof ClassType)
31: return new ApplyExp(SlotSet.set$Mnstatic$Mnfield$Ex, args);
32:
33: if (type instanceof ClassType) {
34: Object part = SlotSet.lookupMember((ClassType) type, mname,
35: caller);
36: if (part != null) {
37: // FIXME: future kludge to avoid re-doing SlotGet.getField.
38: // args = new Expression[] { context, new QuoteExp(part) });
39: return new ApplyExp(SlotSet.set$Mnfield$Ex, args);
40: }
41: }
42: return exp;
43: }
44:
45: public Object apply3(Object container, Object part, Object value) {
46: /*
47: if (container implements HasNamedParts)
48: return ((HasNamedParts) container).getNamedPart(part);
49: */
50: if (container instanceof Namespace) {
51: Namespace ns = (Namespace) container;
52: String uri = ns.getName();
53: if (uri.startsWith("class:"))
54: container = ClassType.make(uri.substring(6));
55: else {
56: Symbol sym = ns.getSymbol(part.toString());
57: Environment env = Environment.getCurrent();
58: Environment.getCurrent().put(sym, value);
59: return Values.empty;
60: }
61: }
62: if (container instanceof Class)
63: container = (ClassType) Type.make((Class) container);
64: if (container instanceof ClassType) {
65: try {
66: gnu.kawa.reflect.SlotSet.setStaticField(container, part
67: .toString(), value);
68: return Values.empty;
69: } catch (Throwable ex) {
70: // FIXME!
71: }
72: }
73:
74: gnu.kawa.reflect.SlotSet.setField(container, part.toString(),
75: value);
76: return Values.empty;
77: }
78: }
|