Appendix A: Pascal Language Quick Reference

This appendix provides a comprehensive quick reference for the Pascal language as implemented in Free Pascal (FPC) 3.2+ using {$mode objfpc}` or `{$mode delphi}. It is organized by topic and designed to serve as a desk reference while you write code. Every syntax form includes a short example. For detailed explanations and extended discussion, refer back to the relevant chapter.


A.1 Program Structure

Minimal Program

program Hello;
begin
  WriteLn('Hello, world!');
end.

Full Program Skeleton

program ProjectName;

{$mode objfpc}{$H+}

uses
  SysUtils, Classes;

const
  MaxItems = 100;

type
  TItemArray = array[0..MaxItems - 1] of Integer;

var
  Items: TItemArray;
  Count: Integer;

{ Procedure and function declarations go here }

begin
  { Main block }
end.

Unit Structure

unit MyUnit;

{$mode objfpc}{$H+}

interface

uses
  SysUtils;

type
  TMyRecord = record
    Name: String;
    Value: Integer;
  end;

procedure DoSomething(const AName: String);

implementation

procedure DoSomething(const AName: String);
begin
  WriteLn('Hello, ', AName);
end;

initialization
  { Runs when unit is loaded }

finalization
  { Runs when program exits }

end.

A.2 Data Types

Ordinal Types

Type Size Range
Byte 1 byte 0..255
ShortInt 1 byte -128..127
Word 2 bytes 0..65535
SmallInt 2 bytes -32768..32767
LongWord / Cardinal 4 bytes 0..4294967295
LongInt / Integer 4 bytes -2147483648..2147483647
QWord 8 bytes 0..2^64-1
Int64 8 bytes -2^63..2^63-1
Boolean 1 byte True / False
Char 1 byte ASCII character
WideChar 2 bytes UTF-16 code unit

Floating-Point Types

Type Size Significant Digits Range (approx.)
Single 4 bytes 7-8 1.5e-45..3.4e+38
Double / Real 8 bytes 15-16 5.0e-324..1.7e+308
Extended 10 bytes 19-20 3.6e-4951..1.1e+4932
Currency 8 bytes 4 decimal places -922337203685477.5808..922337203685477.5807

String Types

Type Description
ShortString Length 0..255, statically allocated, 1-indexed
AnsiString / String Reference-counted, heap-allocated, dynamic length (with {$H+})
WideString COM-compatible wide string
UnicodeString Reference-counted UTF-16 string
PChar Pointer to null-terminated character array
String[n] ShortString with max length n (1..255)

With {$H+}` (the default in most modes), `String` is `AnsiString`. With `{$H-}, String is ShortString.


A.3 Variables and Constants

Variable Declarations

var
  X: Integer;
  Name: String;
  A, B, C: Double;
  Data: array[1..10] of Byte;

Typed Constants (Initialized Variables)

const
  Counter: Integer = 0;      { Mutable in {$J+} mode, immutable in {$J-} }
  Greeting: String = 'Hello';

True Constants

const
  Pi = 3.14159265358979;     { Inferred type }
  MaxSize = 1024;
  AppName = 'MyApp';
  Debug = True;

Type Declarations

type
  TScore = Integer;
  TName = String[50];
  TColor = (Red, Green, Blue, Yellow);
  TRange = 1..100;
  TCallback = procedure(Sender: TObject);
  TCompareFunc = function(A, B: Integer): Integer;

A.4 Operators

Arithmetic Operators

Operator Operation Operand Types Result Type
+ Addition Integer, Real Same or Real
- Subtraction Integer, Real Same or Real
* Multiplication Integer, Real Same or Real
/ Real division Integer, Real Real
div Integer division Integer Integer
mod Modulus Integer Integer
- (unary) Negation Integer, Real Same

Comparison Operators

Operator Meaning
= Equal to
<> Not equal to
< Less than
> Greater than
<= Less than or equal
>= Greater than or equal
in Set membership

Boolean Operators

Operator Operation Operands
not Logical NOT Boolean
and Logical AND Boolean
or Logical OR Boolean
xor Logical XOR Boolean

By default, Free Pascal uses short-circuit evaluation: in A and B, if A is False, B is not evaluated. Similarly for or. Control this with {$B+}` (full evaluation) or `{$B-} (short-circuit, the default).

Bitwise Operators

Operator Operation
not Bitwise NOT
and Bitwise AND
or Bitwise OR
xor Bitwise XOR
shl Shift left
shr Shift right

String Operators

Operator Operation Example
+ Concatenation 'Hello' + ' World'
=, <>, <, >, <=, >= Lexicographic comparison 'abc' < 'abd'

Set Operators

Operator Operation Example
+ Union [1,2] + [3,4] = [1,2,3,4]
- Difference [1,2,3] - [2] = [1,3]
* Intersection [1,2,3] * [2,3,4] = [2,3]
= Equality [1,2] = [2,1] is True
<> Inequality
<= Subset [1,2] <= [1,2,3] is True
>= Superset
in Membership 2 in [1,2,3] is True

Operator Precedence (Highest to Lowest)

Precedence Operators
1 (highest) not, @, unary -
2 *, /, div, mod, and, shl, shr, as
3 +, -, or, xor
4 (lowest) =, <>, <, >, <=, >=, in, is

A.5 Control Flow

If/Then/Else

if Condition then
  Statement;

if Condition then
  Statement1
else
  Statement2;

if Condition then
begin
  Statement1;
  Statement2;
end
else
begin
  Statement3;
  Statement4;
end;

No semicolon before else.

Case Statement

case Selector of
  1:      WriteLn('One');
  2, 3:   WriteLn('Two or Three');
  4..10:  WriteLn('Four through Ten');
else
  WriteLn('Something else');
end;

The selector must be an ordinal type (integer, char, boolean, enumeration). Strings are supported in {$mode delphi} with FPC 3.2+.

For Loop

for I := 1 to 10 do
  WriteLn(I);

for I := 10 downto 1 do
  WriteLn(I);

for Item in Collection do
  WriteLn(Item);

The loop variable must not be modified inside the loop body. After the loop exits, the loop variable's value is undefined (do not rely on it).

While Loop

while Condition do
begin
  { body }
end;

Repeat/Until Loop

repeat
  { body — always executes at least once }
until Condition;

Break and Continue

for I := 1 to 100 do
begin
  if I mod 7 = 0 then
    Continue;           { Skip to next iteration }
  if I > 50 then
    Break;              { Exit loop entirely }
  WriteLn(I);
end;

Exit

procedure DoWork;
begin
  if not Ready then
    Exit;               { Leave procedure immediately }
  { ... }
end;

function Compute(X: Integer): Integer;
begin
  if X < 0 then
    Exit(-1);           { Return -1 and leave function }
  Result := X * X;
end;

A.6 Procedures and Functions

Procedure Declaration

procedure Greet(const Name: String);
begin
  WriteLn('Hello, ', Name, '!');
end;

Function Declaration

function Add(A, B: Integer): Integer;
begin
  Result := A + B;      { Or: Add := A + B; }
end;

Parameter Passing Modes

Mode Syntax Behavior
Value procedure P(X: Integer) Copy of argument; changes do not affect caller
Variable (var) procedure P(var X: Integer) Reference to argument; changes affect caller
Constant (const) procedure P(const X: Integer) Read-only reference; efficient, no copy for large types
Out procedure P(out X: Integer) Like var but initial value is undefined on entry
Constref procedure P(constref X: TBigRec) Always passed by reference, read-only

Default Parameter Values

procedure Log(const Msg: String; Level: Integer = 0);
begin
  if Level >= CurrentLevel then
    WriteLn('[', Level, '] ', Msg);
end;

Log('Starting');        { Level defaults to 0 }
Log('Error!', 3);       { Level is 3 }

Overloading

function Max(A, B: Integer): Integer; overload;
begin
  if A > B then Result := A else Result := B;
end;

function Max(A, B: Double): Double; overload;
begin
  if A > B then Result := A else Result := B;
end;

Nested Routines

procedure Outer;
  procedure Inner;
  begin
    WriteLn('Inner can access Outer''s local variables');
  end;
begin
  Inner;
end;

Forward Declarations

procedure B(X: Integer); forward;

procedure A(X: Integer);
begin
  if X > 0 then B(X - 1);
end;

procedure B(X: Integer);
begin
  if X > 0 then A(X - 1);
end;

A.7 Arrays

Static Arrays

var
  Scores: array[1..5] of Integer;
  Grid: array[0..2, 0..3] of Double;     { 2D array }
  Letters: array['A'..'Z'] of Boolean;    { Indexed by Char }

type
  TRow = array[0..9] of Integer;
  TMatrix = array[0..4] of TRow;          { Array of arrays }

Dynamic Arrays

var
  Data: array of Integer;

begin
  SetLength(Data, 10);          { Allocate 10 elements, indexed 0..9 }
  Data[0] := 42;
  SetLength(Data, 20);          { Resize, preserving existing data }
  WriteLn(Length(Data));         { 20 }
  WriteLn(Low(Data));           { 0 }
  WriteLn(High(Data));          { 19 }
end;

Multidimensional Dynamic Arrays

var
  Matrix: array of array of Double;

begin
  SetLength(Matrix, 3, 4);     { 3 rows, 4 columns }
  Matrix[0][0] := 1.0;
end;

Open Array Parameters

function Sum(const Arr: array of Integer): Integer;
var
  I: Integer;
begin
  Result := 0;
  for I := Low(Arr) to High(Arr) do
    Result := Result + Arr[I];
end;

WriteLn(Sum([1, 2, 3, 4, 5]));     { 15 }

Array Utility Functions

Function Description
Length(A) Number of elements
Low(A) Lowest index
High(A) Highest index
SetLength(A, N) Resize dynamic array
Copy(A, Start, Count) Return subarray
Insert(Source, A, Index) Insert elements
Delete(A, Index, Count) Delete elements
Concat(A, B) Concatenate arrays

A.8 Records

Simple Record

type
  TStudent = record
    Name: String;
    Age: Integer;
    GPA: Double;
  end;

var
  S: TStudent;
begin
  S.Name := 'Alice';
  S.Age := 20;
  S.GPA := 3.85;
end;

Record with Methods (Advanced Record / Extended Record)

type
  TPoint = record
    X, Y: Double;
    function DistanceTo(const Other: TPoint): Double;
    class function Origin: TPoint; static;
  end;

function TPoint.DistanceTo(const Other: TPoint): Double;
begin
  Result := Sqrt(Sqr(X - Other.X) + Sqr(Y - Other.Y));
end;

class function TPoint.Origin: TPoint;
begin
  Result.X := 0;
  Result.Y := 0;
end;

Advanced records require {$mode objfpc}` or `{$mode delphi} with FPC 2.6+.

Variant Record

type
  TShapeKind = (skCircle, skRect);

  TShape = record
    X, Y: Double;
    case Kind: TShapeKind of
      skCircle: (Radius: Double);
      skRect:   (Width, Height: Double);
  end;

The with Statement

with S do
begin
  Name := 'Bob';
  Age := 22;
  GPA := 3.50;
end;

Use with sparingly. In complex code it can obscure which record a field belongs to, making maintenance harder.


A.9 Sets and Enumerations

Enumerations

type
  TDay = (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
  TSeason = (Spring, Summer, Autumn, Winter);

var
  Today: TDay;
begin
  Today := Wednesday;
  WriteLn(Ord(Today));        { 2 (zero-based) }
  WriteLn(Succ(Today));       { Thursday }
  WriteLn(Pred(Today));       { Tuesday }
end;

Sets

type
  TDaySet = set of TDay;

var
  Weekend, WorkDays: TDaySet;
begin
  Weekend := [Saturday, Sunday];
  WorkDays := [Monday..Friday];

  if Today in Weekend then
    WriteLn('Relax!')
  else
    WriteLn('Work!');
end;

Sets can be based on any ordinal type with no more than 256 possible values (ordinal values 0..255).

type
  TCharSet = set of Char;
  TByteSet = set of Byte;

var
  Vowels: TCharSet;
begin
  Vowels := ['A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o', 'u'];
  if Ch in Vowels then
    WriteLn('Vowel');
end;

A.10 Pointers

Typed Pointers

type
  PInteger = ^Integer;

var
  P: PInteger;
  X: Integer;
begin
  X := 42;
  P := @X;                { P points to X }
  WriteLn(P^);            { 42 — dereference }
  P^ := 100;              { X is now 100 }
end;

Dynamic Allocation

var
  P: PInteger;
begin
  New(P);                 { Allocate memory for one Integer }
  P^ := 42;
  WriteLn(P^);
  Dispose(P);             { Free memory }
  P := nil;               { Good practice }
end;

Untyped Pointers

var
  P: Pointer;
begin
  GetMem(P, 1024);        { Allocate 1024 bytes }
  FillChar(P^, 1024, 0);  { Zero the memory }
  FreeMem(P, 1024);       { Free it }
end;

PChar (Null-Terminated Strings)

var
  S: String;
  P: PChar;
begin
  S := 'Hello';
  P := PChar(S);           { Convert String to PChar }
  WriteLn(P);
end;

A.11 Files

Text Files

var
  F: TextFile;
  Line: String;
begin
  AssignFile(F, 'data.txt');

  { Writing }
  Rewrite(F);
  WriteLn(F, 'First line');
  WriteLn(F, 'Second line');
  CloseFile(F);

  { Reading }
  Reset(F);
  while not Eof(F) do
  begin
    ReadLn(F, Line);
    WriteLn(Line);
  end;
  CloseFile(F);

  { Appending }
  Append(F);
  WriteLn(F, 'Appended line');
  CloseFile(F);
end;

Typed Files

type
  TRecord = record
    ID: Integer;
    Name: String[50];
  end;

var
  F: file of TRecord;
  Rec: TRecord;
begin
  AssignFile(F, 'data.dat');
  Rewrite(F);
  Rec.ID := 1;
  Rec.Name := 'Alice';
  Write(F, Rec);
  CloseFile(F);

  Reset(F);
  while not Eof(F) do
  begin
    Read(F, Rec);
    WriteLn(Rec.ID, ': ', Rec.Name);
  end;
  CloseFile(F);
end;

Untyped Files

var
  F: file;
  Buffer: array[0..1023] of Byte;
  BytesRead: Integer;
begin
  AssignFile(F, 'binary.dat');
  Reset(F, 1);                      { Record size = 1 byte }
  BlockRead(F, Buffer, SizeOf(Buffer), BytesRead);
  CloseFile(F);
end;

File Utility Routines

Routine Description
FileExists(FileName) Returns True if file exists
DeleteFile(FileName) Deletes a file
RenameFile(Old, New) Renames a file
DirectoryExists(Dir) Returns True if directory exists
CreateDir(Dir) Creates a directory
GetCurrentDir Returns current working directory
ExtractFileName(Path) Filename from full path
ExtractFileExt(Path) Extension from full path
ExtractFilePath(Path) Directory from full path
ChangeFileExt(FN, Ext) Changes a filename's extension

A.12 Object-Oriented Programming

Class Declaration

type
  TAnimal = class
  private
    FName: String;
    FAge: Integer;
  protected
    procedure SetAge(AValue: Integer);
  public
    constructor Create(const AName: String; AAge: Integer);
    destructor Destroy; override;
    procedure Speak; virtual; abstract;
    property Name: String read FName;
    property Age: Integer read FAge write SetAge;
  end;

Constructor and Destructor

constructor TAnimal.Create(const AName: String; AAge: Integer);
begin
  inherited Create;
  FName := AName;
  FAge := AAge;
end;

destructor TAnimal.Destroy;
begin
  { Clean up resources }
  inherited Destroy;
end;

Inheritance

type
  TDog = class(TAnimal)
  private
    FBreed: String;
  public
    constructor Create(const AName: String; AAge: Integer; const ABreed: String);
    procedure Speak; override;
    property Breed: String read FBreed;
  end;

constructor TDog.Create(const AName: String; AAge: Integer; const ABreed: String);
begin
  inherited Create(AName, AAge);
  FBreed := ABreed;
end;

procedure TDog.Speak;
begin
  WriteLn(Name, ' says: Woof!');
end;

Interfaces

type
  ISerializable = interface
    ['{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}']
    function Serialize: String;
    procedure Deserialize(const AData: String);
  end;

  TConfig = class(TInterfacedObject, ISerializable)
  public
    function Serialize: String;
    procedure Deserialize(const AData: String);
  end;

Visibility Specifiers

Specifier Access
private Same class only (FPC: same unit in {$mode delphi})
strict private Same class only (never visible to other code in unit)
protected Same class and descendants
strict protected Same class and descendants only
public Accessible from anywhere
published Like public + RTTI (for streaming/IDE)

Properties

type
  TCircle = class
  private
    FRadius: Double;
    function GetArea: Double;
  public
    property Radius: Double read FRadius write FRadius;
    property Area: Double read GetArea;      { Read-only }
  end;

function TCircle.GetArea: Double;
begin
  Result := Pi * FRadius * FRadius;
end;

A.13 Generics

Generic Classes (objfpc Mode)

type
  generic TStack<T> = class
  private
    FItems: array of T;
    FCount: Integer;
  public
    procedure Push(const AItem: T);
    function Pop: T;
    function Peek: T;
    property Count: Integer read FCount;
  end;

procedure TStack.Push(const AItem: T);
begin
  if FCount >= Length(FItems) then
    SetLength(FItems, FCount * 2 + 4);
  FItems[FCount] := AItem;
  Inc(FCount);
end;

function TStack.Pop: T;
begin
  Dec(FCount);
  Result := FItems[FCount];
end;

function TStack.Peek: T;
begin
  Result := FItems[FCount - 1];
end;

Specialization (objfpc Mode)

type
  TIntStack = specialize TStack<Integer>;
  TStringStack = specialize TStack<String>;

var
  Stack: TIntStack;
begin
  Stack := TIntStack.Create;
  Stack.Push(10);
  Stack.Push(20);
  WriteLn(Stack.Pop);     { 20 }
  Stack.Free;
end;

Generic Functions

generic function Min<T>(A, B: T): T;
begin
  if A < B then Result := A else Result := B;
end;

WriteLn(specialize Min<Integer>(3, 7));

A.14 Exception Handling

Try/Except

try
  X := StrToInt(Input);
  Result := 100 div X;
except
  on E: EConvertError do
    WriteLn('Invalid number: ', E.Message);
  on E: EDivByZero do
    WriteLn('Cannot divide by zero');
  on E: Exception do
    WriteLn('Unexpected error: ', E.Message);
end;

Try/Finally

Stream := TFileStream.Create('data.bin', fmOpenRead);
try
  { Work with stream }
  Stream.Read(Buffer, SizeOf(Buffer));
finally
  Stream.Free;                { Always executes }
end;

Raising Exceptions

if Age < 0 then
  raise EArgumentException.Create('Age cannot be negative');

raise EMyCustomError.CreateFmt('Invalid value: %d', [Value]);

Common Exception Classes

Class Raised When
Exception Base class for all exceptions
EConvertError Type conversion failure
ERangeError Value out of range (with {$R+})
EDivByZero Integer division by zero
EInvalidOp Invalid floating-point operation
EOverflow Arithmetic overflow
EAccessViolation Invalid memory access (nil pointer, etc.)
EInOutError File I/O error
EOutOfMemory Memory allocation failure
EAbstractError Abstract method called
EAssertionFailed Assert condition failed
EStringListError TStringList index error

A.15 Units

Using Units

uses
  SysUtils,     { String/date/file utilities }
  Classes,      { TList, TStringList, TStream, etc. }
  Math,         { Extended math functions }
  StrUtils,     { Additional string functions }
  DateUtils,    { Date/time utilities }
  TypInfo,      { RTTI }
  Generics.Collections;  { TList<T>, TDictionary<K,V> in Delphi mode }

Commonly Used Units

Unit Contents
System Auto-included. WriteLn, Read, basic types, memory
SysUtils Format, IntToStr, FileExists, Now, exceptions
Classes TList, TStringList, TStream, TComponent, TThread
Math Max, Min, Power, Log, Sin, Cos, statistical functions
StrUtils ContainsStr, ReplaceStr, SplitString, StartsStr
DateUtils DaysBetween, IncMonth, DateTimeToUnix
FileUtil Lazarus file utilities (cross-platform)
LazFileUtils Additional Lazarus file path utilities
fgl Free Pascal generic list (TFPGList, TFPGMap)

A.16 Compiler Directives

Mode Directives

{$mode objfpc}       { Free Pascal's OOP mode (recommended for new code) }
{$mode delphi}       { Delphi compatibility mode }
{$mode fpc}          { Traditional Free Pascal mode }
{$mode tp}           { Turbo Pascal 7 compatibility }
{$mode macpas}       { Mac Pascal compatibility }

Common Switches

Directive Effect
{$H+}` / `{$H-} AnsiString / ShortString as default String
{$R+}` / `{$R-} Range checking on / off
{$Q+}` / `{$Q-} Overflow checking on / off
{$I+}` / `{$I-} I/O checking on / off
{$B+}` / `{$B-} Full boolean evaluation / Short-circuit evaluation
{$J+}` / `{$J-} Typed constants writable / read-only
{$S+}` / `{$S-} Stack checking on / off
{$T+}` / `{$T-} Typed @ operator / Untyped @ operator
{$INLINE ON} Enable inline expansion
{$OPTIMIZATION ON} Enable optimizations
{$INTERFACES CORBA} Use CORBA-style interfaces (no ref counting)
{$INTERFACES COM} Use COM-style interfaces (ref counting, default)

Conditional Compilation

{$IFDEF WINDOWS}
  uses Windows;
{$ENDIF}

{$IFDEF LINUX}
  uses Unix;
{$ENDIF}

{$IF FPC_VERSION >= 3}
  { Code for FPC 3.x and later }
{$ENDIF}

{$DEFINE DEBUG}
{$IFDEF DEBUG}
  WriteLn('Debug mode active');
{$ENDIF}

Include Files

{$I myinclude.inc}        { Include a file }
{$INCLUDE settings.inc}   { Same, long form }

A.17 Useful Built-in Functions Quick Table

String Functions

Function Description Example
Length(S) String length Length('abc') = 3
Copy(S, Pos, Len) Substring Copy('Hello', 1, 3) = 'Hel'
Pos(Sub, S) Find substring Pos('ll', 'Hello') = 3
Concat(S1, S2, ...) Concatenate Concat('A', 'B') = 'AB'
UpperCase(S) To uppercase UpperCase('hi') = 'HI'
LowerCase(S) To lowercase LowerCase('HI') = 'hi'
Trim(S) Strip whitespace Trim(' hi ') = 'hi'
IntToStr(N) Integer to string IntToStr(42) = '42'
StrToInt(S) String to integer StrToInt('42') = 42
FloatToStr(X) Float to string FloatToStr(3.14) = '3.14'
StrToFloat(S) String to float StrToFloat('3.14') = 3.14
Format(Fmt, Args) Formatted string Format('%s is %d', ['Age', 30])
StringReplace(S, Old, New, Flags) Replace StringReplace('aabbcc', 'bb', 'xx', [])

Math Functions

Function Description
Abs(X) Absolute value
Sqr(X) Square (X*X)
Sqrt(X) Square root
Round(X) Round to nearest integer
Trunc(X) Truncate toward zero
Frac(X) Fractional part
Int(X) Integer part (as Real)
Sin(X), Cos(X), Tan(X) Trig (radians)
ArcTan(X) Inverse tangent
Ln(X) Natural log
Exp(X) e^X
Power(Base, Exp) Base^Exp (uses Math)
Random(N) Random integer 0..N-1
Random Random real 0..1
Randomize Seed from clock

Ordinal Functions

Function Description
Ord(X) Ordinal value
Chr(N) Character from ordinal
Succ(X) Next value
Pred(X) Previous value
Inc(X) / Inc(X, N) Increment
Dec(X) / Dec(X, N) Decrement
Low(X) Lowest value of type/array
High(X) Highest value of type/array

This reference covers the most commonly used features of Free Pascal. For complete documentation, consult the Free Pascal Reference Guide and the Free Pascal Programmer's Guide.