Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(762)

Side by Side Diff: frog/leg/operations.dart

Issue 9873021: Move frog/leg to lib/compiler/implementation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/leg/native_handler.dart ('k') | frog/leg/resolver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 interface Operation {
6
7 }
8
9 interface UnaryOperation extends Operation {
10 /** Returns [:null:] if it was unable to fold the operation. */
11 Constant fold(Constant constant);
12 }
13
14 class BitNotOperation implements UnaryOperation {
15 const BitNotOperation();
16 Constant fold(Constant constant) {
17 if (constant.isInt()) {
18 IntConstant intConstant = constant;
19 return new IntConstant(~intConstant.value);
20 }
21 return null;
22 }
23 }
24
25 class NegateOperation implements UnaryOperation {
26 const NegateOperation();
27 Constant fold(Constant constant) {
28 if (constant.isInt()) {
29 IntConstant intConstant = constant;
30 return new IntConstant(-intConstant.value);
31 }
32 if (constant.isDouble()) {
33 DoubleConstant doubleConstant = constant;
34 return new DoubleConstant(-doubleConstant.value);
35 }
36 return null;
37 }
38 }
39
40 class NotOperation implements UnaryOperation {
41 const NotOperation();
42 Constant fold(Constant constant) {
43 if (constant.isBool()) {
44 BoolConstant boolConstant = constant;
45 return boolConstant.negate();
46 }
47 return null;
48 }
49 }
50
51 interface BinaryOperation extends Operation {
52 /** Returns [:null:] if it was unable to fold the operation. */
53 Constant fold(Constant left, Constant right);
54 }
55
56 /**
57 * Operations that only work if both arguments are integers.
58 */
59 class BinaryIntOperation implements BinaryOperation {
60 const BinaryIntOperation();
61 Constant fold(Constant left, Constant right) {
62 if (left.isInt() && right.isInt()) {
63 IntConstant leftInt = left;
64 IntConstant rightInt = right;
65 int resultValue = foldInts(leftInt.value, rightInt.value);
66 if (resultValue === null) return null;
67 return new IntConstant(resultValue);
68 }
69 return null;
70 }
71
72 abstract int foldInts(int left, int right);
73 }
74
75 class BitOrOperation extends BinaryIntOperation {
76 const BitOrOperation();
77 int foldInts(int left, int right) => left | right;
78 }
79
80 class BitAndOperation extends BinaryIntOperation {
81 const BitAndOperation();
82 int foldInts(int left, int right) => left & right;
83 }
84
85 class BitXorOperation extends BinaryIntOperation {
86 const BitXorOperation();
87 int foldInts(int left, int right) => left ^ right;
88 }
89
90 class ShiftLeftOperation extends BinaryIntOperation {
91 const ShiftLeftOperation();
92 int foldInts(int left, int right) {
93 // TODO(floitsch): find a better way to guard against excessive shifts to
94 // the left.
95 if (right > 100 || right < 0) return null;
96 return left << right;
97 }
98 }
99
100 class ShiftRightOperation extends BinaryIntOperation {
101 const ShiftRightOperation();
102 int foldInts(int left, int right) {
103 if (right < 0) return null;
104 return left >> right;
105 }
106 }
107
108 class BinaryBoolOperation implements BinaryOperation {
109 const BinaryBoolOperation();
110 Constant fold(Constant left, Constant right) {
111 if (left.isBool() && right.isBool()) {
112 BoolConstant leftBool = left;
113 BoolConstant rightBool = right;
114 bool resultValue = foldBools(leftBool.value, rightBool.value);
115 return new BoolConstant(resultValue);
116 }
117 return null;
118 }
119
120 abstract bool foldBools(bool left, bool right);
121 }
122
123 class BooleanAnd extends BinaryBoolOperation {
124 const BooleanAnd();
125 bool foldBools(bool left, bool right) => left && right;
126 }
127
128 class BooleanOr extends BinaryBoolOperation {
129 const BooleanOr();
130 bool foldBools(bool left, bool right) => left || right;
131 }
132
133 class ArithmeticNumOperation implements BinaryOperation {
134 const ArithmeticNumOperation();
135 Constant fold(Constant left, Constant right) {
136 if (left.isNum() && right.isNum()) {
137 NumConstant leftNum = left;
138 NumConstant rightNum = right;
139 num foldedValue;
140 if (left.isInt() && right.isInt()) {
141 foldedValue = foldInts(leftNum.value, rightNum.value);
142 } else {
143 foldedValue = foldNums(leftNum.value, rightNum.value);
144 }
145 // A division by 0 means that we might not have a folded value.
146 if (foldedValue === null) return null;
147 if (left.isInt() && right.isInt() && !isDivide()) {
148 assert(foldedValue is int);
149 return new IntConstant(foldedValue);
150 } else {
151 return new DoubleConstant(foldedValue);
152 }
153 }
154 }
155
156 bool isDivide() => false;
157 num foldInts(int left, int right) => foldNums(left, right);
158 abstract num foldNums(num left, num right);
159 }
160
161 class SubtractOperation extends ArithmeticNumOperation {
162 const SubtractOperation();
163 num foldNums(num left, num right) => left - right;
164 }
165
166 class MultiplyOperation extends ArithmeticNumOperation {
167 const MultiplyOperation();
168 num foldNums(num left, num right) => left * right;
169 }
170
171 class ModuloOperation extends ArithmeticNumOperation {
172 const ModuloOperation();
173 int foldInts(int left, int right) {
174 if (right == 0) return null;
175 return left % right;
176 }
177 num foldNums(num left, num right) => left % right;
178 }
179
180 class TruncatingDivideOperation extends ArithmeticNumOperation {
181 const TruncatingDivideOperation();
182 int foldInts(int left, int right) {
183 if (right == 0) return null;
184 return left ~/ right;
185 }
186 num foldNums(num left, num right) => left ~/ right;
187 }
188
189 class DivideOperation extends ArithmeticNumOperation {
190 const DivideOperation();
191 num foldNums(num left, num right) => left / right;
192 bool isDivide() => true;
193 }
194
195 class AddOperation implements BinaryOperation {
196 const AddOperation();
197 Constant fold(Constant left, Constant right) {
198 if (left.isInt() && right.isInt()) {
199 IntConstant leftInt = left;
200 IntConstant rightInt = right;
201 return new IntConstant(leftInt.value + rightInt.value);
202 } else if (left.isNum() && right.isNum()) {
203 NumConstant leftNum = left;
204 NumConstant rightNum = right;
205 return new DoubleConstant(leftNum.value + rightNum.value);
206 } else if (left.isString() && !right.isObject()) {
207 PrimitiveConstant primitiveRight = right;
208 DartString rightDartString = primitiveRight.toDartString();
209 StringConstant leftString = left;
210 if (rightDartString.isEmpty()) {
211 return left;
212 } else if (leftString.value.isEmpty()) {
213 return new StringConstant(rightDartString);
214 } else {
215 DartString concatenated =
216 new ConsDartString(leftString.value, rightDartString);
217 return new StringConstant(concatenated);
218 }
219 } else {
220 return null;
221 }
222 }
223 }
224
225 class RelationalNumOperation implements BinaryOperation {
226 const RelationalNumOperation();
227 Constant fold(Constant left, Constant right) {
228 if (left.isNum() && right.isNum()) {
229 NumConstant leftNum = left;
230 NumConstant rightNum = right;
231 bool foldedValue = foldNums(leftNum.value, rightNum.value);
232 assert(foldedValue != null);
233 return new BoolConstant(foldedValue);
234 }
235 }
236
237 abstract bool foldNums(num left, num right);
238 }
239
240 class LessOperation extends RelationalNumOperation {
241 const LessOperation();
242 bool foldNums(num left, num right) => left < right;
243 }
244
245 class LessEqualOperation extends RelationalNumOperation {
246 const LessEqualOperation();
247 bool foldNums(num left, num right) => left <= right;
248 }
249
250 class GreaterOperation extends RelationalNumOperation {
251 const GreaterOperation();
252 bool foldNums(num left, num right) => left > right;
253 }
254
255 class GreaterEqualOperation extends RelationalNumOperation {
256 const GreaterEqualOperation();
257 bool foldNums(num left, num right) => left >= right;
258 }
259
260 class EqualsOperation implements BinaryOperation {
261 const EqualsOperation();
262 Constant fold(Constant left, Constant right) {
263 if (left.isNum() && right.isNum()) {
264 // Numbers need to be treated specially because: NaN != NaN, -0.0 == 0.0,
265 // and 1 == 1.0.
266 NumConstant leftNum = left;
267 NumConstant rightNum = right;
268 return new BoolConstant(leftNum.value == rightNum.value);
269 }
270 if (left.isConstructedObject()) {
271 // Unless we know that the user-defined object does not implement the
272 // equality operator we cannot fold here.
273 return null;
274 }
275 return new BoolConstant(left == right);
276 }
277 }
278
279 class IdentityOperation implements BinaryOperation {
280 const IdentityOperation();
281 Constant fold(Constant left, Constant right) {
282 return new BoolConstant(left == right);
283 }
284 }
OLDNEW
« no previous file with comments | « frog/leg/native_handler.dart ('k') | frog/leg/resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698