How to create an array containing a range of numbers (PHP: $arr = range(3, 8) print_r($arr)) in COBOL

1 Answer

0 votes
*> ===============================================================
*> MAIN PROGRAM - demo of range(3, 8)
*> ===============================================================
 IDENTIFICATION DIVISION.
 PROGRAM-ID. RANGEDEMO.

 DATA DIVISION.
 WORKING-STORAGE SECTION.
*> Parameters passed to the subprogram
 01  WS-START             PIC S9(9) COMP VALUE 3.
 01  WS-END               PIC S9(9) COMP VALUE 8.
 01  WS-STEP              PIC S9(9) COMP VALUE 1.

*> Result table: WS-COUNT holds the number of valid elements
 01  WS-RESULT.
     05  WS-COUNT         PIC 9(4) COMP VALUE 0.
     05  WS-ITEM          PIC S9(9) COMP
                          OCCURS 1 TO 1000 TIMES
                          DEPENDING ON WS-COUNT.

 01  WS-RC                PIC S9(4) COMP VALUE 0.
 01  WS-I                 PIC 9(4) COMP.
 01  WS-IDX-OUT           PIC Z(3)9.
 01  WS-VAL-OUT           PIC -(9)9.

 PROCEDURE DIVISION.
 MAIN-PARA.
     CALL "RANGEARR" USING WS-START WS-END WS-STEP
                           WS-RESULT WS-RC
     END-CALL

*> Always check the return code
     EVALUATE WS-RC
         WHEN 0
             PERFORM PRINT-ARRAY
         WHEN 1
             DISPLAY "Error: step must not be zero"
         WHEN 2
             DISPLAY "Error: range exceeds table capacity (1000)"
         WHEN OTHER
             DISPLAY "Unknown error: " WS-RC
     END-EVALUATE

     STOP RUN.

*> Mimics PHP's print_r() output
 PRINT-ARRAY.
     DISPLAY "Array"
     DISPLAY "("
     PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-COUNT
         COMPUTE WS-IDX-OUT = WS-I - 1      *> 0-based like PHP
         MOVE WS-ITEM(WS-I) TO WS-VAL-OUT
         DISPLAY "    [" FUNCTION TRIM(WS-IDX-OUT) "] => "
                 FUNCTION TRIM(WS-VAL-OUT)
     END-PERFORM
     DISPLAY ")".
 END PROGRAM RANGEDEMO.


*> ===============================================================
*> SUBPROGRAM RANGEARR - fills a table with start..end (inclusive)
*>
*>   LS-START : first value
*>   LS-END   : last value (may be lower than start -> descending)
*>   LS-STEP  : step size, magnitude only (direction is inferred)
*>   LS-RESULT: output table (count + items)
*>   LS-RC    : 0 = OK, 1 = step is zero, 2 = too many elements
*> ===============================================================
 IDENTIFICATION DIVISION.
 PROGRAM-ID. RANGEARR.

 DATA DIVISION.
 WORKING-STORAGE SECTION.
 01  WS-MAX-ITEMS         PIC 9(4) COMP VALUE 1000.
 01  WS-STEP-ABS          PIC 9(9) COMP.
 01  WS-DIRECTION         PIC S9    COMP.   *> +1 or -1
 01  WS-SPAN              PIC 9(9) COMP.
 01  WS-N                 PIC 9(9) COMP.    *> number of elements
 01  WS-I                 PIC 9(9) COMP.

 LINKAGE SECTION.
 01  LS-START             PIC S9(9) COMP.
 01  LS-END               PIC S9(9) COMP.
 01  LS-STEP              PIC S9(9) COMP.
 01  LS-RESULT.
     05  LS-COUNT         PIC 9(4) COMP.
     05  LS-ITEM          PIC S9(9) COMP
                          OCCURS 1 TO 1000 TIMES
                          DEPENDING ON LS-COUNT.
 01  LS-RC                PIC S9(4) COMP.

 PROCEDURE DIVISION USING LS-START LS-END LS-STEP
                          LS-RESULT LS-RC.
 MAIN-PARA.
     MOVE 0 TO LS-RC
     MOVE 0 TO LS-COUNT

*> 1. Validate input
     IF LS-STEP = 0
         MOVE 1 TO LS-RC
         GOBACK
     END-IF

*> 2. Work out direction and number of elements
     MOVE FUNCTION ABS(LS-STEP) TO WS-STEP-ABS
     IF LS-END >= LS-START
         MOVE 1 TO WS-DIRECTION
         COMPUTE WS-SPAN = LS-END - LS-START
     ELSE
         MOVE -1 TO WS-DIRECTION
         COMPUTE WS-SPAN = LS-START - LS-END
     END-IF
*> Integer division truncates, so this gives floor(span/step) + 1
     COMPUTE WS-N = (WS-SPAN / WS-STEP-ABS) + 1

*> 3. Guard against overflowing the table
     IF WS-N > WS-MAX-ITEMS
         MOVE 2 TO LS-RC
         GOBACK
     END-IF

*> 4. Set the logical size FIRST, then fill the table
     MOVE WS-N TO LS-COUNT
     PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-N
         COMPUTE LS-ITEM(WS-I) =
             LS-START + (WS-DIRECTION * (WS-I - 1) * WS-STEP-ABS)
     END-PERFORM

     GOBACK.
 END PROGRAM RANGEARR.
 
 
*> run:
*>
*> Array
*> (
*>     [0] => 3
*>     [1] => 4
*>     [2] => 5
*>     [3] => 6
*>     [4] => 7
*>     [5] => 8
*> )

 



answered 2 days ago by avibootz
edited 2 days ago by avibootz
...