KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > es > parser > BinaryExpr


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.es.parser;
30
31 import com.caucho.es.ESBase;
32 import com.caucho.es.ESException;
33 import com.caucho.es.ESNumber;
34 import com.caucho.es.ESWrapperException;
35
36 import java.io.IOException JavaDoc;
37
38 /**
39  * Expr is an intermediate form representing an expression.
40  */

41 class BinaryExpr extends Expr {
42   Expr left;
43   Expr right;
44   int op;
45   String JavaDoc temp;
46   boolean isSimple;
47   
48   protected BinaryExpr(Block block, Expr left, Expr right, int op)
49   {
50     super(block);
51     
52     this.left = left;
53     this.right = right;
54     this.op = op;
55     isSimple = left.isSimple();
56     if ((op == Lexer.AND || op == Lexer.OR) && ! isSimple)
57       temp = block.function.getTemp();
58   }
59
60   static Expr create(Block block, Expr left, Expr right, int op)
61     throws ESException
62   {
63     if (left != null)
64       left.setUsed();
65     if (right != null)
66       right.setUsed();
67     
68     if (! (left instanceof LiteralExpr) || ! (right instanceof LiteralExpr))
69       return new BinaryExpr(block, left, right, op);
70
71     ESBase lvalue = ((LiteralExpr) left).getLiteral();
72     ESBase rvalue = ((LiteralExpr) right).getLiteral();
73     ESBase value;
74
75     try {
76       switch (op) {
77       case '*':
78         value = ESNumber.create(lvalue.toNum() * rvalue.toNum());
79         break;
80       
81       case '/':
82         value = ESNumber.create(lvalue.toNum() / rvalue.toNum());
83         break;
84       
85       case '-':
86         value = ESNumber.create(lvalue.toNum() - rvalue.toNum());
87         break;
88       
89       case '%':
90         value = ESNumber.create(lvalue.toNum() % rvalue.toNum());
91         break;
92
93       case Lexer.LSHIFT:
94         value = ESNumber.create(lvalue.toInt32() << rvalue.toInt32());
95         break;
96
97       case Lexer.RSHIFT:
98         value = ESNumber.create(lvalue.toInt32() >> rvalue.toInt32());
99         break;
100
101       case Lexer.URSHIFT:
102         value = ESNumber.create(lvalue.toInt32() >>> rvalue.toInt32());
103         break;
104
105       case '&':
106         value = ESNumber.create(lvalue.toInt32() & rvalue.toInt32());
107         break;
108
109       case '|':
110         value = ESNumber.create(lvalue.toInt32() | rvalue.toInt32());
111         break;
112
113       case '^':
114         value = ESNumber.create(lvalue.toInt32() ^ rvalue.toInt32());
115         break;
116
117       case Lexer.AND:
118         value = lvalue.toBoolean() ? rvalue : lvalue;
119         break;
120
121       case Lexer.OR:
122         value = lvalue.toBoolean() ? lvalue : rvalue;
123         break;
124
125       case ',':
126         value = rvalue;
127         break;
128
129       default:
130         throw new RuntimeException JavaDoc("" + (char) op);
131       }
132     } catch (Throwable JavaDoc e) {
133       throw new ESWrapperException(e);
134     }
135
136     return new LiteralExpr(block, value);
137   }
138   
139   int getType()
140   {
141     
142     switch (op) {
143     case '*':
144     case '/':
145     case '%':
146       return TYPE_NUMBER;
147       
148     case '-':
149       if (left.getType() == TYPE_INTEGER && right.getType() == TYPE_INTEGER)
150         return TYPE_INTEGER;
151       else
152         return TYPE_NUMBER;
153
154     case Lexer.LSHIFT:
155     case Lexer.RSHIFT:
156     case Lexer.URSHIFT:
157     case '&':
158     case '|':
159     case '^':
160       return TYPE_INTEGER;
161
162     case Lexer.AND:
163     case Lexer.OR:
164       if (left.getType() == right.getType())
165         return left.getType();
166       else if (left.isNum() && right.isNum())
167         return TYPE_NUMBER;
168       else
169         return TYPE_ES;
170
171     case ',':
172       return TYPE_ES;
173
174     default:
175       throw new RuntimeException JavaDoc("" + (char) op + " " + op);
176     }
177   }
178
179   void exprStatement(Function fun) throws ESException
180   {
181     switch (op) {
182     default:
183       left.exprStatement(fun);
184       right.exprStatement(fun);
185       break;
186     }
187   }
188
189   void printNumImpl() throws IOException JavaDoc
190   {
191     cl.print("(");
192     
193     switch (op) {
194     case '*':
195     case '/':
196     case '-':
197     case '%':
198       left.printNum();
199       cl.print(" " + (char) op + " ");
200       right.printNum();
201       break;
202
203     case Lexer.AND:
204       if (isSimple) {
205         left.printBoolean();
206         cl.print(" ? ");
207         right.printNum();
208         cl.print(":");
209         left.printNum();
210       }
211       else {
212         cl.print("(" + temp + " = ");
213         left.print();
214         cl.print(").toBoolean() ? ");
215         right.printNum();
216         cl.print(":" + temp + ".toNum()");
217       }
218       break;
219
220     case Lexer.OR:
221       if (isSimple) {
222         left.printBoolean();
223         cl.print(" ? ");
224         left.printNum();
225         cl.print(":");
226         right.printNum();
227       }
228       else {
229         cl.print("(" + temp + " = ");
230         left.print();
231         cl.print(").toBoolean() ? " + temp + ".toNum() : ");
232         right.printNum();
233       }
234       break;
235
236     default:
237       throw new IOException JavaDoc("foo");
238     }
239     
240     cl.print(")");
241   }
242
243   void printInt32Impl() throws IOException JavaDoc
244   {
245     cl.print("(");
246     
247     switch (op) {
248     case '-':
249       left.printInt32();
250       cl.print(" " + (char) op + " ");
251       right.printInt32();
252       break;
253
254     case Lexer.LSHIFT:
255       left.printInt32();
256       cl.print(" << ");
257       right.printInt32();
258       break;
259
260     case Lexer.RSHIFT:
261       left.printInt32();
262       cl.print(" >> ");
263       right.printInt32();
264       break;
265
266     case Lexer.URSHIFT:
267       left.printInt32();
268       cl.print(" >>> ");
269       right.printInt32();
270       break;
271
272     case '&':
273     case '|':
274     case '^':
275       left.printInt32();
276       cl.print(" " + (char) op + " ");
277       right.printInt32();
278       break;
279
280     case Lexer.AND:
281       if (isSimple) {
282         left.printBoolean();
283         cl.print(" ? ");
284         right.printInt32();
285         cl.print(":");
286         left.printInt32();
287       }
288       else {
289         cl.print("(" + temp + " = ");
290         left.print();
291         cl.print(").toBoolean() ? ");
292         right.printInt32();
293         cl.print(":" + temp + ".toInt32()");
294       }
295       break;
296
297     case Lexer.OR:
298       if (isSimple) {
299         left.printBoolean();
300         cl.print(" ? ");
301         left.printInt32();
302         cl.print(":");
303         right.printInt32();
304       }
305       else {
306         cl.print("(" + temp + " = ");
307         left.print();
308         cl.print(").toBoolean() ? " + temp + ".toInt32() : ");
309         right.printInt32();
310       }
311       break;
312
313     default:
314       throw new IOException JavaDoc("foo");
315     }
316     
317     cl.print(")");
318   }
319
320   void printBoolean() throws IOException JavaDoc
321   {
322     switch (op) {
323     case Lexer.AND:
324       cl.print("(");
325       left.printBoolean();
326       cl.print(" && ");
327       right.printBoolean();
328       cl.print(")");
329       break;
330
331     case Lexer.OR:
332       cl.print("(");
333       left.printBoolean();
334       cl.print(" || ");
335       right.printBoolean();
336       cl.print(")");
337       break;
338
339     default:
340       super.printBoolean();
341     }
342   }
343
344   void printBooleanImpl() throws IOException JavaDoc
345   {
346     cl.print("(");
347     
348     switch (op) {
349     case Lexer.AND:
350       left.printBoolean();
351       cl.print(" && ");
352       right.printBoolean();
353       break;
354
355     case Lexer.OR:
356       left.printBoolean();
357       cl.print(" || ");
358       right.printBoolean();
359       break;
360
361     default:
362       throw new IOException JavaDoc("foo");
363     }
364     
365     cl.print(")");
366   }
367
368   void printImpl() throws IOException JavaDoc
369   {
370     switch (op) {
371     case Lexer.AND:
372       if (isSimple) {
373         left.printBoolean();
374         cl.print(" ? ");
375         right.print();
376         cl.print(":");
377         left.print();
378       }
379       else {
380         cl.print("((" + temp + " = ");
381         left.print();
382         cl.print(").toBoolean() ? ");
383         right.print();
384         cl.print(":" + temp + ")");
385       }
386       break;
387
388     case Lexer.OR:
389       if (isSimple) {
390         left.printBoolean();
391         cl.print(" ? ");
392         left.print();
393         cl.print(":");
394         right.print();
395       }
396       else {
397         cl.print("((" + temp + " = ");
398         left.print();
399         cl.print(").toBoolean() ? " + temp + " : ");
400         right.print();
401         cl.print(")");
402       }
403       break;
404
405     case ',':
406       cl.print("_env.comma(");
407       left.print();
408       cl.print(", ");
409       right.print();
410       cl.print(")");
411       break;
412
413     default:
414       throw new IOException JavaDoc("foo");
415     }
416   }
417 }
418
Popular Tags