01: // Copyright (c) 2000, 2001 Per M.A. Bothner.
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.expr;
05:
06: import gnu.bytecode.*;
07:
08: /**
09: * A Target which is some variable that implements gnu.lists.Consumer.
10: */
11:
12: public class ConsumerTarget extends Target {
13: Variable consumer;
14:
15: public ConsumerTarget(Variable consumer) {
16: this .consumer = consumer;
17: }
18:
19: public Variable getConsumerVariable() {
20: return consumer;
21: }
22:
23: /** Compile an expression using a temporary Consumer, if needed. */
24: public static void compileUsingConsumer(Expression exp,
25: Compilation comp, Target target) {
26: if (target instanceof ConsumerTarget
27: || target instanceof IgnoreTarget)
28: exp.compile(comp, target);
29: else {
30: CodeAttr code = comp.getCode();
31: Scope scope = code.pushScope();
32: Variable values = scope.addVariable(code, comp.typeValues,
33: null);
34: ConsumerTarget ctarget = new ConsumerTarget(values);
35: code.emitInvokeStatic(comp.typeValues.getDeclaredMethod(
36: "make", 0));
37: code.emitStore(values);
38: exp.compile(comp, ctarget);
39: code.emitLoad(values);
40: code.popScope();
41: target.compileFromStack(comp, Compilation.typeValues);
42: }
43: }
44:
45: public void compileFromStack(Compilation comp, Type stackType) {
46: CodeAttr code = comp.getCode();
47: String methodName = null;
48: Method method = null;
49: if (stackType instanceof PrimType) {
50: char sig = stackType.getSignature().charAt(0);
51: switch (sig) {
52: case 'B':
53: case 'S':
54: case 'I':
55: methodName = "writeInt";
56: break;
57: case 'J':
58: methodName = "writeLong";
59: break;
60: case 'F':
61: methodName = "writeFloat";
62: break;
63: case 'D':
64: methodName = "writeDouble";
65: break;
66: case 'C':
67: methodName = "writeChar";
68: break;
69: case 'Z':
70: methodName = "writeBoolean";
71: break;
72: case 'V':
73: return;
74: }
75: } else {
76: if (SeriesTarget.isSingletonType(stackType))
77: methodName = "writeObject";
78: else {
79: method = comp.typeValues.getDeclaredMethod(
80: "writeValues", 2);
81: code.emitLoad(consumer);
82: code.emitInvokeStatic(method);
83: return;
84: }
85: }
86: code.emitLoad(consumer);
87: code.emitSwap();
88: if (method == null && methodName != null)
89: method = Compilation.typeConsumer.getDeclaredMethod(
90: methodName, 1);
91: if (method != null)
92: code.emitInvokeInterface(method);
93: }
94:
95: public Type getType() {
96: return Compilation.scmSequenceType;
97: }
98: }
|