Control flow
Jump to navigation
Jump to search
Control Flow[edit]
Project: pgcobol — Prime Numbers Application
Version: 1.0 (reverse-engineered)
Date: 2026-03-17
1. Conventions[edit]
- PERFORM — synchronous paragraph call; returns to the next statement after the PERFORM.
- CALL — dynamic subprogram call; passes a data block by reference; returns via EXIT PROGRAM.
- EVALUATE TRUE — multi-way branch on 88-level conditions; equivalent to a CASE statement.
- PERFORM … UNTIL — loop; condition tested before each iteration (DO-WHILE in reverse — test first).
2. primesmain — Paragraph Map[edit]
PROCEDURE DIVISION │ ├── ACCEPT / MOVE setup ├── PERFORM r90-start-session ──────────────────────────────► r90-start-session │ │ CALL primesui "start" │ │ IF ok: CALL primesui "log-message" ×2 │ │ ELSE: DISPLAY + STOP RUN │ └── return │ ├── EVALUATE TRUE │ WHEN report-primes ──────────────────────────────────────► CALL primesui "log-message" │ │ PERFORM r92-generate-primes ──► r92-generate-primes │ │ │ CALL primesgen │ │ └── return │ WHEN generate-primes ────────────────────────────────────► CALL primesui "log-message" │ │ *** PERFORM commented out *** │ WHEN OTHER ─────────────────────────────────────────────► CALL primesui "log-message" │ PERFORM r99-stop-session │ STOP RUN │ ├── CALL primesui "log-message" ├── PERFORM r99-stop-session ───────────────────────────────► r99-stop-session │ │ CALL primesui "stop" │ └── return └── STOP RUN
CALLs issued by primesmain:
| Call | Using | Condition |
|---|---|---|
CALL "primesui"
|
primes-ui | ui-methods = "start"
|
CALL "primesui"
|
primes-ui | ui-methods = "log-message" (multiple)
|
CALL "primesgen"
|
primes-session | method = “report” or “generate” |
CALL "primesui"
|
primes-ui | ui-methods = "stop"
|
3. primesgen — Paragraph Map[edit]
PROCEDURE DIVISION USING primes-session
│
└── EVALUATE TRUE on methods
WHEN report-primes
│ PERFORM r90-start-primes-report ──────────────────► r90-start-primes-report
│ │ │ CALL primes "connect"
│ │ │ CALL primes "cursor"
│ │ │ PERFORM r94-fetch ──► r94-fetch
│ │ │ │ CALL primes "next-prime"
│ │ │ └── return
│ │ └── return
│ │
│ IF session-method-ok
│ PERFORM r86-report-primes UNTIL session-method-eof
│ │ ┌──────────────────────────────────────────────► r86-report-primes (loop body)
│ │ │ CALL primesui "write"
│ │ │ PERFORM r94-fetch ──────────────────────────► r94-fetch
│ │ │ │ CALL primes "next-prime"
│ │ │ └── return
│ │ └── (loop back)
│
WHEN generate-primes
│ PERFORM r91-start-primes-generation ──────────────► r91-start-primes-generation
│ │ │ CALL primes "connect"
│ │ └── return
│ │
│ IF session-method-ok
│ PERFORM r80-test-number UNTIL test-number = 999999999
│ │ ┌──────────────────────────────────────────────► r80-test-number (loop body)
│ │ │ DIVIDE test-number BY test-divider → test-rest
│ │ │ EVALUATE TRUE
│ │ │ WHEN test-rest = 0
│ │ │ PERFORM r82-next-test-number ──────────► r82-next-test-number
│ │ │ │ ADD 2 TO test-number
│ │ │ │ COMPUTE sqrt
│ │ │ │ MOVE 1 TO old-ident
│ │ │ │ PERFORM r89-get-next-divider ──► r89-get-next-divider
│ │ │ │ │ CALL primes "get"
│ │ │ │ └── return
│ │ │ └── return
│ │ │ WHEN test-divider > test-number-sqr
│ │ │ PERFORM r85-write-prime ─────────────► r85-write-prime
│ │ │ │ │ CALL primes "write"
│ │ │ │ │ CALL primesui "write"
│ │ │ │ └── return
│ │ │ PERFORM r82-next-test-number (as above)
│ │ │ WHEN OTHER
│ │ │ PERFORM r89-get-next-divider (as above)
│ │ └── (loop back)
│
WHEN OTHER
LOG "Bad method"
│
└── PERFORM r99-close-primes ────────────────────────────► r99-close-primes
│ │ CALL primes "disconnect"
│ └── return
EXIT PROGRAM
Loop summary — primesgen:
| Loop | Type | Condition | Paragraph |
|---|---|---|---|
| Report read | PERFORM UNTIL | session-method-eof (result = 9)
|
r86-report-primes |
| Sieve | PERFORM UNTIL | test-number = 999999999
|
r80-test-number |
| Inner (test-number) | EVALUATE inside PERFORM | drives calls to r82 / r85 / r89 | r80-test-number |
4. primes (DAL) — Paragraph Map[edit]
PROCEDURE DIVISION USING primes-dal
│
└── EVALUATE TRUE on dal-methods
WHEN next-prime → PERFORM r80-get-next-prime ──────► r80-get-next-prime
│ │ PERFORM s02-fetch ──► s02-fetch
│ │ │ EXEC SQL FETCH
│ │ └── return
│ └── return
WHEN next-divider → PERFORM r81-get-next-divider ────► r81-get-next-divider
│ │ ADD 1 TO old-ident → new-ident
│ │ EXEC SQL SELECT prime WHERE ident=new-ident
│ │ MOVE new-ident TO old-ident
│ └── return
WHEN write-prime → PERFORM r83-write-prime ──────────► r83-write-prime
│ │ EXEC SQL INSERT
│ └── return
WHEN db-connect → PERFORM s00-connect ──────────────► s00-connect
│ │ EXEC SQL CONNECT
│ └── return
WHEN db-cursor → PERFORM s01-cursor ───────────────► s01-cursor
│ │ EXEC SQL START TRANSACTION
│ │ EXEC SQL OPEN primescursor
│ └── return
WHEN db-disconnect → PERFORM s99-disconnect ───────────► s99-disconnect
│ │ EXEC SQL CONNECT RESET
│ └── return
WHEN OTHER → dal-result = 1
│
└── EXIT PROGRAM
No loops in primes.cbl. Each invocation handles exactly one SQL operation and returns.
5. primesui — Paragraph Map[edit]
PROCEDURE DIVISION USING primes-ui
│
└── EVALUATE TRUE on ui-methods
WHEN start-ui → PERFORM r90-start-primesui ────────► r90-start-primesui
│ │ OPEN OUTPUT fprinter
│ │ IF ok: result=0, idx=1
│ │ PERFORM r98-message-ui ──► r98-message-ui
│ │ │ DISPLAY on scherm
│ │ └── return
│ └── return
WHEN write-ui → PERFORM r92-write-primesui ─────────► r92-write-primesui
│ │ load cell(primes-idx)
│ │ idx + 1
│ │ IF new-page → PERFORM r93-new-page ──► r93-new-page
│ │ │ WRITE heading
│ │ │ WRITE col header
│ │ │ new-page = 0
│ │ └── return
│ │ IF idx = 7 → WRITE line, idx = 1
│ │ IF linage = 53 → PERFORM r94-eop ──► r94-eop
│ │ │ WRITE blank
│ │ │ WRITE footing
│ │ │ page-number + 1
│ │ │ new-page = 1
│ │ └── return
│ └── return
WHEN message-ui → PERFORM r98-message-ui (as above)
WHEN stop-ui → PERFORM r99-stop-primesui ──────────► r99-stop-primesui
│ │ u-sequence = 0, u-number = 0
│ │ PERFORM r92-write-primesui UNTIL new-page ← flush loop
│ │ PERFORM r98-message-ui
│ │ CLOSE fprinter
│ └── return
WHEN OTHER → ui-method-result = 1
│
└── EXIT PROGRAM
Loop summary — primesui:
| Loop | Type | Condition | Location |
|---|---|---|---|
| Flush partial line | PERFORM UNTIL | new-page (print-new-page = 1)
|
r99-stop-primesui |
6. Cross-Program Control Flow Summary[edit]
OS
└─► primesmain PROCEDURE DIVISION
│
├─► CALL primesui (start, log×n, stop)
│ └── EXIT PROGRAM back to primesmain
│
└─► CALL primesgen (once, with primes-session)
│
├─► CALL primes (connect)
│ └── EXIT PROGRAM back to primesgen
├─► CALL primes (cursor / next-prime / next-divider / write / disconnect)
│ └── EXIT PROGRAM back to primesgen [repeated in loop]
├─► CALL primesui (log-message / write)
│ └── EXIT PROGRAM back to primesgen [repeated in loop]
└── EXIT PROGRAM back to primesmain
All inter-program communication is by reference (shared data blocks). There are no GOTO statements in the current source. All branching is via PERFORM, EVALUATE, and IF/ELSE. No COPY-based GOTO or ALTER is used.
Terug naar: Primes_programs_specifications | Cobol and PostgreSQL