6.2 Statements

A statement describes a specific action that may be executed by the computer. Such an action may be a simple action or consist of a sequence of actions. We have the following kind of statements assignments, conditional statements, loop statements, break statements, method invocations, and object instantiation.

Some of the statements are primitives of the qBeta language and others are defined in the qBeta library. We return to this is in the last section on this chapter.

The assignment statement

In the previous chapters, the assignment statement has been used to describe actions carried out by methods like addInterest, deposit and withdraw. The assignment statement has the form:

VariableDataItem := Expression 

The left side of the statement must be the name of a variable data-item such as balance defined within the various descriptions of accounts. A variable data-item is declared using var or ref.

The right-side of the statement is an expression which describes the computation of a datum. An expression may be an arithmetic expression like balance - amount, as described in the previous section. This expression evaluates to a primitive value of type float. In the statement below, assigns this value the integer variable balance:

balance := balance + amount

Conditional statements

Sometimes the actions of a method depends on the values of data-items of the object or other conditions. One example is withdraw where you may not be able to withdraw an amount that is greater than the balance. We may describe this using a conditional statement like an if:then statement or an if:then:else-statement.

The if:then statement

An if:then statement describes a conditional execution of a sequence of items. An example of an if:then statement is shown in section . It has the form:

if (condition) :then
   thenPart

The condition is a boolean expression that evaluates to ether true or false. The thenPart clause consists of a sequence of items and as mentioned, an item may be a declaration or a statement. The thenPart is only executed if the condition evaluates to true.

The if:then:else statement

An if:then:else statement describes a conditional execution selecting between two sequences of items and it has the form:

if (condition) :then
   thenPart
:else
   elsePart

As for the if:then statement, the condition must be an expression that evaluates to the Boolean value true or false. The clauses thenPart and elsePart are both a sequence of items. If the condition evaluates to true, then the items describe by thenPart are executed. Otherwise the items described by elsePart are executed.

An example of an if:then:else statement is given in section where the body of withdraw has an if:then:else statement:

class Account(owner: ref Customer):
   balance: var float;
   ...
   withdraw(amount: var float) -> newB: var float:
      if (amount <= balance) :then
         balance := balance - amount
      :else
         console.print("The balance is less than the amount")
      newB := balance 

In the example, the condition is amount <= balance where <= means less-than-or-equal. This means that amount <= balance evaluates to true if amount is less-than-or-equal to balance. Otherwise it evaluates to false.

In the example, thenPart is an assignment statement as in the previous example of withdraw. The elsePart is a statement that prints the String "The balance is less than the amount" on a console.

We assume that our system has an object console that represents a window on the screen of the computer executing the bank system. We also assume that the console object has a print method that takes a String as an argument and prints it in the window.

Loop statements

A loop statement executes a list of statements forever or until some condition is met or interrupted by a break statement. We have three forms of loop statements cycle, while-loop and for-loop:

The cycle statement

A cycle statement has the form:

cycle
   items

where Statements is a sequence of items. Execution of a cycle statement implies that items are executed forever unless interrupted by a possible break statement (see below) in Items.

In our bank system we assume that interest is added to each account on the first day of every month. To do this, the following cycle statement may be executed by some agent in the bank system:

cycle
   if (today.isFirstDayOfMonth) :then
      JohnSmithsAccount.addInterest
      ...

The above example is quite tentative. We have not specified what an agent might be – an agent may be a parallel process running in the bank system – we describe parallel processes in section . Also the condition today.isFirstDayOfMonth is left unspecified for now – we return to that in section xxx. Some more immediately useful examples of cycle will be shown in the following.

The while-loop

A while statements repeatedly executes a list of statements as long as a given condition evaluates to true. It has the form:

while (BooleanExp) :do
   Items 

where BooleanExp is a boolean expression and Items is a list of statements.

In section on the data type String, we have seen an example of a while-loop:

while (aName.get[i] <> ' ') :repeat
    console.print(aName.get[i])
    i := i + 1 

The for-loop

A for loop executes a list of statements a specific number of times. It has the form:

for (StartValue):to(EndValue):repeat
   Items

where StartValue and EndValue are expressions that evaluate to integer values, and Items is a list of items. If StartValue evaluates to n1 and EndValue evaluates to n2, then the Items are evaluated (n2 - n1 + 1) times.

Within Items, the integer variable inx has the value of the current iteration number. That is, inx goes through the values n1, n1 + 1, n1 + 1, … , n2.

In section , the following example makes use of a for loop:

balanceSum -> bal: var float:
   for (1):to(noOfAccounts):repeat
       bal := bal + accounts.get[inx].balance 

If noOfAccounts evaluates to the value 3, the statement in the for-loop is executed 3 times and inx goes through the values 1, 2, and 3. The effect is that the following statements are executed:

bal := bal + accounts.get[1].balance
bal := bal + accounts.get[2].balance
bal := bal + accounts.get[3].balance

Break statements

A break-statement transfers the control-flow to another point in the program and is also called a jump-statement. The flow of control may be to the beginning or end of the current method object or the beginning or end of an enclosing method object or object.

We have two kinds of break-statements leave and restart.

The leave statement

The leave statement has the form:

leave (AttributeName)

where AttributeName is the name of an enclosing class, method or singular object.

If L is the name of an enclosing attribute, then leave(L) will transfer control to the end of the statement-part of L.

As an example, we may make a more safe version of the method for printing the first name in a given string by testing that there is actually a blank character in the String and if not leave the while-loop:

L:
   while (aName.get[i] <> ' ') :repeat
       console.print(aName.get[i])
       i := i + 1
       if (i > aName.length) :then
          console.print("No blank char in String")
          leave(L)

Here we have given the while-loop the name L id we get at the end of aName without meeting blank, leave(L) will terminate the while-loop.

The restart statement

The restart statement has the form:

restart (AttributeName)

where AttributeName is the name of an enclosing class, method or singular object.

If L is the name of an enclosing attribute, then restart(L) will transfer control to the beginning of the statement-part of L.

We may use restart to write another variant of the first name in the String aName:

firstName:
   i: var integer
   i := i + 1
   if (i <= aName.length) :then
      if (aName.get[i] <> ' ') :then
         console.print(aName.get[i])
         restart(firstName)
   :else
      console.print("No space in String")

The inner-most if:then-statement prints the next character in a possible first name and then restart execution from the beginning of firstName. All local data-items of firstName – in this case the variable i, keeps its values, so i is incremented in each iteration.

Method invocation

As mentioned in the previous section, a method invocation may be part of an expression. It may, however, also just appear as a statement in case no value is returned by the invocation or if the value is not used:

  account_1010.addInterest

Here account_1010.addInterest is an example of a method invocation being used as a statement.

For further descriptions of object instantiation and method invocation, see chapter  and chapter .

Object instantiation

An object instantiation may in principle also be used as a statement although it in most cases appears as an expression since the resulting reference is assigned to a reference variable.

On defining control abstractions

Just a few of the statement types described above are primitives of the qBeta language. These include assignment, the if:then statement and the break statements. All the other statement types described are defined in the qBeta library. The user of qBeta may in a similar way define his or her own control statements, defined by methods, which we here refer to as control abstractions. This is described in chapter . In this chapter, we also explain that most of the above control statements in fact describe invocations of singular method objects similar to singular data-objects declared using obj.