HP 3000 Manuals

Logical Expressions [ SPL to HP C/XL Migration Guide ] MPE/iX 5.0 Documentation


SPL to HP C/XL Migration Guide

Logical Expressions 

          Table 5-22.  Logical Expressions 

-------------------------------------------------------------------------------------------------------
|                                                 |                                                   |
|                       SPL                       |                HP C/XL Equivalent                 |
|                                                 |                                                   |
-------------------------------------------------------------------------------------------------------
|                                                 |                                                   |
| logical-expression:                             | Same as SPL, except:                              |
|                                                 |                                                   |
|      *logical-elem [log-bit-op logical-elem]    |                                                   |
|                                                 |                                                   |
|      *lower <= test <= upper                    |      ((lower) <= (test) & (test) <= (upper))      |
|                                                 |                                                   |
|                                                 | The parentheses may be necessary for              |
| lower, test, upper:                             | correct evaluation if the elements are            |
|                                                 | expressions or if the entire expression is        |
|   are integer expressions.                      | combined with other expressions.                  |
|                                                 |                                                   |
|                                                 |                                                   |
|                                                 | &:                                                |
|                                                 |   Same as SPL LAND. See below.                    |
|                                                 |                                                   |
-------------------------------------------------------------------------------------------------------
|                                                 |                                                   |
| logical-elem:                                   | Same as SPL.                                      |
|                                                 |                                                   |
|      logical-expression                         |                                                   |
|                                                 |                                                   |
|      logical-primary [rel-op logical-primary]   |                                                   |
|                                                 |                                                   |
|      arith-expression rel-op arith-expression   |                                                   |
|                                                 |                                                   |
|      logical-primary logical-op logical-primary |                                                   |
|                                                 |                                                   |
|      byte-comparison                            |                                                   |
|                                                 |                                                   |
-------------------------------------------------------------------------------------------------------
|                                                 |                                                   |
| logical-primary is one of:                      | Same as SPL, except:                              |
|                                                 |                                                   |
|      logical-variable                           |                                                   |
|      logical/integer-constant                   |                                                   |
|      string-constant                            |                                                   |
|      logical-bit-operation                      |                                                   |
|      ( logical-expression )                     |                                                   |
|      logical-function-designator                |                                                   |
|      ( logical-assignment )                     |                                                   |
|      NOT logical-primary  (bitwise negation)    |      ~ logical-primary  (bitwise negation; tilde) |
|                                                 |                                                   |
-------------------------------------------------------------------------------------------------------
|                                                 |                                                   |
| log-bit-op:                                     | log-bit-op:                                       |
|                                                 |                                                   |
|      LAND  (logical bitwise AND)                |      &  (bitwise AND)                             |
|      LOR    (logical bitwise inclusive OR)      |      |  (bitwise inclusive OR)                    |
|      XOR    (logical bitwise exclusive OR)      |      ^  (bitwise exclusive OR; circumflex)        |
|                                                 |                                                   |
|                                                 | Note:  The HP C/XL exclusive OR operator,         |
|                                                 | "^", is the SPL exponentiation operator.          |
|                                                 |                                                   |
-------------------------------------------------------------------------------------------------------
|                                                 |                                                   |
| The bit-wise operators, NOT, LAND, LOR, and     | Similar to SPL. Operands may be any numeric       |
| XOR, perform Boolean operations on the          | types.  Results correspond to operand             |
| corresponding bits of their operands and        | types.                                            |
| produce a numeric result of type LOGICAL.       |                                                   |
|                                                 |                                                   |
-------------------------------------------------------------------------------------------------------
|                                                                                                     |
|                                              Continued                                              |
|                                                                                                     |
-------------------------------------------------------------------------------------------------------

          Logical Expressions(cont.) 

---------------------------------------------------------------------------------------------
|                                             |                                             |
|                     SPL                     |             HP C/XL Equivalent              |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| logical-op:                                 | Same as SPL, except:                        |
|                                             |                                             |
|      +     (unsigned addition)              |                                             |
|      -     (unsigned subtraction)           |                                             |
|      *     (unsigned multiplication)        |                                             |
|      /     (unsigned division)              |                                             |
|      MOD   (unsigned modulus)               |      %     (unsigned modulus)               |
|      **    (unsigned multiplication)        |      *     (unsigned multiplication)        |
|      //    (unsigned division)              |      /     (unsigned division)              |
|      MODD  (unsigned modulus)               |      %     (unsigned modulus)               |
|                                             |                                             |
| (**, //, and MODD give DOUBLE result)       | Use (long int) cast if needed for the       |
|                                             | conversions from **, //, and MODD.          |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| The logical-op operators perform unsigned   | Similar to SPL. Operands may be any numeric |
| integer arithmetic on their operands and    | types.  Results correspond to operand       |
| produce a numeric result of type LOGICAL.   | types.                                      |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| rel-op:                                     | Same as SPL, except:                        |
|                                             |                                             |
|      <   (less than)                        |                                             |
|      <=  (less than or equal to)            |                                             |
|      >    (greater than)                    |                                             |
|      >=   (greater than or equal to)        |                                             |
|      =    (equal to)                        |      ==   (equal to)                        |
|      <>  (not equal to)                     |      !=   (not equal to)                    |
|                                             |                                             |
| Note:  The SPL equality operator, "=", is   |                                             |
| the HP C/XL assignment operator.            |                                             |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| The rel-op operators perform arithmetic     | Similar to SPL, except:  True is returned   |
| comparisons on their operands and produce a | as int 1.  False is returned as int 0.      |
| Boolean result (true or false) of type      |                                             |
| LOGICAL.                                    | Operands may be any numeric types.  Results |
|                                             | correspond to operand types.                |
| True is returned as LOGICAL 65535 (INTEGER  |                                             |
| -1).  False is returned as LOGICAL 0.       |                                             |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| The reserved word TRUE has the LOGICAL      | No direct equivalent.                       |
| value 65535 (INTEGER -1).                   |                                             |
|                                             | You could use #define directives to define  |
| The reserved word FALSE has the LOGICAL     | SPLTRUE as 65535 and SPLFALSE as 0:         |
| value 0 (INTEGER 0).                        |                                             |
|                                             |      #define SPLTRUE 65535                  |
|                                             |      #define SPLFALSE 0                     |
|                                             |                                             |
|                                             | and then change all TRUE and FALSE          |
|                                             | references to the special names.  This      |
|                                             | would help you to locate instances where    |
|                                             | they were used in bit or numeric            |
|                                             | operations.                                 |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| In tests for true and false, an odd number  | A nonzero number is true; a zero number is  |
| is true (bit 15 is on); an even number is   | false.                                      |
| false (bit 15 is off).                      |                                             |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| Examples:                                   | Examples:                                   |
|                                             |                                             |
|      L                                      |      L                                      |
|      L + NOT L1 LAND L2                     |      L + ~L1 & L2                           |
|      I <= N <= 100                          |      I <= N & N <= 100                      |
|      L                                      |      L != L1                                |
|      L1                                     |      L ^ L1 % L2                            |
|      L XOR L1 MOD L2                        |                                             |
|                                             |                                             |
---------------------------------------------------------------------------------------------

Conversion Issues 

SPL NOT Operator. 

SPL uses the same operator, NOT, for both bitwise negation and Boolean
negation.  HP C/XL uses two operators:  "~" (tilde) for bitwise negation
and "!" for Boolean negation.  They give different results, as shown in
Table 5-23.

          Table 5-23.  Logical and Bitwise Negation 

---------------------------------------------------------------------------------------------
|                                             |                                             |
|                     SPL                     |             HP C/XL Equivalent              |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
|                                             |                                             |
|      NOT(0) = -1 (or LOGICAL 65535)         |      ~(0) == -1  (or unsigned 4294967295)   |
|              16 off bits turned on          |              32 off bits turned on          |
|                                             |      !(0) ==  1                             |
|                                             |              since 0 means false            |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
|                                             |                                             |
|      NOT(-1) = 0                            |      ~(-1) == 0                             |
|              16 on bits turned off          |              32 on bits turned off          |
|                                             |      !(-1) == 0                             |
|                                             |              since nonzero means true       |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
|                                             |                                             |
|      NOT(%(16)F0F0) = %(16)0F0F             |      ~(0xF0F0) == 0xFFFF0F0F                |
|              16 bits negated                |              32 bits negated                |
|              original value is false        |              both values are true           |
|              result value is true           |      !(0xF0F0) == 0                         |
|                                             |              since nonzero means true       |
|                                             |                                             |
---------------------------------------------------------------------------------------------

The HP C/XL "~" operator is probably the better first-pass replacement
for the SPL NOT.

SPL TRUE and FALSE Constants. 

SPL returns a 16-bit LOGICAL 65535 (INTEGER -1) for true and 0 for false.
However, when testing a value for true or false in a condition clause,
SPL examines only bit 15 for 1 or 0, ignoring bits 0-14.

HP C/XL returns a 32-bit integer 1 for true and 0 for false.  When
testing a value for true or false, HP C/XL tests the whole number for
nonzero or 0.

These variations will have no effect on the value of a condition clause
except if the expressions in the clause use the returned true or false
values numerically, as in bit manipulation.

Many SPL programmers have taken advantage of the way SPL tests bit 15 for
true or false, and existing SPL code must be carefully examined for
examples of this practice.  Too direct a translation of bit operations
such as these is discouraged, as the resulting HP C/XL code will lack
portability and be more difficult to maintain.

Numeric Conversion.  Unless a logical expression used in a condition
clause results in true or false values that are not 65535 or 0
respectively, or a relational (true/false) result is used in a bitwise or
numeric operation (not a recommended coding practice), there should be no
problem with a simple substitution of operator symbols.

In other words, if a test for true or false is not really a test for odd
or even, and if the values true and false are not used as numbers, the
results should be the same.

Converting a Range Test.  The conversion of a range test, such as

     X <= Y <= Z

may be performed in two steps.

(The example is true if X is less than or equal to Y, AND Y is less than
or equal to Z.)

Step 1:  In SPL, change the expression to two "<=" tests joined with
LAND, for example:

     (X) <= (Y) LAND (Y) <= (Z)

The parentheses may be needed to ensure the correct evaluation of the
expressions.

Step 2:  In HP C/XL, replace LAND with either "&" or "&&":

     (X) <= (Y) & (Y) <= (Z)
     (X) <= (Y) && (Y) <= (Z)

The "&" bitwise AND is the "precise" conversion operator, but the "&&"
Boolean AND operator (described in "Condition Clauses" in this chapter)
is more efficient.

Other Notes.  Note that the SPL test for equality "=" is the assignment
operator in HP C/XL. Failure to convert an SPL "=" to an HP C/XL "=="
will result in a statement which compiles without error, but which
performs a very different operation at runtime.

SPL uses relational operators to compare byte strings.  See "Comparing
Byte Strings" below for an explanation and examples.

Sequence of Operations (Logical) 

          Table 5-24.  Order of Evaluation of Logical Operators 

---------------------------------------------------------------------------------------------
|                                             |                                             |
|                     SPL                     |             HP C/XL Equivalent              |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| Order of evaluation:                        | Same as SPL, except for the following:      |
|                                             |                                             |
|                                             | bit operations                              |
|    1.  logical bit operations               |   Implemented as function calls; same       |
|        logical expressions in parentheses   |   sequence level.                           |
|        logical function designators         |                                             |
|        logical assignment statements in     | equality tests                              |
|        parentheses                          |   == and != evaluate below <, <=, >, >=.    |
|                                             |   Parentheses may be needed.                |
|    2.  *, ** (logical multiply; 16- and     |                                             |
|        32-bit)                              | range tests                                 |
|        /, // (logical divide; 16- and       |   The conversion of SPL's X<=Y<=Z construct |
|        32-bit)                              |   to HP C/XL's X<=Y & Y<=Z will probably    |
|        MOD, MODD (logical modulus; 16- and  |   need parentheses around the X, Ys, and Z. |
|        32-bit)                              |                                             |
|                                             |                                             |
|    3.  + (logical addition)                 |                                             |
|        - (logical subtraction)              |                                             |
|                                             |                                             |
|    4.  <, <=, >, >=, =, <> (algebraic and   |                                             |
|        logical comparisons)                 |                                             |
|                                             |                                             |
|    5.  LAND (logical bitwise AND)           |                                             |
|                                             |                                             |
|    6.  XOR (logical bitwise exclusive OR)   |                                             |
|                                             |                                             |
|    7.  LOR (logical bitwise inclusive OR)   |                                             |
|        lower <= test <= upper (range test)  |                                             |
|                                             |                                             |
---------------------------------------------------------------------------------------------

Type Mixing (Logical) 

The mixing of data types across operands is not allowed in SPL. Type
transfer functions (see "Expression Types" above) are used to convert
data types.  See "Type Mixing (Arithmetic)" above for more detail.

Comparing Byte Strings 

          Table 5-25.  Comparing Byte Strings 

----------------------------------------------------------------------------------------------------
|                                                |                                                 |
|                      SPL                       |               HP C/XL Equivalent                |
|                                                |                                                 |
----------------------------------------------------------------------------------------------------
|                                                |                                                 |
| byte-comparison:                               | byte-comparison:                                |
|                                                |                                                 |
|      1. byte-ref rel-op byte-ref , ( count )   |      1. strncmp ( byte-ref , byte-ref , count ) |
|                                                |                                                 |
|             [, stack-decr]                     |                                rel-op 0         |
|                                                |                                                 |
|      2. byte-ref rel-op *PB , ( count )        |      2. (No direct equivalent;                  |
|                                                |                                                 |
|             [, stack-decr]                     |      convert to format 1)                       |
|                                                |                                                 |
|      3. byte-ref rel-op string-const           |      3. strcmp ( byte-ref , string-const )      |
|                                                |                                                 |
|             [, stack-decr]                     |                               rel-op 0          |
|                                                |                                                 |
|      4. byte-ref rel-op ( value-group [,...] ) |      4. (No direct equivalent;                  |
|                                                |                                                 |
|             [, stack-decr]                     |      convert to format 3)                       |
|                                                |                                                 |
|      5a. byte-variable = ALPHA                 |      5a. isalpha ( byte-variable )              |
|                                                |                                                 |
|      5b. byte-variable <> ALPHA                |      5b. !isalpha ( byte-variable )             |
|                                                |                                                 |
|      5c. byte-variable = NUMERIC               |      5c. isdigit ( byte-variable )              |
|                                                |                                                 |
|      5d. byte-variable <> NUMERIC              |      5d. !isdigit ( byte-variable )             |
|                                                |                                                 |
|      5e. byte-variable = SPECIAL               |      5e. !isalnum ( byte-variable )             |
|                                                |                                                 |
|      5f. byte-variable <> SPECIAL              |      5f. isalnum ( byte-variable )              |
|                                                |                                                 |
----------------------------------------------------------------------------------------------------
|                                                |                                                 |
| byte-reference:                                | byte-reference:                                 |
|                                                |                                                 |
|      a1. array/pointer-id                      |      a1. array/pointer-id                       |
|                                                |                                                 |
|      a2. array/pointer-id ( index )            |      a2. & array/pointer-id "[" index "]"       |
|                                                |                                                 |
|      b. *                                      |      b. (No equivalent;                         |
|                                                |                                                 |
|                                                |      stack reference requires recoding)         |
|                                                |                                                 |
|                                                | The str...  functions expect addresses of       |
|                                                | the strings; hence, the "&" in the indexed      |
|                                                | format.  Note that array/pointer-id alone       |
|                                                | is an address (of cell zero).                   |
|                                                |                                                 |
----------------------------------------------------------------------------------------------------
|                                                |                                                 |
| count:                                         | The equivalent syntaxes work left-to-right      |
|   is the number of characters to compare.      | only.  An alternate user-defined function,      |
|   If count is negative, the comparison is      | BYTECMP, that handles both cases is shown       |
|   right-to-left.                               | below.                                          |
|                                                |                                                 |
----------------------------------------------------------------------------------------------------
|                                                |                                                 |
| stack-decr:                                    | The equivalent syntaxes above work only for     |
|   is the number of items to remove from the    | a decrement of 3.  The functionality of         |
|   stack.  The default value is 3.              | other values is provided in the                 |
|                                                | user-defined function BYTECMP, shown below.     |
|                                                |                                                 |
----------------------------------------------------------------------------------------------------
|                                                |                                                 |
| value-group:                                   | This element and its surrounding                |
|   is a numerically defined byte string.        | parentheses must be converted to an HP C/XL     |
|                                                | character string.                               |
|                                                |                                                 |
----------------------------------------------------------------------------------------------------
|                                                |                                                 |
| byte-variable                                  | Same as SPL. The is...  functions expect a      |
|   is a reference to a single byte, either      | character value.                                |
|   as an array or pointer cell reference or     |                                                 |
|   as a simple byte variable.                   |                                                 |
|                                                |                                                 |
----------------------------------------------------------------------------------------------------

Here are five examples of the basic forms of byte comparison:

---------------------------------------------------------------------------------------------
|                                             |                                             |
|                     SPL                     |             HP C/XL Equivalent              |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| A < B(3), (5),3                             | strncmp(A,&B[3],5) < 0                      |
|                                             |                                             |
| B(5) >= *PB,(5)                             | No equivalent                               |
|                                             |                                             |
| A <= "string"                               | strcmp(A,"string") <= 0                     |
|                                             |                                             |
| B = ("ab",%07)                              | strcmp(B,"ab\7") == 0                       |
|                                             |                                             |
| C <> ALPHA                                  | !isalpha(C)                                 |
|                                             |                                             |
---------------------------------------------------------------------------------------------

The second example above, which compares bytes to a previously stacked
PB-relative address, is a hardware-dependent construct that has no
equivalent in HP C/XL.

The isalnum, isalpha, isdigit, strcmp, and strncmp functions are all
members of the standard HP C/XL function library.

Some more examples, used here as condition clauses of IF statements:

---------------------------------------------------------------------------------------------
|                                             |                                             |
|                     SPL                     |             HP C/XL Equivalent              |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| IF A = B,(5) THEN...                        | if (strncmp(A,B,5) == 0)...                 |
|                                             |                                             |
| IF A <> B,(5) THEN...                       | if (strncmp(A,B,5) != 0)...                 |
|                                             |                                             |
| IF A > B,(5) THEN...                        | if (strncmp(A,B,5) > 0)...                  |
|                                             |                                             |
| IF A < B,(5) THEN...                        | if (strncmp(A,B,5) < 0)...                  |
|                                             |                                             |
| IF A >= B,(5) THEN...                       | if (strncmp(A,B,5) >= 0)...                 |
|                                             |                                             |
| IF A(5) = "abc" THEN...                     | if (strcmp(&A(5),"abc") == 0)...            |
|                                             |                                             |
| IF B <> "abc" THEN...                       | if (strcmp(B,"abc") != 0)...                |
|                                             |                                             |
---------------------------------------------------------------------------------------------

These HP C/XL statements are equivalent to the SPL versions if the byte
strings (character strings) being compared do not contain a NUL character
in the range being tested.

The SPL byte comparisons scan exactly the number of characters indicated
by count or the number of character values in the string or value-groups.

By definition, an HP C/XL string is terminated by the ASCII NUL character
('\0', numeric value 0).  HP C/XL functions that scan strings usually
stop scanning when they find a NUL character or when they reach a
specified count.

However, because NUL equals zero and is the lowest character value, these
comparison functions should work well, except in the following situation.
Consider the case where both strings are equal up to a NUL character and
different afterward:  In HP C/XL notation,

    A == "ab\0de" (character values 'a', 'b',NUL,'d','e')

  and

    B == "ab\0fg" (character values 'a','b',NUL,'f','g')

  The SPL comparison "A = B,(5)" would be false, because d is less than
  f.  But the HP C/XL comparison "strncmp(A,B,5)==0" would be true,
  because strncmp stops scanning at the NULs.

The HP C/XL functions strcmp and strncmp return a value less than zero if
the string pointed to by the first parameter compares less than the
string pointed to by the second parameter, greater than zero if the first
is greater than the second, and equal to zero if they are equal.

The three HP C/XL library functions isalpha, isdigit, and isalnum are not
affected by this NUL "problem".  They provide equivalents for all the
corresponding SPL byte tests.

If the NUL character can be an embedded character, or if the count is
negative, requiring a right-to-left scan, or if you wish to make use of
the values left on the stack by the SPL byte comparisons, then the
user-defined function BYTECMP can help.  See Figure 5-18 in this chapter.

BYTECMP accepts the first byte-reference, the comparison code, the second
byte reference, the count, and the stack decrement, as given in SPL
syntax form 1.  It also accepts the addresses where it can return the
byte count and the left and right byte addresses where the comparison
ended.

Also see "SPL BYTECMP Procedure:  Byte Comparison" and "HP C/XL BYTECMP
Function:  Byte Comparison" for further details.
____________________________________________________________________
|                                                                  |
|     enum CMP { LSS, LEQ, EQU, NEQ, GEQ, GTR };                   |
|                                                                  |
|     int BYTECMP(left,cmp,right,count,sdec,caddr,laddr,raddr)     |
|        char *left, *right, **laddr, **raddr;                     |
|        enum CMP cmp;                                             |
|        int count, sdec, *caddr;                                  |
|                                                                  |
|     {                                                            |
|     #define ADJ {if (count > 0) {--count;++left;++right;} \      |
|                            else {++count;--left;--right;}}       |
|                                                                  |
|     switch (cmp)                                                 |
|        {                                                         |
|        case LSS:  /* compare < */                                |
|                   while ((count != 0) && (*left < *right))  ADJ; |
|                   break;                                         |
|        case LEQ:  /* compare <= */                               |
|                   while ((count != 0) && (*left <= *right))  ADJ;|
|                   break;                                         |
|        case EQU:  /* compare == */                               |
|                   while ((count != 0) && (*left == *right))  ADJ;|
|                   break;                                         |
|        case NEQ:  /* compare != */                               |
|                   while ((count != 0) && (*left != *right))  ADJ;|
|                   break;                                         |
|        case GEQ:  /* compare >= */                               |
|                   while ((count != 0) && (*left >= *right))  ADJ;|
|                   break;                                         |
|        case GTR:  /* compare >  */                               |
|                   while ((count != 0) && (*left > *right))  ADJ; |
|                   break;                                         |
|        }                                                         |
|                                                                  |
|     switch (sdec)                                                |
|        {                                                         |
|        case 0:  *raddr = right;                                  |
|        case 1:  *laddr = left;                                   |
|        case 2:  *caddr = count;                                  |
|        case 3:  ;  /* nil */                                     |
|        }                                                         |
|     return (count == 0)                                          |
|                                                                  |
|     #undef ADJ                                                   |
|     }                                                            |
____________________________________________________________________

          Figure 5-18.  HP C/XL BYTECMP Function:  Byte Comparison 



MPE/iX 5.0 Documentation