Expressions


Expressions Overview

Expression Definition

 

A PL/B expression combines operands, operators, and parentheses to produce a single value. Depending on the operands and operators used, the result can be a numeric value, a string value, or a logical value.

 

An expression is identified by enclosing the complete expression in parentheses. Additional parentheses may be used within the expression to control evaluation order and make the intended operation easier to understand.

 

      MOVE ( A + B ), nResult

      MOVE ( dName1 + dName2 ), dResult

      MOVE ( A > B ), nResult

 

Operand terminology. In operator descriptions, Operand1 is the value to the left of the operator and Operand2 is the value to the right of the operator.

 

Example naming convention. In this section, names beginning with 'd' represent DIM variables and names beginning with 'n' represent numeric variables. Other names are used according to context.

Expression Result Categories

 

Category

Description

Numeric expression

Produces a numeric value. Arithmetic operators produce calculated numeric values; numeric comparison and logical operators produce 0 or 1.

String expression

Produces a string value. The + operator concatenates string operands.

Conditional expression

Is interpreted as TRUE or FALSE. It may contain numeric comparisons, string comparisons, logical operators, condition flags, function keys, or other conditional values.

Logical Values

 

PL/B represents a logical FALSE result as numeric zero (0) and a logical TRUE result as numeric one (1).

 

When a numeric operand is evaluated as a logical condition, zero is treated as FALSE and any nonzero value is treated as TRUE. Comparison and logical operators return either zero or one.

 

      MOVE ( A > B ), nResult

      MOVE ( A & B ), nResult

      MOVE ( A | B ), nResult

 

      IF ( A > B )

          // Do condition TRUE logic!

      ELSE

          // Do condition FALSE logic!

      ENDIF

 

Operator Precedence and Evaluation Order

 

Parentheses should be used whenever the intended order of evaluation might be unclear. Even when additional parentheses are not required, they can improve readability and reduce maintenance errors.

 

The following table shows the precedence organization of expression operators. Operators at a higher precedence level are evaluated before operators at a lower precedence level.

 

 

Precedence

Category

Operators

Notes

1 (highest)

Parenthesized subexpressions

( ... )

Defined explicitly by parentheses.

2

Unary operators

!, NOT, unary +, unary -

Unary operators are supported in the contexts documented for each operator.

3

Exponentiation

**

Left associativity is used.

4

Multiplicative

*, /, %

Left-to-right associativity.

5

Additive

+, -

Left-to-right associativity.

6

Comparison and pattern matching

=, ==, !=, <>, <, >, <=, >=, LIKE, REGEX

LIKE and REGEX apply only where structured logic permits and are not supported in MOVE expressions.

7

Logical AND

&, &&, AND

Evaluated before Logical OR.

8 (lowest)

Logical OR

|, ||, OR

Evaluated after Logical AND.

 

Logical AND has higher precedence than Logical OR. Therefore, when AND and OR occur in the same expression without additional parentheses, the AND operation is evaluated first.

 

      IF ( A | B & C )

 

      // Equivalent evaluation:

      IF ( A | ( B & C ) )

 

      IF ( A || B && C )

 

      // Equivalent evaluation:

      IF ( A || ( B && C ) )

 

To force OR to be evaluated first, use explicit parentheses.

 

      IF ( ( A | B ) & C )

 

Examples using explicit parentheses:

 

      MOVE ( A * ( B + C ) ), nResult

      MOVE ( ( A > B ) & ( C <> 0 ) ), nResult

      IF ( !( A == B ) )

 

Numeric/Arithmetic Expressions

 

A numeric expression uses numeric variables, numeric literals, arithmetic operators, comparison operators, logical operators, and parentheses. Arithmetic operators produce numeric calculation results. Numeric comparison and logical operators produce either 0 or 1.

Arithmetic Operators

 

Operator

Operation

Example

Description

+

Addition

MOVE ( A + B ), nResult

Adds B to A and stores the result in nResult.

-

Subtraction

MOVE ( A - B ), nResult

Subtracts B from A and stores the result in nResult.

*

Multiplication

MOVE ( A * B ), nResult

Multiplies A by B and stores the result in nResult.

/

Division

MOVE ( A / B ), nResult

Divides A by B and stores the result in nResult.

%

Modulo

MOVE ( A % B ), nResult

Calculates A modulo B and stores the result in nResult.

**

Exponentiation

MOVE ( A ** B ), nResult

Raises A to the power of B and stores the result in nResult.

 

Unary operators are supported as follows:

 

Operator

Operation

Example

Description

Unary +

Returns operand unchanged

MOVE ( +B ), nResult

The unchanged value of B is stored in nResult.

Unary -

Returns additive inverse of operand

MOVE ( -B ), nResult

The negative value of B is stored in nResult.

 

Numeric Comparison Operators

 

Each comparison operator returns 1 when the stated relationship is true; otherwise, it returns 0.

 

Operator

Operation

Example

Description

= or ==

Equal

MOVE ( A = B ), nResult

Returns 1 when A equals B; otherwise, returns 0.

!= or <>

Not equal

MOVE ( A != B ), nResult

Returns 1 when A does not equal B; otherwise, returns 0.

>

Greater than

MOVE ( A > B ), nResult

Returns 1 when A is greater than B; otherwise, returns 0.

<

Less than

MOVE ( A < B ), nResult

Returns 1 when A is less than B; otherwise, returns 0.

>=

Greater than or equal

MOVE ( A >= B ), nResult

Returns 1 when A is greater than or equal to B; otherwise, returns 0.

<=

Less than or equal

MOVE ( A <= B ), nResult

Returns 1 when A is less than or equal to B; otherwise, returns 0.

Logical Operators

 

Operator

Operation

Example

Description

! or NOT

Logical NOT

IF ( !A )

IF ( NOT A )

The condition is TRUE when A equals 0; otherwise, it is FALSE. Use NOT and ! only in structured logic where permitted.

& or && or AND

Logical AND

MOVE ( A & B ), nResult

Returns 1 when both A and B are nonzero; otherwise, returns 0.

| or || or OR

Logical OR

MOVE ( A | B ), nResult

Returns 1 when either A or B is nonzero; otherwise, returns 0.

 

The symbolic ! operator or word NOT may be used to negate a numeric operand or parenthesized condition where supported by expression syntax. The symbolic ! operator and word NOT are not supported in a MOVE ( expression ), variable instruction. Where supported by structured logic, ! or NOT should immediately precede the operand or parenthesized condition that it negates.

 

Numeric-Operation Details for Numeric Expressions

Division by Zero

 

By default, a divide by zero in a CALC or numeric expression gives a result of zero or a FALSE condition. If SETMODE *STRICTMATH=1 is in effect, a divide by zero in a CALC or numeric expression causes a U60 error.

Precision and Destination Effects

 

Internal expression precision is dependent upon the types of variables and literals used within the expression. Integer significance is maintained with the precision of a FORM 32 variable for operations that do not involve a decimal point. Real significance is maintained with the precision of a FORM 32.32 variable for operations that involve a decimal point.

Modulo

 

Generate/bullet1.gif    Modulo operands are treated as integers.

Generate/bullet1.gif    Only the absolute value of each input value is used for the modulo calculation.

Generate/bullet1.gif    Negative values are not used in the modulo calculation.

Generate/bullet1.gif    If an input value has a fractional component, the fractional component is truncated; values are not rounded.

Generate/bullet1.gif    If the modulo divisor is zero, a runtime F01 error is generated.

Power (**) Operator

 

Generate/bullet1.gif    The power operation used by the numeric expression ** operator and the PL/B POWER instruction follows the same runtime error-handling rules.

Generate/bullet1.gif    If the exponentiation result is valid and finite, the result is stored normally.

Generate/bullet1.gif    If the expression 0 ** 0 is encountered, the result is zero.

Generate/bullet1.gif    If exponentiation produces a domain error or invalid numeric result, the runtime generates an F19 numeric field content error in numeric operation. The F19 error may include a power-operation-specific subcode and extended text identifying the cause.

Generate/bullet1.gif    If exponentiation produces a range error or infinity, the runtime uses the standard PL/B numeric overflow handling rules and the OVER flag is set to TRUE.

Generate/bullet1.gif    If SETMODE *STRICTMATH=1 is in effect, a range error or infinity causes an F19 error that can include a power-operation-specific subcode and extended text identifying the cause.

String Expressions

 

String operations use DIM variables, string literals, string operators, and parentheses. The concatenation operator produces a string value. String comparison operators supported in expression contexts produce a numeric logical result of 0 or 1. The LIKE, REGEX, and NOCASE operators are supported in structured IF/ELSE IF logic as described below, but they are not supported in a MOVE ( expression ), variable instruction.

 

Only the logical contents of a DIM variable participate in the operation. The logical contents begin at the Form Pointer and continue through the Logical Length. Characters before the Form Pointer and characters beyond the Logical Length are not included.

String Concatenation

 

Operator

Operation

Example

Description

+

Concatenation

MOVE ( dA + dB ), dResult

Concatenates dB to the end of dA and stores the resulting string in dResult.

 

String Comparison Operators

 

Each string comparison returns 1 when the stated relationship is true; otherwise, it returns 0.

 

Operator

Operation

Example

Description

= or ==

Equal

MOVE ( dA = dB ), nResult

Returns 1 when dA equals dB; otherwise, returns 0.

!= or <>

Not equal

MOVE ( dA != dB ), nResult

Returns 1 when dA does not equal dB; otherwise, returns 0.

>

Greater than

MOVE ( dA > dB ), nResult

Returns 1 when dA is greater than dB according to the PL/B string comparison rules; otherwise, returns 0.

<

Less than

MOVE ( dA < dB ), nResult

Returns 1 when dA is less than dB according to the PL/B string comparison rules; otherwise, returns 0.

>=

Greater than or equal

MOVE ( dA >= dB ), nResult

Returns 1 when dA is greater than or equal to dB; otherwise, returns 0.

<=

Less than or equal

MOVE ( dA <= dB ), nResult

Returns 1 when dA is less than or equal to dB; otherwise, returns 0.

 

LIKE Pattern Matching

 

The LIKE operator compares Operand1 to the pattern in Operand2. LIKE pattern matching is supported in PL/B structured logic, including IF and ELSE IF conditions within an IF/ELSE/ELSE IF/ENDIF block. LIKE is not supported in a MOVE ( expression ), variable instruction and should not be documented as a MOVE expression operator.

 

      IF ( dName LIKE "ED%" )

      ELSE IF ( dName LIKE "E_%" )

 

 

Pattern

Meaning

_

Matches exactly one character.

%

Matches zero or more characters.

\

Causes the following pattern character to be treated as a literal character rather than as a wildcard.

 

Pattern

Interpretation

"A_"

A followed by exactly one character.

"A%"

A followed by zero or more characters.

"A\_B"

The literal string A_B.

"100\%"

The literal string 100%.

REGEX Pattern Matching

 

The REGEX operator processes Operand1 string data with the pattern in Operand2. REGEX pattern matching is supported in PL/B structured logic, including IF and ELSE IF conditions within an IF/ELSE/ELSE IF/ENDIF block. REGEX is not supported in a MOVE ( expression ), variable instruction and should not be documented as a MOVE expression operator.

 

      IF ( dName REGEX "^ab" )

      ELSE IF ( dName REGEX "xyz$" )

 

Pattern Character

Meaning

^

Start of line.

$

End of line.

 

Pattern

Interpretation

"^ab"

Match 'ab' at the start of the dName data.

"xyz$"

Match 'xyz' at the end of the dName data.

 

See the Regular Expression Support page for a full description of REGEX pattern matching.

NOCASE Operator

 

NOCASE causes the associated string comparison to be performed without regard to character case. NOCASE is supported in PL/B structured logic, including IF and ELSE IF conditions within an IF/ELSE/ELSE IF/ENDIF block. NOCASE is not supported in a MOVE ( expression ), variable instruction.

 

      IF ( NOCASE dName = "edward" )

      ELSE IF ( NOCASE dName LIKE "ed%" )

 

String Comparison Rules

 

String comparisons use the logical contents of the string operands and are performed according to the following rules:

 

Generate/bullet1.gif    String comparisons are case-sensitive by default. When the NOCASE operator is specified in a supported structured-logic expression, character case is ignored for the associated comparison. Characters that differ only by case compare as equal for the purposes of =, !=, <, >, <=, and >=.

Generate/bullet1.gif    String comparisons are based on byte values when using DIM, INIT, or string literals. When using NCHAR, comparisons are made using UTF-8 characters.

Generate/bullet1.gif    Two strings compare equal when they have the same number of characters and all corresponding characters are equal, with NOCASE applied when specified.

Generate/bullet1.gif    String comparison begins with the character identified by the Form Pointer (FP) and continues through the Logical Length (LP). Characters before the Form Pointer and characters beyond the Logical Length do not participate in the comparison.

Generate/bullet1.gif    When the Form Pointer (FP) value of a string is zero, the string is a NULL string having a logical length of zero. A NULL string is equal only to another NULL string. A NULL string is always less than a string that is not NULL.

Generate/bullet1.gif    Characters are compared in sequence from left to right. When corresponding characters differ, the first unequal character determines whether Operand1 is less than or greater than Operand2.

Generate/bullet1.gif    When all corresponding characters are equal through the logical length of the shorter string, but the strings have different logical lengths, the shorter string is less than the longer string.

Generate/bullet1.gif    String operands of type DIM, INIT, string literal, and NCHAR may be mixed in a string comparison. Other PL/B variable types, including FORM, INTEGER, and objects, are not permitted as string-comparison operands.

Logical/Conditional Expressions

 

Logical expressions are combinations of comparison expressions, logical operators, numeric expressions, string expressions, variables, literals, and parentheses that evaluate to a logical TRUE or FALSE result. Logical expressions are primarily used in conditional processing instructions such as IF, WHILE, and other program control operations.

Conditional Expression Evaluation

 

A conditional expression is evaluated as either TRUE or FALSE. Numeric zero (0) is interpreted as FALSE and any nonzero numeric value is interpreted as TRUE. Comparison and logical operators produce 0 for FALSE or 1 for TRUE.

 

Conditional expressions may contain numeric comparisons, string comparisons, logical operators, condition flags, function keys, and other conditional values permitted by the instruction in which the expression is used.

 

See Logical Values for the representation and interpretation of TRUE and FALSE values.

Conditional Expression Syntax

 

The complete conditional expression is enclosed within parentheses. Additional parentheses may be used to group portions of the expression, control evaluation order, and make the intended program logic easier to understand.

 

      IF ( A > B )

          ...

      ENDIF

  

      IF ( ( A > B ) & ( C <> 0 ) )

          ...

      ENDIF

  

      IF ( ( dState = "TX" ) | ( dState = "OK" ) )

          ...

      ENDIF

 

Operator precedence and associativity are defined in Operator Precedence and Evaluation Order. Additional parentheses are recommended whenever the intended evaluation order might not be obvious.

 

When expressions contain CALC-style logic, that logic is evaluated in the same manner as the CALC instruction.

Comparison Operations in Conditional Expressions

 

Numeric and string comparison operations may be used as conditions within logical expressions. Numeric comparison operators are defined in Numeric Comparison Operators. String comparison operators are defined in String Comparison Operators.

 

      IF ( A >= B )

          ...

      ENDIF

  

      IF ( dName = "Edward" )

          ...

      ENDIF

 

Logical Operators in Conditional Expressions

 

Logical operators may be used to combine or negate conditions within a conditional expression. Complete operator definitions and restrictions are given in Logical Operators.

 

Operator

Operation

! or NOT

Logical NOT

& or && or AND

Logical AND

| or || or OR

Logical OR

  

      IF ( ( A > B ) & ( C <> 0 ) )

          ...

      ENDIF

  

      IF ( ( A = 0 ) | ( B = 0 ) )

          ...

      ENDIF

  

      IF ( NOT ( A = B ) )

    ...

      ENDIF

 

Logical AND is evaluated before Logical OR unless parentheses explicitly establish a different evaluation order.

String Conditions and Pattern Matching

 

String comparisons may be used directly as conditions in structured logic. LIKE, REGEX, and NOCASE provide additional string-comparison capabilities in supported structured-logic expressions.

 

      IF ( dName = "EDWARD" )

          ...

      ENDIF

  

      IF ( dName LIKE "ED%" )

          ...

      ENDIF

  

      IF ( dName REGEX "^ED" )

          ...

      ENDIF

  

      IF ( NOCASE dName = "edward" )

          ...

      ENDIF

 

See String Comparison Operators, LIKE Pattern Matching, REGEX Pattern Matching, and NOCASE Operator.

 

Condition Flags and Function Keys

 

PL/B Condition Flags and Function Keys may be used in conditional expressions where permitted by the applicable structured-logic instruction. Their TRUE or FALSE state can participate in the expression and may be combined with other conditions using logical operators.

 

Use the Condition Flags and Function Keys sections of the PL/B Language Reference Manual for the exact identifiers, states, and instruction-specific restrictions. This draft does not invent identifiers that are not defined in the source material.

Expression Complexity and Limits

 

A conditional expression may contain as many as fifty (50) conditions. Parenthesized subexpressions may be used to group individual conditions and establish the intended evaluation order.

 

When constructing complex conditional expressions, additional parentheses are recommended to improve readability and reduce the possibility of unintended evaluation.

Expression Usage

Numeric Expression Usage

 

Numeric expressions may be used in instruction operands where a numeric expression is permitted. The destination receives the numeric result produced by the expression.

 

      MOVE ( A + B ), nResult

      MOVE ( A * ( B + C ) ), nResult

      MOVE ( A > B ), nResult

String Expression Usage

 

String expressions may be used in instruction operands where a string expression is permitted.

 

      MOVE ( dFirst + dLast ), dResult

 

String comparison expressions produce a logical numeric result and may be used in expression contexts that permit comparison operations.

Conditional Expression Usage

 

Conditional expressions are used by PL/B program-control instructions that evaluate a TRUE or FALSE condition. The specific instructions that accept conditional expressions are documented with the applicable instruction.

 

      IF ( A > B )

          ...

      ENDIF

 

A comparison used in a MOVE expression produces a numeric 0 or 1 result, while the same comparison used by a conditional-control instruction is interpreted as FALSE or TRUE.

 

      MOVE ( A > B ), nResult

      IF ( A > B )

Expression Restrictions and Context

Operator Availability Depends on Context

 

Not every expression operator is valid in every PL/B expression context. Arithmetic, comparison, and selected logical operators may be used with MOVE ( expression ), variable as documented in the applicable sections.

 

Operators specific to structured conditional logic, including LIKE, REGEX, NOCASE, and logical NOT where applicable, may be used only in the structured-logic contexts documented for those operators.

 

Operand Type Requirements

 

Generate/bullet1.gif    Arithmetic operations require numeric operands.

Generate/bullet1.gif    String concatenation operates on string operands.

Generate/bullet1.gif    Comparison operations use the numeric or string comparison rules appropriate for their operands.

Generate/bullet1.gif    Additional restrictions applicable to individual operators are described in the corresponding operator sections.

Parentheses and Readability

 

The complete PL/B expression must be enclosed within parentheses where required by the instruction syntax. Additional parentheses should be used whenever they make the intended evaluation order clearer. Explicit grouping is especially recommended when arithmetic, comparison, AND, OR, or other operations are combined within the same expression.

 

Note in the examples below spaces are not necessary for evaluation of the expressions. However, it does aid in reading the program and understanding the logic. See the examples below for further information.

Expression examples:

 

 

IF

(A=B)

 

TRUE when the value in 'A' is equal to the value in 'B'.

 

 

IF

(NOT A=B)

 

FALSE when the value in 'A' is equal to the value in 'B'.

 

 

IF

(A)

 

TRUE if 'A' is not equal to zero.

 

 

IF

(A|B)

or

 

IF

(A or B)

 

TRUE if 'A' or 'B' is not equal to zero.

 

 

IF

(A=B | C=D)

or

 

IF

(A=B or C=D)

 

TRUE if the value in 'A' is equal to the value in 'B' or if the value in 'C' is equal to the value in 'D'.

 

 

IF

(A=B | C=D & E=F | G=H)

 

IF

(A=B | (C=D & E=F) | G=H)

 

IF

(A=B | NOT (C<>D | E<>F) | G=H)

 

TRUE if any of the three sub-expressions are true. That is, if 'A' equals 'B', or 'C' equals 'D' and 'E' equals 'F', or 'G' equals 'H'. These three expressions are diagnosed in the same manner with no additional parentheses given, the first condition evaluated is the and (&) condition.

 

 

IF

(A=B & C=D | E=F & G=H)

 

IF

((A=B & C=D) | (E=F & G=H))

 

TRUE if any of the two sub-expressions are true. That is if 'A' equals 'B' and 'C' equals 'D' or if 'E' equals 'F' and 'G' equals 'H'. These two expressions are diagnosed in the same manner with no additional parentheses given, the first conditions evaluated are the two and (&) conditions.

 

 

IF

(NUMBER/10=100)

 

TRUE if the result of dividing 'NUMBER' by 10 is equal to 100.

 

 

IF

(NUMB/10=100 | NUMB/10=150)

 

TRUE if the result of dividing 'NUMB' by 10 is equal to 100 or 150.

 

 

IF

(A<100 & A>0)

 

TRUE if 'A' is less than 100 and greater than 0.

 

 

IF

(ANS="Y" | ANS="N")

 

TRUE if 'ANS' is equal to Y or N.

 

VAL1

INIT

"AB"

VAL2

INIT

"B•"

 

IF

(VAL1<VAL2)

 

Evaluated as TRUE.

 

 

IF

(A+B*2>10)

 

IF

(A+(B*2)>10)

 

TRUE if the result of multiplying 'B' times 2 and adding 'A' is greater than 10. As above, these two expressions are functionally equivalent.

 

 

IF

(A+B)

 

TRUE if the result of adding 'A' to 'B' is not equal to 0.

 

A

INIT

"abc"

B

INIT

"aBc"

C

INIT

"xyz"

D

INIT

"XYZ"

.

 

 

 

IF

(A = B) // False

.

 

 

 

IF

(NOCASE A = B) // True

.

 

 

 

IF

(NOCASE (A = B)) // True

.

 

 

 

IF

(NOCASE ((A = B) AND (C = D))) //True

 

The above examples show the use of the NOCASE operator in expressions.

 

A

INIT

"SunBelt"

.

 

 

 

IF

(A LIKE "SunBelt") // True

.

 

 

 

IF

(A LIKE "SUNBELT") // False

.

 

 

 

IF

(A LIKE "%BEL%") // False

.

 

 

 

IF

(NOCASE A LIKE "%BEL%") //True

 

The above examples show the use of the LIKE and NOCASE operators in expressions.

 

 

 

See Also: Program Control Instructions

 



PL/B Language Reference Exceptions Flags