An operator is a symbol that represents an action, such as addition or subtraction, that can be performed on data. Operators are used to manipulate data. The data being manipulated are called operands. Literals, function calls, constants, and variables can all serve as operands. For example, in the operation
x + 2
the variable x and the integer 2 are both operands, and + is the operator.
Operations
Operations can be performed on any combination of value types, but will result in a null value if the operation is not defined. Defined operations are listed in the Operand Types column of Table 4.2 on page 12. Any binary operation on a null and a non-null value will result in the non-null value. For example, if
x = null
then
3 * x
will return a value of 3.
A binary operation is an operation that contains an operand on each side of the operator, as in the preceding examples. An operation with only one operand is called a unary operation, and requires the use of a unary operator. An example of a unary operation is
!1
which uses the logical negation operator. It returns a value of 0. The unary operators are sizeof(), head(), tail(), ~ and !.
Operator Precedence and Associativity
Operator rules of precedence and associativity determine in what order operands are evaluated in expressions. Expressions with operators of higher precedence are evaluated first. In the expression
4 + 9 * 5
the * operator has the highest precedence, so the multiplication is performed before the addition. Therefore, the expression evaluates to 49.
The associative operator () is used to group parts of the expression, forcing those parts to be evaluated first. In this way, the rules of precedence can be overridden. For example,
( 4 + 9 ) * 5
causes the addition to be performed before the multiplication, resulting in a value of 65.
When operators of equal precedence occur in an expression, the operands are evaluated according to the associativity of the operators. This means that if an op- erator's associativity is left to right, then the operations will be done starting from the left side of the expression. So, the expression
4 + 9 - 6 + 5
would evaluate to 12. However, if the associative operator is used to group a part or parts of the expression, those parts are evaluated first. Therefore,
( 4 + 9 ) - ( 6 + 5 )
has a value of 2.
The table below lists the operators in order of precedence, from highest to lowest. Operators on the same line have equal precedence, and their associativity is shown in the second column.
|
Operator Symbol |
Associativity |
|---|---|
|
++ -- |
Right to left |
|
[] () |
Left to right |
|
~ ! sizeof head tail |
Right to left |
|
* / % |
Left to right |
|
+ - |
Left to right |
|
<< >> |
Left to right |
|
< > <= >= |
Left to right |
|
== != |
Left to right |
|
& |
Left to right |
|
^ |
Left to right |
|
| |
Left to right |
|
&& |
Left to right |
|
|| |
Left to right |
|
+= *= I= %= >>= <<= &= I= |
Right to left |
|
Symbol |
Description |
Operand Types |
Result Types |
Examples |
|
Index Operator |
||||
|
[ ] |
Index or subscript |
Raw Bytes |
Integer |
Raw = '001122' Raw[1] = 0x11 |
|
List |
Any |
List = [0, 1, 2, 3, [4, 5]] List[2] = 2 List[4] = [4, 5] List[4][1] = 5 Note: If an indexed Raw value is assigned to any value that is not a byte ( > 255 or not an integer), the variable will be promoted to a list before the assignment is performed. |
||
|
Associative Operator |
||||
|
( ) |
Associative |
Any |
Any |
( 2 + 4 ) * 3 = 18 2 + ( 4 * 3 ) = 14 |
|
Arithmetic Operators |
||||
|
* |
Multiplication |
Integer-integer |
Integer |
3 * 1 = 3 |
|
/ |
Division |
Integer-integer |
Integer |
3 / 1 = 3 |
|
% |
Modulus |
Integer-integer |
Integer |
3 % 1 = 0 |
|
+ |
Addition |
Integer-integer |
Integer |
2 + 2 = 4 |
|
String-string |
String |
"one " + "two" = "one two" |
||
|
Raw byte-raw byte |
Raw |
'001122' + '334455' = '001122334455' |
||
|
List-list |
List |
[1, 2] + [3, 4] = [1, 2, 3, 4] |
||
|
Integer-list |
List |
1 + [2, 3] = [1, 2, 3] |
||
|
Integer-string |
String |
"number = " + 2 = "number = 2" Note: Integer-string concatenation uses decimal conversion. |
||
|
String-list |
List |
"one" + ["two"] = ["one", "two"] |
||
|
- |
Subtraction |
Integer-integer |
Integer |
3 – 1 = 2 |
|
Increment and Decrement Operators |
||||
|
++ |
Increment |
Integer |
Integer |
a = 1 ++a = 2
b = 1 b++ = 1 Note that the value of b after execution is 2. |
|
-- |
Decrement |
Integer |
Integer |
a = 2 --a = 1
b = 2 b-- = 2 *Note that the value of b after execution is 1. |
|
Equality Operators |
||||
|
== |
Equal |
Integer-integer |
Integer |
2 == 2 |
|
String-string |
Integer |
"three" == "three" |
||
|
Raw byte-raw byte |
Integer |
'001122' == '001122' |
||
|
List-list |
Integer |
[1, [2, 3]] == [1, [2, 3]] Note: Equality operations on values of different types will evaluate to false. |
||
|
!= |
Not equal |
Integer-integer |
Integer |
2 != 3 |
|
String-string |
Integer |
"three" != "four" |
||
|
Raw byte-raw byte |
Integer |
'001122' != '334455' |
||
|
List-list |
Integer |
[1, [2, 3]] != [1, [2, 4]] Note: Equality operations on values of different types will evaluate to false. |
||
|
Relational Operators |
||||
|
< |
Less than |
Integer-integer |
Integer |
1 < 2 |
|
String-string |
Integer |
"abc" < "def" |
||
|
> |
Greater than |
Integer-integer |
Integer |
2 > 1 |
|
String-string |
Integer |
"xyz" > "abc" |
||
|
<= |
Less than or equal |
Integer-integer |
Integer |
23 <= 27 |
|
String-string |
Integer |
"cat" <= "dog" |
||
|
>= |
Greater than or equal |
Integer-integer |
Integer |
2 >= 1 |
|
String-string |
Integer |
"sun" >= "moon" Note: Relational operations on string values are evaluated according to character order in the ASCII table. |
||
|
Logical Operators |
||||
|
! |
Negation |
All combinations of types |
Integer |
!0 = 1 !"cat" = 0 !9 = 0 !"" = 1 |
|
&& |
Logical AND |
All combinations of types |
Integer |
1 && 1 = 1 1 && !"" = 1 1 && 0 = 0 1 && "cat" = 1 |
|
|| |
Logical OR |
All combinations of types |
Integer |
1 || 1 = 1 0 || 0 = 0 1 || 0 = 1 "" || !"cat" = 0 |
|
Bitwise Logical Operators |
||||
|
~ |
Bitwise complement |
Integer-integer |
Integer |
~0b11111110 = 0b00000001 |
|
& |
Bitwise AND |
Integer-integer |
Integer |
0b11111110 & 0b01010101 = 0b01010100 |
|
^ |
Bitwise exclusive OR |
Integer-integer |
Integer |
0b11111110 ^ 0b01010101 = 0b10101011 |
|
| |
Bitwise inclusive OR |
Integer-integer |
Integer |
0b11111110 | 0b01010101 = 0b11111111 |
|
Shift Operators |
||||
|
<< |
Left shift |
Integer-integer |
Integer |
0b11111110 << 3 = 0b11110000 |
|
>> |
Right shift |
Integer-integer |
Integer |
0b11111110 >> 1 = 0b01111111 |
|
Assignment Operators |
||||
|
= |
Assignment |
Any |
Any |
A = 1 B = C = A |
|
+= |
Addition assignment |
Integer-integer |
Integer |
x = 1 x += 1 = 2 |
|
String-string |
String |
a = "one " a += "two" = "one two" |
||
|
Raw byte-raw byte |
Raw |
z = '001122' z += '334455' = '001122334455' |
||
|
List-list |
List |
x = [1, 2] x += [3, 4] = [1, 2, 3, 4] |
||
|
Integer-list |
List |
y = 1 y += [2, 3] = [1, 2, 3] |
||
|
Integer-string |
String |
a = "number = " a += 2 = "number = 2" Note: Integer-string concatenation uses decimal conversion. |
||
|
String-list |
List |
s = "one" s + ["two"] = ["one", "two"] |
||
|
-= |
Subtraction assignment |
Integer-integer |
Integer |
y = 3 y –= 1 = 2 |
|
*= |
Multiplication assignment |
Integer-integer |
Integer |
x = 3 x *= 1 = 3 |
|
/= |
Division assignment |
Integer-integer |
Integer |
s = 3 s /= 1 = 3 |
|
%= |
Modulus assignment |
Integer-integer |
Integer |
y = 3 y %= 1 = 0 |
|
>>= |
Right shift assignment |
Integer-integer |
Integer |
b = 0b11111110 b >>= 1 = 0b01111111 |
|
<<= |
Left shift assignment |
Integer-integer |
Integer |
a = 0b11111110 a <<= 3 = 0b11111110000 |
|
&= |
Bitwise AND assignment |
Integer-integer |
Integer |
a = 0b11111110 a &= 0b01010101 = 0b01010100 |
|
^= |
Bitwise exclusive OR assignment |
Integer-integer |
Integer |
e = 0b11111110 e ^= 0b01010101 = 0b10101011 |
|
|= |
Bitwise inclusive OR assignment |
Integer-integer |
Integer |
i = 0b11111110 i |= 0b01010101 = 0b11111111 |
|
List Operators |
||||
|
sizeof() |
Number of elements |
Any |
Integer |
sizeof([1, 2, 3]) = 3 sizeof('0011223344') = 5 sizeof("string") = 6 sizeof(12) = 1 sizeof([1, [2, 3]]) = 2 Note: The last example demonstrates that the sizeof() operator returns the shallow count of a complex list. |
|
head() |
Head |
List |
Any |
head([1, 2, 3]) = 1 Note: The Head of a list is the first item in the list. |
|
tail() |
Tail |
List |
List |
tail([1, 2, 3]) = [2, 3] Note: The Tail of a list includes everything except the Head. |