Part 4 of 10 of the COMTRAN Language Definition.
4. Arithmetic and data-manipulation statements
COMTRAN's data-manipulation vocabulary is deliberately small. Two verbs (SET and ADD) "are used for arithmetic" and "form the basis for the three types of arithmetic commands" (SET, ADD, ADD CORRESPONDING) (F p. 44). One verb (MOVE, with its alternate form MOVE CORRESPONDING) "has as its primary function the transmission, or movement, of data from one area of storage to one or more other areas"; data transmission is also implicit in other verbs, e.g. "the SET verb requires the transmission of result data after the computation has been performed" (F p. 41). All other arithmetic (subtraction, multiplication, division, exponentiation) is expressed through the arithmetic expression on the right side of a SET; the SET command "can be used for all arithmetic" (F p. 44).
Statement-level syntax (imperative clauses, sentences, period-blank termination, the Col. 13–72 text area) is covered in the sections on language structure and procedure format; data-description matters (pictorials, modes, levels) in §3 (Data description and storage model). This section covers the arithmetic/transmission verbs themselves, the expression language they share, the mixed-mode conversion rules, and the editing feature.
4.1 Arithmetic expressions
"An arithmetic expression is a combination of data-names, conditional expressions, and/or literals, joined together by one or more arithmetic operators in such a way that the entire expression can be reduced to a single numeric value" (F p. 20). Both simple and compound names may be used in an arithmetic expression (F p. 20). Per the formal rules: "Arithmetic expressions may contain the names of variables, constants and functions, also literals and conditional expressions, joined by arithmetic operators. Subexpressions may be contained in parentheses as required" (F p. 105–106).
4.1.1 Operator inventory
Binary operators (each "relates two quantities", F p. 45):
| Operator | Written as | Citation |
|---|---|---|
| Addition | + |
(F p. 21, p. 45, p. 106) |
| Subtraction | − |
(F p. 21, p. 45, p. 106) |
| Multiplication | * |
(F p. 21, p. 45, p. 106) |
| Division | / |
(F p. 21, p. 45, p. 106) |
| Exponentiation | ** |
(F p. 21, p. 45, p. 106) |
Unary operators ("affect only the quantity or expression which follows", F p. 45):
| Operator | Written as | Citation |
|---|---|---|
| Negation | − |
(F p. 21, p. 45, p. 106) |
| Absolute value | ABS |
(F p. 21, p. 45, p. 106) |
| Truth value | TR |
(F p. 21, p. 45, p. 106) |
ABS yields "the value of a number treated as if the sign were positive" (F p. 21). TR is described in §4.1.4 below. All operator words (TR, ABS) and the option words TRUNCATED and OVERFLOW are reserved and may not be used as Data or Procedure names in the 7090 system (J 02.03.02; see the reserved-words section).
"If the operand of a unary operator is an expression it must be enclosed in parentheses" (F p. 45), as in:
... + ABS (A + B)
... * (−(ON.HAND + ON.ORDER))
... TR (A IS LESS THAN B)
(F p. 45)
4.1.2 Precedence, associativity, parenthesization
The implemented (J) rule, quoted in full:
TR or ABS or - (Negation)
**
* or /
+ or -
"When the hierarchy of arithmetic operations in an expression is not explicitly specified by the use of parentheses, operators are honored in the following order [above] ... When there are two operators of the same hierarchy, ordering proceeds from left to right" (J 02.04.05.01). Worked examples from the same page:
A+B/C+D**E*Fis taken to mean(A+(B/C)) + ((D**E)*F)(J 02.04.05.01)A*B*Cis taken to mean(A*B)*C;A*(B*C)is taken to mean(A*(B*C))(J 02.04.05.01)
The F statement agrees for the binary operators: "the order of operations (working from inside to outside) is assumed to be exponentiation, then multiplication and division, and finally addition and subtraction" (F p. 107), with left-to-right grouping for equal levels, so that "expressions ordinarily considered ambiguous, e.g., A/B · C and A/B/C, are permitted"; A*B/C*D is taken to mean ((A*B)/C)*D (F p. 107).
Additional rules a compiler writer must observe:
- Repeated exponentiation must be parenthesized. "The expression Aᴮᶜ, which is sometimes considered meaningful, cannot be written as ABC; it should be written as (AB)C or A(BC), whichever is intended" (F p. 107). J does not restate this rule; the J left-to-right rule for equal hierarchy would read
A**B**Cas(A**B)**C, but F flatly forbids the form. Treat it as illegal (see the §8.5 catalog). - No two successive binary operators. "The programmer must not write two successive arithmetic operators unless the second of them is either the operator TR or the operator ABS. Where the effect of two successive operators is required, one term may be enclosed in parentheses; thus, while the expression A * -B is illegal, the same value may be written A * (-B)" (F p. 27, rule 6).
- Operators bind to the next item. "All operators act on the next named item, or the next parenthetical expression, following the operator" (F p. 28, rule 9). Parentheses "may be used wherever needed ... for the sake of clarity; where ambiguity would result from their omission, they must be used" (F p. 28, rule 11).
- Blanks around operators are optional and ignored:
A + B * Cmay be writtenA+B*C(F p. 27, rule 6).
The legal symbol-pair table from F Appendix 2 ("1" = permissible pair, "0" = not permissible); note that it admits a leading unary minus only after (, and ABS/TR after a binary operator or ( (F p. 106):
| First Symbol ↓ / Second Symbol → | Variable | + − * / ** | ABS, TR | Negation − | ( | ) |
|---|---|---|---|---|---|---|
| Variable | 0 | 1 | 0 | 0 | 0 | 1 |
| + − * / ** | 1 | 0 | 1 | 0 | 1 | 0 |
| ABS, TR | 1 | 0 | 0 | 0 | 1 | 0 |
| Negation − | 1 | 0 | 0 | 0 | 1 | 0 |
| ( | 1 | 0 | 1 | 1 | 1 | 0 |
| ) | 0 | 1 | 0 | 0 | 0 | 1 |
(F p. 106. Note the table permits "Negation − Variable" and "Negation − (" but no operator directly after negation, and forbids "ABS ABS", "TR TR", "ABS TR" chains.)
F/J divergence (negation precedence): J places unary negation in the highest group ("TR or ABS or - (Negation)" honored before **), so under a literal reading -A**2 would mean (-A)**2, not -(A**2) (J 02.04.05.01). F is compatible: the "next named item" rule (F p. 28, rule 9) has negation act on the immediately following item only. This differs from later-language conventions; see the §8.5 catalog.
4.1.3 Operands: variables, constants, literals
- "Data-names which represent numeric variables or constants may appear anywhere in arithmetic expressions. Those which represent alphameric variables and constants, however, may appear only within truth functions" (F p. 45).
- J restates and sharpens this for SET: "The operands of a SET instruction which are used in an arithmetic expression may be fields of any format except alphameric" (J 02.04.05); any of the field formats of §3 (external decimal, internal decimal, edited, floating point, scientific decimal) is acceptable, with automatic conversion (see §4.2).
- Literals may be used as needed in arithmetic expressions (F p. 45). Numeric-literal rules (see also the constants/literals section): maximum 50 characters, no continuation across lines; only numerals, at most one decimal point, and a sign; the decimal point "is required except where it would be the last character of the literal; in that case it must not be used"; numeric literals must not be enclosed in quotation marks (F p. 18). "If the literal is to be operated on arithmetically, it must contain not more than 20 digits" (F p. 18).
- Floating point literals take "the standard scientific decimal form"
fraction F±exponent(J 02.04.02): fraction and exponent may each be signed or unsigned (positive assumed); a decimal point must be present in the fraction ("20.F+01 is interpreted as a floating point literal, but 20F+01 is interpreted as an arithmetic expression"); the F must be followed by at least one digit, which may be signed (20.F0);Fyields a single precision floating point number,FFdouble precision (J 02.04.02). F's earlier statement of the same form: the fraction, the symbol F, then the exponent, base 10 only, e.g.1.5F3,15F2,.15F4,2F-3; F and the decimal point occupy no storage and are not counted in the literal's length (F p. 18). F/J divergence: F's examples include point-less fractions (15F2,2F-3); J requires the decimal point in the fraction and reads the point-less form as an arithmetic expression. J governs. - Figurative constants (ZERO/ZEROS, BLANK/BLANKS, HIGH.VALUE(S), LOW.VALUE(S)) may be used as source fields by SET as well as MOVE; see the chart in §4.7.4 (J 02.04.01–02).
- Subscripted operands are permitted; a subscript is a name, a literal, or an expression of the form
a * VARIABLE ± bwith a and b literals, and must represent "a positive integral value" (F p. 31). Arrays index from 1: "The initial value of an array is A(1) and not A(0)" (J 02.04.07.01). See §3 and the indexing discussion for positional-indicator behavior and limits. - Function-names may appear as operands (see §4.9).
- A compile-time diagnostic exists for a missing operand: "MISSING OPERAND ASSUMED TO BE ZERO." (J 90.04.01, message 116,00).
4.1.4 Truth functions (TR)
"A conditional expression enclosed in parentheses preceded by the truth operator TR is known as a truth function. A truth function always has one of two values, 1 or 0, depending on whether the conditional expression is true or false" (F p. 45). "Accordingly, a truth function can be manipulated arithmetically in the same manner as any other quantity" (F p. 45–46). The conditional expression is tested at object time; "It is generally used to multiply one or more terms in an arithmetic expression ... it can be used to cancel a term ... if a condition exists in which the term is not wanted" (F p. 20; mechanism restated F p. 24).
SET DISCOUNT = ORDER.AMOUNT * .05 * TR
(ORDER.AMOUNT IS GREATER THAN 1000).
(F p. 24)
SET REORDER = ORDER.AMT * TR (STOCK.LEVEL LT
ORDER.POINT).
(F p. 44; explained F p. 46: REORDER receives the order amount if stock level is below order point, otherwise zero.)
"The truth operator may be used with relational expressions, as in the example given, or with condition-names" (F p. 24). This is the sole channel by which alphameric data participates in arithmetic (F p. 45). The conditional expression inside TR is subject to the J comparison restrictions (numeric may not be compared with alphameric; unequal-length alphameric =/NOT = comparisons always compare unequal; edited fields are converted to pure numeric for comparison; variable length fields may not be compared; zero is considered unsigned); see the conditional-statements section (J 02.04.06, 02.04.07).
4.2 Modes, precision, and mixed-mode evaluation (709/7090)
4.2.1 Where arithmetic is performed
"Arithmetic operations are performed only in the internal (binary) mode. For this reason it is advantageous to have fields used in arithmetic operations in the internal mode when the programmer has a choice. If the fields are in the external mode and reoccur in different arithmetic statements, it is generally more efficient to MOVE this data to an area which has been defined with the mode as internal" (J 02.03.03). The manual's worked example (Data Description: A 999, B 99, C 99, D 999, E 99, all external; X internal right-justified IR999):
SET A = B+C
SET D = A+E
is improved (fewer conversions) by
SET X = B+C
SET D = X+E
and
SET A = B+C
SET D = B+E
by
MOVE B to X
SET A = X+C
SET D = X+E
(J 02.03.03.01). Every reference to an external-mode operand implies an unpack-and-convert at object time; every store into an external or edited target implies a convert-and-edit. "Appropriate conversion is performed in all cases although arithmetic operations are considerably less efficient when performed on fields having dissimilar formats. Generally, fields frequently referenced in arithmetic expressions should be converted to internal form right justified for most efficient operation" (J 02.04.05); "Numeric external fields to be involved in extensive computation should be converted to this internal right justified by a preliminary SET or MOVE in order to prevent repetitive unpacking and converting" (J 02.05.04).
4.2.2 Arithmetic modes and precision
"The 709/7090 Commercial Translator System allows single or double precision arithmetic in either the floating or fixed point modes. Floating point arithmetic is the 709/7090 floating binary arithmetic. Fixed point arithmetic is a binary integer arithmetic with decimal scaling" (J 02.04.05).
Precision is declared through the pictorial: "Fixed point double precision numbers are denoted in the Data Description by formats representing more than 10 digits. Double precision internal floating point numbers are specified by 'FF' in the Data Description" (J 02.05.06). Correspondingly, F vs FF in a literal selects single vs double precision floating point (J 02.04.02). The maximum fractional portion of a scientific decimal field is 16 digits (J 02.05.05, note 4).
Mode-promotion (mixed-mode) rule, quoted in full: "If a floating point or double precision number is encountered in the evaluation of an arithmetic expression, all remaining operations in the expression will be performed in floating point or double precision mode, as appropriate. Once the mode of evaluation is thus changed, the appearance of a number in the other of these modes will force subsequent evaluation to be performed in double precision-floating point mode" (J 02.04.05.01). I.e. evaluation starts in single-precision fixed point; encountering a floating point operand promotes the remainder of the evaluation to floating; encountering a double precision operand promotes to double precision; encountering both promotes to double-precision floating point. Promotion is one-way and applies to "all remaining operations", not retroactively.
Observed processor semantics consistent with this (phrased from the generated-code appendix, not as guidance): fixed-point evaluation uses double-precision binary integer work registers with explicit decimal upscale/downscale steps by constants and by 10**10 (J 90.02.12, 90.02.13); exponentiation is performed by floating point exponential routines in all four single/double combinations of base and power (J 90.02.11, 90.02.13); a dedicated sign-adjustment subroutine exists for double precision fixed point numbers (J 90.02.11.01).
Compile-time scale diagnostics: "DOWNSCALE GENERATED WHICH LOSES ALL SIGNIFICANT FIGURES." (27,00), "ATTEMPTED DIVISION BY ZERO BYPASSED. RESULT TAKEN TO BE ZERO." (28,00), "UPSCALE MAY CAUSE HIGH ORDER TRUNCATION FOR STORE INTO 'NAME.1'" (199,00) (J 90.04.01).
4.2.3 Legal operand/target formats — summary
| Context | Rule | Citation |
|---|---|---|
| Operand of an arithmetic expression | Any field format except alphameric | (J 02.04.05) |
| Alphameric data in arithmetic | Only within a truth function | (F p. 45) |
| Result field of SET | Any format, including alphameric; SET alpha.field.1 = alpha.field.2 is allowed "since no arithmetic expression is specified" |
(J 02.04.05) |
| Comparison operands (inside TR) | Numeric may not be compared to alphameric | (J 02.04.06) |
A statement operating on a field whose format is improper draws "OPERATION IGNORED BECAUSE 'NAME.1' HAS IMPROPER DATA FORMAT ( E A(2) ) FOR THIS USE." (J 90.04.01, message 25,00).
4.3 The SET command — arithmetic assignment
General form:
SET variable.1, variable.2, ... variable.n = arithmetic expression
(F p. 44). The concise Appendix-2 form shows the two optional phrases (brackets = optional):
SET variable.1, variable.2, ... variable.n = arithmetic expression
[TRUNCATED][, ON OVERFLOW any imperative clause]
(F p. 109)
"The equal sign in the SET command is used in the sense of replacement. It means, 'replace the value of the variable(s) on the left side of the equal sign with the value of the expression on the right'" (F p. 44).
Examples from the manual (F p. 44):
SET GROSS.PAY = BASE.RATE * 40.
SET NET.PAY = GROSS.PAY − (FICA + STATE.TAX +
DEDUCTIONS).
SET A= B * (C + D), ON OVERFLOW GO TO ERROR.
SET REORDER = ORDER.AMT * TR (STOCK.LEVEL LT
ORDER.POINT).
SET APPROX = 2 * SQUARE.ROOT ((X)) TRUNCATED.
SET A, B, C =D.
These examples collectively use every element that may appear in an arithmetic expression: "arithmetic operators, names of variables and constants, literals, truth functions, and function-names" (F p. 45).
4.3.1 Result editing and multiple results
- "If required, the result of a computation will be edited automatically according to the format of a receiving field as specified in the data description. For example, if a result represents an amount of money, editing appropriate to the defined format of the money field will be performed" (F p. 44).
- Multiple result fields are permitted (
SET A, B, C = D.); the expression is written once and each named variable is replaced by its value (F p. 44). The manuals do not state the order of the stores nor whether each store draws on the full-precision intermediate (see the §8.5 catalog; the natural reading of "replace the value of the variable(s) ... with the value of the expression" is that each target independently receives the expression value, edited/aligned to its own format).
4.3.2 Rounding and TRUNCATED
"Ordinarily the result of the SET operation will be rounded to the number of places indicated by the format description of the result field or fields. If the dropping of digits (instead of rounding) is desired, the arithmetic expression is followed by
... TRUNCATED
" (F p. 44). So rounding-on-store is the default; TRUNCATED suppresses it. TRUNCATED is a reserved word in J (J 02.03.02). The rounding rule is stated in F's glossary (ROUND): the least significant remaining digit "is increased by 1 when the part removed is greater than or equal to one-half", with worked examples rounding 126.5027 to 127, to 126.503 (six positions), and to 13 "understood to be 130" (two positions) (F p. 115); the companion TRUNCATED entry contrasts 2063.78 → 2063.7 truncated vs 2063.8 rounded (F p. 116). Negative-value handling and rounding-induced overflow remain unstated (see §8.5). The generated-code appendix shows explicit "Round current character" subroutine steps (SYS)219–222) inside the numeric move/convert packages (J 90.02.16, 90.02.17), confirming rounding is applied character-wise at store/convert time.
4.3.3 Overflow and ON OVERFLOW
"In the process of storing the final result of a SET command it is possible for a loss of significant high-order digits to occur. For example, if a result field has been defined as having three places to the left of the decimal point and a result such as 1001 is developed, the high-order '1' will be lost. This situation is known as 'overflow.' If the SET command specifies just one result field (i.e., if it has only one variable-name to the left of the equal sign), the programmer may anticipate and provide for an overflow by appending
..., ON OVERFLOW any imperative clause
at the end of the SET command. In the event of an overflow, the object program will execute the command thus specified instead of storing the erroneous result" (F p. 44). Key points:
- ON OVERFLOW is legal only when there is a single result field (F p. 44; same restriction for ADD, F p. 47).
- With ON OVERFLOW present, the erroneous result is not stored; the imperative clause executes instead (F p. 44).
- Behavior when overflow occurs and no ON OVERFLOW clause was written is not stated in either manual. Observed processor mechanism: communication cell SYS)130 "is set non-zero whenever any one of the numeric move or convert subroutines of MOVPAK detects the truncation of significant high order values (i.e. overflow)" (J 90.02.10); there is also SYS)131 for "an improper data condition" and SYS)134 for floating point underflow resulting from a Move (J 90.02.10, 90.02.11). See the §8.5 catalog.
- OVERFLOW is a reserved word in J (J 02.03.02).
4.3.4 SET side effects on subscripting
Executing a SET that changes a subscript variable updates the positional indicators of subscripted names using that variable: "In general, positional indicators are evaluated when their subscripts change value. Execution of the code generated for SET K=K+2 would cause the positional indicators for 3 of the subscripted names shown above to be updated: A(J, K), A(2, K), and A(J, K+1)" (J 02.04.07.01). Two consequences for correctness (from the deferred-features appendix):
- "The dimensions of an array must be set before calculation of subscript values associated with the array is performed. Presently, failure to observe this restriction causes invalid object code." The erroneous ordering example given is
SET I = 3, SET J = 5./SET Q = 10.(where Q is the QUANTITY IN variable) /MOVE A (I,J) TO R.: the positional indicator for A(I,J) is computed when I and J are set and is not updated when Q is set (J 90.01.02). - Reuse of one subscript name for many purposes causes unnecessary re-evaluation of all positional indicators containing it (correct, but wasteful); "No object time check is made to insure that subscript references conform to the limits specified by the array dimensions" (J 90.01.02).
4.4 SET used with condition-names
"The SET command has a second function that is not strictly arithmetic. It provides a convenient way of changing the status of a conditional variable, i.e., a variable which has one or more conditions associated with it. When SET is used for this purpose it takes the general form:
SET condition.name
As a result of this command, the variable with which 'condition.name' is associated (in the data description) is assigned the status, or value, of the specified condition" (F p. 46). Example: if MARITAL.STATUS is currently SINGLE, SET MARRIED. "is the equivalent of writing: SET MARITAL.STATUS = 'M'." (F p. 46).
"It is important to recognize the distinction between testing and setting the value of a conditional variable. Testing the value provides a basis for a decision but does not change the value; the testing is accomplished by using a conditional clause, IF . . . THEN. Setting a value ... causes the current value to be replaced by another of the possible values and is effected by means of the SET command" (F p. 46).
Condition-names and their values are declared with the COND type code in the data description (see §3; J 02.05.02). J restriction: "Neither a data item (literal) nor a condition.name may be subscripted. However, a conditional variable may be subscripted" (J 90.01.03); so SET condition.name cannot designate one element of a subscripted conditional variable (open question below). The compiler has a generic diagnostic "INCORRECT USAGE OF FIGURATIVE CONSTANT." (J 90.04.01, message 82,00), whose triggering contexts are not documented; a badly formatted conditional variable draws "FORMAT ERROR FOR CONDITIONAL VARIABLE. 'NAME.1' FORMAT USED." (J 90.04.01, message 37,00).
4.5 The ADD command
General form:
ADD data.name TO variable.1, variable.2, ... variable.n
(F p. 47). "The effect of the ADD command is to increment the one or more named variables by the quantity represented by 'data.name.' In this context, 'data.name' may be a literal or the name of a variable, constant or function" (F p. 47).
"The optional phrases TRUNCATED and ON OVERFLOW described above in conjunction with the SET command are equally applicable to the ADD command. As in the case of SET, the ON OVERFLOW option is permitted only if the command specifies a single result field" (F p. 47).
Examples (F p. 47):
ADD GROSS.PAY TO YR.TO.DATE.GROSS.
ADD 1 TO COUNTER, ON OVERFLOW GO TO BEGIN.
ADD ADJUST.FACTOR TO RATE TRUNCATED.
The Appendix-2 concise form folds ADD and ADD CORRESPONDING together:
ADD [CORRESPONDING] data.name.1 TO data.name.2, data.name.3,
... data.name.n
(F p. 108). Note the Appendix-2 form does not repeat the TRUNCATED/ON OVERFLOW phrases for ADD, but the body text grants them explicitly (F p. 47). J adds no ADD-specific amplification; the mixed-mode conversion rules of §4.2 and the operand-format rules of §4.2.3 apply to each addition.
4.6 The ADD CORRESPONDING command
General form:
ADD CORRESPONDING data.name.1 TO data.name.2, data.name.3,
... data.name.n
(F p. 47). "Each 'data.name' in an ADD CORRESPONDING command must represent an area of storage which is composed of smaller units or fields. The effect of the command is to cause each field in 'data.name.1' to be added to its corresponding field (i.e., a field with the same name) in the 'to' area(s). Non-corresponding fields in 'data.name.1' and in the 'to' areas are not affected by the command" (F p. 47).
The manual's totals-accumulation example: with detail-record fields GROSS.PAY, FICA, FED.TAX, STATE.TAX, DEDUCTIONS and records DEPT.TOTALS and GRAND.TOTALS containing corresponding fields,
ADD CORRESPONDING DETAIL.RECORD TO DEPT.TOTALS,
GRAND.TOTALS.
has the same effect as five explicit ADDs of qualified names (ADD DETAIL.RECORD GROSS.PAY TO DEPT.TOTALS GROSS.PAY, GRAND.TOTALS GROSS.PAY. etc.) (F p. 47).
Matching rules are those of §4.8 (shared by MOVE and ADD; J 02.04.04). Diagnostics: "NEITHER -ADD- NOR -MOVE- PRECEDES -CORRESPONDING-" (63,00); "INVALID -CORRESPONDING- STATEMENT." (97,00) (J 90.04.01).
4.7 The MOVE command
General form:
MOVE data.name.1 TO data.name.2, data.name.3, ... data.name.n
(F p. 42). "The data specified by 'data.name.1' is moved to the area of storage designated by 'data.name.2' and to any other area(s) mentioned in the command ... As used in this command 'data.name' may represent data at any level defined in the data description" (F p. 42). "Note that in each case the data in the sending area remains unaltered after the MOVE has been executed" (F p. 43).
4.7.1 Legality: what may move to what
F's 1960 statement:
- "Information from numeric fields may be moved to other numeric fields, to alphameric fields, and to report fields."
- "Information from alphabetic or alphameric fields may be moved only to other alphabetic or alphameric fields." (F p. 42)
("Report fields" is F's term for fields carrying editing symbols; J's term is "edited field"; see the §8.5 catalog.)
J's 1962 statement, in terms of the six 7090 field types (alphameric, external decimal, internal decimal, edited, floating point, scientific decimal; see §3 and J 02.05.05): "all types of data may be moved into an alphameric field but the contents of an alphameric field may only be moved to another alphameric field" (J 02.04.03). Combined with the F rules, every numeric-to-numeric combination is legal, with automatic conversion; alphameric is a universal sink and an alphameric-only source.
Group items behave as alphameric: "A field for which no pictorial is given is treated as alphameric with length equal to the length of its subfields" (J 02.05.06); this drives the CORRESPONDING error case in §4.8. An illegal move is diagnosed at compile time: "ILLEGAL MOVE - FROM 'NAME.1' ( E A(2) ) TO 'NAME.2' ( IR 999 ). NOTHING DONE ." (J 90.04.01, message 84,00 — i.e. alphameric to internal-decimal is rejected). Also "INCOMPLETE -MOVE- EXPRESSION." (119,00) (J 90.04.01).
4.7.2 Conversion routing between field types (J)
The J chart (a boxes-and-arrows schematic, J 02.04.03; page image J28-6169/images/page-020.png is ground truth) shows internal decimal (right justified) as the hub, with a two-way arrow to internal decimal (not right justified) and two-way spokes to edited field, external decimal, scientific decimal, and floating point; there are also direct two-way arrows edited field ↔ external decimal and scientific decimal ↔ floating point; alphameric field is reached by three arrows: from edited field, external decimal, and scientific decimal. Every box except internal decimal (not right justified) has a self-directed arrow (an IDnj→IDnj move goes via internal decimal right justified, matching prose exception a below). The governing prose:
- a) "When source and target fields have the same format no intermediate form is necessary (except for edited fields and internal decimal fields not right justified) and transmission is direct as indicated by the self-directed arrows" (J 02.04.03).
- b) "When source and target fields of unlike format are involved the conversion steps are defined by the diagram arrows where the route requiring least intermediate steps is used", e.g.: floating point → external decimal requires an intermediate conversion to internal decimal; floating point → alphameric requires conversion to scientific decimal form first; internal decimal → alphameric requires a conversion to external decimal form (J 02.04.03).
- c) The alphameric sink/source rule quoted in §4.7.1 (J 02.04.03).
- d) "Subroutines are normally used to perform the requisite conversion and transmission except where arrows have associated an *. These moves are normally performed by in-line instructions" (J 02.04.04). (Starred in the chart: the internal-decimal (rt. justified) self-move, the floating-point self-move, the alphameric self-move, and the three arrows into alphameric (edited-field→alphameric, external-decimal→alphameric, scientific-decimal→alphameric). The external-decimal, edited-field, and scientific-decimal self-loops are unstarred, i.e. subroutine moves, consistent with MOVPAK's XD→XD subroutine SYS)183, J 90.02.15.)
- e) Scientific decimal sources are free-form: "For the source fields of the scientific decimal type, a free form of data is allowed within the limits of the field. For example, a field with the pictorial -99V-99 may contain the value 1 in any of the following ways, (b represents a space):
b.01b2b (i.e. 01 x 10^2)
1bb+01b (note above scale applies when no point)
.001bb3
b1bbbbb (note above scale applies when no point)
1000.-3
etc.
" (J 02.04.04).
The runtime move/convert machinery is a packaged subroutine set, MOVPAK, whose entries cover XD→XD, XD→ID, ID→XD (unsigned, overpunch-minus, overpunch-plus variants), XD→EF, EF→XD, and EF→EF moves, with per-call instruction words for characters-to-move, characters-to-test-for-overflow, characters-to-bypass, leading/trailing zeros to insert, "Round current character", and target numeric length (J 90.02.10, 90.02.15–90.02.19); observed semantics: numeric moves are character-serial with in-flight rounding, overflow testing, and zero insertion.
4.7.3 The editing feature
"Editing of the data in the sending area to conform to the format of the receiving area is a feature of the MOVE command. Such editing occurs automatically if an explicit format definition, i.e., a field pictorial, is given in the data description for both the 'from' and the 'to' areas" (F p. 42). The conventions, quoted in full (F p. 42):
Numeric information: "The data from the sending area is aligned with respect to the decimal point (assumed or actual) in the receiving area. Such alignment may involve the dropping of leading digits or low-order digits (or both if the sending field is larger than the receiving one). If the 'from' area is smaller than the 'to' area, the excess positions of the receiving area will be replaced by zeros."
Alphameric information: "If the sending area is larger than the receiving area, the data being moved will be left-justified and truncated; i.e., low-order characters will be dropped as may be necessary to make the data fit into the receiving area. If the sending area is the smaller, the data will be left-justified in its new location. The low-order positions of the receiving area, i.e., the excess positions, will be filled with blanks."
The manual's worked examples (F p. 43; verified against the page scan). In the pictorials, 9 = any digit, A = any non-numeric character, X = any character, V = assumed decimal point:
| Sending Pictorial | Sending data before/after MOVE | Receiving Pictorial | Receiving before | Receiving after |
|---|---|---|---|---|
| 99V99 | 1234 | 99V99 | 8765 | 1234 |
| 99V99 | 1234 | 99V9 | 876 | 123 |
| 9V9 | 12 | 99V99 | 8765 | 0120 |
| AAAAA | JONES | AAAAA | VWXYZ | JONES |
| 99999 | 01234 | 999V9 | 7777 | 2340 |
| AAA | RUN | AAAXX | JOB #2 | RUN␢␢ |
| AAAAA | BLACK | AAA | RED | BLA |
(Sixth example: "the information in the two excess positions of the receiving area is replaced by blanks", F p. 43. In the fifth, integer 01234 aligned into 999V9 keeps digits 234 and zero-fills the fraction place; in the third, 1.2 into 99V99 gives 01.20.)
Editing/format characters. Editing behavior on output is entirely driven by the receiving field's pictorial, declared in the data description (declaration side: §3). The complete F table of format characters (F p. 80):
| Format Character | Meaning and use |
|---|---|
A |
Any non-numeric character, including the blank. |
X |
Alphameric character (any character in the machine's character set). |
9 |
Any numeric character. |
8 |
Numeric character, "to be replaced automatically by a blank whenever it is a non-significant zero" (zero suppression). |
* |
Numeric character, "to be replaced automatically by an asterisk whenever it is a non-significant zero" (check protection). |
V |
Assumed decimal point; used for calculation/alignment; reserves no storage space; not required for integers. |
. |
True decimal point; reserves an actual space in storage. |
S |
Scale factor: a "filler"/"spacer" when input data does not show the decimal position. VS9 makes values 1–9 read as .01–.09; 999SSS provides for 000,000–999,000 with the three low-order zeros absent from input. |
$ |
Dollar sign, placed in the indicated position, "provided it is not followed by the symbol 8. In the latter case, the dollar sign will 'float'—i.e., it will be placed immediately to the left of the first significant digit remaining." |
, |
True comma; reserves a space; "may be replaced by a blank, asterisk, or dollar sign, if the operation of a preceding 8 or * has resulted in the elimination of non-significant zeros to the left." |
+ |
Plus or minus sign, one of which is always placed in the reserved space according to the value's sign. May occupy a column by itself (reserving a space), or be an "overpunch" with a format character 8 or 9 "in either the units or high-order position of a field", in which case no space is reserved. |
- |
Minus sign, placed when the value is negative; blank when positive. Same by-itself/overpunch placement rules as +. |
F |
Floating point indicator; reserves no space; placed between the fraction's and the exponent's format characters, e.g. +99V9F+99. |
(n) |
Repetition: a parenthesized number after a format character multiplies it; 9(4)A(12) ≡ 9999AAAAAAAAAAAA. |
Range examples (F p. 81): AAA (all non-numeric); 88999 (000 to 99999); ****.99 (****.00 to 9999.99); $888,888.99 ($.00 to $999,999.99).
The J field-type chart classifies a field as an Edited Field when its pictorial contains any of 8 * . , $ + - or when the BLANK WHEN ZERO clause is used; legitimate format characters for an edited field are 9 8 * . , $ + - S V (n), with 8̅ or 9̅ or 8⁺ or 9⁺ in rightmost character (overpunched sign; all four glyphs marked in the scan; see §8.5.8); the field content is "digits and leading blanks; an overpunch with the rightmost digit" (J 02.05.05). "An edited field may have a character position reserved for the sign or may have the sign over the rightmost digit" (J 02.05.05, note 2). "Numeric external fields may contain leading blanks which are treated as leading zeros" (J 02.05.05, note 3).
BLANK WHEN ZERO: "When associated with an output field this clause indicates that the field is to be replaced with blanks when it becomes zero. Since leading blanks in numeric input fields are automatically treated as zeros, the use of this clause is redundant [for input]. In some cases it may even result in decreased efficiency in the object program as these fields are treated as edited types" (J 02.05.07).
J restrictions touching edited fields and pictorials:
- Constants cannot be defined "in a field whose pictorial characterizes it as an edited field" (J 02.05.06; "CONSTANT CANNOT BE GIVEN FOR EDITED TYPE FIELD.", J 90.04.01 message 57,00).
- "A field may not be described as a mixed numeric and alphameric field, i.e., both A's and 9's in a pictorial. If this specification is made the field is treated as alphameric" (J 90.01.03).
- Pictorial characters A and X are synonymous in the 7090 compiler (J 02.05.04).
- Any non-format character in a pictorial causes it to be interpreted as a name (J 02.05.06).
- Internal-table limit: at most approximately 35 "different edited field formats" per program (J 90.01.05; overrun draws "NUMBER OF DIFFERENT EDIT FIELDS EXCEEDS INTERNAL TABLE CAPACITY.", J 90.04.01 message 204,00).
- For comparisons, "edited fields ... are converted to pure numeric fields. They may not be compared to alphameric fields" (J 02.04.07).
Observed processor semantics for edited targets (J 90.02.17): each edited-target move is parameterized by which editing characters the pictorial contains (asterisks, commas, decimal point, dollar sign, Blank When Zero), by the counts of leading */8 positions and of positions left of the real or implied decimal point, and by a target sign convention distinguishing no sign, overpunch minus/plus, right minus/plus, and left minus/plus, confirming the full sign-placement matrix implied by the F +/- format-character rules (sign by itself at either end, or overpunched).
4.7.4 Figurative constants as MOVE/SET sources
"Figurative constants may be used as source fields by both MOVE and SET" (J 02.04.01). E.g. MOVE ZEROS TO COUNTER, MOVE BLANKS TO AMOUNT: "the specified area will be completely filled with characters of the value named" (F p. 20); MOVE ZEROS TO MONTH.TOTAL, YEAR.TOTAL, CUMUL.TOTAL. (F p. 42).
Values on the 7090: "HIGH.VALUE will be considered to be the left parenthesis, (, and LOW.VALUE the zero, 0, unless the Commercial collating sequence (COM) is specified in the Environment Description. The Commercial HIGH.VALUE is 9 and the LOW.VALUE is blank" (J 02.04.01).
Result of MOVEing/SETting figurative constants into each target type (J 02.04.02; * = "An error message is given for each doubtful or illegal usage", # = "Value dependent upon collating sequence order specified (Commercial or 709)"):
| Figurative Constant | Alphameric | External Decimal | Internal Decimal | Edited Field | Floating Point | Scientific Decimal |
|---|---|---|---|---|---|---|
| BLANK or BLANKS | blanks | blanks* | 0's* | blanks* | 0's* | blanks* |
| ZERO or ZEROS | 0's | 0's | 0's | 0's Edited | 0's | 0's Edited |
| LOW.VALUE or LOW.VALUES | 0's# or blanks | 0's #* or blanks | Illegal* | 0's #* or blanks | Illegal* | 0's #* or blanks |
| HIGH.VALUE or HIGH.VALUES | ('s# or 9's | ('s #* or 9's | Illegal* | ('s #* or 9's | Illegal* | ('s #* or 9's |
Restrictions:
- "Figurative constants may not be moved to variable length arrays, i.e., to fields with which QUANTITY IN is associated ... However, figurative constants may be moved to a particular element of a variable length array" (J 02.04.01); with the illustrated data description, "the sentence MOVE BLANKS TO ARRAY is illegal, whereas MOVE BLANKS TO FIELD(3) is proper" (J 02.04.01). Restated in the deferred-features appendix: "Figurative constants may not be moved to variable length arrays; they may, however, be moved to fixed length arrays or to array elements" (J 90.01.02). Diagnostic: "MOVE OF FIGURATIVE CONSTANT TO VARIABLE LENGTH FIELD NOT YET HANDLED BY SYSTEM." (J 90.04.01, message 180,00).
- "Figurative constants may not be moved to fields which are longer than 2^15 - 1 characters" (J 02.04.01). The corresponding diagnostic reads "MOVE OF FIGURATIVE CONSTANT TO FIELD LONGER THAN 32766 CHARACTERS NOT YET HANDLED BY SYSTEM." (J 90.04.01, message 181,00): an off-by-one against 2^15−1 = 32767; see the §8.5 catalog.
- In comparisons (relevant inside TR): "ZERO may be compared to either numeric or alphameric fields. HIGH.VALUE, LOW.VALUE and BLANK may be compared to alphameric fields only" (J 02.04.01).
4.7.5 Other MOVE facts and limits
- Multiple receiving areas are permitted; the sending area is unchanged, so a value may be distributed to several areas in one command (F p. 42–43).
- A record obtained by GET may be operated on by SET and MOVE; MOVE operations on a record are "based upon the 80 characters specified in the Data Description of the record rather than the 84 characters appearing on tape" for the card-image case discussed there (J 02.07.14; record/file interaction is covered in the input/output section).
- Records whose fields are referenced only infrequently "in arithmetic, MOVE, or indexing operations" may be processed in locate mode; "In general, a record should be transmitted if the number of words in the record is less than three times the total number of arithmetic and MOVE references to fields of the record" (J 02.07.05; see the input/output section for locate/transmit mode).
- MOVE to/from subscripted operands is legal (e.g.
MOVE RATE (DESTINATION) TO LIST.A,MOVE ONE.WAY (MIAMI) TO BILL.AMOUNT, F p. 30); subscript-order caveats of §4.3.4 apply.
4.8 The MOVE CORRESPONDING command and CORRESPONDING matching rules
General form:
MOVE CORRESPONDING data.name.1 TO data.name.2, data.name.3,
... data.name.n
(F p. 43). "This command can be thought of as a series of MOVE commands, each of which is governed by the rules for MOVE. It is assumed, however, that each 'data.name' represents an area of storage which is subdivided into smaller areas such as fields. The effect of MOVE CORRESPONDING is to move each field for which a corresponding field (i.e., a field having the same name) exists in the receiving area(s). The order of the corresponding fields need not be the same in the sending and the receiving areas" (F p. 43). "Non-corresponding fields in the sending area are not moved. Non-corresponding fields in the receiving area remain unaltered" (F p. 43).
Editing feature: "Automatic editing of data to conform to the format of the receiving areas is done in essentially the same manner as in the MOVE command. Such editing, however, operates on subdivisions, or fields, of the data specified in the command. Accordingly, in order for editing to occur, the corresponding fields or smaller units must have explicit format definitions in the data description" (F p. 43).
4.8.1 Matching rules (J, definitive)
"Correspondence is determined at the lowest possible level on the basis of name only. All qualifiers must be present and identical through the level of the name itself to meet the criteria of correspondence. Note, however, that the resultant MOVE or ADD may be affected since the rules governing these commands are the same whether or not the CORRESPONDING option is exercised" (J 02.04.04). The three worked cases, for MOVE CORRESPONDING DATA.1 to DATA.2.:
a) Absolute level numbers are irrelevant; only the name hierarchy matters:
DATA.1 01 DATA.2 04
GROUP 02 GROUP 05
ITEM 03 ITEM 06
FIELD.1 04 FIELD.1 08
FIELD.2 04 FIELD.2 08
"correspondence would be found at FIELD.1 and FIELD.2 level, and instructions would be generated to
MOVE DATA.1 GROUP ITEM FIELD.1 TO DATA.2 GROUP ITEM FIELD.1.
MOVE DATA.1 GROUP ITEM FIELD.2 TO DATA.2 GROUP ITEM FIELD.2.
" (J 02.04.04).
b) A missing intermediate qualifier defeats correspondence entirely:
DATA.1 01 DATA.2 01
GROUP 02
ITEM 03 ITEM 03
FIELD.1 04 FIELD.1 04
FIELD.2 04 FIELD.2 04
"no fields would be found to correspond due to the absence of the qualifier GROUP in DATA.2" (J 02.04.04).
c) Correspondence may be found at a group level; the group then moves as an (assumed-alphameric) unit, and the ordinary MOVE legality rules apply:
DATA.1 05 DATA.2 01
GROUP 06 GROUP 02
ITEM 07 ITEM 03
FIELD.1 08
FIELD.2 08
"correspondence would be determined at the ITEM level, and an attempt would be made to generate the instructions to MOVE DATA.1 GROUP ITEM TO DATA.2 GROUP ITEM. Since the field DATA.1 GROUP ITEM has sub-fields, it has no format characteristics of its own and is assumed to be alphameric. If DATA.2 GROUP ITEM is a field into which alphameric information may not be legally moved, an error will be noted" (J 02.04.04–02.04.05).
4.8.2 Subscripting with CORRESPONDING
"Data items referenced in a MOVE or ADD CORRESPONDING clause may be subscripted. The compiler simply appends the designated subscript to the generated instructions." For example a) above, MOVE CORRESPONDING DATA.1 TO DATA.2 (I) (with appropriate quantity values in the Data Description) generates
MOVE DATA.1 GROUP ITEM FIELD.1 TO DATA.2 GROUP ITEM FIELD.1(I)
MOVE DATA.1 GROUP ITEM FIELD.2 TO DATA.2 GROUP ITEM FIELD.2(I)
(J 02.04.05).
4.9 Functions in arithmetic and data-manipulation statements
4.9.1 The F (1960) function mechanism
"The term function is used in the Commercial Translator to mean a result obtained as a consequence of some procedure. More precisely, it means a result obtained from a procedure specified by a BEGIN SECTION command, and, in particular, it is a result named in the GIVING clause of that command" (F p. 32). The data named in the USING clause are parameters (F p. 32). Full mechanics of BEGIN SECTION USING ... GIVING and DO ... USING ... GIVING (data substitution by positional order, values moved into parameter fields before execution and out of function fields after) belong to the control-statements section (F p. 32–33, p. 52–53, p. 57–58).
On the statement side, a function-name may be written directly in a procedure statement in place of a DO: "the programmer may write the name of a function directly in a procedure statement, together with the names of the data items to be substituted for the parameters, and the system will carry out the BEGIN SECTION procedure just as if the DO command had been written. In order to achieve this result, the programmer must specify the data to be used by placing the data-names in double parentheses immediately after the function-name. These names must be separated by single commas" (F p. 34; rule restated as punctuation rule 15, F p. 28). When this form is used the result is obtainable only from the function field itself (no GIVING redirection) (F p. 34). Examples (F p. 34; the period after MARKET.PRICE in the first example is a printing inconsistency preserved from the source):
MOVE MINIMUM ((CALCULATED.PRICE, MARKET.PRICE.
HIGH.VALUES)) TO PRICE.LIST.
SET SHIPPING.COST = MINIMUM ((RAIL.EXPRESS, AIR.FREIGHT,
PARCEL.POST)) * QUANTITY.
SET RATE.FACTOR = MINIMUM ((FLAT.RATE, QUANTITY.RATE,
HIGH.VALUES)) * 1.15.
In arithmetic expressions "a function-name is treated as a quantity, as in the fifth of the preceding examples of the SET command, where the square root of X is multiplied by 2 and truncated to obtain the result ... Function-names ... imply an evaluation process at object time. The evaluation is carried out by procedural statements identified by a BEGIN SECTION command ... These procedure statements deliver a value to be used in computing the value of the arithmetic expression" (F p. 46). ADD's data.name may likewise be the name of a function (F p. 47).
There is no built-in function library. Neither manual defines any predefined function; MINIMUM and SQUARE.ROOT appear only as programmer-written examples (F p. 32–34, p. 44). The only built-in value-producing operators are ABS and TR (F p. 21, p. 45). The library mechanism that might have supplied stock routines (INCLUDE) is deferred: "Mechanization of the INCLUDE verb has been deferred, and consequently no library facilities are currently available" (J 90.01.02).
Declaration side (1960): "All function-names and all parameter-names used in the program must be written in the data description ... they must be identified by the type codes FUNCT or PARAM, as appropriate" (F p. 34; type-code definitions F p. 73; see §3).
4.9.2 F/J divergence: PARAM and FUNCT type codes withdrawn
F/J divergence: "These two type codes [PARAM and FUNCT] described in the General Information Manual are no longer in the language" (J 02.05.03). The function machinery itself nevertheless survives in the 1962 processor: the compiler's error-message file includes "FUNCTION 'NAME.1' LACKS EXPLICIT SPECIFICATION OF ALL ARGUMENTS." (30,00), "EVALUATION IGNORED FOR FUNCTION 'NAME.1'. TOO MANY ARGUMENTS SPECIFIED." (68,00), and TOO MANY/TOO FEW -USING-/-GIVING- PARAMETERS IN -DO- STATEMENT (72,00–75,00) (J 90.04.01); USING and GIVING remain reserved words (J 02.03.02). The most plausible reading is that in J, parameters and functions are declared as ordinary data description entries (no special type code), while the reference forms (function-name with double-parenthesized arguments, DO/BEGIN SECTION with USING/GIVING) are unchanged; see the §8.5 catalog. Message 30,00 additionally implies that a J function reference must specify all arguments explicitly.
4.10 Restrictions and limits affecting this section (consolidated)
| Restriction / limit | Value / rule | Citation |
|---|---|---|
| Literal length (all literals) | ≤ 50 characters, complete on one line | (F p. 18; alphameric literal limit reconfirmed for DISPLAY, J 02.04.02.01) |
| Literal operated on arithmetically | ≤ 20 digits | (F p. 18) |
| Scientific decimal fractional portion | ≤ 16 digits | (J 02.05.05, note 4) |
| Fixed point double precision threshold | pictorial representing more than 10 digits | (J 02.05.06) |
| Maximum Quantity (array repetition) | 2¹⁵ − 1; no execute-time check | (J 02.05.04) |
| Figurative constant target length | ≤ 2¹⁵ − 1 characters (diagnostic text says "longer than 32766") | (J 02.04.01; J 90.04.01 message 181,00) |
| Figurative constant → variable length array | Illegal (element reference legal) | (J 02.04.01; J 90.01.02) |
| Different edited field formats per program | approx. max 35 | (J 90.01.05) |
| Generated constants in constant pool | approx. max 500 | (J 90.01.05) |
Index expressions (a * VARIABLE ± b) |
approx. max 50 | (J 90.01.05) |
| Positional indicators (unique array+subscript combinations) | approx. max 90 | (J 90.01.05) |
| ON OVERFLOW | only with a single result field (SET and ADD) | (F p. 44, p. 47) |
| Alphameric operand in arithmetic expression | illegal (TR contexts excepted); alphameric result field legal | (J 02.04.05; F p. 45) |
| Alphameric source field | may move only to alphameric | (F p. 42; J 02.04.03) |
| Constants in edited fields | cannot be defined | (J 02.05.06) |
| Mixed A and 9 pictorial | illegal; treated as alphameric | (J 90.01.03) |
| Array dimensions | must be set before subscript values are calculated, else invalid object code | (J 90.01.02) |
| Subscript bounds | no object-time check | (J 90.01.02) |
| Condition-name | may not be subscripted (conditional variable may be) | (J 90.01.03) |
| ABC | must be parenthesized | (F p. 107) |
| Two successive operators | illegal unless second is TR or ABS | (F p. 27) |
4.11 Cross-references
- Field types, pictorials, modes (I/E), justification, COND/RECORD/REDEF/QUANTITY IN, constants: §3 (Data description and storage model) (J 02.05; F Ch. 4).
- Conditional expressions, relational operators, AND/OR/NOT, comparison-mode rules that also govern TR operands: conditional-statements section (F p. 21–24; J 02.04.06–07).
- DO ... USING ... GIVING, BEGIN SECTION, indexing loops (which interact with SET-driven subscript updates): control-statements section (F p. 49–53, p. 56–58).
- GET/FILE record availability for MOVE/SET, locate vs transmit mode: input/output section (J 02.07).
- Reserved words that block use of SET/ADD/MOVE/CORRESPONDING/TRUNCATED/OVERFLOW/TR/ABS etc. as names: reserved-words section (J 02.03.02; F p. 110).
- Generated-code and object-time subroutine details (MOVPAK, scaling, exponential routines): J Appendix 90.02 (cited above only where they settle semantics).