1 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 ; 37 38 41 class BinaryExpr extends Expr { 42 Expr left; 43 Expr right; 44 int op; 45 String 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 ("" + (char) op); 131 } 132 } catch (Throwable 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 ("" + (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 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 ("foo"); 238 } 239 240 cl.print(")"); 241 } 242 243 void printInt32Impl() throws IOException 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 ("foo"); 315 } 316 317 cl.print(")"); 318 } 319 320 void printBoolean() throws IOException 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 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 ("foo"); 363 } 364 365 cl.print(")"); 366 } 367 368 void printImpl() throws IOException 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 ("foo"); 415 } 416 } 417 } 418 | Popular Tags |