1:
31: package ;
32:
33: import ;
34:
35: import ;
36: import ;
37: import ;
38:
39:
46: public class Term extends AbstractLValue
47: {
48: private LValue optimizedHeadValue;
49: private LValue headValue;
50: private ArrayList operators;
51: private ArrayList operands;
52: private InfixOperator[] operatorArray;
53: private LValue[] operandsArray;
54: private boolean initialized;
55:
56: public Term(final LValue headValue)
57: {
58: if (headValue == null)
59: {
60: throw new NullPointerException();
61: }
62:
63: this.headValue = headValue;
64: }
65:
66: public TypeValuePair evaluate() throws EvaluationException
67: {
68: TypeValuePair result = optimizedHeadValue.evaluate();
69: for (int i = 0; i < operandsArray.length; i++)
70: {
71: final LValue value = operandsArray[i];
72: final InfixOperator op = operatorArray[i];
73: result = op.evaluate(getContext(), result, value.evaluate());
74: }
75: return result;
76: }
77:
78: public void add(InfixOperator operator, LValue operand)
79: {
80: if (operator == null)
81: {
82: throw new NullPointerException();
83: }
84: if (operand == null)
85: {
86: throw new NullPointerException();
87: }
88:
89: if (operands == null || operators == null)
90: {
91: this.operands = new ArrayList();
92: this.operators = new ArrayList();
93: }
94:
95: operands.add(operand);
96: operators.add(operator);
97: initialized = false;
98: }
99:
100: public void initialize(FormulaContext context) throws EvaluationException
101: {
102: super.initialize(context);
103: if (operands == null || operators == null)
104: {
105: this.optimizedHeadValue = headValue;
106: this.optimizedHeadValue.initialize(context);
107: this.operandsArray = new LValue[0];
108: this.operatorArray = new InfixOperator[0];
109: return;
110: }
111:
112: if (initialized)
113: {
114: optimizedHeadValue.initialize(context);
115: for (int i = 0; i < operandsArray.length; i++)
116: {
117: LValue lValue = operandsArray[i];
118: lValue.initialize(context);
119: }
120: return;
121: }
122:
123: optimize(context);
124: }
125:
126: private void optimize(FormulaContext context) throws EvaluationException
127: {
128: ArrayList operators = (ArrayList) this.operators.clone();
129: ArrayList operands = (ArrayList) this.operands.clone();
130: this.optimizedHeadValue = headValue;
131:
132: while (true)
133: {
134:
135:
136: final InfixOperator op = (InfixOperator) operators.get(0);
137: int level = op.getLevel();
138: boolean moreThanOne = false;
139: for (int i = 1; i < operators.size(); i++)
140: {
141: final InfixOperator operator = (InfixOperator) operators.get(i);
142: final int opLevel = operator.getLevel();
143: if (opLevel != level)
144: {
145: moreThanOne = true;
146: level = Math.min(opLevel, level);
147: }
148: }
149:
150: if (moreThanOne == false)
151: {
152:
153: break;
154: }
155:
156:
157: Term subTerm = null;
158: for (int i = 0; i < operators.size(); i++)
159: {
160: final InfixOperator operator = (InfixOperator) operators.get(i);
161: if (operator.getLevel() != level)
162: {
163: subTerm = null;
164: continue;
165: }
166:
167: if (subTerm == null)
168: {
169: if (i == 0)
170: {
171: subTerm = new Term(optimizedHeadValue);
172: optimizedHeadValue = subTerm;
173: }
174: else
175: {
176: final LValue lval = (LValue) operands.get(i - 1);
177: subTerm = new Term(lval);
178: operands.set(i - 1, subTerm);
179: }
180: }
181:
182:
183: final LValue operand = (LValue) operands.get(i);
184: subTerm.add(operator, operand);
185: operands.remove(i);
186: operators.remove(i);
187:
188:
189: i -= 1;
190: }
191: }
192:
193: this.operatorArray = (InfixOperator[])
194: operators.toArray(new InfixOperator[operators.size()]);
195: this.operandsArray = (LValue[])
196: operands.toArray(new LValue[operands.size()]);
197: this.optimizedHeadValue.initialize(context);
198: for (int i = 0; i < operandsArray.length; i++)
199: {
200: final LValue value = operandsArray[i];
201: value.initialize(context);
202: }
203:
204: }
205:
206:
211: public LValue[] getChildValues()
212: {
213: final LValue[] values = new LValue[operandsArray.length + 1];
214: values[0] = headValue;
215: System.arraycopy(operandsArray, 0, values, 1, operandsArray.length);
216: return values;
217: }
218:
219:
220: public String toString()
221: {
222: StringBuffer b = new StringBuffer();
223:
224: b.append("(");
225: b.append(headValue);
226: if (operands != null && operators != null)
227: {
228: for (int i = 0; i < operands.size(); i++)
229: {
230: InfixOperator op = (InfixOperator) operators.get(i);
231: LValue value = (LValue) operands.get(i);
232: b.append(op);
233: b.append(value);
234: }
235: }
236: b.append(")");
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252: return b.toString();
253: }
254:
255:
261: public boolean isConstant()
262: {
263: if (headValue.isConstant() == false)
264: {
265: return false;
266: }
267:
268: for (int i = 0; i < operands.size(); i++)
269: {
270: LValue value = (LValue) operands.get(i);
271: if (value.isConstant() == false)
272: {
273: return false;
274: }
275: }
276: return true;
277: }
278:
279: public Object clone() throws CloneNotSupportedException
280: {
281: final Term o = (Term) super.clone();
282: if (operands != null)
283: {
284: o.operands = (ArrayList) operands.clone();
285: }
286: if (operators != null)
287: {
288: o.operators = (ArrayList) operators.clone();
289: }
290: o.headValue = (LValue) headValue.clone();
291: o.optimizedHeadValue = null;
292: o.operandsArray = null;
293: o.operatorArray = null;
294: o.initialized = false;
295: return o;
296: }
297:
298: public InfixOperator[] getOperands ()
299: {
300: return (InfixOperator[]) operands.toArray(new InfixOperator[operands.size()]);
301: }
302:
303: public LValue[] getOperators ()
304: {
305: return (LValue[]) operators.toArray(new LValue[operators.size()]);
306: }
307:
308: public LValue getHeadValue()
309: {
310: return headValue;
311: }
312:
313:
320: public LValue getOptimizedHeadValue()
321: {
322: return optimizedHeadValue;
323: }
324:
325:
330: public InfixOperator[] getOptimizedOperators()
331: {
332: return operatorArray;
333: }
334:
335:
340: public LValue[] getOptimizedOperands()
341: {
342: return operandsArray;
343: }
344: }