OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, 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 library dart2js.operators; | |
6 | |
7 import '../elements/elements.dart'; | |
8 import '../universe/call_structure.dart' show CallStructure; | |
9 import '../universe/selector.dart' show Selector, SelectorKind; | |
10 | |
11 enum UnaryOperatorKind { | |
12 NOT, | |
13 NEGATE, | |
14 COMPLEMENT, | |
15 } | |
16 | |
17 class UnaryOperator { | |
18 final UnaryOperatorKind kind; | |
19 final String name; | |
20 final String selectorName; | |
21 | |
22 const UnaryOperator(this.kind, this.name, this.selectorName); | |
23 | |
24 bool get isUserDefinable => selectorName != null; | |
25 | |
26 Selector get selector => new Selector(SelectorKind.OPERATOR, | |
27 new PublicName(selectorName), CallStructure.NO_ARGS); | |
28 | |
29 String toString() => name; | |
30 | |
31 /// The unary ! operator. | |
32 static const UnaryOperator NOT = | |
33 const UnaryOperator(UnaryOperatorKind.NOT, '!', null); | |
34 | |
35 /// The unary - operator. | |
36 static const UnaryOperator NEGATE = | |
37 const UnaryOperator(UnaryOperatorKind.NEGATE, '-', 'unary-'); | |
38 | |
39 /// The unary ~ operator. | |
40 static const UnaryOperator COMPLEMENT = | |
41 const UnaryOperator(UnaryOperatorKind.COMPLEMENT, '~', '~'); | |
42 | |
43 static UnaryOperator parse(String value) { | |
44 switch (value) { | |
45 case '!': | |
46 return NOT; | |
47 case '-': | |
48 return NEGATE; | |
49 case '~': | |
50 return COMPLEMENT; | |
51 default: | |
52 return null; | |
53 } | |
54 } | |
55 | |
56 // ignore: MISSING_RETURN | |
57 static UnaryOperator fromKind(UnaryOperatorKind kind) { | |
58 switch (kind) { | |
59 case UnaryOperatorKind.NOT: | |
60 return NOT; | |
61 case UnaryOperatorKind.NEGATE: | |
62 return NEGATE; | |
63 case UnaryOperatorKind.COMPLEMENT: | |
64 return COMPLEMENT; | |
65 } | |
66 } | |
67 } | |
68 | |
69 enum BinaryOperatorKind { | |
70 EQ, | |
71 NOT_EQ, | |
72 INDEX, | |
73 ADD, | |
74 SUB, | |
75 MUL, | |
76 DIV, | |
77 IDIV, | |
78 MOD, | |
79 SHL, | |
80 SHR, | |
81 GTEQ, | |
82 GT, | |
83 LTEQ, | |
84 LT, | |
85 AND, | |
86 OR, | |
87 XOR, | |
88 LOGICAL_AND, | |
89 LOGICAL_OR, | |
90 IF_NULL, | |
91 } | |
92 | |
93 class BinaryOperator { | |
94 final BinaryOperatorKind kind; | |
95 final String name; | |
96 | |
97 const BinaryOperator._(this.kind, this.name); | |
98 | |
99 /// `true` if this operator can be implemented through an `operator [name]` | |
100 /// method. | |
101 bool get isUserDefinable => true; | |
102 | |
103 String get selectorName => name; | |
104 | |
105 String toString() => name; | |
106 | |
107 /// The == operator. | |
108 static const BinaryOperator EQ = | |
109 const BinaryOperator._(BinaryOperatorKind.EQ, '=='); | |
110 | |
111 /// The != operator. | |
112 static const BinaryOperator NOT_EQ = const _NotEqualsOperator(); | |
113 | |
114 /// The [] operator. | |
115 static const BinaryOperator INDEX = | |
116 const BinaryOperator._(BinaryOperatorKind.INDEX, '[]'); | |
117 | |
118 /// The binary + operator. | |
119 static const BinaryOperator ADD = | |
120 const BinaryOperator._(BinaryOperatorKind.ADD, '+'); | |
121 | |
122 /// The binary - operator. | |
123 static const BinaryOperator SUB = | |
124 const BinaryOperator._(BinaryOperatorKind.SUB, '-'); | |
125 | |
126 /// The binary * operator. | |
127 static const BinaryOperator MUL = | |
128 const BinaryOperator._(BinaryOperatorKind.MUL, '*'); | |
129 | |
130 /// The binary / operator. | |
131 static const BinaryOperator DIV = | |
132 const BinaryOperator._(BinaryOperatorKind.DIV, '/'); | |
133 | |
134 /// The binary ~/ operator. | |
135 static const BinaryOperator IDIV = | |
136 const BinaryOperator._(BinaryOperatorKind.IDIV, '~/'); | |
137 | |
138 /// The binary % operator. | |
139 static const BinaryOperator MOD = | |
140 const BinaryOperator._(BinaryOperatorKind.MOD, '%'); | |
141 | |
142 /// The binary << operator. | |
143 static const BinaryOperator SHL = | |
144 const BinaryOperator._(BinaryOperatorKind.SHL, '<<'); | |
145 | |
146 /// The binary >> operator. | |
147 static const BinaryOperator SHR = | |
148 const BinaryOperator._(BinaryOperatorKind.SHR, '>>'); | |
149 | |
150 /// The binary >= operator. | |
151 static const BinaryOperator GTEQ = | |
152 const BinaryOperator._(BinaryOperatorKind.GTEQ, '>='); | |
153 | |
154 /// The binary > operator. | |
155 static const BinaryOperator GT = | |
156 const BinaryOperator._(BinaryOperatorKind.GT, '>'); | |
157 | |
158 /// The binary <= operator. | |
159 static const BinaryOperator LTEQ = | |
160 const BinaryOperator._(BinaryOperatorKind.LTEQ, '<='); | |
161 | |
162 /// The binary < operator. | |
163 static const BinaryOperator LT = | |
164 const BinaryOperator._(BinaryOperatorKind.LT, '<'); | |
165 | |
166 /// The binary & operator. | |
167 static const BinaryOperator AND = | |
168 const BinaryOperator._(BinaryOperatorKind.AND, '&'); | |
169 | |
170 /// The binary | operator. | |
171 static const BinaryOperator OR = | |
172 const BinaryOperator._(BinaryOperatorKind.OR, '|'); | |
173 | |
174 /// The binary ^ operator. | |
175 static const BinaryOperator XOR = | |
176 const BinaryOperator._(BinaryOperatorKind.XOR, '^'); | |
177 | |
178 /// The logical && operator. | |
179 static const BinaryOperator LOGICAL_AND = | |
180 const _LogicalOperator(BinaryOperatorKind.LOGICAL_AND, '&&'); | |
181 | |
182 /// The binary | operator. | |
183 static const BinaryOperator LOGICAL_OR = | |
184 const _LogicalOperator(BinaryOperatorKind.LOGICAL_OR, '||'); | |
185 | |
186 /// The if-null ?? operator. | |
187 static const BinaryOperator IF_NULL = | |
188 const _IfNullOperator(BinaryOperatorKind.IF_NULL, '??'); | |
189 | |
190 static BinaryOperator parse(String value) { | |
191 switch (value) { | |
192 case '==': | |
193 return EQ; | |
194 case '!=': | |
195 return NOT_EQ; | |
196 case '[]': | |
197 return INDEX; | |
198 case '*': | |
199 return MUL; | |
200 case '/': | |
201 return DIV; | |
202 case '%': | |
203 return MOD; | |
204 case '~/': | |
205 return IDIV; | |
206 case '+': | |
207 return ADD; | |
208 case '-': | |
209 return SUB; | |
210 case '<<': | |
211 return SHL; | |
212 case '>>': | |
213 return SHR; | |
214 case '>=': | |
215 return GTEQ; | |
216 case '>': | |
217 return GT; | |
218 case '<=': | |
219 return LTEQ; | |
220 case '<': | |
221 return LT; | |
222 case '&': | |
223 return AND; | |
224 case '^': | |
225 return XOR; | |
226 case '|': | |
227 return OR; | |
228 case '&&': | |
229 return LOGICAL_AND; | |
230 case '||': | |
231 return LOGICAL_OR; | |
232 case '??': | |
233 return IF_NULL; | |
234 default: | |
235 return null; | |
236 } | |
237 } | |
238 | |
239 // ignore: MISSING_RETURN | |
240 static BinaryOperator fromKind(BinaryOperatorKind kind) { | |
241 switch (kind) { | |
242 case BinaryOperatorKind.EQ: | |
243 return EQ; | |
244 case BinaryOperatorKind.NOT_EQ: | |
245 return NOT_EQ; | |
246 case BinaryOperatorKind.INDEX: | |
247 return INDEX; | |
248 case BinaryOperatorKind.MUL: | |
249 return MUL; | |
250 case BinaryOperatorKind.DIV: | |
251 return DIV; | |
252 case BinaryOperatorKind.MOD: | |
253 return MOD; | |
254 case BinaryOperatorKind.IDIV: | |
255 return IDIV; | |
256 case BinaryOperatorKind.ADD: | |
257 return ADD; | |
258 case BinaryOperatorKind.SUB: | |
259 return SUB; | |
260 case BinaryOperatorKind.SHL: | |
261 return SHL; | |
262 case BinaryOperatorKind.SHR: | |
263 return SHR; | |
264 case BinaryOperatorKind.GTEQ: | |
265 return GTEQ; | |
266 case BinaryOperatorKind.GT: | |
267 return GT; | |
268 case BinaryOperatorKind.LTEQ: | |
269 return LTEQ; | |
270 case BinaryOperatorKind.LT: | |
271 return LT; | |
272 case BinaryOperatorKind.AND: | |
273 return AND; | |
274 case BinaryOperatorKind.XOR: | |
275 return XOR; | |
276 case BinaryOperatorKind.OR: | |
277 return OR; | |
278 case BinaryOperatorKind.LOGICAL_AND: | |
279 return LOGICAL_AND; | |
280 case BinaryOperatorKind.LOGICAL_OR: | |
281 return LOGICAL_OR; | |
282 case BinaryOperatorKind.IF_NULL: | |
283 return IF_NULL; | |
284 } | |
285 } | |
286 } | |
287 | |
288 /// The operator !=, which is not user definable operator but instead is a | |
289 /// negation of a call to user definable operator, namely ==. | |
290 class _NotEqualsOperator extends BinaryOperator { | |
291 const _NotEqualsOperator() : super._(BinaryOperatorKind.NOT_EQ, '!='); | |
292 | |
293 bool get isUserDefinable => false; | |
294 | |
295 String get selectorName => '=='; | |
296 } | |
297 | |
298 /// The operators && and || which are not user definable operators but control | |
299 /// structures. | |
300 class _LogicalOperator extends BinaryOperator { | |
301 const _LogicalOperator(BinaryOperatorKind kind, String name) | |
302 : super._(kind, name); | |
303 | |
304 bool get isUserDefinable => false; | |
305 | |
306 String get selectorName => null; | |
307 } | |
308 | |
309 /// The operators ?? is not user definable. | |
310 class _IfNullOperator extends BinaryOperator { | |
311 const _IfNullOperator(BinaryOperatorKind kind, String name) | |
312 : super._(kind, name); | |
313 | |
314 bool get isUserDefinable => false; | |
315 | |
316 String get selectorName => '??'; | |
317 } | |
318 | |
319 enum AssignmentOperatorKind { | |
320 ASSIGN, | |
321 IF_NULL, | |
322 ADD, | |
323 SUB, | |
324 MUL, | |
325 DIV, | |
326 IDIV, | |
327 MOD, | |
328 SHL, | |
329 SHR, | |
330 AND, | |
331 OR, | |
332 XOR, | |
333 } | |
334 | |
335 class AssignmentOperator { | |
336 final AssignmentOperatorKind kind; | |
337 final BinaryOperator binaryOperator; | |
338 final String name; | |
339 final bool isUserDefinable; | |
340 | |
341 const AssignmentOperator._(this.kind, this.name, this.binaryOperator, | |
342 {this.isUserDefinable: true}); | |
343 | |
344 String get selectorName { | |
345 return binaryOperator != null ? binaryOperator.selectorName : null; | |
346 } | |
347 | |
348 String toString() => name; | |
349 | |
350 /// The = operator. | |
351 static const AssignmentOperator ASSIGN = const AssignmentOperator._( | |
352 AssignmentOperatorKind.ASSIGN, '=', null, | |
353 isUserDefinable: false); | |
354 | |
355 /// The ??= operator. | |
356 static const AssignmentOperator IF_NULL = const AssignmentOperator._( | |
357 AssignmentOperatorKind.IF_NULL, '??=', BinaryOperator.IF_NULL, | |
358 isUserDefinable: false); | |
359 | |
360 /// The += assignment operator. | |
361 static const AssignmentOperator ADD = const AssignmentOperator._( | |
362 AssignmentOperatorKind.ADD, '+=', BinaryOperator.ADD); | |
363 | |
364 /// The -= assignment operator. | |
365 static const AssignmentOperator SUB = const AssignmentOperator._( | |
366 AssignmentOperatorKind.SUB, '-=', BinaryOperator.SUB); | |
367 | |
368 /// The *= assignment operator. | |
369 static const AssignmentOperator MUL = const AssignmentOperator._( | |
370 AssignmentOperatorKind.MUL, '*=', BinaryOperator.MUL); | |
371 | |
372 /// The /= assignment operator. | |
373 static const AssignmentOperator DIV = const AssignmentOperator._( | |
374 AssignmentOperatorKind.DIV, '/=', BinaryOperator.DIV); | |
375 | |
376 /// The ~/= assignment operator. | |
377 static const AssignmentOperator IDIV = const AssignmentOperator._( | |
378 AssignmentOperatorKind.IDIV, '~/=', BinaryOperator.IDIV); | |
379 | |
380 /// The %= assignment operator. | |
381 static const AssignmentOperator MOD = const AssignmentOperator._( | |
382 AssignmentOperatorKind.MOD, '%=', BinaryOperator.MOD); | |
383 | |
384 /// The <<= assignment operator. | |
385 static const AssignmentOperator SHL = const AssignmentOperator._( | |
386 AssignmentOperatorKind.SHL, '<<=', BinaryOperator.SHL); | |
387 | |
388 /// The >>= assignment operator. | |
389 static const AssignmentOperator SHR = const AssignmentOperator._( | |
390 AssignmentOperatorKind.SHR, '>>=', BinaryOperator.SHR); | |
391 | |
392 /// The &= assignment operator. | |
393 static const AssignmentOperator AND = const AssignmentOperator._( | |
394 AssignmentOperatorKind.AND, '&=', BinaryOperator.AND); | |
395 | |
396 /// The |= assignment operator. | |
397 static const AssignmentOperator OR = const AssignmentOperator._( | |
398 AssignmentOperatorKind.OR, '|=', BinaryOperator.OR); | |
399 | |
400 /// The ^= assignment operator. | |
401 static const AssignmentOperator XOR = const AssignmentOperator._( | |
402 AssignmentOperatorKind.XOR, '^=', BinaryOperator.XOR); | |
403 | |
404 static AssignmentOperator parse(String value) { | |
405 switch (value) { | |
406 case '=': | |
407 return ASSIGN; | |
408 case '??=': | |
409 return IF_NULL; | |
410 case '*=': | |
411 return MUL; | |
412 case '/=': | |
413 return DIV; | |
414 case '%=': | |
415 return MOD; | |
416 case '~/=': | |
417 return IDIV; | |
418 case '+=': | |
419 return ADD; | |
420 case '-=': | |
421 return SUB; | |
422 case '<<=': | |
423 return SHL; | |
424 case '>>=': | |
425 return SHR; | |
426 case '&=': | |
427 return AND; | |
428 case '^=': | |
429 return XOR; | |
430 case '|=': | |
431 return OR; | |
432 default: | |
433 return null; | |
434 } | |
435 } | |
436 | |
437 // ignore: MISSING_RETURN | |
438 static AssignmentOperator fromKind(AssignmentOperatorKind kind) { | |
439 switch (kind) { | |
440 case AssignmentOperatorKind.ASSIGN: | |
441 return ASSIGN; | |
442 case AssignmentOperatorKind.IF_NULL: | |
443 return IF_NULL; | |
444 case AssignmentOperatorKind.ADD: | |
445 return ADD; | |
446 case AssignmentOperatorKind.SUB: | |
447 return SUB; | |
448 case AssignmentOperatorKind.MUL: | |
449 return MUL; | |
450 case AssignmentOperatorKind.DIV: | |
451 return DIV; | |
452 case AssignmentOperatorKind.IDIV: | |
453 return IDIV; | |
454 case AssignmentOperatorKind.MOD: | |
455 return MOD; | |
456 case AssignmentOperatorKind.SHL: | |
457 return SHL; | |
458 case AssignmentOperatorKind.SHR: | |
459 return SHR; | |
460 case AssignmentOperatorKind.AND: | |
461 return AND; | |
462 case AssignmentOperatorKind.OR: | |
463 return OR; | |
464 case AssignmentOperatorKind.XOR: | |
465 return XOR; | |
466 } | |
467 } | |
468 } | |
469 | |
470 enum IncDecOperatorKind { INC, DEC } | |
471 | |
472 class IncDecOperator { | |
473 final IncDecOperatorKind kind; | |
474 final String name; | |
475 final BinaryOperator binaryOperator; | |
476 | |
477 const IncDecOperator._(this.kind, this.name, this.binaryOperator); | |
478 | |
479 String get selectorName => binaryOperator.selectorName; | |
480 | |
481 String toString() => name; | |
482 | |
483 /// The prefix/postfix ++ operator. | |
484 static const IncDecOperator INC = | |
485 const IncDecOperator._(IncDecOperatorKind.INC, '++', BinaryOperator.ADD); | |
486 | |
487 /// The prefix/postfix -- operator. | |
488 static const IncDecOperator DEC = | |
489 const IncDecOperator._(IncDecOperatorKind.DEC, '--', BinaryOperator.SUB); | |
490 | |
491 static IncDecOperator parse(String value) { | |
492 switch (value) { | |
493 case '++': | |
494 return INC; | |
495 case '--': | |
496 return DEC; | |
497 default: | |
498 return null; | |
499 } | |
500 } | |
501 | |
502 // ignore: MISSING_RETURN | |
503 static IncDecOperator fromKind(IncDecOperatorKind kind) { | |
504 switch (kind) { | |
505 case IncDecOperatorKind.INC: | |
506 return INC; | |
507 case IncDecOperatorKind.DEC: | |
508 return DEC; | |
509 } | |
510 } | |
511 } | |
OLD | NEW |