Skip to content

Commit 6a0d1d9

Browse files
committed
feat(compiler): Implement Phase 2 Procedures, Functions & Loop Control
Completes all Phase 2 tasks by adding full support for subroutines and advanced loop control statements. - Implements functions and procedures with support for value, `var`, and `const` parameters. - Adds `external` function declarations and all BNF-specified calling conventions (`cdecl`, `stdcall`, `fastcall`, `register`) for C ABI interoperability. - Adds support for `break` and `continue` statements with contextual validation. - Fixes memory corruption and dangling pointer bugs by implementing correct ownership semantics for parameter symbols in the symbol table. - Corrects parser logic for statement separator handling. - Updates `coverage.pas` with comprehensive tests for all new capabilities.
1 parent 4b8b182 commit 6a0d1d9

12 files changed

+1743
-330
lines changed

bin/res/src/coverage.cpas

Lines changed: 126 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,94 @@
11
program FullCoverageTest;
22

33
var
4-
// Declarations Test
5-
i, j, k: Int32; // Multiple identifiers, single line
6-
sum: Int32; // Separate line declaration
7-
r1, r2: Single; // Real type test
4+
// Global Declarations
5+
i, j, k: Int32;
6+
sum: Int32;
7+
r1, r2: Single;
88
r3: Double;
9+
exit_test_val: Int32;
10+
11+
// --- Procedure and Function Declarations ---
12+
13+
procedure ModifyGlobal();
14+
var
15+
local_i: Int32;
16+
begin
17+
local_i := 100;
18+
i := i + local_i; // Modify global 'i'
19+
end;
20+
21+
function GetValue(): Int32;
22+
var
23+
multiplier: Int32;
24+
begin
25+
multiplier := 10;
26+
Result := j * multiplier; // Use global 'j' and assign to Result
27+
end;
28+
29+
procedure TestExitProc();
30+
begin
31+
exit_test_val := 1;
32+
exit;
33+
exit_test_val := -1; // This line should not be reached
34+
end;
35+
36+
function TestExitFunc(): Int32;
37+
begin
38+
Result := 99;
39+
exit;
40+
Result := -99; // This line should not be reached
41+
end;
42+
43+
// --- Parameter Passing Tests ---
44+
45+
function AddValues(a, b: Int32): Int32;
46+
begin
47+
Result := a + b;
48+
end;
49+
50+
procedure Swap(var x, y: Int32);
51+
var
52+
temp: Int32;
53+
begin
54+
temp := x;
55+
x := y;
56+
y := temp;
57+
end;
58+
59+
procedure Calculate(a, b: Int32; var sum_res: Int32; const multiplier: Int32);
60+
begin
61+
sum_res := (a + b) * multiplier;
62+
end;
63+
64+
// --- External Function Declaration Tests ---
65+
66+
// Test for cdecl (standard C calling convention)
67+
function abs(i: Int32): Int32; cdecl; external;
68+
69+
// Test for stdcall (Windows API calling convention)
70+
function GetLastError(): UInt32; stdcall; external;
71+
72+
// Test for fastcall
73+
procedure MyFastCallProc(i: Int32); fastcall; external;
74+
75+
// Test for register (Note: Often architecture-specific, but should parse)
76+
procedure MyRegisterProc(i: Int32); register; external;
77+
78+
79+
// --- Main Program Block ---
980
begin
1081
// Integer Expression and Assignment Test
1182
i := 10;
1283
j := 20;
13-
k := i + j * 2; // Precedence test: k = 10 + 40 = 50
14-
sum := (i + j) * 2; // Parentheses test: sum = (10 + 20) * 2 = 60
15-
i := -k; // Unary minus test: i = -50
84+
k := i + j * 2; // Precedence test: k should be 50
85+
sum := (i + j) * 2; // Parentheses test: sum should be 60
86+
i := -k; // Unary minus test: i should be -50
1687

1788
// Real Expression and Assignment Test
18-
r1 := 1.5; // Real literal test
89+
r1 := 1.5;
1990
r2 := 2.5;
20-
r3 := r1 + r2 / 2.0; // Precedence test: r3 = 1.5 + 1.25 = 2.75
91+
r3 := r1 + r2 / 2.0; // Precedence test: r3 should be 2.75
2192
r1 := -r3; // Unary minus test
2293

2394
// Statement Tests
@@ -33,22 +104,64 @@ begin
33104
else
34105
k := 200;
35106

36-
// Test previously added loops to ensure no regressions
37-
// While Loop
107+
// --- Base Loop Tests ---
38108
i := 0;
39109
while i < 5 do
40110
begin
41111
i := i + 1;
42112
end;
43113

44-
// Repeat-Until Loop
114+
i := 5;
45115
repeat
46116
i := i - 1;
47117
until i = 0;
48118

49-
// For Loop
50119
sum := 0;
51120
for j := 1 to 10 do
52121
sum := sum + j;
53122

123+
// --- Loop Control Tests ---
124+
sum := 0;
125+
i := 0;
126+
while i < 10 do
127+
begin
128+
sum := sum + i;
129+
i := i + 1;
130+
if i = 5 then
131+
break;
132+
end;
133+
134+
sum := 0;
135+
for j := 1 to 5 do
136+
begin
137+
if j = 3 then
138+
continue;
139+
sum := sum + j;
140+
end;
141+
142+
// --- Procedure and Function Call Tests ---
143+
i := 10;
144+
j := 20;
145+
ModifyGlobal(); // Call procedure. 'i' should become 110.
146+
k := GetValue(); // Call function. 'k' should become 200.
147+
148+
// --- Exit Statement Tests ---
149+
exit_test_val := 0;
150+
TestExitProc(); // exit_test_val should be 1, not -1
151+
sum := TestExitFunc(); // sum should be 99, not -99
152+
153+
// --- Argument Passing Tests ---
154+
sum := AddValues(k, i); // sum should be 200 + 110 = 310
155+
156+
i := 5;
157+
j := 10;
158+
Swap(i, j); // i should become 10, j should become 5
159+
160+
k := 0;
161+
Calculate(i, j, k, 3); // k should become (10 + 5) * 3 = 45
162+
163+
// --- External Function Call Test ---
164+
sum := -123;
165+
sum := abs(sum); // sum should become 123
166+
54167
end.

0 commit comments

Comments
 (0)