Using variables and values in computation

From m204wiki
Jump to: navigation, search

Contents

Overview

SOUL lets you use variables to represent values. You can use a SOUL variable, called percent variable (%variable), because variable names must start with a percent sign, any place in a SOUL statement that requires a value.

You can declare %variables for a single value or as an array. For the purposes of discussing SOUL, the term %variable is used to mean both a %variable and an element of a %variable array. The features discussed in this article enable you to generate additional information based on data in the file.

Special types of variables

In addition to the basic %variables (and variable arrays) discussed in this article, SOUL provides the following types of variables:

Type of variable See...
Field name Field name variables
Screen variables Full-screen variables
Image variables Defining image items and the sections that follow describing types of images
%Variables as parameters Flow of control in User Language

Values

You can specify SOUL values by using:

  • Literals (quoted strings)
  • Numeric constants
  • Field values (values derived from field retrievals)
  • %Variables

SOUL performs value conversions on values, as described in this article.

Arithmetic operations

Using values and/or %variables, you can construct expressions to perform arithmetic operations, which are discussed in this article.

Default variable attributes

Model 204 parameters that set default attributes for variables

Model 204 parameters that set default attributes for variables lists three Model 204 parameters that establish the default type, length, and number of decimal places for all types of SOUL variables:

%variable parameters
Parameter Meaning Default
VTYPE Type: Fixed, Float, String, or Undefined String
VLEN Length of String variables 20
VDP Number of decimal places in Fixed or String variables 0

You can change the defaults established by these parameters as follows:

  • The values of VTYPE, VLEN, and/or VDP can be changed by any user for the duration of the terminal session with the RESET command.
  • The value of any of these parameters can be overridden for the duration of a request with the Variables Are statement.
  • The variable type, length, and/or number of decimal places for any given variable can be explicitly specified in the declaration statement for that variable. This has the effect of overriding the respective values established by VTYPE, VLEN, and VDP, as well as the values established by the Variables Are statement.

VTYPE, VLEN, and VDP are discussed where relevant elsewhere in this article. Also, refer to the List of Model 204 parameters and List of Model 204 commands for more on user parameters.

Relationship between default values and variable declarations

A variable can be declared:

  • Explicitly, in a declaration statement (see DECLARE statements for %variables)
  • Implicitly, in an assignment statement (see Assignment statements). When a variable is declared implicitly, it takes on the attributes established by the VTYPE, VLEN, and VDP parameters (as modified by any Variables Are statement that may precede the assignment statement).

Variables Are statement

The Variables Are statement overrides, for the remainder of the current request, the default variable type, length, and/or number of decimal places established by the VTYPE, VLEN, and/or VDP parameters, or by an earlier Variables Are statement. It is particularly useful if you don't want to rely on VTYPE, VLEN, and VDP, and when most of the %variables used in a request are of the same type and length.

A Variables Are declaration has no effect on variables which have been declared (either implicitly or explicitly) earlier in the request. The defaults established by a Variables Are statement remain in effect until the next Variables Are declaration or until the end of the request, whichever comes first.

Syntax

The format of the Variables Are statement is:

Variables Are {Fixed [Dp n] | Float | String [Len n] [Dp {n | *}] | Undefined}

Variables Are Undefined statement

The Variables Are Undefined statement forces you to explicitly declare all variables. If this statement is used in a request and Model 204 encounters an undeclared variable, an error message is issued.

The Variables Are Undefined statement sets both the default Len and Dp options to 0. Therefore, when Variables Are Undefined is in effect, %variables declared as String must have the Len specified or an error message is issued.

Declaring %variables and %variable arrays

You can declare a variable and subsequently assign and reset that variable any number of times during a SOUL request. You can use a variable declaration statement to specify:

  • Type of variable
  • Length of the variable and number of decimal places
  • Number of elements if the variable is an array
  • Use of the optional field save feature

Variable arrays

Variables also can be declared to be arrays of up to three dimensions. An element of a %variable array is equivalent to a %variable that is not part of an array. It can be used anywhere that a %variable can be used.

Declare statements for %variables

To temporarily set or reset the default variable type, length, and number of decimal places for a particular %variable or %variable array in a request, use the Declare statement.

Syntax

In the following syntax diagrams, the first declaration statement is for numeric %variables and the second declaration statement is for string %variables

  • Syntax for numeric %variables:

    [Declare] %variable [Is] {Fixed [Dp n] | Float} [Array(d1 [,d2 [,d3]])] [Initial(numeric-expression)] [Static] [Common]

  • Syntax for string %variables:

    [Declare] %variable [Is] String [Len n] [Dp [n |*}] [Array(d1 [,d2 [,d3]])] [No Field Save] [Initial('EBCDIC-string' | expression)] [Static] [Common]

Where:

  • The keyword Declare is optional.
  • The Initial attribute assigns an initial value to a %variable at compilation time, without using any excess QTBL, STBL, or VTBL space and CPU usage. The Initial attribute is permitted only for numeric expressions or EBCDIC string variables, and not for arrays of any type or DBCS variables.
  • The Static attribute limits assignment to a %variable to the Initial attribute and requires the Initial attribute to set the %variable's initial (and only) value.
  • The various other components of this statement, except for Common, are described later in this article; Common is discussed in Common elements.

    If you want to use the Common attribute on a %variable declaration with the Initial and Static attributes, the Common attribute must be the last token in the statement. For example:

    %x is float initial (3) static common

Usage

%Variable Initial value assignment

An Initial value longer than the maximum length results in a compilation warning message:

M204.2493: VARIABLE TOO SMALL FOR INITIAL VALUE

Examples

The following examples use the Static or Initial attribute.

  • In the first example, set %X to the value ABC, using the Static attribute. The value cannot be changed during request evaluation:

    %X IS STRING LEN 3 INITIAL('ABC') STATIC

  • The next example uses a %variable that can be changed during request evaluation:

    %Y IS STRING LEN 3 INITIAL('ABC')

  • The following compiler error message is displayed if you attempt to assign a value to a %variable that has been declared Static:

    *** M204.0542: EDIT COMPLETE - GO *** 1 M204.2490: ILLEGAL ASSIGNMENT TO STATIC %VARIABLE  %X=5 (FILE=CCATEMP, PROCEDURE=0, LINE=3) ==5 *** 2 M204.0228: PART OF STATEMENT IGNORED *** M204.1042: COMPILATION ERRORS

  • The next example illustrates using the Static attribute and an expression with the Initial attribute.

    BEGIN %X IS STRING LEN 3 INITIAL('ABC') STATIC %Y IS STRING LEN 3 INITIAL('DEF') STATIC %ALPHA IS STRING LEN 6 - INITIAL($SUBSTR(%X,2,1) WITH $SUBSTR(%Y,2,1)) STATIC PRINT %ALPHA END ***M204.0542:EDIT COMPLETE - GO BE

%Variable names

A variable name can consist of any number of letters, numbers, and some special characters (for example, underscore).

The first character of the name must be a percent sign (%).

The . (period) character is not allowed in the name of a variable that is declared as a Json object.

A variable name can have no embedded blanks, colons, or any of the following Model 204 reserved characters:

= + $
( * , (not sign — see Note below)
) ' - (minus sign/hyphen)
; < /
, > :

Note: The , reserved character is the EBCDIC "not sign," which has the hexadecimal value 5f.

The following guidelines apply to certain special characters that are allowed in %variable names:

  • The @ and # characters also are reserved, unless they are reset by the user through the FLUSH and ERASE parameters.
  • Dummy string characters (??, ?$, ?&) can be used in variable names, but they perform dummy string substitution, as described in Using ?$ and ?& dummy strings.

Relationship to Variables Are statement

The type, length, and decimal place settings established for a particular %variable by a DECLARE %variable statement are not overridden by a Variables Are statement. For example, if the statement:

DECLARE %NAME STRING LEN 30

is followed by the statement:

VARIABLES ARE FIXED

then %NAME remains a string of length 30.

%Variable types

A %variable can be declared as one of several distinct types:

  • Fixed (fixed-point numeric)
  • Float (floating-point numeric)
  • String (alphanumeric string)

And these, as of Version 7.5 of Model 204:

Using Fixed or Float for arithmetic statements

Defining %variables as Fixed or Float improves the performance of arithmetic statements. If the result of an arithmetic operation is being assigned to a %variable, the result is not converted before assignment if the arithmetic operands are of the same type.

Arithmetic operations are performed most efficiently if all %variables are defined with matching options: either as Float or as Fixed, and with no decimal places or the same number of decimal places. To operate Model 204 as efficiently as possible, avoid mixed-type arithmetic. Use String variables only when string manipulations are required.

An arithmetic operation where both operands are Fixed requires rules to determine the scale (number of decimal places) of the result. See Fixed precision arithmetic for detailed information on the way Model 204 handles Fixed arithmetic operations.

Arithmetic result types

Arithmetic result types shows the types and the results for various combinations of operands in an arithmetic statement. The result described in the table refers to the result of an arithmetic operation, which might be an intermediate result. If the final result is being assigned to a %variable of a different type, it is converted to match.

%Variable types for arithmetic results
Operand 1 Operand 2 Arithmetic result type
Float Float Float
Float Fixed Float
String Float Float
String String Float
String Fixed Fixed
Fixed Fixed Fixed

%Variable lengths

Fixed %variables

%Variables declared as Fixed can have a decimal place specification associated with them. For example:

Declare %total Fixed dp 2

represents a dollar total. A Fixed %variable can contain as many as 15 significant digits, including decimal places. There can be as many as 9 decimal places.

Float %variables

Variables declared as Float are stored as double-precision floating-point numbers. Precision is guaranteed to 15 decimal digits; the exponent must be between 75 and -74.

String %variables

Variables declared as String can have a maximum length as well as an optional decimal place specification associated with them. For example:

DECLARE %NAME STRING LEN 20 DP 2 VARIABLES ARE STRING LEN 7

The first statement (above) declares the %NAME variable as String, with a maximum length of 20 and two decimal places. The second statement sets the defaults for %variables not explicitly declared: String with a maximum length of 7 and no decimal places.

Additionally, the decimal place for String %variables can be variable by specifying DP *. This causes all decimal digits to be placed in the string. For example:

BEGIN  %AMOUNT IS STRING LEN 10 DP *  %AMOUNT = 1.2 PRINT %AMOUNT  %AMOUNT = 1.23 PRINT %AMOUNT  %AMOUNT = 1.234 PRINT %AMOUNT END

Yields:

1.2 1.23 1.234

The maximum length of a String variable is 255 characters. Decimal places, and the decimal point itself, are included in the specified length. Alternatively, the default values for length and decimal places can be used. An attempt to store a value longer than the declared or default length results in truncation.

The current length of a String variable is determined by the value put into the String variable. You can use the $Len function to find the current length of a String variable.

If the Variables Are Undefined statement is used, the values for length and decimal places must be specified with each String %variable declaration.

%Variable arrays

You can define %variables as arrays of one, two, or three dimensions with the Declare %variable statement. For example:

DECLARE %CODES STRING LEN 5 ARRAY(100)

defines a one-dimensional array of up to 100 message codes, each five characters in length.

DECLARE %TRANSACTION FIXED DP 2 ARRAY(12,10000)

defines a two-dimensional array of dollar transactions for a store. The array contains up to 10,000 transactions for each of 12 departments.

DECLARE %READINGS FLOAT ARRAY(3,10,80)

defines a three-dimensional array consisting of up to 80 atmospheric readings of three distinct types from 10 monitoring stations.

Array elements must be of one type

All elements of an array must have the same type (Fixed, Float, or String) and element length.

%Variable array references

An array can be referred to only after it has been declared in an array can have as many as three declared dimensions. A subscript value must be supplied for each dimension.

If a variable is declared as an array, it must always be referenced with subscripts.

Each of the subscript values that refers to a dimension can be a number or an expression. For example:

%CODE(2) %READING(3,200-%A/%B,%N)

As shown in the examples, the expression can contain references to other %variables. The subscript value is converted to an integer. Any fraction is truncated before the subscript value is used as the array subscript. The subscript value must fall within the declared range of dimensions.

No Field Save option

When a String %variable array is declared, you can specify:

No Field Save

If you do not intend to use any of the String array elements as field name variables, you should select the No Field Save option, to save space in the user work areas described in STBL (character string table). (Field name variables are discussed in detail on Field name variables.)

An element of a String array can be used as a field name variable even if No Field Save is specified. However, when the value of the element is referred to as a field name, extra processing and additional disk I/O are required for each reference after the first.

Assigning values to %variables

Assignment statements

Syntax

The format of the statement used to calculate and assign the value of %variables is:

%variablename = expression

The name of the %variable to be set appears to the left of the equal sign and the expression to whose value the %variable is to be set is at the right. (See also Expressions.)

For Large Object data, a compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.

M204.2691: BUFFER ASSIGNMENT MUST REFERENCE LARGE OBJECT FIELD

and/or

M204.2704: BUFFER REFERENCE REQUIRES LOB FIELD

Example

These statements are valid assignments:

%AGENT = AGENT %NAME = 'DALE STERN' %RESULT = (%INCREASE + TOTAL PREMIUM) * .01

Note that %AGENT is legal as a variable name even if AGENT is a field name in the file. The variable and the field are not related to each other.

Relationship between %variable assignment and declaration

Normally, an assignment statement precedes a %variable reference in another statement. If a %variable is going to be declared with the Declare %variable statement, the declaration must precede the first use of the %variable. If an assignment statement does not precede the %variable reference, or the variable has not been declared, then default values (null values for String types, 0 for Fixed and Float) are assigned to the %variable.

Truncation vs. rounding on assignment

In an assignment statement, it is possible for the length of the assigned value to exceed the maximum length for that %variable (as determined in the variable declaration statement, the Variables Are statement, or the value of the VLEN or VDP parameter). The way Model 204 treats this situation depends on the %variable type.

  • For Float %variables, the assigned value is rounded to 15 significant digits.
  • For Fixed %variables, if the number of places to the left of the decimal point in the assigned value, plus the number of decimal places declared (not assigned) exceeds 15, Model 204 returns an error message and assigns a value of zero. Otherwise, if the number of decimal places assigned exceeds the number declared, Model 204 truncates the assigned value to the number of decimal places declared. For example, the following request:

    BEGIN %X IS FIXED DP 0 %Y IS FLOAT %Z IS FLOAT %X = 1.9 %Y = 5 %Z = %X * %Y PRINT '%X = ' WITH %X PRINT '%Y = ' WITH %Y PRINT '%X * %Y = ' WITH %Z END

    results in this output:

    %X = 1 %Y = 5 %X * %Y = 5

    The value of %X is truncated from 1.9 to 1 upon assignment for both display and computation.

  • For String %variables, if the number of characters in the assigned value exceeds the maximum declared length (or, if not declared, the default length set by the VLEN parameter), the assigned value is truncated to the maximum length allowed.

Changing %variable values

You can change the value of a %variable at any point in a request by using an assignment statement. The variable is stored for the duration of the request that assigns it, including any continuations, and is then deleted.

At the beginning of a request, all %variables are set equal to a null string, or to zero, depending on their types.

During a request, a %variable can be set equal to another %variable, a quoted string, a number, a field value, a noted value, a function, a count of records or field occurrences, an occurrence number, a null value, or the result of a computation.

Understanding Initial processing

Code written using an Initial assignment for both %variables results in the assigned value of %X as the Initial value assigned for %Y as both assignments are resolved at compilation. For example:

BEGIN %X IS STRING LEN 1 INITIAL(1) * %X assigned the INITIAL value of 1, at compilation %Y IS FIXED INITIAL(%X) * %Y assigned the INITIAL value of %X, at compilation PRINT 'Y = ' %Y END Y = 1

An Initial value assignment in the format %Y IS FIXED INITIAL (%X), will not resolve to the value of %X, if %X was assigned in the format %X=1. %X=1 format variable assignments are resolved at evaluation, subsequent to compilation. Initial value assignments are resolved at compilation.

The following code reflects this processing:

BEGIN %X IS STRING LEN 1 %X = 1 * %X assigned the value of 1 at evaluation %Y IS FIXED INITIAL(%X) * %Y assigned the INITIAL value at compilation PRINT 'Y = ' %Y END Y = 0

The %X value is assigned at evaluation. The Initial value is assigned at compilation, prior to the evaluation of %X=1. The result is that %Y is assigned the default value, zero (0), for its type of Fixed.

Expressions

Expressions are evaluated by Model 204 and used to assign values to %variables and function arguments, or included as operands in computation or conditional statements.

Syntax

An expression has this format:

{operand | (expression)} [operator {operand | (expression)}]...

Where:

  • operand is one of the following:
    • %%variable (field name variable)
    • %variable or element of %variable array
    • Count In label
    • Field name
    • Function
    • Number
    • Occurrence In label
    • Quoted string
    • Value In label
  • operator can be arithmetic, Boolean, comparison, or concatenation.

Operator order of precedence

The following table lists the operators used within expressions in order of precedence. Parentheses can be used to override the order.

Operator order of precedence in expressions
Order of precedence Operator
First IS PRESENT, IS NOT PRESENT
Second - (unary minus)
Third *,/
Fourth +,-
Fifth WITH
Sixth EQ, =, LE, <=, GT, >, GE, >=, NE, ,=, LT, IS [NOT] LIKE
Seventh NOT
Eighth AND
Ninth OR
Tenth AND (implied by a new line; occurs only in an If statement)
Notes:
  • The first character (,) of the inequality test above is the EBCDIC "not sign", which has the hexadecimal value 5f.
  • For a description of the IS [NOT] LIKE clauses, see the syntax of Is Like patterns.

Incomplete expressions

Incomplete expressions, such as the following:

IF %X = 10 OR %Y > 40 AND %A = %B WITH

produce this message:

M204.0052 ILLEGAL TERM

Compilation does not succeed and the procedure does not run.

Using expressions for value retrieval

You can use expressions for value retrieval in the following SOUL statements:

  • Update statements (Store Record, Add, Change, Delete, Insert)
  • File Records
  • Find
  • Find...Point$ condition
  • Find...Sfl$ and Find...Sfge$ conditions
  • For Each Record In Order By
  • For Each Record Where
  • Find All Values
  • For Each Value
  • For Record Number

Expression types supported in SOUL statements

The following table provides examples of the types of expressions that you can use to supply retrieval values for statements.

Expression types supported in statements
Expression type Example
Function call

In ?&File Fd ORDER.DATE Eq Value($Date(1,''))

String concatenation

In ?&File Fd BIRTH.DATE Eq Value(%yyyy With %mm With %dd)

Arithmetic operation

In ?&File Fd SALES.VALUE Eq Value(%item.value * %item.sales)

SOUL construct

In ?&File Fd NUM.ORDERS Eq Value(Count In FD.ORDERS)

Boolean expression

In ?&File Fd ORDER.STATUS Eq Value(%status Is Like 'A*')

Example

The following example shows these different types of expressions used as values.

B %MM IS STRING LEN 2 %DD IS STRING LEN 2 %BASE.PREMIUM IS FLOAT %PCT.INCREASE IS FLOAT * * function call expression * PRINT 'FD1' FD1: IN CLIENTS FPC INCIDENT DATE EQ - VALUE($DATECHG('YYYYMMDD',$DATE(1,''),-3169)) END FIND FR FD1 PAI PRINT END FOR * * string concatenation expression * PRINT 'FD2' %MM = '09' %DD = '17' FD2: IN CLIENTS FPC ANNIV DATE EQ VALUE(%MM WITH %DD) END FIND FR FD2 PAI PRINT END FOR * * arithmetic operation expression * PRINT 'FD3' %BASE.PREMIUM = 1280 %PCT.INCREASE = 1.25 FD3: IN CLIENTS FPC TOTAL PREMIUM EQ VALUE(%BASE.PREMIUM * %PCT.INCREASE) END FIND FR FD3 PAI FEO1: FEO VIN * * UL syntax expression * PRINT 'FD4' FD4: IN VEHICLES FPC VIN EQ VALUE(VALUE IN FEO1) END FIND FR FD4 PAI PRINT END FOR END FOR END FOR * * boolean expression * PRINT 'FD5' FD5: IN CLIENTS FPC INCIDENT EQ VALUE('T' WITH (%DD IS LIKE '1*')) END FIND FR FD5 PAI PRINT END FOR END

Operators

This section describes the use of four types of operators:

  • Arithmetic
  • Comparison
  • Boolean
  • With

See the previous section for a discussion of expressions, and the next section for a discussion of operands. See Fixed precision arithmetic for a more detailed discussion.

Arithmetic operators

The following table lists the arithmetic operators:

+ Addition
- Subtraction, unary minus
* Multiplication
/ Division

Order of operations

The arithmetic operators are used to compute the value of a %variable or they can be included in an expression. When an expression contains several arithmetic operations, the operations are performed in the order shown in Operator order of precedence. Operators of equal precedence are evaluated in order of appearance, from left to right. For example:

%result = 8*7 + 4

sets %result to 60.

Parentheses change the order of operations; expressions within parentheses are compiled first. For example:

4-5*2*3 = -26 (4-5)*(2*3) = -6 (4-(5*2))*3 = -18

Arithmetic overflow

An arithmetic overflow might occur during evaluation of a computation statement. If such an overflow occurs, the request is cancelled and an appropriate error message is issued.

Comparison operators

The following comparison operators are used to compare two objects, two strings, two numbers, or a string and a number:

Operator Meaning
EQ, = Equal
NE, ^= Not equal
GT, > Greater than
LT, < Less than
GE, >= Greater than or equal to
LE, <= Less than or equal to
IS [NOT] LIKE Pattern matching equivalents
IS [NOT] PRESENT Field existence

When a comparison operator is included in an expression, a value of 1 results if the stated relation between operands is true; if false, a value of 0, provided that one of the following conditions apply (using the expression %I = (%A<=%B) to illustrate):

  • Either %A or %B (or both) is declared as Fixed or Float.
  • Either %A or %B (or both) is signed in the expression; for example, %I = (+%A <=%B).
  • VTYPE = FLOAT or FIXED, and VLEN is greater than zero.

The resulting value returned from the expression might be invalid if all the following conditions apply:

  • Neither %A nor %B is declared.
  • The expression does not sign the variable.
  • The system default for VTYPE is String and VLEN is greater than zero.
Notes:
  • See the discussion about the conditional statement in Comparison operators for a description of these operators in conditional statements.
  • The first character (,) of the inequality test above is the EBCDIC "not sign", which has the hexadecimal value 5f.
  • For a description of the IS [NOT] LIKE clauses, see the syntax of Is Like patterns.

Boolean operators

Use the Boolean operators listed in the following table to modify or link together comparison expressions. (See the discussion about Boolean operators and conditional statements for information on comparisons.)

Boolean operators
Operator Meaning
Not The value of the comparison is reversed.
And Both comparisons must be true.
Or Either comparison must be true.

Boolean operators are not restricted to comparisons. They also can be used in the middle of expressions (for example, 1 AND 2).

With operator

With can be used in an expression to concatenate two strings. For example:

%A = '$' WITH TOTAL PREMIUM PRINT %A TO COLUMN 10

results in:

$550 $1092 $605

Operands

This section describes the use of four types of operands:

  • %variables
  • Quoted strings
  • Numbers
  • Fields

See also

Variables as operands

After you define a %variable, you can use it to change other %variables. For example:

%COUNT = %NUM

sets %COUNT, and:

%COUNT = %COUNT + 1

replaces the value of %COUNT%COUNT by its former value plus 1.

Quoted strings

Examples of %variables set to quoted strings are provided here:

%NAME = 'TETLEY' %AGE = '53' %TITLE = 'QUARTERLY REPORT' %SPOUSE =

In the preceding example, %SPOUSE is a quoted string that has a length of 0.

Additional information about the use of quotation marks is provided in Quotation marks.

Numbers

A number used as the value of a %variable or as a term in an expression can be a string of digits containing an optional sign and an embedded decimal point.

For example:

3 +0.002 45.7 -37

The magnitude of the number is limited by the magnitude of the largest number that can be represented in a floating point number. Therefore the number's exponent (if the number is expressed in exponent notation) must be between 75 and -74.

Fields

Field values, referred to by field name, can be used in an assignment statement, but only inside a FOR EACH RECORD loop. To evaluate an expression, Model 204 uses the value of the field for the current record each time through the loop. For example:

FOR EACH RECORD IN FIND.RECS  %PROFIT = %INCREASE - TOTAL PREMIUM PRINT %PROFIT END FOR

calculates profit from the data in each record and prints it. %PROFIT changes for each record.

In expressions, the values of most types of fields are treated as character strings. The values of fields defined with the FLOAT attribute are treated as numbers. If a field is missing from a record being processed, the value used is a null string.

Fixed precision arithmetic

An arithmetic operation where both operands are Fixed requires rules to determine the scale (maximum numbers of digits and decimal places) of the result.

Scale of intermediate results

Model 204 determines the scale of intermediate results (the number of decimal places) using the following rules.

Addition and subtraction

When an expression requires either addition or subtraction, the scale of the temporary variable containing the result equals the larger of the scales of the two operands. For example, the scale for the result of the following expression is 3:

12.345 + 3.6

If the result exceeds 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. If a 15 digit number cannot be produced even by dropping all decimal places, an overflow condition is indicated.

Multiplication

When an expression requires multiplication, the scale of the temporary variable containing the result is equal to the sum of the scales of the two operands. For example, the scale for the result of the following expression is 5 (3+2):

12.345 * 3.64

If the sum of the scales of the operands exceeds 9 or if the result is larger than 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. As with addition and subtraction, if the result has more than 15 digits with all decimal places discarded, an overflow condition is indicated.

Division

When an expression requires division, the scale of the temporary variable containing the result is equal to the larger of:

  • 9
  • the largest possible scale that fits in 15 digits

For example, the scale for the result of this expression is 9 (the calculated result is 3.529411764):

12 / 3.4

Causes of overflow conditions

The following situations are treated as overflow conditions:

  • When the integer portion of any intermediate or final result is larger than 15 digits.
  • For addition and multiplication, when the scale of the final result variable is so large that the integer portion of the result cannot fit into the maximum allotted size. For example:

    BEGIN  %A IS FIXED DP 0  %B IS FIXED DP 0  %C IS FIXED DP 9  %A = 999999  %B = 1  %C = %A + %B PRINT 'C = ' %C END *** M204.0542: EDIT COMPLETE - GO *** M204.0552: VARIABLE TOO SMALL FOR RESULT C = 0.000000000

Because the scale of the variable which contains the final result (%C) is 9, the integer portion of the result is limited to no more than 6 digits. Because the integer portion of the result requires 7 digits, an overflow condition is triggered.

This example illustrates that Model 204 takes into consideration the scale of the final result variable. The example below is identical to the one above except that the scale of %C is set to 8. The request executes successfully because this frees the required 7 digits for the integer portion of the result:

BEGIN  %A IS FIXED DP 0  %B IS FIXED DP 0  %C IS FIXED DP 8  %A = 999999  %B = 1  %C = %A + %B PRINT 'C = ' %C END *** M204.0542: EDIT COMPLETE - GO C = 1000000.00000000

How Model 204 responds to overflow conditions

Overflowing to zero

When Model 204 detects an overflow condition, the intermediate result is set to 1015. Since this is a 16-digit number, it is illegal in SOUL and tends to cause a cascade of overflow conditions in a complex expression, which can generate the following error message:

M204.0552: VARIABLE TOO SMALL FOR RESULT

The final result of the expression is usually 0, which lets you see that an overflow error might have occurred.

Overflowing to very large, obviously incorrect number

An exception to the rule of a 0 final result is the case where an overflow occurs in an intermediate step and the next step (whether intermediate or final) involves subtracting a value whose scale is 0 so that the result is less than 1015. In this case, you get a large, incorrect, result. For example:

BEGIN  %X IS FIXED DP 0  %Y IS FIXED DP 0  %Z IS FIXED DP 0  %X = 10E13  %Y = 350000  %Z = 10 * (%X * %Y) WILL OVERFLOW AND BECOME 10E15  %X = (%X * %Y) - %Z PRINT 'X =' %X END *** M204.0542: EDIT COMPLETE - GO *** 1 M204.0563: ARITHMETIC OVERFLOW X = 999999999999990

Value In, Count In, and Occurrence In phrases

You can set a %variable value based on the following elements of a SOUL request:

  • Value In phrase

    A %variable can be set equal to a noted value, as illustrated below:

    %DRIVER = VALUE IN NOTE.DRIVER

    This phrase also can be included in an expression or used to include the current value in a For Each Occurrence or For Each Value loop.

  • COUNT IN phrase

    A %variable can be set equal to the number of records counted, as in:

    %COUNT = COUNT IN NO.OF.VINS

    This phrase also can be included in an expression.

  • OCCURRENCE IN phrase

    A %variable can be set equal to the subscript value of the current occurrence of a field in a record, as in:

    %OCCUR = OCCURRENCE IN INCIDENT.TYPE

    where INCIDENT.TYPE is the statement label of a For Each Occurrence statement. This phrase also can be included in an arithmetic expression.

Conversions and significant digits

Numeric terms

The following expression terms are considered numeric:

  • Literal (unquoted) numbers: -3, .0079
  • Count In phrases
  • Occurrence In phrases
  • Some functions (see List of mathematical $functions)
  • Results of numeric expressions
  • Fixed or Float %variables
  • FLOAT fields

Character terms

The following expression terms are considered character:

  • Quoted strings: 'SMITH', '.0079'
  • Non-FLOAT fields: NAME, ADDRESS
  • Value In phrases
  • Some functions (see $Functions)
  • String %variables

Conversion

In the expression AGE + 10, the value of the field AGE (character) is added to a literal number (numeric). Model 204 converts the value of AGE to a number. If the value is a proper number (for example, 5, -3.943, +.0003), the conversion is obvious; if not, the value is not a proper number (for example, FIVE, ", ABCD) or a number with too many digits, it is converted to a zero.

In the expression 'NUMBER' WITH -3.8, a quoted string is to be concatenated with a number. Model 204 first converts the number to a character string. In such a conversion, all decimal places are lost; the number is truncated to an integer and the result is NUMBER-3.

Significant digits in computations

SOUL can accept as input to computations the largest floating point number that can be expressed in exponent notation and can produce results of that magnitude.

However, all results contain at most 15 significant decimal digits, with zeros in the low-order positions. Model 204 preserves 15 digits in all intermediate results, rounding each result to 15 digits before going on to the next intermediate calculation.

If the final result is assigned to a String %variable, that result is truncated on the right to the maximum length specified for the %variable.

Sample request using %variables

The following request illustrates an assignment statement. The request computes the total settlement amount for each claim type within a file. Output consists of a 2-column table, giving a total amount for each type as well as a grand total settlement amount.

For example:

BEGIN VARIABLES ARE STRING DP 2 SET HEADER 2 'TOTAL' TO COLUMN 34 SET HEADER 3 'CLAIM TYPE' - WITH 'SETTLEMENT AMOUNT' TO COLUMN 40 SET HEADER 4 NEW PAGE EACH.TYPE: FOR EACH VALUE OF CLAIM TYPE TYPE.MATCH: FIND ALL RECORDS FOR WHICH CLAIM TYPE = VALUE IN EACH.TYPE END FIND FOR EACH RECORD IN TYPE.MATCH  %TOT = %TOT + SETTLEMENT AMOUNT END FOR PRINT VALUE IN EACH.TYPE AT COLUMN 6 - WITH %TOT TO COLUMN 36  %GRANDTOT = %GRANDTOT + %TOT  %TOT = 0 END FOR SKIP 1 LINE  %GRANDTOT = '$' WITH %GRANDTOT PRINT 'GRAND TOTAL:' WITH %GRANDTOT TO COLUMN 36 END

Note that the user resets the value of %TOT to 0 after each pass through the value loop. Because %variables retain their values until explicitly reset, the user is responsible for clearing %variables that are to be reused. Model 204 does not perform this type of housekeeping routine automatically.

The output resulting from the preceding request is:

TOTAL CLAIM TYPE SETTLEMENT AMOUNT O 52905.00 C 53310.00 L 51773.00 GRAND TOTAL: $157988.00

Using %variables in place of the Note statement

In most cases the Note statement can be replaced with an assignment statement to achieve the same results.

Example

In this example, POLICY NO is assigned to a variable rather than a Note statement:

BEGIN POL.HOLDERS: FIND ALL RECORDS FOR WHICH RECTYPE = POLICYHOLDER END FIND FOR EACH RECORD IN POL.HOLDERS  %POLICY.NO = POLICY NO EACH.POL.NO: FIND ALL RECORDS FOR WHICH POLICY NO = %POLICY.NO RECTYPE = DRIVER END FIND FOR EACH RECORD IN EACH.POL.NO PRINT %POLICY.NO AND FULLNAME END FOR END FOR END

Caution: Some caution is required when substituting %variables for Note statement values. The Note statement retains up to 255 characters, while an undeclared %variable retains only the default length set by the VLEN parameter. If a %variable is used for a long field value, the length parameter for the %variable must be reset to avoid truncation.

Impact on STBL space

Another difference between %variables and Note statement values is the use of space in the system work area STBL. For more information on STBL, refer to STBL (character string table).

Field name variables

Field name variables permit indirect reference to field names, thereby permitting many procedures and requests to be generalized without using dummy strings (refer to Dummy strings in procedures for a discussion). The actual field names used in a particular procedure or request are specified when the request is executed. Field name variables are extensions of the %variables described in the preceding section.

Syntax

A field name %variable is indicated in this format:

%%name

For example:

%%DISCOUNT

Using field name variables

During the evaluation phase of a request, a string value can be assigned to a %variable:

%DISCOUNT = 'DISCOUNT'

and that %variable can then be used in SOUL statements where field names normally appear, as in this example:

ADD.REC: STORE RECORD  %%DISCOUNT = .055 END STORE

A field name variable and a variable with identical names are actually the same variable. When the variable is used in %variable context (for example, on the left hand side of an assignment statement), it takes the usual %name form. If the same variable is used in a field name context (for example, to the left of an equal sign (=) in a FIND condition), it takes the %%name form. In the latter case, the value of the variable (when the Find statement is evaluated) is used as the field name.

Example

BEGIN START.REQUEST: %A = $READ('ENTER FIELD NAME') IF.QUIT: IF %A EQ 'QUIT' THEN JUMP TO STOP.REQUEST END IF  %B = $READ('ENTER VALUE') MATCH.SET: FIND ALL RECORDS FOR WHICH  %%A = %B END FIND FOR EACH RECORD IN MATCH.SET PRINT.INFO: PRINT 'RECNO ' WITH RECNO - WITH %A AT COLUMN 15 AND %%A END FOR JUMP TO START.REQUEST STOP.REQUEST: PRINT 'END OF REQUEST' END

If the file consists of these two records:

RECNO = 1 RECNO = 2 AGE = 23 AGE = 1 WEIGHT = 146 WEIGHT = 23

and the user replies to the $READ prompts with:

AGE 23 WEIGHT 23 QUIT

The output from the request is:

RECNO 1 AGE 23 RECNO 2 WEIGHT 23 END OF REQUEST

The START.REQUEST and IF.QUIT statements use %A as a variable. When %A is used as a field name variable in the FIND condition of the MATCH.SET statement, it appears as %%A. In the PRINT.INFO statement, both %A and %%A are used. First the value of %A (the string value that represents the field name) is printed. Then %%A is used as a field name, printing the value of that field within the record.

Assigning values to field name variables

You need to be aware of the difference between the following statements:

FIELD.VAR: %a = EMPLOYEE NUM STRING.VAR: %a = 'EMPLOYEE NUM'

The FIELD.VAR statement assigns the value of the field named EMPLOYEE NUM from the current record to %variable a. The FIELD.VAR statement must appear within a For Each Record loop.

In contrast, the STRING.VAR statement assigns the character string EMPLOYEE NUM as the value of %variable a. If %variable a is to be used subsequently as a field name variable, it must contain a valid field name for the file(s) being examined by the request.

Subscripted field name variables

You can use subscripts with field name variables, as discussed in Subscripts. This is often useful in specifying indirect references to particular occurrences of multiply occurring fields. Any field name variable can be followed by a parenthesized expression. The value of this expression is used as a subscript that specifies the desired occurrence of the named field.

For example, the field name variable reference:

%%DISCOUNT(5)

refers to the fifth value of the field represented by the field name variable, %%DISCOUNT.

The evaluation of subscript expressions is subject to the rules of assignment to an integer discussed earlier in this section.

It is also possible for the field name variable being subscripted to be an element of an array. The format of such a reference is:

%%variable (a1 [, a2 [, a3] ]) (n)

where a1, a2, and a3 are the subscripts of the array, and n is the occurrence subscript. For example:

%%ITEM(3,5) (4)

indicates the fourth occurrence of the field. The actual value of the field name variable is saved as the element of the array, %ITEM, with subscripts (3,5).

Resolution of field types and levels

Some statements operate only on fields of a particular type. Such requirements usually are enforced when a request is compiled. The use of field name variables defers error checking until the request is evaluated and the values of the variables are known. The value of a field name variable is checked for the same errors as field names known at compilation time (a reference to an undefined field, an attempt to print an INVISIBLE field, a length error on a preallocated field, or a security access violation). If an error is detected the request evaluation is cancelled.

Possible file inconsistency

Cancellation of a request during a sequence of statement updates could leave a file in a logically inconsistent state.

This occurs if a change is made before an incorrect reference to a field name variable, and also before a dependent change is made. A request that stores records using field name variables for some fields, or a request that operates on fields with security levels, could leave a file in an inconsistent state if an error occurs for one or more of the fields. The result might be a record without some or all of its fields.

The field type and security level of a variable can be checked before updating by using the $Dscr, $FlsAcc, and $FlsChk functions.