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 |