boa/syntax/ast/op.rs
1//! This module implements various structure for logic handling.
2
3use crate::gc::{empty_trace, Finalize, Trace};
4use std::fmt::{Display, Formatter, Result};
5
6#[cfg(feature = "deser")]
7use serde::{Deserialize, Serialize};
8
9/// Arithmetic operators take numerical values (either literals or variables)
10/// as their operands and return a single numerical value.
11///
12/// More information:
13/// - [MDN documentation][mdn]
14///
15/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Arithmetic
16#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
17#[derive(Clone, Copy, Debug, Finalize, PartialEq)]
18pub enum NumOp {
19 /// The addition operator produces the sum of numeric operands or string concatenation.
20 ///
21 /// Syntax: `x + y`
22 ///
23 /// More information:
24 /// - [ECMAScript reference][spec].
25 /// - [MDN documentation][mdn]
26 ///
27 /// [spec]: https://tc39.es/ecma262/#sec-addition-operator-plus
28 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Addition
29 Add,
30
31 /// The subtraction operator subtracts the two operands, producing their difference.
32 ///
33 /// Syntax: `x - y`
34 ///
35 /// More information:
36 /// - [ECMAScript reference][spec].
37 /// - [MDN documentation][mdn]
38 ///
39 /// [spec]: https://tc39.es/ecma262/#sec-subtraction-operator-minus
40 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Subtraction
41 Sub,
42
43 /// The division operator produces the quotient of its operands where the left operand
44 /// is the dividend and the right operand is the divisor.
45 ///
46 /// Syntax: `x / y`
47 ///
48 /// More information:
49 /// - [ECMAScript reference][spec]
50 /// - [MDN documentation][mdn]
51 ///
52 /// [spec]: https://tc39.es/ecma262/#prod-MultiplicativeOperator
53 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Division
54 Div,
55
56 /// The multiplication operator produces the product of the operands.
57 ///
58 /// Syntax: `x * y`
59 ///
60 /// More information:
61 /// - [ECMAScript reference][spec]
62 /// - [MDN documentation][mdn]
63 ///
64 /// [spec]: https://tc39.es/ecma262/#prod-MultiplicativeExpression
65 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Multiplication
66 Mul,
67
68 /// The exponentiation operator returns the result of raising the first operand to
69 /// the power of the second operand.
70 ///
71 /// Syntax: `x ** y`
72 ///
73 /// The exponentiation operator is right-associative. a ** b ** c is equal to a ** (b ** c).
74 ///
75 /// More information:
76 /// - [ECMAScript reference][spec]
77 /// - [MDN documentation][mdn]
78 ///
79 /// [spec]: https://tc39.es/ecma262/#sec-exp-operator
80 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation
81 Exp,
82
83 /// The remainder operator returns the remainder left over when one operand is divided by a second operand.
84 ///
85 /// Syntax: `x % y`
86 ///
87 /// The remainder operator always takes the sign of the dividend.
88 ///
89 /// More information:
90 /// - [ECMAScript reference][spec]
91 /// - [MDN documentation][mdn]
92 ///
93 /// [spec]: https://tc39.es/ecma262/#prod-MultiplicativeOperator
94 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder
95 Mod,
96}
97
98impl Display for NumOp {
99 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
100 write!(
101 f,
102 "{}",
103 match *self {
104 Self::Add => "+",
105 Self::Sub => "-",
106 Self::Div => "/",
107 Self::Mul => "*",
108 Self::Exp => "**",
109 Self::Mod => "%",
110 }
111 )
112 }
113}
114
115unsafe impl Trace for NumOp {
116 empty_trace!();
117}
118
119/// A unary operator is one that takes a single operand/argument and performs an operation.
120///
121/// A unary operation is an operation with only one operand. This operand comes either
122/// before or after the operator. Unary operators are more efficient than standard JavaScript
123/// function calls.
124///
125/// More information:
126/// - [ECMAScript reference][spec]
127/// - [MDN documentation][mdn]
128///
129/// [spec]: https://tc39.es/ecma262/#prod-UnaryExpression
130/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Unary
131#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
132#[derive(Clone, Copy, Debug, Finalize, PartialEq)]
133pub enum UnaryOp {
134 /// The increment operator increments (adds one to) its operand and returns a value.
135 ///
136 /// Syntax: `++x`
137 ///
138 /// This operator increments and returns the value after incrementing.
139 ///
140 /// More information:
141 /// - [ECMAScript reference][spec]
142 /// - [MDN documentation][mdn]
143 ///
144 /// [spec]: https://tc39.es/ecma262/#sec-postfix-increment-operator
145 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Increment
146 IncrementPost,
147
148 /// The increment operator increments (adds one to) its operand and returns a value.
149 ///
150 /// Syntax: `x++`
151 ///
152 /// This operator increments and returns the value before incrementing.
153 ///
154 /// More information:
155 /// - [ECMAScript reference][spec]
156 /// - [MDN documentation][mdn]
157 ///
158 /// [spec]: https://tc39.es/ecma262/#sec-prefix-increment-operator
159 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Increment
160 IncrementPre,
161
162 /// The decrement operator decrements (subtracts one from) its operand and returns a value.
163 ///
164 /// Syntax: `--x`
165 ///
166 /// This operator decrements and returns the value before decrementing.
167 ///
168 /// More information:
169 /// - [ECMAScript reference][spec]
170 /// - [MDN documentation][mdn]
171 ///
172 /// [spec]: https://tc39.es/ecma262/#sec-postfix-decrement-operator
173 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Decrement
174 DecrementPost,
175
176 /// The decrement operator decrements (subtracts one from) its operand and returns a value.
177 ///
178 /// Syntax: `x--`
179 ///
180 /// This operator decrements the operand and returns the value after decrementing.
181 ///
182 /// More information:
183 /// - [ECMAScript reference][spec]
184 /// - [MDN documentation][mdn]
185 ///
186 /// [spec]: https://tc39.es/ecma262/#sec-prefix-decrement-operator
187 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Decrement
188 DecrementPre,
189
190 /// The unary negation operator precedes its operand and negates it.
191 ///
192 /// Syntax: `-x`
193 ///
194 /// Converts non-numbers data types to numbers like unary plus,
195 /// however, it performs an additional operation, negation.
196 ///
197 /// More information:
198 /// - [ECMAScript reference][spec]
199 /// - [MDN documentation][mdn]
200 ///
201 /// [spec]: https://tc39.es/ecma262/#sec-unary-minus-operator
202 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_negation
203 Minus,
204
205 /// The unary plus operator attempts to convert the operand into a number, if it isn't already.
206 ///
207 /// Syntax: `+x`
208 ///
209 /// Although unary negation (`-`) also can convert non-numbers, unary plus is the fastest and preferred
210 /// way of converting something into a number, because it does not perform any other operations on the number.
211 /// It can convert `string` representations of integers and floats, as well as the non-string values `true`, `false`, and `null`.
212 ///
213 /// More information:
214 /// - [ECMAScript reference][spec]
215 /// - [MDN documentation][mdn]
216 ///
217 /// [spec]: https://tc39.es/ecma262/#sec-unary-plus-operator
218 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus
219 Plus,
220
221 /// Returns `false` if its single operand can be converted to `true`; otherwise, returns `true`.
222 ///
223 /// Syntax: `!x`
224 ///
225 /// Boolean values simply get inverted: `!true === false` and `!false === true`.
226 /// Non-boolean values get converted to boolean values first, then are negated.
227 /// This means that it is possible to use a couple of NOT operators in series to explicitly
228 /// force the conversion of any value to the corresponding boolean primitive.
229 ///
230 /// More information:
231 /// - [ECMAScript reference][spec]
232 /// - [MDN documentation][mdn]
233 ///
234 /// [spec]: https://tc39.es/ecma262/#sec-logical-not-operator
235 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT
236 Not,
237
238 /// Performs the NOT operator on each bit.
239 ///
240 /// Syntax: `~x`
241 ///
242 /// NOT `a` yields the inverted value (or one's complement) of `a`.
243 /// Bitwise NOTing any number x yields -(x + 1). For example, ~-5 yields 4.
244 ///
245 /// More information:
246 /// - [ECMAScript reference][spec]
247 /// - [MDN documentation][mdn]
248 ///
249 /// [spec]: https://tc39.es/ecma262/#sec-bitwise-not-operator
250 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT
251 Tilde,
252
253 /// The `typeof` operator returns a string indicating the type of the unevaluated operand.
254 ///
255 /// Syntax: `typeof x` or `typeof(x)`
256 ///
257 /// The `typeof` is a JavaScript keyword that will return the type of a variable when you call it.
258 /// You can use this to validate function parameters or check if variables are defined.
259 /// There are other uses as well.
260 ///
261 /// More information:
262 /// - [ECMAScript reference][spec]
263 /// - [MDN documentation][mdn]
264 ///
265 /// [spec]: https://tc39.es/ecma262/#sec-typeof-operator
266 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
267 TypeOf,
268
269 /// The JavaScript `delete` operator removes a property from an object.
270 ///
271 /// Syntax: `delete x`
272 ///
273 /// Unlike what common belief suggests, the delete operator has nothing to do with
274 /// directly freeing memory. Memory management is done indirectly via breaking references.
275 /// If no more references to the same property are held, it is eventually released automatically.
276 ///
277 /// The `delete` operator returns `true` for all cases except when the property is an
278 /// [own](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty)
279 /// [non-configurable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_delete)
280 /// property, in which case, `false` is returned in non-strict mode.
281 ///
282 /// More information:
283 /// - [ECMAScript reference][spec]
284 /// - [MDN documentation][mdn]
285 ///
286 /// [spec]: https://tc39.es/ecma262/#sec-delete-operator
287 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
288 Delete,
289
290 /// The `void` operator evaluates the given `expression` and then returns `undefined`.
291 ///
292 /// Syntax: `void x`
293 ///
294 /// This operator allows evaluating expressions that produce a value into places where an
295 /// expression that evaluates to `undefined` is desired.
296 /// The `void` operator is often used merely to obtain the `undefined` primitive value, usually using `void(0)`
297 /// (which is equivalent to `void 0`). In these cases, the global variable undefined can be used.
298 ///
299 /// When using an [immediately-invoked function expression](https://developer.mozilla.org/en-US/docs/Glossary/IIFE),
300 /// `void` can be used to force the function keyword to be treated as an expression instead of a declaration.
301 ///
302 /// More information:
303 /// - [ECMAScript reference][spec]
304 /// - [MDN documentation][mdn]
305 ///
306 /// [spec]: https://tc39.es/ecma262/#sec-void-operator
307 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
308 Void,
309}
310
311impl Display for UnaryOp {
312 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
313 write!(
314 f,
315 "{}",
316 match *self {
317 Self::IncrementPost | Self::IncrementPre => "++",
318 Self::DecrementPost | Self::DecrementPre => "--",
319 Self::Plus => "+",
320 Self::Minus => "-",
321 Self::Not => "!",
322 Self::Tilde => "~",
323 Self::Delete => "delete",
324 Self::TypeOf => "typeof",
325 Self::Void => "void",
326 }
327 )
328 }
329}
330
331unsafe impl Trace for UnaryOp {
332 empty_trace!();
333}
334
335/// A bitwise operator is an operator used to perform bitwise operations
336/// on bit patterns or binary numerals that involve the manipulation of individual bits.
337///
338/// More information:
339/// - [MDN documentation][mdn]
340///
341/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise
342#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
343#[derive(Clone, Copy, Debug, Finalize, PartialEq)]
344pub enum BitOp {
345 /// Performs the AND operation on each pair of bits. a AND b yields 1 only if both a and b are 1.
346 ///
347 /// Syntax: `x & y`
348 ///
349 /// More information:
350 /// - [ECMAScript reference][spec]
351 /// - [MDN documentation][mdn]
352 ///
353 /// [spec]: https://tc39.es/ecma262/#prod-BitwiseANDExpression
354 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_AND
355 And,
356
357 /// Performs the OR operation on each pair of bits. a OR b yields 1 if either a or b is 1.
358 ///
359 /// Syntax: `x | y`
360 ///
361 /// More information:
362 /// - [ECMAScript reference][spec]
363 /// - [MDN documentation][mdn]
364 ///
365 /// [spec]: https://tc39.es/ecma262/#prod-BitwiseORExpression
366 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_OR
367 Or,
368
369 /// Performs the XOR operation on each pair of bits. a XOR b yields 1 if a and b are different.
370 ///
371 /// Syntax: `x ^ y`
372 ///
373 /// More information:
374 /// - [ECMAScript reference][spec]
375 /// - [MDN documentation][mdn]
376 ///
377 /// [spec]: https://tc39.es/ecma262/#prod-BitwiseXORExpression
378 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR
379 Xor,
380
381 /// This operator shifts the first operand the specified number of bits to the left.
382 ///
383 /// Syntax: `x << y`
384 ///
385 /// Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right.
386 ///
387 /// More information:
388 /// - [ECMAScript reference][spec]
389 /// - [MDN documentation][mdn]
390 ///
391 /// [spec]: https://tc39.es/ecma262/#sec-left-shift-operator
392 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Left_shift
393 Shl,
394
395 /// This operator shifts the first operand the specified number of bits to the right.
396 ///
397 /// Syntax: `x >> y`
398 ///
399 /// Excess bits shifted off to the right are discarded. Copies of the leftmost bit
400 /// are shifted in from the left. Since the new leftmost bit has the same value as
401 /// the previous leftmost bit, the sign bit (the leftmost bit) does not change.
402 /// Hence the name "sign-propagating".
403 ///
404 /// More information:
405 /// - [ECMAScript reference][spec]
406 /// - [MDN documentation][mdn]
407 ///
408 /// [spec]: https://tc39.es/ecma262/#sec-signed-right-shift-operator
409 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Right_shift
410 Shr,
411
412 /// This operator shifts the first operand the specified number of bits to the right.
413 ///
414 /// Syntax: `x >>> y`
415 ///
416 /// Excess bits shifted off to the right are discarded. Zero bits are shifted in
417 /// from the left. The sign bit becomes 0, so the result is always non-negative.
418 /// Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer.
419 ///
420 /// More information:
421 /// - [ECMAScript reference][spec]
422 /// - [MDN documentation][mdn]
423 ///
424 /// [spec]: https://tc39.es/ecma262/#sec-unsigned-right-shift-operator
425 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Unsigned_right_shift
426 UShr,
427}
428
429impl Display for BitOp {
430 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
431 write!(
432 f,
433 "{}",
434 match *self {
435 Self::And => "&",
436 Self::Or => "|",
437 Self::Xor => "^",
438 Self::Shl => "<<",
439 Self::Shr => ">>",
440 Self::UShr => ">>>",
441 }
442 )
443 }
444}
445
446unsafe impl Trace for BitOp {
447 empty_trace!();
448}
449
450/// A comparison operator compares its operands and returns a logical value based on whether the comparison is true.
451///
452/// The operands can be numerical, string, logical, or object values. Strings are compared based on standard
453/// lexicographical ordering, using Unicode values. In most cases, if the two operands are not of the same type,
454/// JavaScript attempts to convert them to an appropriate type for the comparison. This behavior generally results in
455/// comparing the operands numerically. The sole exceptions to type conversion within comparisons involve the `===` and `!==`
456/// operators, which perform strict equality and inequality comparisons. These operators do not attempt to convert the operands
457/// to compatible types before checking equality.
458///
459/// More information:
460/// - [ECMAScript reference][spec]
461/// - [MDN documentation][mdn]
462///
463/// [spec]: tc39.es/ecma262/#sec-testing-and-comparison-operations
464/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Comparison
465#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
466#[derive(Clone, Copy, Debug, Finalize, PartialEq)]
467pub enum CompOp {
468 /// The equality operator converts the operands if they are not of the same type, then applies
469 /// strict comparison.
470 ///
471 /// Syntax: `y == y`
472 ///
473 /// If both operands are objects, then JavaScript compares internal references which are equal
474 /// when operands refer to the same object in memory.
475 ///
476 /// More information:
477 /// - [ECMAScript reference][spec]
478 /// - [MDN documentation][mdn]
479 ///
480 /// [spec]: https://tc39.es/ecma262/#sec-abstract-equality-comparison
481 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality
482 Equal,
483
484 /// The inequality operator returns `true` if the operands are not equal.
485 ///
486 /// Syntax: `x != y`
487 ///
488 /// If the two operands are not of the same type, JavaScript attempts to convert the operands
489 /// to an appropriate type for the comparison. If both operands are objects, then JavaScript
490 /// compares internal references which are not equal when operands refer to different objects
491 /// in memory.
492 ///
493 /// More information:
494 /// - [ECMAScript reference][spec]
495 /// - [MDN documentation][mdn]
496 ///
497 /// [spec]: https://tc39.es/ecma262/#prod-EqualityExpression
498 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Inequality
499 NotEqual,
500
501 /// The identity operator returns `true` if the operands are strictly equal **with no type
502 /// conversion**.
503 ///
504 /// Syntax: `x === y`
505 ///
506 /// Returns `true` if the operands are equal and of the same type.
507 ///
508 /// More information:
509 /// - [ECMAScript reference][spec]
510 /// - [MDN documentation][mdn]
511 ///
512 /// [spec]: https://tc39.es/ecma262/#sec-strict-equality-comparison
513 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity
514 StrictEqual,
515
516 /// The non-identity operator returns `true` if the operands **are not equal and/or not of the
517 /// same type**.
518 ///
519 /// Syntax: `x !== y`
520 ///
521 /// Returns `true` if the operands are of the same type but not equal, or are of different type.
522 ///
523 /// More information:
524 /// - [ECMAScript reference][spec]
525 /// - [MDN documentation][mdn]
526 ///
527 /// [spec]: https://tc39.es/ecma262/#prod-EqualityExpression
528 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Nonidentity>
529 StrictNotEqual,
530
531 /// The greater than operator returns `true` if the left operand is greater than the right
532 /// operand.
533 ///
534 /// Syntax: `x > y`
535 ///
536 /// Returns `true` if the left operand is greater than the right operand.
537 ///
538 /// More information:
539 /// - [ECMAScript reference][spec]
540 /// - [MDN documentation][mdn]
541 ///
542 /// [spec]: https://tc39.es/ecma262/#prod-RelationalExpression
543 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_operator
544 GreaterThan,
545
546 /// The greater than or equal operator returns `true` if the left operand is greater than or
547 /// equal to the right operand.
548 ///
549 /// Syntax: `x >= y`
550 ///
551 /// Returns `true` if the left operand is greater than the right operand.
552 ///
553 /// More information:
554 /// - [ECMAScript reference][spec]
555 /// - [MDN documentation][mdn]
556 ///
557 /// [spec]: https://tc39.es/ecma262/#prod-RelationalExpression
558 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_operator
559 GreaterThanOrEqual,
560
561 /// The less than operator returns `true` if the left operand is less than the right operand.
562 ///
563 /// Syntax: `x < y`
564 ///
565 /// Returns `true` if the left operand is less than the right operand.
566 ///
567 /// More information:
568 /// - [ECMAScript reference][spec]
569 /// - [MDN documentation][mdn]
570 ///
571 /// [spec]: https://tc39.es/ecma262/#prod-RelationalExpression
572 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Less_than_operator
573 LessThan,
574
575 /// The less than or equal operator returns `true` if the left operand is less than or equal to
576 /// the right operand.
577 ///
578 /// Syntax: `x <= y`
579 ///
580 /// Returns `true` if the left operand is less than or equal to the right operand.
581 ///
582 /// More information:
583 /// - [ECMAScript reference][spec]
584 /// - [MDN documentation][mdn]
585 ///
586 /// [spec]: https://tc39.es/ecma262/#prod-RelationalExpression
587 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Less_than_or_equal_operator
588 LessThanOrEqual,
589
590 /// The `in` operator returns `true` if the specified property is in the specified object or
591 /// its prototype chain.
592 ///
593 /// Syntax: `prop in object`
594 ///
595 /// Returns `true` the specified property is in the specified object or its prototype chain.
596 ///
597 /// More information:
598 /// - [ECMAScript reference][spec]
599 /// - [MDN documentation][mdn]
600 ///
601 /// [spec]: https://tc39.es/ecma262/#prod-RelationalExpression
602 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in
603 In,
604
605 /// The `instanceof` operator returns `true` if the specified object is an instance of the
606 /// right hand side object.
607 ///
608 /// Syntax: `obj instanceof Object`
609 ///
610 /// Returns `true` the `prototype` property of the right hand side constructor appears anywhere
611 /// in the prototype chain of the object.
612 ///
613 /// More information:
614 /// - [ECMAScript reference][spec]
615 /// - [MDN documentation][mdn]
616 ///
617 /// [spec]: https://tc39.es/ecma262/#prod-RelationalExpression
618 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
619 InstanceOf,
620}
621
622impl Display for CompOp {
623 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
624 write!(
625 f,
626 "{}",
627 match *self {
628 Self::Equal => "==",
629 Self::NotEqual => "!=",
630 Self::StrictEqual => "===",
631 Self::StrictNotEqual => "!==",
632 Self::GreaterThan => ">",
633 Self::GreaterThanOrEqual => ">=",
634 Self::LessThan => "<",
635 Self::LessThanOrEqual => "<=",
636 Self::In => "in",
637 Self::InstanceOf => "instanceof",
638 }
639 )
640 }
641}
642
643unsafe impl Trace for CompOp {
644 empty_trace!();
645}
646
647/// Logical operators are typically used with Boolean (logical) values; when they are, they return a Boolean value.
648///
649/// However, the `&&` and `||` operators actually return the value of one of the specified operands,
650/// so if these operators are used with non-Boolean values, they may return a non-Boolean value.
651///
652/// More information:
653/// - [ECMAScript reference][spec]
654/// - [MDN documentation][mdn]
655///
656/// [spec]: https://tc39.es/ecma262/#sec-binary-logical-operators
657/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical
658#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
659#[derive(Clone, Copy, Debug, Finalize, PartialEq)]
660pub enum LogOp {
661 /// The logical AND operator returns the value of the first operand if it can be coerced into `false`;
662 /// otherwise, it returns the second operand.
663 ///
664 /// Syntax: `x && y`
665 ///
666 /// More information:
667 /// - [ECMAScript reference][spec]
668 /// - [MDN documentation][mdn]
669 ///
670 /// [spec]: https://tc39.es/ecma262/#prod-LogicalANDExpression
671 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_AND
672 And,
673
674 /// The logical OR operator returns the value the first operand if it can be coerced into `true`;
675 /// otherwise, it returns the second operand.
676 ///
677 /// Syntax: `x || y`
678 ///
679 /// More information:
680 /// - [ECMAScript reference][spec]
681 /// - [MDN documentation][mdn]
682 ///
683 /// [spec]: https://tc39.es/ecma262/#prod-LogicalORExpression
684 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR
685 Or,
686
687 /// The nullish coalescing operator is a logical operator that returns the second operand
688 /// when its first operand is null or undefined, and otherwise returns its first operand.
689 ///
690 /// Syntax: `x ?? y`
691 ///
692 /// More information:
693 /// - [ECMAScript reference][spec]
694 /// - [MDN documentation][mdn]
695 ///
696 /// [spec]: https://tc39.es/ecma262/#prod-CoalesceExpression
697 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
698 Coalesce,
699}
700
701impl Display for LogOp {
702 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
703 write!(
704 f,
705 "{}",
706 match *self {
707 Self::And => "&&",
708 Self::Or => "||",
709 Self::Coalesce => "??",
710 }
711 )
712 }
713}
714
715unsafe impl Trace for LogOp {
716 empty_trace!();
717}
718
719/// This represents a binary operation between two values.
720#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
721#[derive(Clone, Copy, Debug, Finalize, PartialEq)]
722pub enum BinOp {
723 /// Numeric operation.
724 ///
725 /// see: [`NumOp`](enum.NumOp.html)
726 Num(NumOp),
727
728 /// Bitwise operation.
729 ///
730 /// see: [`BitOp`](enum.BitOp.html).
731 Bit(BitOp),
732
733 /// Comparitive operation.
734 ///
735 /// see: [`CompOp`](enum.CompOp.html).
736 Comp(CompOp),
737
738 /// Logical operation.
739 ///
740 /// see: [`LogOp`](enum.LogOp.html).
741 Log(LogOp),
742
743 /// Assign operation.
744 ///
745 /// see: [`AssignOp`](enum.AssignOp.html).
746 Assign(AssignOp),
747
748 /// Comma operation.
749 Comma,
750}
751
752impl From<NumOp> for BinOp {
753 fn from(op: NumOp) -> Self {
754 Self::Num(op)
755 }
756}
757
758impl From<BitOp> for BinOp {
759 fn from(op: BitOp) -> Self {
760 Self::Bit(op)
761 }
762}
763
764impl From<CompOp> for BinOp {
765 fn from(op: CompOp) -> Self {
766 Self::Comp(op)
767 }
768}
769
770impl From<LogOp> for BinOp {
771 fn from(op: LogOp) -> Self {
772 Self::Log(op)
773 }
774}
775
776impl From<AssignOp> for BinOp {
777 fn from(op: AssignOp) -> Self {
778 Self::Assign(op)
779 }
780}
781
782impl Display for BinOp {
783 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
784 write!(
785 f,
786 "{}",
787 match *self {
788 Self::Num(ref op) => op.to_string(),
789 Self::Bit(ref op) => op.to_string(),
790 Self::Comp(ref op) => op.to_string(),
791 Self::Log(ref op) => op.to_string(),
792 Self::Assign(ref op) => op.to_string(),
793 Self::Comma => ",".to_string(),
794 }
795 )
796 }
797}
798
799unsafe impl Trace for BinOp {
800 empty_trace!();
801}
802
803/// An assignment operator assigns a value to its left operand based on the value of its right operand.
804///
805/// The simple assignment operator is equal (`=`), which assigns the value of its right operand to its
806/// left operand. That is, `x = y` assigns the value of `y to x`.
807///
808/// There are also compound assignment operators that are shorthand for the operations
809///
810/// More information:
811/// - [ECMAScript reference][spec]
812/// - [MDN documentation][mdn]
813///
814/// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
815/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment
816#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
817#[derive(Clone, Copy, Debug, Finalize, PartialEq)]
818pub enum AssignOp {
819 /// The addition assignment operator adds the value of the right operand to a variable and assigns the result to the variable.
820 ///
821 /// Syntax: `x += y`
822 ///
823 /// The types of the two operands determine the behavior of the addition assignment operator. Addition or concatenation is possible.
824 ///
825 /// More information:
826 /// - [ECMAScript reference][spec]
827 /// - [MDN documentation][mdn]
828 ///
829 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
830 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Addition_assignment
831 Add,
832
833 /// The subtraction assignment operator subtracts the value of the right operand from a variable and assigns the result to the variable.
834 ///
835 /// Syntax: `x -= y`
836 ///
837 /// More information:
838 /// - [ECMAScript reference][spec]
839 /// - [MDN documentation][mdn]
840 ///
841 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
842 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Subtraction_assignment
843 Sub,
844
845 /// The multiplication assignment operator multiplies a variable by the value of the right operand and assigns the result to the variable.
846 ///
847 /// Syntax: `x *= y`
848 ///
849 /// More information:
850 /// - [ECMAScript reference][spec]
851 /// - [MDN documentation][mdn]
852 ///
853 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
854 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Multiplication_assignment
855 Mul,
856
857 /// The division assignment operator divides a variable by the value of the right operand and assigns the result to the variable.
858 ///
859 /// Syntax: `x /= y`
860 ///
861 /// More information:
862 /// - [ECMAScript reference][spec]
863 /// - [MDN documentation][mdn]
864 ///
865 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
866 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Division_assignment
867 Div,
868
869 /// The remainder assignment operator divides a variable by the value of the right operand and assigns the remainder to the variable.
870 ///
871 /// Syntax: `x %= y`
872 ///
873 /// More information:
874 /// - [ECMAScript reference][spec]
875 /// - [MDN documentation][mdn]
876 ///
877 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
878 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Remainder_assignment
879 Mod,
880
881 /// The exponentiation assignment operator raises the value of a variable to the power of the right operand.
882 ///
883 /// Syntax: `x ** y`
884 ///
885 /// More information:
886 /// - [ECMAScript reference][spec]
887 /// - [MDN documentation][mdn]
888 ///
889 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
890 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Exponentiation_assignment
891 Exp,
892
893 /// The bitwise AND assignment operator uses the binary representation of both operands, does a bitwise AND operation on
894 /// them and assigns the result to the variable.
895 ///
896 /// Syntax: `x &= y`
897 ///
898 /// More information:
899 /// - [ECMAScript reference][spec]
900 /// - [MDN documentation][mdn]
901 ///
902 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
903 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Bitwise_AND_assignment
904 And,
905
906 /// The bitwise OR assignment operator uses the binary representation of both operands, does a bitwise OR operation on
907 /// them and assigns the result to the variable.
908 ///
909 /// Syntax: `x |= y`
910 ///
911 /// More information:
912 /// - [ECMAScript reference][spec]
913 /// - [MDN documentation][mdn]
914 ///
915 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
916 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Bitwise_OR_assignment
917 Or,
918
919 /// The bitwise XOR assignment operator uses the binary representation of both operands, does a bitwise XOR operation on
920 /// them and assigns the result to the variable.
921 ///
922 /// Syntax: `x ^= y`
923 ///
924 /// More information:
925 /// - [ECMAScript reference][spec]
926 /// - [MDN documentation][mdn]
927 ///
928 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
929 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Bitwise_XOR_assignment
930 Xor,
931
932 /// The left shift assignment operator moves the specified amount of bits to the left and assigns the result to the variable.
933 ///
934 /// Syntax: `x <<= y`
935 ///
936 /// More information:
937 /// - [ECMAScript reference][spec]
938 /// - [MDN documentation][mdn]
939 ///
940 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
941 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Left_shift_assignment
942 Shl,
943
944 /// The right shift assignment operator moves the specified amount of bits to the right and assigns the result to the variable.
945 ///
946 /// Syntax: `x >>= y`
947 ///
948 /// More information:
949 /// - [ECMAScript reference][spec]
950 /// - [MDN documentation][mdn]
951 ///
952 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
953 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Right_shift_assignment
954 Shr,
955
956 /// The unsigned right shift assignment operator moves the specified amount of bits to the right and assigns the result to the variable.
957 ///
958 /// Syntax: `x >>>= y`
959 ///
960 /// More information:
961 /// - [ECMAScript reference][spec]
962 /// - [MDN documentation][mdn]
963 ///
964 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
965 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment
966 Ushr,
967
968 /// The logical and assignment operator only assigns if the target variable is truthy.
969 ///
970 /// Syntax: `x &&= y`
971 ///
972 /// More information:
973 /// - [ECMAScript reference][spec]
974 /// - [MDN documentation][mdn]
975 ///
976 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentExpression
977 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment
978 BoolAnd,
979
980 /// The logical or assignment operator only assigns if the target variable is falsy.
981 ///
982 /// Syntax: `x ||= y`
983 ///
984 /// More information:
985 /// - [ECMAScript reference][spec]
986 /// - [MDN documentation][mdn]
987 ///
988 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentExpression
989 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment
990 BoolOr,
991
992 /// The logical nullish assignment operator only assigns if the target variable is nullish (null or undefined).
993 ///
994 /// Syntax: `x ??= y`
995 ///
996 /// More information:
997 /// - [ECMAScript reference][spec]
998 /// - [MDN documentation][mdn]
999 ///
1000 /// [spec]: https://tc39.es/ecma262/#prod-AssignmentExpression
1001 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment
1002 Coalesce,
1003}
1004
1005unsafe impl Trace for AssignOp {
1006 empty_trace!();
1007}
1008
1009impl Display for AssignOp {
1010 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
1011 write!(
1012 f,
1013 "{}",
1014 match *self {
1015 Self::Add => "+=",
1016 Self::Sub => "-=",
1017 Self::Mul => "*=",
1018 Self::Exp => "**=",
1019 Self::Div => "/=",
1020 Self::Mod => "%=",
1021 Self::And => "&=",
1022 Self::Or => "|=",
1023 Self::Xor => "^=",
1024 Self::Shl => "<<=",
1025 Self::Shr => ">>=",
1026 Self::Ushr => ">>>=",
1027 Self::BoolAnd => "&&=",
1028 Self::BoolOr => "||=",
1029 Self::Coalesce => "??=",
1030 }
1031 )
1032 }
1033}