← DL-Pascal collectioncov02.pas
DOWNLOAD ORIGINAL FILE
{ 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.