If atomic values are the building blocks of expressions then operators are the cement. With operators you can perform arithmetic, make comparisons and assign new values to variables. from them.
Operator precedence is used to resolve ambiguities in an expression. Each operator has a precedence level which determines its priority in an expression. For example, the expression 12 + 3 * 4 parses as though it were 12 + (3 * 4) and not as (12 + 3) * 4 because multiplication has higher precedence than addition.
Table 6.1. Operator Precedence Table
Precedence | Operators | Description |
---|---|---|
Highest | () | Parenthesis |
Function/method calls, new | Function calls (see Function Calls), object creation (see new) | |
++, -- | Postfix increment/decrement (see Increment/Decrement) | |
++, --, +, - | Prefix increment/decrement (see Increment/Decrement), unary sign change | |
(int), (double), (string), (boolean), ! | Type Casts, logical not (see Logical Operators) | |
*, /, % | Multiplication/division (see Arithmetic Operators) | |
+, - | Addition/substraction (see Arithmetic Operators) | |
<, <=, >, >= | Numerical or string comparisons (see Comparison Operators) | |
==, != | Equality comparisons (see Comparison Operators) | |
&& | Logical and (see Logical Operators) | |
|| | Logical or (see Logical Operators) | |
Lowest | =, +=, -=, *=, /=, %=, | Assignment Operators |
The new operator is used to create instances of object type variables. Currently the only object in RSP that can be created with new is the Connection object.
The syntax is new ObjectType(arguments...). It calls a special method of the object being created called the constructor. The arguments required by the constructor will depend on the object, but the parenthesis are required even if no arguments are needed.
The ++ (increment) and -- (decrement) operators are used in expressions to increment or decrement an lvalue - either an int or a double.
If used as a prefix then the increment/decrement will be carried out before the rest of the expression is evaluated, otherwise it is carried out after the expression is evaluate. If there are multiple prefix operators or multiple postfix operators in an expression then no guarantee can be made about the order in which they will execute.
Use type casts to convert one type of variable to another. The table below shows the data types that can be legally cast.
Table 6.2. Type Conversion Table
From int | From double | From boolean | From string | |
To int | No effect. | The value is rounded down. | true becomes 1, false becomes 0. | If the string consists of decimal digits then it will be converted to an integer value. Otherwise the result is 0. The string may be prefixed with "-" to denote a negative number. |
To double | No effect. | No effect. | true becomes 1.0, false becomes 0.0. | If the string follows the same lexical pattern as a double then it will be converted to a double. Otherwise the result is undefined but probably zero (it will not be a run time error). |
To boolean | A nonzero value becomes true, a value of zero becomes false. | A nonzero value becomes true, a value of zero becomes false. | No effect. |
The following strings get converted to true, where the test is case insensitive:
|
To string | The integer is converted to its decimal string representation. | The double is converted to its string representation. | true becomes "True", false becomes "False". | No effect. |
The arithmetic operators perform basic arithmetic on numerical types. Note that you cannot mix integers and doubles in arithmetic expressions without using type casts.
The + operator can also be used for string concatention. Any basic type can be concatenated to a string.
The equality operators == and != are used to determine if two values are equal or not equal respectively. The left and right hand sides must be of the same type, and may not be object references or arrays (although array elements are allowed).
The comparison operators <, <=, > and >= are used for numerical and string comparisons. The left and right hand sides must be of the same type and may be either integers, doubles or strings. String comparisons are done lexiographically and are case sensitive.
The result type of a comparison expression is always a boolean.
Logical operators operate on boolean values only. The logical not (!) unary operator returns the complement of a boolean value. The operators && and || perform logical 'and' and 'or' respectively.
RSP uses shortcut semantics for its logical operators. This means that if the left hand side of an && operator evaluates to false then the right hand side will not be evaluated because it is already certain that the result of the operator will be false. Similarly if the left hand side of an || operator is true then the result will be true without evaluating the right hand side.
It is important to understand shortcut semantics because it has relevance when the right hand side expression has a side effect. For example, it may be a function call. If it is not evaluated then the function will never be called.
Use the assignment operators to assign new value to variable references. The left hand side of an assignment operator must be an lvalue.
The value of an assignment expression is the new value of the variable being assigned. In the case of the basic assignment operator = this will be the same as the right hand side. The other assignment operators combine an assignment with the arithmetic.
Example 6.6. Assignments Example
int num, a, b, c; string str; // Simple assignment num = 42; str = "Hello"; // Chained assignment - a, b, c and num now all equal 48 a = b = c = num += 6; // More arithmetic num /= 6; // num = 8 num -= 4; // num = 4 num *= 3; // num = 12 num += num; // num = 24 // And with strings str += ", world!";