Expressions and Operators

Expressions in REXX are a general mechanism for combining one or more pieces of data in various ways to produce a result, usually different from the original data.

Expressions

Expressions consist of one or more terms (literal strings, symbols, function calls, or subexpressions) interspersed with zero or more operators that denote operations to be carried out on terms. A subexpression is a term in an expression bracketed within a left and a right parenthesis.

Terms include:

Evaluation of an expression is left to right, modified by parentheses and by operator precedence in the usual algebraic manner (see section Parentheses and Operator Precedence). Expressions are wholly evaluated, unless an error occurs during evaluation.

All data is in the form of "typeless" character strings (typeless because it is not--as in some other languages--of a particular declared type, such as Binary, Hexadecimal, Array, and so forth). Consequently, the result of evaluating any expression is itself a character string. Terms and results (except arithmetic and logical expressions) may be the null string (a string of length 0). Note that REXX imposes no restriction on the maximum length of results. However, there is a 16MB limitation on the amount of a single storage request available to the language processor. See the note on page *** for more information.

Operators

An operator is a representation of an operation, such as addition, to be carried out on one or two terms. The following pages describe how each operator (except for the prefix operators) acts on two terms, which may be symbols, strings, function calls, intermediate results, or subexpressions. Each prefix operator acts on the term or subexpression that follows it. Blanks (and comments) adjacent to operator characters have no effect on the operator; thus, operators constructed from more than one character can have embedded blanks and comments. In addition, one or more blanks, where they occur in expressions but are not adjacent to another operator, also act as an operator. There are four types of operators:

String Concatenation

The concatenation operators combine two strings to form one string by appending the second string to the right-hand end of the first string. The concatenation may occur with or without an intervening blank. The concatenation operators are:

(blank)
Concatenate terms with one blank in between
||
Concatenate without an intervening blank
(abuttal)
Concatenate without an intervening blank

You can force concatenation without a blank by using the || operator.

The abuttal operator is assumed between two terms that are not separated by another operator. This can occur when two terms are syntactically distinct, such as a literal string and a symbol, or when they are separated only by a comment.

Examples:

An example of syntactically distinct terms is: if Fred has the value 37.4, then Fred'%' evaluates to 37.4%.

If the variable PETER has the value 1, then (Fred)(Peter) evaluates to 37.41.

In EBCDIC, the two adjoining strings, one hexadecimal and one literal,

'c1 c2'x'CDE'

evaluate to ABCDE.

In the case of:

        Fred/* The NOT operator precedes Peter. */¬Peter

there is no abuttal operator implied, and the expression is not valid. However,

        (Fred)/* The NOT operator precedes Peter. */(¬Peter)

results in an abuttal, and evaluates to 37.40.

Arithmetic

You can combine character strings that are valid numbers (see page ***) using the arithmetic operators:

+
Add
-
Subtract
*
Multiply
/
Divide
%
Integer divide (divide and return the integer part of the result)
//
Remainder (divide and return the remainder--not modulo, because the result may be negative)
**
Power (raise a number to a whole-number power)
Prefix -
Same as the subtraction: 0 - number
Prefix +
Same as the addition: 0 + number.

See Numbers and Arithmetic for details about precision, the format of valid numbers, and the operation rules for arithmetic. Note that if an arithmetic result is shown in exponential notation, it is likely that rounding has occurred.

Comparison

The comparison operators compare two terms and return the value 1if the result of the comparison is true, or 0 otherwise.

The strict comparison operators all have one of the characters defining the operator doubled. The ==, \==, /==, and ¬== operators test for an exact match between two strings. The two strings must be identical (character by character) and of the same length to be considered strictly equal. Similarly, the strict comparison operators such as >> or << carry out a simple character-by-character comparison, with no padding of either of the strings being compared. The comparison of the two strings is from left to right. If one string is shorter than and is a leading substring of another, then it is smaller than (less than) the other. The strict comparison operators also do not attempt to perform a numeric comparison on the two operands.

For all the other comparison operators, if both terms involved are numeric, a numeric comparison (in which leading zeros are ignored, and so forth--see section Numeric Comparisons) is effected. Otherwise, both terms are treated as character strings (leading and trailing blanks are ignored, and then the shorter string is padded with blanks on the right).

Character comparison and strict comparison operations are both case-sensitive, and for both the exact collating order may depend on the character set used for the implementation. For example, in an EBCDIC environment, lowercase alphabetics precede uppercase, and the digits 0-9 are higher than all alphabetics.

The comparison operators and operations are:

=
True if the terms are equal (numerically or when padded, and so forth)
\=, ¬=, /=
True if the terms are not equal (inverse of =)
>
Greater than
<
Less than
><
Greater than or less than (same as not equal)
<>
Greater than or less than (same as not equal)
>=
Greater than or equal to
\<, ¬<
Not less than
<=
Less than or equal to
\>, ¬>
Not greater than
==
True if terms are strictly equal (identical)
\==, ¬==, /==
True if the terms are NOT strictly equal (inverse of ==)
>>
Strictly greater than
<<
Strictly less than
>>=
Strictly greater than or equal to
\<<, ¬<<
Strictly NOT less than
<<=
Strictly less than or equal to
\>>, ¬>>
Strictly NOT greater than
Note:
Throughout the language, the not character, ¬, is synonymous with the backslash (\). You can use the two characters interchangeably, according to availability and personal preference. The backslash can appear in the following operators: \ (prefix not), \=, \==, \<, \>, \<<, and \>>.

Logical (Boolean)

A character string is taken to have the value false if it is 0, and true if it is 1. The logical operators take one or two such values (values other than 0 or 1 are not allowed) and return 0 or 1 as appropriate:

&
AND

Returns 1 if both terms are true.

|
Inclusive OR

Returns 1 if either term is true.

&&
Exclusive OR

Returns 1 if either (but not both) is true.

Prefix \,¬
Logical NOT

Negates; 1 becomes 0, and 0 becomes 1.

Parentheses and Operator Precedence

Expression evaluation is from left to right; parentheses and operator precedence modify this:

For example, * (multiply) has a higher priority than + (add), so 3+2*5 evaluates to 13 (rather than the 25 that would result if strict left to right evaluation occurred). To force the addition to occur before the multiplication, you could rewrite the expression as (3+2)*5. Adding the parentheses makes the first three tokens a subexpression. Similarly, the expression -3**2 evaluates to 9 (instead of -9) because the prefix minus operator has a higher priority than the power operator.

The order of precedence of the operators is (highest at the top):

+ - ¬ \
(prefix operators)

**
(power)

* / % //
(multiply and divide)

+ -
(add and subtract)

(blank) || (abuttal)
(concatenation with or without blank)

= > <
(comparison operators)
== >> <<
 
\= ¬=
 
>< <>
 
\> ¬>
 
\< ¬<
 
\== ¬==
 
\>> ¬>>
 
\<< ¬<<
 
>= >>=
 
<= <<=
 
/= /==
 

&
(and)

| &&
(or, exclusive or)

Examples:

Suppose the symbol A is a variable whose value is 3, DAY is a variable whose value is Monday, and other variables are uninitialized. Then:

A+5                  ->    '8'
A-4*2                ->    '-5'
A/2                  ->    '1.5'
0.5**2               ->    '0.25'
(A+1)>7              ->    '0'         /* that is, False */
' '=''               ->    '1'         /* that is, True  */
' '==''              ->    '0'         /* that is, False */
' '¬==''             ->    '1'         /* that is, True  */
(A+1)*3=12           ->    '1'         /* that is, True  */
'077'>'11'           ->    '1'         /* that is, True  */
'077' >> '11'        ->    '0'         /* that is, False */
'abc' >> 'ab'        ->    '1'         /* that is, True  */
'abc' << 'abd'       ->    '1'         /* that is, True  */
'ab ' << 'abd'       ->    '1'         /* that is, True  */
Today is Day         ->    'TODAY IS Monday'
'If it is' day       ->    'If it is Monday'
Substr(Day,2,3)      ->    'ond'    /* Substr is a function */
'!'xxx'!'            ->    '!XXX!'
'000000' >> '0E0000' ->    '1'         /* that is, True  */
Note:
The last example would give a different answer if the > operator had been used rather than >>. Because '0E0000' is a valid number in exponential notation, a numeric comparison is done; thus '0E0000' and '000000' evaluate as equal. The REXX order of precedence usually causes no difficulty because it is the same as in conventional algebra and other computer languages. There are two differences from common notations: For example:
-3**2     ==  9  /* not -9  */
-(2+1)**2 ==  9  /* not -9  */
2**2**3   == 64  /* not 256 */