f (f-correlative) processing code
.mdThe f-correlative is used in the conversion (attribute 7), correlative (attribute 8), and input-conversion (attribute 14) attributes of attribute-defining items to create and modify the associated attribute value using various mathematical and logical operations.
The attribute values should be stored without a decimal point, and are reconstituted upon output, that is:
• Value entered is 100.25
• Input processing code mr2 stores the value as 10025
• Output processing code mr2 recreates the original value, and outputs as 100.25
Performing arithmetic on two internal values is done as two integers, and care should be taken to rescale the result properly to preserve the proper placement of the decimal place.
Division by 0 produces a result of 0 with no error message.
If arithmetic must be performed on internal values that contain a decimal point, then the processing code must normalize the value to a number with a fixed number of decimal places, and descale the result before output. For example:
fx(G0.1);x(G1.1);(S;*;"0");(ML%5);:;(MR5)
where:
| x | Uses attribute number ( in the above example x=1 or x=2 ). |
| x(G0.1) | Retrieves the integer part. |
| x(G1.1) | Retrieves the decimal part. |
| (S;*;"0") | Forces trailing zeroes if there is not any decimal point. |
| (ML%5) | Normalizes the decimal part into five digits. |
| (MR5) | Outputs the number with five decimal places. |
Since this must be done with each attribute, the structure of the data can avoid this situation, meaning that it is a good idea to try to ensure that the raw data in decimal attributes not contain decimal points.
Syntax
f{;}element{;element...}
Parameter(s)
| element | Elements in an f-correlative are operands
and operators in reverse Polish notation separated by semicolons.
|
Reverse Polish Notation
Reverse Polish notation is a written syntax where the operators follow the operands. For example, to total one and two is written as:
1 2 +
This notation is used by Hewlett Packard calculators and the D3 f processing code. To total one and two in an f-correlative is written as:
f;’1’;’2’;+
This notation is easier for a programmer to program, but harder for a user to use. So the a processing code was created to support embedded operators, providing the syntax of:
a’1’+’2’
Operands and operators may appear in any order and after all the operand pushes and operator operations have been processed, and the right end of the f-correlative has been reached, what remains on the stack is the result.
Operands
| ac{r} | Attribute value of the attribute whose attribute count is ac. The r option specifies that the first value or subvalue of an attribute is to be used repeatedly when using it against a MultiValue or a subvalue. |
| "string" | Immediate literal string. |
| cn | Numeric constant n. |
| d | System date in internal format. |
| lpv | Last processing code value (result of the previous processing code). |
| nb | Break level number. The break level number has a value of 255 on the grand-total line and a value of 0 on detail lines. The lowest level control-break in the sentence has a value of 1. |
| nd | Pushes the number of detail lines since the last break-on on the stack. On a detail line, nd has a value of 1. On a grand-total line, nd equals the item counter (nd can be used to generate averages in conjunction with control-breaks). |
| ni | Pushes the current item counter (number of items listed or selected) on the stack. |
| ns | Pushes the current subMultiValue counter on the stack (for columnar listing only). |
| nv | Pushes the current MultiValue counter on the stack (for columnar listing only). |
| t | Pushes the current time (in 00:00:00 format) on the stack. |
Operators
The stack number is used in the descriptions below to indicate the stack level where the data resides (level 1 being the top, 2 being the next level, and so on).
| *{n} | Multiplies stack 1 by stack 2. If the optional n is used, the result is divided by 10 to the power of (n-1). (This is not available as an a-correlative operator. Use the division operator with the appropriate literal value, that is /"100".) |
| / | Divides stack 2 by stack 1, and returns quotient to stack 1. Results of division operations are rounded down. |
| r | This is the same as /, except the remainder of the division is returned to stack 1. |
| + | Adds the top two entries in the stack and returns the sum to stack 1. |
| - | Subtracts stack 1 from stack 2 and returns the result to stack 1. |
| : | Concatenates the string value in stack 1 to the end of the string value in stack 2 and returns the result to stack 1. |
| [] | Extracts a substring from string value in stack 3, using stack 2 as the starting character position, and stack 1 as the number of characters to extract. The result is placed in stack 1. |
| s | Adds MultiValues in stack 1 (if any) and returns the sum to stack 1. |
| _ | Exchanges the top two positions in stack. |
| p | Pushes the top stack value back on the stack, resulting in the same value in stack 1 and stack 2. |
| (processing.code) | Operates on the top stack value and the result replaces the original top stack value. A standard processing code such as d (date), g (group), and so on, may be specified. |
Relational Operators
Relational operators compare stack 1 to stack 2 entries. A 1 is returned to stack 1 if the condition evaluates to true. A 0 is returned to stack 1 if the condition is false.
| = | True, if stack 1 equals stack 2. |
| < | True, if stack 1 is less than stack 2. |
| > | True, if stack 1 is greater than stack 2. |
| # | True, if stack 1 does not equal stack 2. |
| [ | True, if stack 1 is equal to or greater than stack 2. |
| ] | True, if stack 1 is equal to or less than stack 2. |
Branching
It is possible to label stack entries and then use the branch option to access a particular stack entry.
| j label | Branches to the label. |
| jf label | Branches to the specified label if the top stack entry is 0. |
| jt label | Branches to the specified label if the top stack entry is nonzero. |
| ~label | A tilde followed by any ASCII character other than a semicolon, space, attribute mark, or value mark, which ends the label. |
Conditionals
Conditionals are constructed using a syntax very similar to the FlashBASIC if...then...else construct and have the general form:
if condition then f.code{else f.code}{end} if condition else f.code{end} if condition then f.code{end}
If the condition evaluates to 0, it is considered false, and the else clause is taken (if present). If the evaluation is false, and the else clause is missing, a null is returned.
If the condition evaluates to nonzero, it is considered true, and the then clause is taken (if present). If the evaluation is true, and there is no then clause, a null is returned.
If end is not specified, the else is paired with the previous if. The end is used to close off the current if and associates the else with the previous if.
Example(s)
Example 1
Outputs a literal “Hello”:
f;"Hello"
Example 2
Outputs the value of attribute 9 subtracted from attribute 18:
f;18;9;-
Example 3
Sums the products of attribute 26 times attribute 30 and attribute 26 times attribute 29, then subtracts that from the product of attribute 26 times attribute 27:
f;26;27;*;26;30;*;26;29;*;+;-
Example 4
Creates a 6-digit year-month period by doing a DY output conversion on attribute 9 and concatenating a DM output conversion on attribute 9, the month portion being right justified into a 2-byte zero-filled field before the concatenation:
f;9;(dy);9;(dm);(mr%2);:
Example 5
Uses attribute 8 as an item ID to read attribute 2 of a file, then uses the result as an item ID to read attribute 1 of another file:
f;8(tterritories;x;;2);(tsalesreps;x;;1)