Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
|
ngeoffray
2012/08/17 08:32:59
Maybe change this file to dart_operations.dart?
floitsch
2012/09/03 14:34:52
Done.
| |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 interface Operation { | 5 interface Operation { |
| 6 final SourceString name; | 6 final SourceString name; |
| 7 bool isUserDefinable(); | 7 bool isUserDefinable(); |
| 8 } | 8 } |
| 9 | 9 |
| 10 interface UnaryOperation extends Operation { | 10 interface UnaryOperation extends Operation { |
| 11 /** Returns [:null:] if it was unable to fold the operation. */ | 11 /** Returns [:null:] if it was unable to fold the operation. */ |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 } | 56 } |
| 57 | 57 |
| 58 interface BinaryOperation extends Operation { | 58 interface BinaryOperation extends Operation { |
| 59 /** Returns [:null:] if it was unable to fold the operation. */ | 59 /** Returns [:null:] if it was unable to fold the operation. */ |
| 60 Constant fold(Constant left, Constant right); | 60 Constant fold(Constant left, Constant right); |
| 61 } | 61 } |
| 62 | 62 |
| 63 /** | 63 /** |
| 64 * Operations that only work if both arguments are integers. | 64 * Operations that only work if both arguments are integers. |
| 65 */ | 65 */ |
| 66 class BinaryIntOperation implements BinaryOperation { | 66 class BinaryBitOperation implements BinaryOperation { |
| 67 bool isUserDefinable() => true; | 67 bool isUserDefinable() => true; |
| 68 const BinaryIntOperation(); | 68 const BinaryBitOperation(); |
| 69 Constant fold(Constant left, Constant right) { | 69 Constant fold(Constant left, Constant right) { |
| 70 if (left.isInt() && right.isInt()) { | 70 if (left.isInt() && right.isInt()) { |
| 71 IntConstant leftInt = left; | 71 IntConstant leftInt = left; |
| 72 IntConstant rightInt = right; | 72 IntConstant rightInt = right; |
| 73 int resultValue = foldInts(leftInt.value, rightInt.value); | 73 int resultValue = foldInts(leftInt.value, rightInt.value); |
| 74 if (resultValue === null) return null; | 74 if (resultValue === null) return null; |
| 75 return new IntConstant(resultValue); | 75 return new IntConstant(resultValue); |
| 76 } | 76 } |
| 77 return null; | 77 return null; |
| 78 } | 78 } |
| 79 | 79 |
| 80 abstract int foldInts(int left, int right); | 80 abstract int foldInts(int left, int right); |
| 81 } | 81 } |
| 82 | 82 |
| 83 class BitOrOperation extends BinaryIntOperation { | 83 class BitOrOperation extends BinaryBitOperation { |
| 84 final SourceString name = const SourceString('|'); | 84 final SourceString name = const SourceString('|'); |
| 85 const BitOrOperation(); | 85 const BitOrOperation(); |
| 86 int foldInts(int left, int right) => left | right; | 86 int foldInts(int left, int right) => left | right; |
| 87 } | 87 } |
| 88 | 88 |
| 89 class BitAndOperation extends BinaryIntOperation { | 89 class BitAndOperation extends BinaryBitOperation { |
| 90 final SourceString name = const SourceString('&'); | 90 final SourceString name = const SourceString('&'); |
| 91 const BitAndOperation(); | 91 const BitAndOperation(); |
| 92 int foldInts(int left, int right) => left & right; | 92 int foldInts(int left, int right) => left & right; |
| 93 } | 93 } |
| 94 | 94 |
| 95 class BitXorOperation extends BinaryIntOperation { | 95 class BitXorOperation extends BinaryBitOperation { |
| 96 final SourceString name = const SourceString('^'); | 96 final SourceString name = const SourceString('^'); |
| 97 const BitXorOperation(); | 97 const BitXorOperation(); |
| 98 int foldInts(int left, int right) => left ^ right; | 98 int foldInts(int left, int right) => left ^ right; |
| 99 } | 99 } |
| 100 | 100 |
| 101 class ShiftLeftOperation extends BinaryIntOperation { | 101 class ShiftLeftOperation extends BinaryBitOperation { |
| 102 final SourceString name = const SourceString('<<'); | 102 final SourceString name = const SourceString('<<'); |
| 103 const ShiftLeftOperation(); | 103 const ShiftLeftOperation(); |
| 104 int foldInts(int left, int right) { | 104 int foldInts(int left, int right) { |
| 105 // TODO(floitsch): find a better way to guard against excessive shifts to | 105 // TODO(floitsch): find a better way to guard against excessive shifts to |
| 106 // the left. | 106 // the left. |
| 107 if (right > 100 || right < 0) return null; | 107 if (right > 100 || right < 0) return null; |
| 108 return left << right; | 108 return left << right; |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 | 111 |
| 112 class ShiftRightOperation extends BinaryIntOperation { | 112 class ShiftRightOperation extends BinaryBitOperation { |
| 113 final SourceString name = const SourceString('>>'); | 113 final SourceString name = const SourceString('>>'); |
| 114 const ShiftRightOperation(); | 114 const ShiftRightOperation(); |
| 115 int foldInts(int left, int right) { | 115 int foldInts(int left, int right) { |
| 116 if (right < 0) return null; | 116 if (right < 0) return null; |
| 117 return left >> right; | 117 return left >> right; |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 | 120 |
| 121 class BinaryBoolOperation implements BinaryOperation { | 121 class BinaryBoolOperation implements BinaryOperation { |
| 122 bool isUserDefinable() => false; | 122 bool isUserDefinable() => false; |
| 123 const BinaryBoolOperation(); | 123 const BinaryBoolOperation(); |
| 124 Constant fold(Constant left, Constant right) { | 124 Constant fold(Constant left, Constant right) { |
| 125 if (left.isBool() && right.isBool()) { | 125 if (left.isBool() && right.isBool()) { |
| 126 BoolConstant leftBool = left; | 126 BoolConstant leftBool = left; |
| 127 BoolConstant rightBool = right; | 127 BoolConstant rightBool = right; |
| 128 bool resultValue = foldBools(leftBool.value, rightBool.value); | 128 bool resultValue = foldBools(leftBool.value, rightBool.value); |
| 129 return new BoolConstant(resultValue); | 129 return new BoolConstant(resultValue); |
| 130 } | 130 } |
| 131 return null; | 131 return null; |
| 132 } | 132 } |
| 133 | 133 |
| 134 abstract bool foldBools(bool left, bool right); | 134 abstract bool foldBools(bool left, bool right); |
| 135 } | 135 } |
| 136 | 136 |
| 137 class BooleanAnd extends BinaryBoolOperation { | 137 class BooleanAndOperation extends BinaryBoolOperation { |
| 138 final SourceString name = const SourceString('&&'); | 138 final SourceString name = const SourceString('&&'); |
| 139 const BooleanAnd(); | 139 const BooleanAndOperation(); |
| 140 bool foldBools(bool left, bool right) => left && right; | 140 bool foldBools(bool left, bool right) => left && right; |
| 141 } | 141 } |
| 142 | 142 |
| 143 class BooleanOr extends BinaryBoolOperation { | 143 class BooleanOrOperation extends BinaryBoolOperation { |
| 144 final SourceString name = const SourceString('||'); | 144 final SourceString name = const SourceString('||'); |
| 145 const BooleanOr(); | 145 const BooleanOrOperation(); |
| 146 bool foldBools(bool left, bool right) => left || right; | 146 bool foldBools(bool left, bool right) => left || right; |
| 147 } | 147 } |
| 148 | 148 |
| 149 class ArithmeticNumOperation implements BinaryOperation { | 149 class ArithmeticNumOperation implements BinaryOperation { |
| 150 bool isUserDefinable() => true; | 150 bool isUserDefinable() => true; |
| 151 const ArithmeticNumOperation(); | 151 const ArithmeticNumOperation(); |
| 152 Constant fold(Constant left, Constant right) { | 152 Constant fold(Constant left, Constant right) { |
| 153 if (left.isNum() && right.isNum()) { | 153 if (left.isNum() && right.isNum()) { |
| 154 NumConstant leftNum = left; | 154 NumConstant leftNum = left; |
| 155 NumConstant rightNum = right; | 155 NumConstant rightNum = right; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 return null; | 292 return null; |
| 293 } | 293 } |
| 294 return new BoolConstant(left == right); | 294 return new BoolConstant(left == right); |
| 295 } | 295 } |
| 296 } | 296 } |
| 297 | 297 |
| 298 class IdentityOperation implements BinaryOperation { | 298 class IdentityOperation implements BinaryOperation { |
| 299 final SourceString name = const SourceString('==='); | 299 final SourceString name = const SourceString('==='); |
| 300 bool isUserDefinable() => false; | 300 bool isUserDefinable() => false; |
| 301 const IdentityOperation(); | 301 const IdentityOperation(); |
| 302 Constant fold(Constant left, Constant right) { | 302 BoolConstant fold(Constant left, Constant right) { |
| 303 // In order to preserve runtime semantics which says that NaN !== NaN don't | 303 // In order to preserve runtime semantics which says that NaN !== NaN don't |
| 304 // constant fold NaN === NaN. Otherwise the output depends on inlined | 304 // constant fold NaN === NaN. Otherwise the output depends on inlined |
| 305 // variables and other optimizations. | 305 // variables and other optimizations. |
| 306 if (left.isNaN() && right.isNaN()) return null; | 306 if (left.isNaN() && right.isNaN()) return null; |
| 307 return new BoolConstant(left == right); | 307 return new BoolConstant(left == right); |
| 308 } | 308 } |
| 309 } | 309 } |
| 310 | |
| 311 interface FoldingOperations { | |
| 312 BinaryOperation get add(); | |
| 313 BinaryOperation get bitAnd(); | |
| 314 UnaryOperation get bitNot(); | |
| 315 BinaryOperation get bitOr(); | |
| 316 BinaryOperation get bitXor(); | |
| 317 BinaryOperation get booleanAnd(); | |
| 318 BinaryOperation get booleanOr(); | |
| 319 BinaryOperation get divide(); | |
| 320 BinaryOperation get equal(); | |
| 321 BinaryOperation get greaterEqual(); | |
| 322 BinaryOperation get greater(); | |
| 323 BinaryOperation get identity(); | |
| 324 BinaryOperation get lessEqual(); | |
| 325 BinaryOperation get less(); | |
| 326 BinaryOperation get modulo(); | |
| 327 BinaryOperation get multiply(); | |
| 328 UnaryOperation get negate(); | |
| 329 UnaryOperation get not(); | |
| 330 BinaryOperation get shiftLeft(); | |
| 331 BinaryOperation get shiftRight(); | |
| 332 BinaryOperation get subtract(); | |
| 333 BinaryOperation get truncatingDivide(); | |
| 334 } | |
| 335 | |
| 336 /** Folding operations following the Dart semantics. */ | |
| 337 class DartFoldingOperations implements FoldingOperations { | |
| 338 final add = const AddOperation(); | |
| 339 final bitAnd = const BitAndOperation(); | |
| 340 final bitNot = const BitNotOperation(); | |
| 341 final bitOr = const BitOrOperation(); | |
| 342 final bitXor = const BitXorOperation(); | |
| 343 final booleanAnd = const BooleanAndOperation(); | |
| 344 final booleanOr = const BooleanOrOperation(); | |
| 345 final divide = const DivideOperation(); | |
| 346 final equal = const EqualsOperation(); | |
| 347 final greaterEqual = const GreaterEqualOperation(); | |
| 348 final greater = const GreaterOperation(); | |
| 349 final identity = const IdentityOperation(); | |
| 350 final lessEqual = const LessEqualOperation(); | |
| 351 final less = const LessOperation(); | |
| 352 final modulo = const ModuloOperation(); | |
| 353 final multiply = const MultiplyOperation(); | |
| 354 final negate = const NegateOperation(); | |
| 355 final not = const NotOperation(); | |
| 356 final shiftLeft = const ShiftLeftOperation(); | |
| 357 final shiftRight = const ShiftRightOperation(); | |
| 358 final subtract = const SubtractOperation(); | |
| 359 final truncatingDivide = const TruncatingDivideOperation(); | |
| 360 | |
| 361 const DartFoldingOperations(); | |
| 362 } | |
| OLD | NEW |