COMTRAN Reconstruction

The language reference is this project’s reading of the two manuals, not IBM’s text. Every claim in it cites a page, and each citation opens that page beside its scan.

Part 5 of 10 of the COMTRAN Language Definition.

5. Control-flow statements

COMTRAN control flow is built from four elements: the default sequential execution of sentences; the conditional sentence (IF ... THEN ... OTHERWISE); the three control commands GO TO, DO, and STOP (F p. 48); and the sectioning apparatus (BEGIN SECTION / END) that creates the named units to which control can be transferred (F pp. 56–57). This section covers all of these, together with the conditional expressions (relations, condition-names, AND/OR/NOT, truth functions) that drive the conditional constructs, and the J-processor's comparison semantics, restrictions, and limits.

Throughout: F = F28-8043 (June 1960 General Information Manual, the language vision); J = J28-6169-1 (Jan 1962 709/7090 Processor manual, authoritative for the implemented language).

5.1 Default sequential flow and sentence boundaries

5.2 The conditional statement (IF ... THEN ... OTHERWISE)

Neither manual gives a boxed "general form" for the conditional statement (it is not a verb command); its shape is defined by prose rules in F Chapter 2:

IF OUT.OF.ZONE THEN
IF AMOUNT GT 200 THEN
IF MARRIED AND OVER.21 THEN
IF A = B OR A = C AND A GT D THEN

(F p. 25 — examples of conditional clauses)

IF MARRIED THEN MOVE NAME TO MAILING.LIST.M,
    ADD 1 TO COUNTER.
IF GROSS.PAY LT NET.PAY THEN GO TO ERROR.ROUTINE.
IF OUT.OF.ZONE THEN DO BILLING.ROUTINE.A OTHERWISE
    DO BILLING.ROUTINE.B.

(F p. 25 — example sentences)

Consequences a compiler writer must observe:

5.3 Conditional expressions

A conditional expression "may be either true or false, depending on conditions existing when the expression is examined"; it may contain data-names, condition-names, arithmetic expressions, and relational expressions, and expressions may be joined by AND and OR into compound conditional expressions (F p. 21). The two principal types are (1) relations and (2) condition-names (F p. 21).

Conditional expressions appear in exactly these control contexts: the IF clause (F p. 25), the WHEN clauses of the conditional GO TO (F p. 48), and inside truth functions TR( ) in arithmetic expressions (F pp. 20, 24; see §5.3.5). SET's ON OVERFLOW and GET's AT END phrases are not conditional expressions but appended event clauses (F pp. 40, 44; see the SET/arithmetic and Input/Output sections).

5.3.1 Relations

"Six basic relational expressions may be used in conditional expressions, each of which may be written in a full form or in an abbreviated form" (F p. 21):

Relational expression Abbreviated form
IS GREATER THAN GT
IS NOT GREATER THAN NOT GT
IS EQUAL TO =
IS NOT EQUAL TO NOT =
IS LESS THAN LT
IS NOT LESS THAN NOT LT

(F p. 21)

5.3.2 Comparison semantics (J 02.04.C — authoritative)

J 02.04.06–02.04.07, "C. Conditional Statements", gives the implemented comparison rules:

  1. "Comparisons may not be made between numeric and alphameric fields." Given ABC alphameric (AAA) and DEF numeric (999), IF ABC = DEF THEN --- is an invalid comparison; "The implied or explicit specification of DEF as an external decimal field does not affect the validity of the comparison" (J 02.04.06).
  2. Fields of unequal length (J 02.04.07):
    • a) "Numeric fields are compared arithmetically without regard to length."
    • b) Alphameric fields of unequal length are treated on the basis of the operator:
      • i. "In tests for an = or NOT = condition the fields will always be found to be unequal." For unequal-length alphameric A and B, given IF A = B THEN GO TO C OTHERWISE GO TO D. "the only code generated will be a transfer to D"; for IF A NOT = B THEN GO TO D OTHERWISE GO TO C. likewise (J 02.04.07). I.e. the compiler folds the comparison at compile time.
      • ii. "In tests for NOT greater or less conditions the lengths are made equal by right truncation of the longer field" (J 02.04.07). (On the reading of this phrase see the ambiguities register; the plausible sense is: for the relative-magnitude operators (GT, LT, NOT GT, NOT LT) as opposed to =/NOT =.)
  3. "For purposes of comparison edited fields (see 02.05 for definition) are converted to pure numeric fields. They may not be compared to alphameric fields" (J 02.04.07).
  4. "All non-format fields (see 02.05 for definition) are compared alphamerically, subject to rules stated in 2b above" (J 02.04.07). (A field with no pictorial is treated as alphameric with length equal to its subfields, J 02.05.06; group items in a MOVE/ADD CORRESPONDING are likewise assumed alphameric, J 02.04.05.)
  5. "Variable length fields may not be compared. (A variable length field is a field which uses the QUANTITY IN option)" (J 02.04.07); enforced by "CANNOT USE VARIABLE LENGTH ITEMS FOR COMPARISON." (J 90.04.01, message 123,00).
  6. "For comparison purposes zero is considered an unsigned number, even though computational sequences generated by the compiler may produce negative or positive zeros" (J 02.04.07).
  7. Structural errors are reported as "ILLEGAL COMPARISON STRUCTURE." (J 90.04.01, message 107,00).

Figurative constants in comparisons (J 02.04.01): "ZERO may be compared to either numeric or alphameric fields. HIGH.VALUE, LOW.VALUE and BLANK may be compared to alphameric fields only."

Collating sequence. The compiler "normally generates comparison type instructions based on the 709/7090 collating sequence"; the Environment OPTION card COLLATE COM selects the Commercial (705) collating sequence instead, optionally limited to one section by IN section.name (reverting to normal at the end of that section; the modes may be altered any number of times) (J 02.06.16–02.06.17). The OPTION card general form:

Name   Type     Description

       OPTION   [COLLATE COM]                 [IN section.name]

                [, CONSERVE {SPACE}]           [IN section.name]
                            {TIME }

(J 02.06.16)

The 709/7090 sequence runs (lowest to highest) 0 through 9 = ' + A–I ⟨+0⟩ . ) − J–R ⟨−0⟩ $ * blank / S–Z ⟨rm⟩ , ( (digits lowest, ( highest) and the Commercial (705) sequence runs from Blank (lowest) through the specials and letters to 0 through 9 (highest) (J 02.06.16; scan-resolved reading — full displays and glyph legend in §1.1). Note the operational consequence: under the native 709/7090 sequence digits collate low and letters high; under COM, blank collates lowest and digits highest.

Consistently, the figurative-constant extremes depend on the sequence chosen: "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). F defines LOW.VALUE/HIGH.VALUE only abstractly as "the lowest and highest characters in the collating sequence of the system for which the program is written" (F p. 20).

Object code: alphabetic comparison of two fields is performed by generated subroutine SYS)162, using conversion table SYS)161; "OP is a CVR or NOP depending of the need to adjust the collating sequence before the comparison" (J 90.02.12 — "depending of" is the original's typo).

F/J divergence: F never restricts comparisons by type or length (F pp. 21–24 are silent); all of the above type/length/collating machinery is J's implemented tightening and must be treated as the language definition.

5.3.3 Condition-name tests

Name             Type    Description

condition.name   COND    KEYS 'nn'

(J 02.06.17)

'nn' is 12 octal digits giving "on" settings; "When the condition.name is tested in a procedure statement only the keys specified in 'nn' are tested for 'on' setting. The specified console keys must all be 'on' for the condition to be true. No 'off' or 'on' test is made for the non-specified keys" (J 02.06.17). This gives the object program an operator-controlled switch testable by IF, a facility absent from F. F/J divergence.

5.3.4 AND, OR, and NOT — combination rules and precedence

Compound conditions are formed with AND and OR, with parentheses where needed; "The negative form of a conditional expression may also be used; this is obtained by placing the word NOT before the expression" (F p. 23). The four interpretation rules (F p. 23):

  1. OR is inclusive: "either or both".
  2. AND means "both"; both conditions must be true.
  3. Each conditional expression must be completely stated (no elliptical second operand).
  4. "When a compound conditional expression contains both the word OR and the word AND, it will be interpreted as if the terms connected by AND were enclosed in parentheses. ... If a contrary sense is intended, parentheses must be used to show it."

Thus AND binds tighter than OR: "The conditional expression 'C1 OR C2 AND C3' is identical with 'C1 OR (C2 AND C3)' but is not the same as '(C1 OR C2) AND C3.' ... conditional expressions are grouped first according to AND and subsequently by OR. However, the programmer's use of parentheses will affect the order of grouping" (F p. 105, rule 3).

Truth-table statement of the operators (F p. 105, rule 1):

The Conditional Expression Is True If
C1 C1 is true
NOT C1 C1 is false
C1 AND C2 Both C1 and C2 are true
C1 OR C2 Either C1 is true, C2 is true, or both are true
NOT (C1 AND C2) C1 is false, C2 is false, or both are false
NOT (C1 OR C2) C1 and C2 are both false

Closure rule: if C1, C2 are conditional expressions then so are "C1 AND C2", "C1 OR C2" and NOT-forms, reducible by successive substitution, e.g. C1 AND (C2 OR NOT (C3 OR C4)) (F p. 105, rule 2).

Legal symbol pairs (1 = permissible, 0 = not) (F p. 106, rule 4):

First Symbol \ Second C OR AND NOT ( )
C 0 1 1 0 0 1
OR 1 0 0 1 1 0
AND 1 0 0 1 1 0
NOT 1 0 0 0 1 0
( 1 0 0 1 1 0
) 0 1 1 0 0 1

"Thus, the pair 'OR NOT' is permissible, while 'NOT OR' is not permissible" (F p. 106). Note in particular: NOT NOT is not permissible; NOT may be followed by a condition or by "(" but not by another NOT. NOT before a relation is built into the relation spellings themselves (NOT GT, NOT =, NOT LT) (F p. 21), and NOT before a condition-name or parenthesized compound negates it (F pp. 23, 105). Parentheses "may be used wherever needed ... in compound conditional expressions for the sake of clarity; where ambiguity would result from their omission, they must be used" (F p. 28, rule 11).

Worked interpretations of mixed AND/OR expressions are tabulated at F pp. 23–24 (e.g. MARRIED OR OVER.21 AND HOURLY.RATE IS GREATER THAN 3.50 = MARRIED, or the AND-pair, or both; the parenthesized variant regroups it).

J adds no separate AND/OR/NOT rules; its only related capacity note is message 187,00 (conditional expression test capacity; rewrite as two or more expressions) and the 60-operator sentence limit (171,00) (J 90.04.01).

5.3.5 Truth functions (TR)

SET DISCOUNT = ORDER.AMOUNT * .05 * TR
    (ORDER.AMOUNT IS GREATER THAN 1000).

5.4 The GO TO command

"The GO TO command is used to specify transfer-type operations. It has three forms" (F p. 48).

Legal targets, all three forms: "The 'procedure.name' may be the name of either a sentence or a section in the procedural part of the source program" (F p. 48). J enforces this: "TRANSFER BYPASSED BECAUSE 'NAME.1' IS NOT A STATEMENT OR SECTION NAME." (127,00); "OPERATION IGNORED BECAUSE 'NAME.1' IS ILLEGAL TRANSFER ADDRESS." (26,00); and transfers into DO-addressed procedures are rejected: "TRANSFER BYPASSED BECAUSE 'NAME.1' IS A STATEMENT OR SECTION NAME ADDRESSED BY A -DO-." (128,00) (all J 90.04.01). Since processor commands (other than BEGIN SECTION/END) are unnamed, control cannot be transferred to them (F p. 60).

5.4.1 Unconditional GO TO

GO TO procedure.name

(F p. 48)

"It provides a transfer of control, or branching, to the item of procedure named in the command" (F p. 48). Examples: GO TO MAIN.ROUTINE., GO TO CALC.ORDER.POINT. (F p. 48). An unconditional GO TO placed immediately after a STOP yields a "dead-end" halt (F p. 54; §5.6). All overlapped procedures should end with an unconditional GO TO (F p. 56 — LOAD/OVERLAP deferred in J, see §5.7).

5.4.2 Conditional GO TO (WHEN)

"essentially a multiple branch or switching point" (F p. 48):

GO TO procedure.name.1 WHEN conditional expression 1,
     procedure.name.2 WHEN conditional expression 2, ...
     procedure.name.n WHEN conditional expression n

(F p. 48)

Semantics: "each conditional expression is evaluated in turn until one is found to be true. Thereupon, control is transferred to the 'procedure.name' associated with that conditional expression. Any remaining conditional expressions are left unevaluated. If none of the conditional expressions in the command is found to be true, control passes to the next clause or sentence in sequence" (F p. 48). I.e. first-match wins, evaluation is short-circuited, and no-match falls through.

GO TO ERROR.RTN WHEN DETAIL IS LESS THAN MASTER,
     PROCESSING WHEN DETAIL IS EQUAL TO MASTER,
     NO.ACTIVITY WHEN DETAIL IS GREATER THAN MASTER.

(F p. 48)

WHEN is one of the words "always interpreted as Key words" and may never be a programmer name (J 02.03.02). Real usage with fall-through (J 90.05, listing PDF p. 195):

COMPARE.EMPLOYEE.NUMBERS.  GO TO CHECK.NEW.DEPT WHEN D.EMP.NO =
                            M.EMP.NO,  LOW.DETAIL WHEN D.EMP.NO LT M.EMP.NO.
HIGH.DETAIL.    ...

When neither WHEN condition holds, control falls into the next sentence (HIGH.DETAIL).

5.4.3 Assigned GO TO (ON index)

"also serves as a multiple branch point ... the transfer of control depends upon the prior setting of an index rather than on the truth or falsity of conditional expressions. The setting of the index may have occurred in one of two ways: 1. Through bringing the index into storage as a constant or file variable. 2. As a result of computation involving the index" (F pp. 48–49).

GO TO ( procedure.1, procedure.2, ... procedure.n ) ON index.name

(F p. 49)

GO TO (PIECE.WORK, INCENTIVE, HOURLY.RATE, SALARY) ON
     PAY.TYPE.

(F p. 49 — PAY.TYPE is a field in each employee record containing 1, 2, 3, or 4)

5.4.4 SET condition.name (switch setting for conditional tests)

For completeness of the "switch" picture (full SET coverage belongs with arithmetic/assignment):

SET condition.name

(F p. 46)

"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). SET MARRIED. ≡ SET MARITAL.STATUS = 'M'. (F p. 46). J's SET discussion (J 02.04.05, "6. SET") covers only the arithmetic form and never re-states the condition-name form; nothing in J 90.01 defers it, and conditional variables remain fully supported (J 02.05.02; J 90.04.01 messages 37,00/38,00). Presume it implemented as per F (flagged in the ambiguities register).

5.5 The DO command

"The DO command provides a means of departing from the normal sequence of program steps in order to execute some procedure ... and then return to the original sequence. In other words, the DO is used to execute subroutines which, in the Commercial Translator system, are either named sentences or sections" (F p. 49). "The DO command may take one of several forms. In the simplest form ... the procedure is executed once each time the DO is encountered. Expanded forms of the command permit repetitive execution, or 'looping,' of the subroutine and control of subscripts. Data substitution, which is an optional feature, is also provided" (F p. 49).

Consolidated general forms (F p. 108, Appendix 2 — brackets denote optional phrases):

DO procedure.name [EXACTLY n TIMES] [USING data.name.1, data.name.2, ..
    data.name.n] [GIVING result.name.1, result.name.2, ... result.name.n]

DO procedure.name FOR index.name.1 = p.1(q.1)r.1 [, index.name.2 =
    p.2(q.2)r.2, index.name.3 = p.3(q.3)r.3] [USING data.name.1, data.name.2,
    ... data.name.n] [GIVING result.name.1, result.name.2, ... result.name.n]

5.5.1 Simple DO and DO ... EXACTLY n TIMES

DO procedure.name
DO procedure.name EXACTLY n TIMES

(F p. 49)

5.5.2 DO with indexing (FOR index = p(q)r)

DO procedure.name FOR index.name = p(q)r

(F p. 50)

        SET i = p.
START.  DO rtn.
        IF i = r THEN GO TO NEXT.
        ADD q TO i.
        GO TO START.
NEXT.   .
        .
        .

(F p. 51 — "the command, 'DO rtn FOR i = p(q)r' is the equivalent of" this expansion)

Consequences: the body executes with i = p first and executes for i = r (termination is checked after the body); the index equals r on exit; the body always runs at least once (consistent with J 90.01.02); if the step never makes i exactly equal r the expansion never terminates (see ambiguities).

DO procedure.name FOR index.name.1 = p.1(q.1)r.1, index.name.2 = p.2(q.2)r.2

(F p. 51)

5.5.3 DO with data substitution (USING ... GIVING ...)

Procedures to be used with data substitution "are always defined by the two processor commands 'BEGIN SECTION USING . . . GIVING . . .' and 'END'" (F p. 52). The simplest substituting DO:

DO procedure.name USING data.name.1, data.name.2, ...
     data.name.n GIVING result.name.1, result.name.2 ...
     result.name.n

(F p. 52)

"if data substitution is desired in the other forms of the DO command, the 'USING . . . GIVING . . .' option is simply appended to the command" (F p. 52). The matching section header:

BEGIN SECTION USING parameter.1, parameter.2, ...
     parameter.n GIVING function.1, function.2, ... function.n

(F p. 57)

Semantics (F pp. 32–33, 52–53): at object time, data named in the DO's USING phrase is moved positionally into the parameter fields named in the BEGIN SECTION's USING phrase ("items of data named in a DO command will be placed in the parameter fields named in the BEGIN SECTION command in the order in which they are named", F p. 33); the procedure executes; then results are moved from the function fields (BEGIN SECTION GIVING) to the fields named in the DO's GIVING phrase (F p. 33). DO MIN.ROUT USING R.RATE, E.RATE, M.RATE GIVING MIN.RATE. is equivalent to three MOVEs in, DO MIN.ROUT., and one MOVE out (F pp. 52–53). Literals may be substituted: DO MIN.ROUT USING INSURED.AGE, BENEFIC.AGE, 70 GIVING LOW.AGE. (F p. 53), as may figurative constants such as HIGH.VALUES (F pp. 33–34).

5.5.4 DO with named END (early exit from an iteration)

"When a DO command is compiled, the processor places appropriate instructions in the object program to effect transfer of control between the DO and the associated procedure and to perform any indexing operations specified in the DO. For correct functioning of the DO, these control instructions must be executed each time an iteration of the associated procedure is executed. The control instructions are performed following the last program command specified in the procedure." When the logic requires a conditional exit before the last command, "The solution ... is to name the 'END procedure.name' sentence which terminates the procedure and to use this name as an exit point. (Normally the END sentence is not named; this is the only exception to the rule.) This provides the necessary linkage with the control instructions" (F p. 53). Illustration (F p. 53):

DO REORDER.RTN FOR PART.NO = 1001(1)1499.
        .
        .
        .
REORDER.RTN.  BEGIN SECTION.
        IF QTY.ON.HAND(PART.NO) IS GREATER THAN ORDER.POINT
             (PART.NO) THEN GO TO EXIT.
        SET REORDER.AMT(PART.NO) = ORDER.AMT(PART.NO) -
             QTY.ON.HAND(PART.NO).
EXIT.   END REORDER.RTN.

I.e. GO TO the named END sentence terminates the current iteration while preserving the loop/return linkage. The same pattern appears in the field-test sample program: BOND.ROUTINE contains ... GO TO BOND.END. with BOND.END. END BOND.ROUTINE., and SEARCH has SEARCH.END. END SEARCH. as the target of its in-loop GO TO (J 90.05, listing PDF pp. 196–197).

5.5.5 The closed-subroutine rule, entry, and exits

5.6 The STOP command; STOP RUN

F form:

STOP n

(F p. 54): "where n is an integer. The number n will be displayed when the command is executed, i.e., when the machine halts. Restarting the machine causes execution of the object program to be resumed beginning with the next command in sequence. For a 'dead-end' halt, an unconditional GO TO command placed immediately following the STOP can be used to effect a transfer back to the STOP command" (F p. 54). (F p. 25 also shows the bare example sentence STOP. with no operand, and the F payroll example uses STOP 1234. (F pp. 92, 101, Appendix 1); see ambiguities.)

J forms and semantics: the STOP display subroutine SYS)178 records "the Statement Number of the Stop (in BCD), and the type of STOP (STOP NNN or STOP RUN)" (J 90.02.14). At execution (J 05.06.04):

STOP RUN is mandatory in J: "A STOP RUN instruction must be included in each program to provide for transfer of control to the CT Supervisor at conclusion of execution of the object program. All open files are closed prior to this transfer of control as if a CLOSE ALL FILES had been supplied" (J 02.04.06, "9. STOP RUN"). Diagnostic: "NO -STOP RUN- IN PROGRAM." (J 90.04.01, message 175,00). Files closed by CLOSE ALL FILES (hence by STOP RUN) "may not be subsequently reopened by the program" (J 02.04.06, "8. CLOSE ALL FILES"). Sample usage: CLOSE ALL FILES, STOP RUN. (J 90.05, listing PDF p. 196).

F/J divergence: F has only STOP n (halt-and-resume); STOP RUN (normal program termination returning control to the supervisor) is a J addition (RUN is reserved in J: key-word list J 02.03.02; message 2,00 "-RUN- DELETED. ITS USE IS RESTRICTED TO PROCESSOR."). J bounds n at 6 digits (J 05.06.04); F gives no bound.

5.7 Sections, procedure-names, and structural constraints on transfer targets

Control transfers are defined in terms of named sentences and sections, so the sectioning rules are part of control flow:

procedure.name.  BEGIN SECTION.
     any sentence.
     .
     .
     .
     any sentence.
END procedure.name.

(F p. 57)

5.8 Numeric limits and restrictions bearing on control flow (J)

Item Limit / rule Citation
Operators per sentence max 60, sentence deleted if exceeded J 90.04.01 (171,00)
Conditional expression tests per expression internal capacity; "rewrite as two or more separate expressions" J 90.04.01 (187,00)
Number of SECTIONS approx. max 35 J 90.01.05
Depth of nested sections approx. max 18 J 90.01.05
Number of index expressions (a * VARIABLE ± b) approx. max 50 J 90.01.05
Number of positional indicators (unique array+subscript combinations) approx. max 90 J 90.01.05
Internal dictionary (all names, programmer + generated) approx. max 3500 J 90.01.05
Generated constants in constant pool approx. max 500 J 90.01.05
DO loop body executions always at least once, regardless of loop-control values J 90.01.02
DO indices per command max 3; rightmost varies fastest F p. 51
Assigned GO TO index integer 1..n, else fall through F p. 49
Subscript range at object time no object-time check against array dimensions J 90.01.02
Array origin A(1), not A(0) J 02.04.07.01
STOP operand ≤ 6 digits J 05.06.04
STOP RUN required once per program; implies CLOSE ALL FILES J 02.04.06; 90.04.01 (175,00)
Procedure-name length 1–30 characters, followed by period + blank F p. 37
Statement numbering xxxxx,yy: line , clause J 02.02.01
Severity codes 1 = still runnable; >1 no compile-and-go; 5 stops compilation, no deck J 90.04.02; J 02.01.01
INCLUDE (library procedures) deferred; no library facilities J 90.01.02
LOAD / OVERLAP (segmentation) deferred J 90.01.03; 90.01.05 (B.2)
PARAM / FUNCT type codes "no longer in the language" (USING/GIVING remain) J 02.05.03
AT END clause single imperative statement only; must name a statement/section J 02.07.05; 90.04.01 (106,00)

5.9 Flagged ambiguities (summary)

The following points, developed above, are recorded in full in the ambiguities register accompanying this document: (1) the DO ... FOR equality-termination test and non-reaching step values; (2) the "index.name.1 is set to p.1 + q.1" wording in the two-index DO; (3) the phrase "tests for NOT greater or less conditions" in the unequal-length comparison rule; (4) legality/semantics of GO TO out of a DO'd procedure; (5) bare STOP. vs STOP n; (6) whether an object-time range check is generated for the assigned GO TO; (7) the undocumented PROGRAM.START facility; (8) the reserved word EQUALS; (9) SET condition.name in J; (10) nested/recursive DO.