Statements

# Statements

In this chapter, we deal with the statements of Pascal. These statements control most of the actions performed by a program.

Note that Alice can only handle lines shorter than 256 characters. If you have a very long line, you will have to break it up into smaller pieces.

## Comments

Comments are not really statements at all, but it is convenient to deal with them at this time. Comments are enclosed in brace brackets. Everything between the "{" and the "}" is ignored.

Because of Alice's tight structure, comments may only appear in two places: as part of a template (where they are included automatically) and on a line all on their own. If you have a comment that extends over several lines, each line must be enclosed in brace brackets, as in

>     {    This}
>     {    is}
>     {    a}
>     {    comment!}

## The Assignment Statement

The most basic statement type in Pascal is the assignment. It has the form

variable := expression

where the type of expression is assignment-compatible with the type of variable. An assignment statement stores the value of the expression in the given variable.

You may not assign values to variables that have a file type, or records or arrays that contain a file type.

If a string value (constant or variable) is assigned to a variable of a string type, the result depends on the relative lengths of the two strings. If you assign a longer string to a shorter one, the assigned string will be truncated to the appropriate length. For example, if `str3` is a string variable of length `3`,

>     str3 := 'abcde';

stores the string `"abc"` in `str3`.

If you assign a shorter string to a longer one, the characters of the shorter string are placed in the longer string, and then the special `StrEnd` character is placed after the last character to mark the end of the string. For example, if `str5` is a string of length `5`,

>     str5 := 'abc';

gives `str5` the following elements.

>     str5[1] = 'a'
>     str5[2] = 'b'
>     str5[3] = 'c'
>     str5[4] = StrEnd
>     str5[5] is undefined

Alice also lets you assign string constants to `Pointer` variables. The string is created in memory and the `Pointer` variable receives a pointer to the first character in the string. For example, you might write

>     type
>         str10 = packed array [1..10] of char;
>     var
>         p : Pointer;
>         sp : ^str10;
>     begin
>     p := 'SMILE!';
>     sp := p;
>     writeln(sp^[1]);

This will write out the letter `S`.

You can also assign variables of type `String` to `Pointer` variables; the resulting pointer points at the first character of the string (not at the 0th element).

The assignment statement is also used in functions (subprograms that return values to their callers). The function indicates its return value by assigning the value to the name of the function. For example, in a function called `func`

>     func := 3;

means that the function should return the value `3`. The type of the value assigned to the function name should be assignment compatible with the type declared for the function.

This sort of assignment does not cause the function to return immediately. The function may have several statements that assign values to the function name. The return value for the function will be the last value that was assigned to the function name.

## Procedure Calls

A procedure call is another common kind of statement. The general form of a procedure call is

procname( argument,argument,... )

where procname is the name of the procedure that is being called. If no arguments are being passed to the procedure, the parentheses are omitted, as in

>     writeln;

Chapter 6 discusses function calls in more detail.

## The goto Statement

The goto statement can be used to jump to a labelled statement. The label must be a positive integer constant that has been declared in the label declaration section of the program or subprogram that contains the goto. (Note that the label cannot be a constant expression or a variable.) A typical goto statement might be

>     goto 12;

The scope of a label is the subprogram in which it was defined. It is not possible to jump from a subprogram into an entirely separate subprogram. However, if one subprogram is declared inside another subprogram, you may jump out of the inner subprogram to the outer -- simply declare a label in the outside subprogram and the scope of the label will include the inner subprogram.

You cannot jump into a begin block or any statement whose template contains a begin block. You can, however, jump out of a begin block, provided that you are not superstepping or using Alice's EXECUTE command.

## Structured Statements

The statements we have discussed up to this point were simple statements. The ones that follow are known as structured statements. Structured statements are ones that can contain other statements.

### Compound Statements

A compound statement is made up of one or more other statements. A compound statement may be used anywhere a simple statement may be used.

Compound statements start with the keyword begin and end with the keyword end. Statements inside a compound statement are separated with semicolons. The standard form of a compound statement is

begin

statement;

statement;

statement;

...

statement

end

(Note that the block can contain a single statement as well as a number of statements.)

Normally, compound statements are not used explicitly in Alice, since all structured statements automatically contain a compound statement. This is shown in the sections that follow.

### The if Statement

There are two forms of the Pascal if statement. The first is

>     if Condition then begin
>         Statement
>         Statement
>               ...
>         Statement
>         end;

The `Condition` is a `Boolean` expression. If the result is `true`, the statement(s) in the begin block are executed. If the result is `false`, Alice will skip to whatever follows the end of the block. For example,

>     if A > B then begin
>         C := A;
>         end;

will do the assignment `C:=A` if `A` is greater than `B`. If `A` is not greater than `B`, control will skip to whatever follows the end.

The second form of the if statement is

>     if Condition then begin
>         Statement
>           ...
>         end
>      else begin
>         Statement
>           ...
>         end;

Again, the `Condition` is a `Boolean` expression. If this result is `true`, the statement(s) in the first begin block are executed. If the result is `false`, the statements in the second begin block are executed.

You may nest ifs and elses if you wish. Alice will show how ifs and elses pair up by indentation.

### The case Statement

The case statement contains several blocks of code. It decides which of these blocks should be executed by looking at the value of an expression. The statement has the form

>     case Value of
>         Case-Instance
>         Case-Instance
>         Case-Instance
>             ...
>         Case-Instance
>         end;

The `Case-Instance` blocks take the form

>     Constant : begin
>         Statement
>         end;

or

>     Constant, Constant, ... : begin
>         Statement
>         Statement
>             ...
>         Statement
>         end;

or

>     Constant..Constant: begin
>         Statement
>         Statement
>             ...
>         Statement
>         end;

The first step in executing the case statement is to evaluate the `Value` that follows the keyword case. This expression may have any scalar type.

The next step is to see if the result of the expression matches any of the constants that begin individual case instances. These constants are known as case labels. The case label values must be of the same scalar type as the expression that follows the keyword case. The result of this expression matches a case label if it is equal to one of the constant values given in the label, or if it falls in the range of a

>     Constant..Constant

form. The first time that a case label matches the result of the expression, the begin block following the case label will be executed. Once this statement has been executed, Alice will jump to whatever follows the end that marks the end of the whole case statement.

As a simple example, suppose the variable `i` is a `integer` variable.

>     case i%3 of
>       0 : begin
>           writeln('Number is multiple of three');
>           end;
>       1,2 : begin
>           writeln('Number is not a multiple of three');
>           end;
>       end;

This code determines whether `i` is an even multiple of three and prints out the result.

In addition to normal case instances, every case statement can contain a special case instance of the form

>     else begin
>         Statement
>         Statement
>             ...
>         Statement
>         end;

The begin block in this case instance is executed if the case expression does not match any of the other case labels. For example, you might have

>     case c of
>       'a'..'z' : begin
>           writeln('Lower case');
>           end;
>       'A'..'Z' : begin
>           writeln('Upper case');
>           end;
>       else begin
>           writeln('Not a letter');
>           end;
>       end;

If `c` is an upper or lower case letter, an appropriate message is printed. Otherwise, the `Not a letter` message is printed.

The else does not have to be the last in the list of cases. If a case statement has two else clauses, you will be given an error message when you run the program. If a case statement has no else clause and the case expression value does not match any of the case labels, you will also be given an error at run-time.

### The while Statement

The while statement has the form

>     while Condition do begin
>         Statement
>         Statement
>             ...
>         Statement
>         end;

The `Condition` is a `Boolean` expression. The statements in the begin block will be executed over and over again as long as the condition is `true` at the beginning of the block. The looping stops when the condition is found to be `false` at the beginning of the block. For example,

>     i := 1;
>     while arr[i] > 0 do begin
>         i := i + 1;
>         end;

begins with the index `i` at `1` and loops until it finds an element of the array `arr` that is less than or equal to zero.

If the expression at the beginning of the while loop is `false` to begin with, the begin block is not executed. In the example above, if `arr1` was not greater than `0`, the statement inside the while loop would not even be executed once.

### The repeat Statement

The repeat statement is similar to the while statement. It has the form

>     repeat
>         Statement
>         Statement
>         Statement
>             ...
>         Statement
>     until Condition;

The `Condition` is a `Boolean` expression. The statements between the repeat and until will be repeated until the result of the condition is `true` at the end of an execution of the block.

The statements between repeat and until will always be executed at least once -- the condition is tested after the statements have been executed, unlike while, where the condition is tested before the statements are executed. For example, in

>     i := 0;
>     repeat
>         i := i + 1
>     until arr[i] <= 0;

the assignment incrementing `i` will always be executed at least once.

### The for Statement

The for statement is another way of repeating a block of statements. It has the form

>     for variable := start to finish do begin
>         Statement
>         Statement
>         Statement
>             ...
>         Statement
>         end;

The `variable` is called the control variable of the for loop. It may have any scalar type. The expressions `start` and `finish` must have the same scalar type.

The first step in executing the for statement is comparing the expressions `start` and `finish`. If `start` is greater than `finish`, the begin block that comes after the keyword do will not be executed at all.

If `start` is less than or equal to `finish`, the value of `start` will be assigned to the control variable. The begin block after the do will then be executed. When the statement is finished, Alice will change the value of the control variable to its successor using the `succ` function and the statement will be executed again. (The `succ` function is described in Chapter 8.) This process will be repeated, until Alice has finished executing the statement with the control variable having the value given by `finish`. When this is finished, Alice will go on to whatever follows the end of the for loop block.

As an example,

>     for i := 1 to 10 do begin
>         arr[i] := 0;
>         end;

zeroes the first `10` elements of an array `arr`. The statement after do is executed once for every value of `i` between `1` and `10` (inclusive).

At the end of a for loop, the value of the control variable is undefined. If control passes out of the loop by means of a goto, the value of the control variable will be whatever it was when the goto was encountered.

The for statement can also be written as

>     for variable := start downto finish do begin
>         Statement
>         Statement
>         Statement
>             ...
>         Statement
>         end;

In this case, `start` should be greater than `finish`. The control variable begins at `start` and goes down step by step (using the `pred` function) until it reaches `finish`. (The `pred` function is described in Chapter 8.) Apart from this, the downto form is the same as the to form.

You should not assign values to the control variable inside a for block, and you may not pass the control variable as a var argument to a subprogram.

### The with Statement

The with statement is used to simplify work with record variables. It has the form

>     with record-variable do begin
>         Statement
>         Statement
>         Statement
>             ...
>         Statement
>         end;

Inside a with block, you can refer to fields of the given record variable without putting the usual

>     record-variable.

prefix in front of them. For example, suppose we have declared

    type
        personnel = record
                        name : packed array [1..40] of char;
                        empno, age : integer;
                        income : real
                    end;
    var
        Bob, Rick, Nancy : personnel;

We might have a with statement of the form

>     with Bob do begin
>         name := 'Bob Jones';
>         age := 35;
>         income := 30000.00
>         end;

This is equivalent to

>     begin
>         Bob.name := 'Bob Jones';
>         Bob.age := 35;
>         Bob.income := 30000.00
>         end;

Inside the with statement, we can use field names without the usual prefix. If a field name happens to be the same as the name of another variable, the reference inside the with statement will always be to the field, not the variable with the same name.

Note that some versions of Pascal let you write

>     with A,B do ...

to represent

>     with A do begin
>         with B do begin...

The abbreviated form is not used in Alice. However, the APIN program recognizes the form and will convert it properly if you are reading in a program for some other version of Pascal.