{ DL-Pascal Coverage Section 2: Control Flow } { Exercises IF/THEN/ELSE, WHILE, REPEAT/UNTIL, } { FOR TO/DOWNTO, CASE/OF, nested combinations, } { GOTO, and edge cases. } { Expected: runs without error, displays results } {$D-C-R-} PROGRAM Section2; VAR i, j, k : Integer; b : Boolean; c : Char; PROCEDURE Check(msg : STRING; passed : Boolean); BEGIN IF passed THEN WriteLn('OK ', msg) ELSE WriteLn('FAIL ', msg); END; { ---- IF / THEN / ELSE ---- } PROCEDURE TestIf; VAR n : Integer; BEGIN { Simple true branch } n := 0; IF 5 > 3 THEN n := 1; Check('IF true branch', n = 1); { Simple false branch - no else } n := 0; IF 3 > 5 THEN n := 1; Check('IF false no-else', n = 0); { IF THEN ELSE true } n := 0; IF 5 > 3 THEN n := 1 ELSE n := 2; Check('IF-ELSE true', n = 1); { IF THEN ELSE false } n := 0; IF 3 > 5 THEN n := 1 ELSE n := 2; Check('IF-ELSE false', n = 2); { Nested IF - dangling else binds to nearest IF } n := 0; b := True; IF b THEN b := False; IF b THEN n := 1 ELSE n := 2; Check('Nested IF else', n = 2); { Chained IF ELSE IF } n := 5; IF n < 0 THEN i := -1 ELSE IF n = 0 THEN i := 0 ELSE IF n < 10 THEN i := 1 ELSE i := 2; Check('Chained IF', i = 1); { IF with compound statement } n := 0; b := True; IF b THEN BEGIN n := n + 1; n := n + 1; END; Check('IF compound', n = 2); { IF ELSE with compound } n := 0; b := False; IF b THEN BEGIN n := 99; END ELSE BEGIN n := n + 3; n := n + 3; END; Check('IF-ELSE compound', n = 6); { Boolean variable in IF } b := (7 MOD 2) = 1; IF b THEN n := 7 ELSE n := 0; Check('IF bool var', n = 7); END; { ---- WHILE / DO ---- } PROCEDURE TestWhile; VAR n, sum : Integer; BEGIN { Basic count } n := 0; sum := 0; WHILE n < 5 DO BEGIN sum := sum + n; Inc(n); END; Check('WHILE sum 0..4', sum = 10); { Zero iterations } n := 0; b := False; WHILE b DO Inc(n); Check('WHILE zero iters', n = 0); { Single iteration } n := 0; WHILE n = 0 DO Inc(n); Check('WHILE one iter', n = 1); { Nested WHILE } n := 0; i := 0; WHILE i < 3 DO BEGIN j := 0; WHILE j < 3 DO BEGIN Inc(n); Inc(j); END; Inc(i); END; Check('WHILE nested 3x3', n = 9); { WHILE with compound condition } n := 0; i := 10; WHILE (n < 5) AND (i > 0) DO BEGIN Inc(n); Dec(i, 2); END; Check('WHILE compound cond', (n = 5) AND (i = 0)); { Countdown } n := 10; WHILE n > 0 DO Dec(n); Check('WHILE countdown', n = 0); END; { ---- REPEAT / UNTIL ---- } PROCEDURE TestRepeat; VAR n, sum : Integer; BEGIN { Basic - always executes at least once } n := 0; REPEAT Inc(n); UNTIL n = 5; Check('REPEAT to 5', n = 5); { Always executes once even if condition true } n := 99; REPEAT n := 1; b := True; UNTIL b; Check('REPEAT once', n = 1); { Sum via repeat } n := 1; sum := 0; REPEAT sum := sum + n; Inc(n); UNTIL n > 5; Check('REPEAT sum 1..5', sum = 15); { Nested REPEAT } n := 0; i := 0; REPEAT j := 0; REPEAT Inc(n); Inc(j); UNTIL j = 4; Inc(i); UNTIL i = 4; Check('REPEAT nested 4x4', n = 16); { Compound condition } n := 0; i := 0; REPEAT Inc(n); Inc(i); UNTIL (n >= 3) OR (i >= 10); Check('REPEAT compound', n = 3); END; { ---- FOR TO / DOWNTO ---- } PROCEDURE TestFor; VAR n, sum : Integer; li : LongInt; BEGIN { Basic TO } sum := 0; FOR i := 1 TO 5 DO sum := sum + i; Check('FOR TO sum 1..5', sum = 15); { Zero iterations when start > end } n := 0; FOR i := 5 TO 1 DO Inc(n); Check('FOR TO zero iters', n = 0); { DOWNTO } sum := 0; FOR i := 5 DOWNTO 1 DO sum := sum + i; Check('FOR DOWNTO sum', sum = 15); { Zero iters DOWNTO } n := 0; FOR i := 1 DOWNTO 5 DO Inc(n); Check('FOR DOWNTO zero', n = 0); { Single iteration } n := 0; FOR i := 3 TO 3 DO n := i; Check('FOR single iter', n = 3); { Nested FOR } n := 0; FOR i := 1 TO 4 DO FOR j := 1 TO 4 DO Inc(n); Check('FOR nested 4x4', n = 16); { FOR with step via LongInt range } li := 0; FOR i := 1 TO 100 DO Inc(li, i); Check('FOR sum 1..100', li = 5050); { FOR over char range } n := 0; FOR c := 'A' TO 'Z' DO Inc(n); Check('FOR char A..Z', n = 26); { Ensure loop var has final value after loop } FOR i := 1 TO 5 DO ; Check('FOR final var', i = 5); END; { ---- CASE / OF ---- } PROCEDURE TestCase; VAR n : Integer; BEGIN { Integer CASE } i := 2; CASE i OF 1 : n := 10; 2 : n := 20; 3 : n := 30; END; Check('CASE int match', n = 20); { CASE with ELSE } i := 99; CASE i OF 1 : n := 1; 2 : n := 2; ELSE n := 0; END; Check('CASE else', n = 0); { CASE no match no else - value unchanged } n := 42; i := 99; CASE i OF 1 : n := 1; 2 : n := 2; END; Check('CASE no match', n = 42); { CASE with range } i := 5; CASE i OF 1..3 : n := 1; 4..6 : n := 2; 7..9 : n := 3; END; Check('CASE range', n = 2); { CASE with list } i := 3; CASE i OF 1, 3, 5, 7, 9 : n := 1; { odd } 2, 4, 6, 8 : n := 2; { even } END; Check('CASE list odd', n = 1); i := 4; CASE i OF 1, 3, 5, 7, 9 : n := 1; 2, 4, 6, 8 : n := 2; END; Check('CASE list even', n = 2); { CASE on Char } c := 'B'; CASE c OF 'A' : n := 1; 'B', 'C' : n := 2; 'D'..'Z' : n := 3; ELSE n := 0; END; Check('CASE char', n = 2); { CASE with compound statement } i := 1; n := 0; CASE i OF 1 : BEGIN n := n + 1; n := n + 1; END; 2 : n := 99; END; Check('CASE compound', n = 2); END; { ---- Mixed / nested control structures ---- } PROCEDURE TestMixed; VAR n, sum : Integer; BEGIN { FOR containing IF } sum := 0; FOR i := 1 TO 10 DO IF Odd(i) THEN sum := sum + i; Check('FOR+IF odd sum', sum = 25); { 1+3+5+7+9 } { WHILE containing CASE } n := 1; sum := 0; WHILE n <= 5 DO BEGIN CASE n OF 1, 2 : Inc(sum, 1); 3 : Inc(sum, 10); 4, 5 : Inc(sum, 100); END; Inc(n); END; Check('WHILE+CASE', sum = 212); { 1+1+10+100+100 } { REPEAT containing FOR } n := 0; sum := 0; REPEAT FOR j := 1 TO 3 DO Inc(sum); Inc(n); UNTIL n = 4; Check('REPEAT+FOR', sum = 12); { Fibonacci via WHILE } i := 0; j := 1; n := 0; WHILE j < 100 DO BEGIN k := i + j; i := j; j := k; Inc(n); END; Check('Fibonacci count', n = 10); { 1,1,2,3,5,8,13,21,34,55,89 } Check('Fibonacci last', i = 55); { Triangular numbers via nested FOR } sum := 0; FOR i := 1 TO 5 DO FOR j := 1 TO i DO Inc(sum); Check('Triangular 5', sum = 15); { 1+2+3+4+5 } END; { ---- GOTO ---- } PROCEDURE TestGoto; LABEL skip, done; VAR n : Integer; BEGIN n := 0; GOTO skip; n := 99; { should be skipped } skip: n := n + 1; Check('GOTO forward', n = 1); { GOTO to exit a loop early (legitimate use) } n := 0; FOR i := 1 TO 10 DO BEGIN Inc(n); IF n = 5 THEN GOTO done; END; done: Check('GOTO exit loop', n = 5); END; { ---- Edge cases ---- } PROCEDURE TestEdge; VAR n : Integer; BEGIN { Empty WHILE body } i := 0; WHILE i < 5 DO Inc(i); Check('WHILE no BEGIN', i = 5); { FOR with max range check } n := 0; FOR i := -5 TO 5 DO Inc(n); Check('FOR negative start', n = 11); { Deeply nested IF } i := 3; IF i > 0 THEN IF i > 1 THEN IF i > 2 THEN IF i > 3 THEN n := 0 ELSE n := 3 ELSE n := 2 ELSE n := 1 ELSE n := 0; Check('Deep nested IF', n = 3); { CASE boundary values } i := 0; CASE i OF 0 : n := 99; 1..9 : n := 1; END; Check('CASE zero', n = 99); END; { ---- Main ---- } BEGIN WriteLn('=== Section 2: Control Flow ==='); WriteLn; WriteLn('-- IF/THEN/ELSE --'); TestIf; WriteLn; WriteLn('-- WHILE/DO --'); TestWhile; WriteLn; WriteLn('-- REPEAT/UNTIL --'); TestRepeat; WriteLn; WriteLn('-- FOR TO/DOWNTO --'); TestFor; WriteLn; WriteLn('-- CASE/OF --'); TestCase; WriteLn; WriteLn('-- Mixed/Nested --'); TestMixed; WriteLn; WriteLn('-- GOTO --'); TestGoto; WriteLn; WriteLn('-- Edge Cases --'); TestEdge; WriteLn; WriteLn('=== Section 2 complete ==='); END.