Subsections

- 1 Simple statements
  - 1 Assignments
  - 2 Procedure statements
  - 3 Goto statements
- 2 Structured statements
  - 1 Compound statements
  - 2 The `Case` statement
  - 3 The `If..then..else` statement
  - 4 The `For..to/downto..do` statement
  - 5 The `Repeat..until` statement
  - 6 The `While..do` statement
  - 7 The `With` statement
  - 8 Exception Statements
- 3 Assembler statements

#
7 Statements

The heart of each algorithm are the actions it takes. These actions are contained in the statements of a program or unit. Each statement can be labeled and jumped to (within certain limits) with `Goto` statements. This can be seen in the following syntax diagram:

> Statements

A label can be an identifier or an integer digit.

# 1 Simple statements

A simple statement cannot be decomposed in separate statements. There are basically 4 kinds of simple statements:

> Simple statements

Of these statements, the raise statement will be explained in the chapter on Exceptions (chapter Exceptions)

## 1 Assignments

Assignments give a value to a variable, replacing any previous value the variable might have had:

> Assignments

In addition to the standard Pascal assignment operator (`:=` ), which simply replaces the value of the varable with the value resulting from the expression on the right of the := operator, Free Pascal supports some c-style constructions. All available constructs are listed in table (assignments) .

Table: Allowed C constructs in Free Pascal
Assignment | Result
a += b | Adds `b` to `a`, and stores the result in `a`.
a -= b | Substracts `b` from `a`, and stores the result in `a`.
a *= b | Multiplies `a` with `b`, and stores the result in `a`.
a /= b | Divides `a` through `b`, and stores the result in `a`.

For these constructs to work, the `-Sc` command-line switch must be specified.

Remark: These constructions are just for typing convenience, they don't generate different code. Here are some examples of valid assignment statements:

    X := X+Y;
    X+=Y;      { Same as X := X+Y, needs -Sc command line switch}
    X/=2;      { Same as X := X/2, needs -Sc command line switch}
    Done := False;
    Weather := Good;
    MyPi := 4* Tan(1);

## 2 Procedure statements

Procedure statements are calls to subroutines. There are different possibilities for procedure calls: A normal procedure call, an object method call (fully qualified or not), or even a call to a procedural type variable. All types are present in the following diagram.

> Procedure statements

The Free Pascal compiler will look for a procedure with the same name as given in the procedure statement, and with a declared parameter list that matches the actual parameter list. The following are valid procedure statements:

    Usage;
    WriteLn('Pascal is an easy language !');
    Doit();

## 3 Goto statements

Free Pascal supports the `goto` jump statement. Its prototype syntax is

> Goto statement

When using `goto` statements, the following must be kept in mind:

1. The jump label must be defined in the same block as the `Goto` statement.
2. Jumping from outside a loop to the inside of a loop or vice versa can have strange effects.
3. To be able to use the `Goto` statement, the `-Sg` compiler switch must be used.

`Goto` statements are considered bad practice and should be avoided as much as possible. It is always possible to replace a `goto` statement by a construction that doesn't need a `goto`, although this construction may not be as clear as a goto statement. For instance, the following is an allowed goto statement:

    label
      jumpto;
    ...
    Jumpto :
      Statement;
    ...
    Goto jumpto;
    ...

# 2 Structured statements

Structured statements can be broken into smaller simple statements, which should be executed repeatedly, conditionally or sequentially:

> Structured statements

Conditional statements come in 2 flavours :

> Conditional statements

Repetitive statements come in 3 flavours:

> Repetitive statements

The following sections deal with each of these statements.

## 1 Compound statements

Compound statements are a group of statements, separated by semicolons, that are surrounded by the keywords `Begin` and `End`. The Last statement doesn't need to be followed by a semicolon, although it is allowed. A compound statement is a way of grouping statements together, executing the statements sequentially. They are treated as one statement in cases where Pascal syntax expects 1 statement, such as in `if ... then` statements.

> Compound statements

## 2 The `Case` statement

Free Pascal supports the `case` statement. Its syntax diagram is

> Case statement

The constants appearing in the various case parts must be known at compile-time, and can be of the following types : enumeration types, Ordinal types (except boolean), and chars. The expression must be also of this type, or a compiler error will occur. All case constants must have the same type. The compiler will evaluate the expression. If one of the case constants values matches the value of the expression, the statement that follows this constant is executed. After that, the program continues after the final `end`. If none of the case constants match the expression value, the statement after the `else` keyword is executed. This can be an empty statement. If no else part is present, and no case constant matches the expression value, program flow continues after the final `end`. The case statements can be compound statements (i.e. a `begin..End` block).

Remark: Contrary to Turbo Pascal, duplicate case labels are not allowed in Free Pascal, so the following code will generate an error when compiling:

    Var i : integer;
    ...
    Case i of
     3 : DoSomething;
     1..5 : DoSomethingElse;
    end;

The compiler will generate a `Duplicate case label` error when compiling this, because the 3 also appears (implicitly) in the range `1..5`. This is similar to Delphi syntax.

The following are valid case statements:

    Case C of
     'a' : WriteLn ('A pressed');
     'b' : WriteLn ('B pressed');
     'c' : WriteLn ('C pressed');
    else
      WriteLn ('unknown letter pressed : ',C);
    end;

Or

    Case C of
     'a','e','i','o','u' : WriteLn ('vowel pressed');
     'y' : WriteLn ('This one depends on the language');
    else
      WriteLn ('Consonant pressed');
    end;

    Case Number of
     1..10   : WriteLn ('Small number');
     11..100 : WriteLn ('Normal, medium number');
    else
     WriteLn ('HUGE number');
    end;

## 3 The `If..then..else` statement

The `If .. then .. else..` prototype syntax is

> If then statements

The expression between the `if` and `then` keywords must have a boolean return type. If the expression evaluates to `True` then the statement following `then` is executed.

If the expression evaluates to `False`, then the statement following `else` is executed, if it is present.

Be aware of the fact that the boolean expression will be short-cut evaluated. (Meaning that the evaluation will be stopped at the point where the outcome is known with certainty) Also, before the `else` keyword, no semicolon (`;`) is allowed, but all statements can be compound statements. In nested `If.. then .. else` constructs, some ambiguity may araise as to which `else` statement pairs with which `if` statement. The rule is that the `else` keyword matches the first `if` keyword not already matched by an `else` keyword. For example:

    If exp1 Then
      If exp2 then
        Stat1
    else
      stat2;

Despite it's appearance, the statement is syntactically equivalent to

    If exp1 Then
       begin
       If exp2 then
          Stat1
       else
          stat2
       end;

and not to

    { NOT EQUIVALENT }
    If exp1 Then
       begin
       If exp2 then
          Stat1
       end
    else
       stat2

If it is this latter construct is needed, the `begin` and `end` keywords must be present. When in doubt, it is better to add them.

The following is a valid statement:

    If Today in [Monday..Friday] then
      WriteLn ('Must work harder')
    else
      WriteLn ('Take a day off.');

## 4 The `For..to/downto..do` statement

Free Pascal supports the `For` loop construction. A for loop is used in case one wants to calculated something a fixed number of times. The prototype syntax is as follows:

> For statement

`Statement` can be a compound statement. When this statement is encountered, the control variable is initialized with the initial value, and is compared with the final value. What happens next depends on whether `to` or `downto` is used:

1. In the case `To` is used, if the initial value larger than the final value then `Statement` will never be executed.
2. In the case `DownTo` is used, if the initial value larger than the final value then `Statement` will never be executed.

After this check, the statement after `Do` is executed. After the execution of the statement, the control variable is increased or decreased with 1, depending on whether `To` or `Downto` is used. The control variable must be an ordinal type, no other types can be used as counters in a loop.

Remark: Contrary to ANSI pascal specifications, Free Pascal first initializes the counter variable, and only then calculates the upper bound.

The following are valid loops:

    For Day := Monday to Friday do Work;
    For I := 100 downto 1 do
      WriteLn ('Counting down : ',i);
    For I := 1 to 7*dwarfs do KissDwarf(i);

If the statement is a compound statement, then the Break and Continue reserved words can be used to jump to the end or just after the end of the `For` statement.

## 5 The `Repeat..until` statement

The `repeat` statement is used to execute a statement until a certain condition is reached. The statement will be executed at least once. The prototype syntax of the `Repeat..until` statement is

> Repeat statement

This will execute the statements between `repeat` and `until` up to the moment when `Expression` evaluates to `True`. Since the `expression` is evaluated after the execution of the statements, they are executed at least once. Be aware of the fact that the boolean expression `Expression` will be short-cut evaluated. (Meaning that the evaluation will be stopped at the point where the outcome is known with certainty) The following are valid `repeat` statements

    repeat
      WriteLn ('I =',i);
      I := I+2;
    until I>100;
    repeat
     X := X/2
    until x<10e-3

The Break and Continue reserved words can be used to jump to the end or just after the end of the `repeat .. until` statement.

## 6 The `While..do` statement

A `while` statement is used to execute a statement as long as a certain condition holds. This may imply that the statement is never executed. The prototype syntax of the `While..do` statement is

> While statements

This will execute `Statement` as long as `Expression` evaluates to `True`. Since `Expression` is evaluated before the execution of `Statement`, it is possible that `Statement` isn't executed at all. `Statement` can be a compound statement. Be aware of the fact that the boolean expression `Expression` will be short-cut evaluated. (Meaning that the evaluation will be stopped at the point where the outcome is known with certainty) The following are valid `while` statements:

    I := I+2;
    while i<=100 do
      begin
      WriteLn ('I =',i);
      I := I+2;
      end;
    X := X/2;
    while x>=10e-3 do
      X := X/2;

They correspond to the example loops for the `repeat` statements.

If the statement is a compound statement, then the Break and Continue reserved words can be used to jump to the end or just after the end of the `While` statement.

##
7 The `With` statement

The `with` statement serves to access the elements of a record or object or class, without having to specify the name of the each time. The syntax for a `with` statement is

> With statement

The variable reference must be a variable of a record, object or class type. In the `with` statement, any variable reference, or method reference is checked to see if it is a field or method of the record or object or class. If so, then that field is accessed, or that method is called. Given the declaration:

    Type Passenger = Record
           Name : String[30];
           Flight : String[10];
           end;
    Var TheCustomer : Passenger;

The following statements are completely equivalent:

    TheCustomer.Name := 'Michael';
    TheCustomer.Flight := 'PS901';

and

    With TheCustomer do
      begin
      Name := 'Michael';
      Flight := 'PS901';
      end;

The statement

    With A,B,C,D do Statement;

is equivalent to

    With A do
     With B do
      With C do
       With D do Statement;

This also is a clear example of the fact that the variables are tried last to first, i.e., when the compiler encounters a variable reference, it will first check if it is a field or method of the last variable. If not, then it will check the last-but-one, and so on. The following example shows this;

    Program testw;
    Type AR = record
          X,Y : Longint;
         end;
         PAR = Record;

    Var S,T : Ar;
    begin
      S.X := 1;S.Y := 1;
      T.X := 2;T.Y := 2;
      With S,T do
        WriteLn (X,' ',Y);
    end.

The output of this program is

    2 2

Showing thus that the `X,Y` in the `WriteLn` statement match the `T` record variable.

Remark: When using a `With` statement with a pointer, or a class, it is not permitted to change the pointer or the class in the `With` block. With the definitions of the previous example, the following illustrates what it is about:

    Var p : PAR;

    begin
      With P^ do
       begin
       // Do some operations
       P:=OtherP;
       X:=0.0;  // Wrong X will be used !!
       end;

The reason the pointer cannot be changed is that the address is stored by the compiler in a temporary register. Changing the pointer won't change the temporary address. The same is true for classes.

## 8 Exception Statements

Free Pascal supports exceptions. Exceptions provide a convenient way to program error and error-recovery mechanisms, and are closely related to classes. Exception support is explained in chapter Exceptions

# 3 Assembler statements

An assembler statement allows to insert assembler code right in the pascal code.

> Assembler statements

More information about assembler blocks can be found in the Programmers' guide. The register list is used to indicate the registers that are modified by an assembler statement in the assembler block. The compiler stores certain results in the registers. If the registers are modified in an assembler statement, the compiler should, sometimes, be told about it. The registers are denoted with their Intel names for the I386 processor, i.e., `'EAX'`, `'ESI'` etc... As an example, consider the following assembler code:

    asm
      Movl $1,%ebx
      Movl $0,%eax
      addl %eax,%ebx
    end; ['EAX','EBX'];

This will tell the compiler that it should save and restore the contents of the `EAX` and `EBX` registers when it encounters this asm statement.

Free Pascal supports various styles of assembler syntax. By default, `AT&T` syntax is assumed for the 80386 and compatibles platform. The default assembler style can be changed with the `{$asmmode xxx}` switch in the code, or the `-R` command-line option. More about this can be found in the Programmers' guide.