Structs in Pascal

Pascal’s `records` are typed collections of fields. They’re useful for grouping data together to form records.

This `person` record type has `name` and `age` fields.

```pascal
type
  person = record
    name: string;
    age: integer;
  end;

newPerson constructs a new person record with the given name.

function newPerson(name: string): person;
var
  p: person;
begin
  p.name := name;
  p.age := 42;
  Result := p;
end;

This syntax creates a new record.

var
  p1: person;
begin
  p1 := person.Create;
  p1.name := 'Bob';
  p1.age := 20;
  writeln(p1.name, ' ', p1.age);
end;

You can name the fields when initializing a record.

var
  p2: person;
begin
  p2.name := 'Alice';
  p2.age := 30;
  writeln(p2.name, ' ', p2.age);
end;

Omitted fields will be zero-valued.

var
  p3: person;
begin
  p3.name := 'Fred';
  writeln(p3.name, ' ', p3.age);  // age will be zero
end;

Using @ yields a pointer to the record.

var
  p4: ^person;
begin
  new(p4);
  p4^.name := 'Ann';
  p4^.age := 40;
  writeln(p4^.name, ' ', p4^.age);
end;

It’s idiomatic to encapsulate new record creation in constructor functions

var
  p5: person;
begin
  p5 := newPerson('Jon');
  writeln(p5.name, ' ', p5.age);
end;

Access record fields with a dot.

var
  s: person;
begin
  s.name := 'Sean';
  s.age := 50;
  writeln(s.name);
end;

You can also use dots with record pointers - the pointers are automatically dereferenced.

var
  sp: ^person;
begin
  new(sp);
  sp^ := s;
  writeln(sp^.age);
end;

Records are mutable.

begin
  sp^.age := 51;
  writeln(sp^.age);
end;

If a record type is only used for a single value, we don’t have to give it a name. The value can have an anonymous record type. This technique is commonly used for table-driven tests.

var
  dog: record
    name: string;
    isGood: boolean;
  end;
begin
  dog.name := 'Rex';
  dog.isGood := true;
  writeln(dog.name, ' ', BoolToStr(dog.isGood, true));
end;
Output (when compiled and run):
Bob 20
Alice 30
Fred 0
Ann 40
Jon 42
Sean
50
51
Rex true

Next example: Methods.