Records, arrays, and pointers
Lesson from the WasmPascal in-browser Learn Pascal tutorial. Source: webpascal/index.html.
A record groups fields; a static array has fixed bounds; pointers (^T) hold addresses you take with @ and follow with p^. Records and arrays nest, and indexed fields work like balls[i].x.
library recs;
type
TPoint = record
x: Integer;
y: Integer;
end;
TGrid = array [0..9] of Integer;
var
p: TPoint;
g: TGrid;
i: Integer;
begin
p.x := 3;
p.y := 4;
writeln('point ', p.x, ',', p.y);
for i := 0 to 9 do g[i] := i * i;
writeln('g[4] = ', g[4]);
end.
Records use FPC natural alignment for layout — relevant only when you reach past a record's fields into raw memory. SizeOf(T) / SizeOf(v) is a compile-time constant (SizeOf(Integer) = 4, SizeOf(String) = 8 — the (addr,len) pair model). nil is the null pointer (assign and compare with =/<>; the TP idiom p <> 0 also works), and Inc(p)/Dec(p, n) move a typed pointer by whole elements — ideal for walking record arrays. A record can also carry variants: a case tag: T of part whose arms share storage, with an else arm as the default. Multi-dim arrays use the TP sugar array[1..3, 1..4] of T with a[i, j] indexing (equivalent to nested arrays). Integer literals can be hex ($FF) or binary (%1010), floats use scientific notation (1e10), and MaxInt is 2147483647.
library recs2;
type
TPair = record
a, b: Integer;
end;
PPair = ^TPair;
TShape = record
case tag: Byte of
0: (r: Single);
1: (w, h: Single);
end;
var
arr: array[0..1] of TPair;
p: PPair;
s: TShape;
begin
p := @arr[0];
Inc(p); // +8: one whole record
p.a := 11;
writeln(arr[1].a); // 11
writeln(SizeOf(TPair)); // 8
s.tag := 1;
s.w := 2.0;
s.h := 3.0;
writeln(s.w); // 2
writeln(SizeOf(s)); // 12
end.
For building games, look at the basic_canvas.pas example: it mixes arrays of records, Byte pixel buffers, and an RNG.
Try it: paste this into the WasmPascal editor and press Run.