7.14.1. INTRODUCTION TO TURING

Copyright©  Department of Computer Science, University of Regina
Originally Written by Zhiwei Wang and Pauline Van Havere

7.14.1.1. BACKGROUND AND RATIONALE

Turing and its extension to OOT (Object Oriented Turing) is a high-level programming language that is easy to learn. It is originally designed in 1982 by R.C. Holt and J.R. Cordy of the Computer Systems Research Institute at the University of Toronto. 'Turing' is named after Alan Turing (1912-1954), the British scientist-mathematician who made extremely important fundamental contributions to the development of modern computers and Computer Science.
 
 

Turing is a general purpose language. The design goals include: easy learning, concise and expressive syntax, effective error treatment, effective program complexity control, precise language definition, and fast implementations.
 
 

Turing is designed for use on a wide range of computers, from PC's to mainframes. Turing as extended with graphics and binary file input/output is the language currently supported on IBM PC compatibles using MS-DOS, Macintoshes and Icons. Object Oriented Turing (OOT), running on UNIX under X Windows and on IBM PC compatibles running Microsoft Windows, extends Turing with two sets of features: The first

It can be used to teach programming concepts at the introductory level, but also to develop serious software. Turing was designed to be as free as possible from rigid syntactical restraints; this makes it an attractive alternative to languages like Pascal.
 
 

This manual will present a brief introduction to the Turing language. If you have any comments or suggestions, please fill out the Readers' Comments page (appended to the manual) and submit it to the Computer Science Department.
 
 

7.14.1.2. COMPILING AND RUNNING

A description of the interface to the Turing compiler is placed at the beginning of this manual to encourage the reader to enter and run small test programs as a knowledge of the Turing language is being acquired.
 
 

The Turing compiler installed here at the University of Regina is referred to as "oot", representing "object oriented turing". While oot is designed to run on x-terminals, "toot" is the terminal oriented interface that can be used on 'dumb' terminals.
 
 

The general format for compiling and running a Turing language source file is:
 
 

toot [-i infilename] [-o outfilename] filename.t

A file extension of .t is expected. The two options, -i and -o allow the user to specify the names of input and/or output files. If these options are not entered, standard input and output are assumed. filename.t is the main program which may reference subroutines contained in other files; these will be brought into the compilation.

If there are no syntax errors, the program will be executed right away.
 
 

The following example shows the contents of a Turing program and illustrates how it can be compiled and run.
 
 

mercury[97]% cat avg.t [return]

% This is a simple little program to average 2 numbers
 
 

var num1, num2: int

var the_sum: real
 
 

put "This program will average 2 numbers."

put "Enter 2 numbers, separated by a space:"

get num1, num2

the_sum := (num1 + num2) / 2

put "The average is ", the_sum
 
 

mercury[98]% toot avg.t [return]

This program will average 2 numbers.

Enter 2 numbers, separated by a space

1 2 [return]

The average is 1.5

mercury[99]%

7.14.2. BASIC CONCEPTS

7.14.2.1. CHARACTERS

Any language consists of words and the words are made up of characters. A character is a letter, or a digit, or a special character. The letters are
 
 

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

a b c d e f g h i j k l m n o p q r s t u v w x y z
 
 

The digits are

0 1 2 3 4 5 6 7 8 9

The special characters include:
 
 

+ - * / ( ) = , . " ' [ ] , . ; : { } | ^ ! ~ % $ _ blank
 
 

Pairs of special characters are often used as special symbols. For example, each of the following pairs has a fixed meaning
 
 

        :=      <=      >=

7.14.2.2. CHARACTER STRINGS

A character string can consist of any legal characters: letters, digits, and special characters. Examples of character strings are:
 
 

Jones,

Character strings enclosed in quotation marks are called explicit string constants. Examples of explicit strings constants are:
 
 

"Jones" "x ="
 
 

An explicit string constant is a sequence of zero or more characters surrounded by double quotes. within explicit string constant, the back slash character (\) is an escape to represent certain characters as follows:
 
 

\" for double quote,

 \n or \N for end of line character,

 \t or \T for tab,

 \f or \F for form feed,

 \r or \R for carriage return,

\b or \B for backspace,

 \e or \E for escape,

 \d or \D for delete,

 \\ for backslash.
 
 

Explicit string constant must not cross line boundaries. Long string constants can be broken at line boundaries and connected by the concatenation operator (+).
 
 

7.14.2.3. NUMBERS

Numbers such as -2, -1, 0, 1, 2 are called integers. Any string of digits preceded by an optional minus sign is an integer constant. Turing software allows a range of integer numbers including -2,147,483,647 to 2,147,483,647.
 
 

Using scientific notation, a number can be represented as an explicit real constant. Here are some examples:
 
 

-32.1e+22

 2e12

 0.

 .1

 3.0
 
 

Generally, an explicit real constant consists of three parts: an optional plus or minus sign, a significant figures part, an exponent part. The significant part consists of a sequence of digits with an optional decimal point. The exponent part consists of the letter e (or E) followed by an optional plus or minus sign followed by one or more digits. The exponent part e12 represents 10 to the 12th power, etc. However, if the significant part contains a decimal point, then the exponent part is optional.
 
 

7.14.2.4. EXPRESSIONS - MATHEMATICAL OPERATORS

"Expression" represents a calculation that returns a value. For example: 24 is an expression representing the integer number 24; 3.5 is a expression that represents a real number 3.5; 2e8 and 32.1e6 represent the number 200000000 and 32100000 respectively. There are also other kinds of expressions. For example, explicit string constants like "Hi, Tony" are also expressions.
 
 

The expressions that are integer or real constants can be combined into compound expressions using mathematical operators.

The mathematical operators are:
 
 

+ for addition

- for subtraction

* for multiplication

** for exponentiation

/ for division

div for integer division

mod for module of one integer with another

rem for remainder of one integer with another

= equal

not= not equal

< less than

<= less than or equal to

> greater than

>= greater than or equal to
 
 

The sum, difference, and product of two numbers are integers if both of the numbers are integers, are of real form if one of the two numbers is of real form. However, if two numbers are to be divided using the slash operator /, the result will be a real value, even if both numbers are integers. For example, 3/2 gives the real result 1.5.

Two numbers may be divided to produce an integer using the integer division operator div. For example, 7 div 2 gives the integer 3.

The mod operator produces the module of one number with another. The result is always a positive number between 0 and the second number. If both numbers are positive, the result is identical to the remainder operator. For example, 7 mod 2 gives 1, -12 mod 5 gives 3.
 
 

The remainder in an integer division can be found out using the operator rem. For example, 7 rem 2 gives 1, -12rem 5 gives -2.
 
 

Numbers may be raised to a power using the exponentiation operator. For example: 3**2 gives 9.
 
 

The rules of precedence among these operations are as following; exponentiation has the highest priority and multiplication and division have precedence over addition and subtraction. The operations div, rem, and mod have the same precedence as / and *.
 
 

When parentheses are used to guide the sequence of evaluation, any expression in parentheses is evaluated first.
 
 

7.14.2.5. EXPRESSIONS - BOOLEAN OPERATORS

Conditions or relational expressions are expressions that can have values of either true or false. These expressions are also called Boolean expressions.

The following are some examples of simple Boolean expressions.
 
 

Relational expression Value

4 = 1 + 3 true

 6 > 4 true

 3 < 9 true

 6 + 2 < 1 + 3 false

 6 not= 10 true

 3 > 3 false

 3 >= 3 true
 
 

In comparisons of strings, the greater than operator (>) indicates `alphabetically greater than' ; similarly, < indicates `alphabetically less than'. This is dependent on the collating sequence of the numerical representation of characters.
 
 

The Boolean operators are:
 
 

not negation (a unary operator)

and and

or or

 => implication
 
 

Compound conditions are formed by taking two single conditions and putting either the Boolean operator called and or or between them. Boolean operators have lower precedence than relational operators. and operator have higher precedence than or operator. With the operator and, the compound condition is true if and only if both of the single conditions are true. With the operator or the compound condition is false if and only if both of the single conditions are false.
 
 

The following are some examples of compound Boolean expressions.
 
 

Compound expression Value

6 < 7 and 5 = 3 + 2 true

 6 > 7 and 5 = 3 + 2 false

 6 > 7 or 5 = 3 + 2 true

 9 < 8 or 6 > 2 true

 9 < 8 or 6 < 2 false

 9 < 8 and 6 > 2 false
 
 

A compiler will evaluate higher precedence operators before those of lower precedence. However, expressions within parentheses are have the highest precedence so if you wish to ensure that the compiler interprets the expression as you desire, use parentheses to force the order of evaluation.

It is possible to have multiple compound conditions. For example,
 
 

(9 > 5 and 3 = 2 + 1) and (6 > 2 or 1 > 5)
 
 

is true.
 
 

And and or are binary operators in the sense that both of them operate on two conditions. Not is a unary Boolean operator that requires only one condition. The condition
 
 

not 4 > 5
 
 

is true since "4 > 5", which is false, is negated by the not operator.
 
 

7.14.2.6. PROGRAM

A program is a set of instructions telling the computer what to do. Every instruction is called a statement. Blank lines can be placed between statements to improve readability. Also, statements can be indented with tab's to improve readability. Let us try to write and run a very simple program. To write a program, you can use a text editor to type down the following statement:
 
 

put "Hi"
 
 

Then you can save it in a file named, say mini.t.. To compile and run it, enter:

toot mini.t [return]

The program mini.t will cause the screen display

Hi
 
 

7.14.2.7. COMMENTS

When a program becomes too complicated to understand, comments are needed to make a program understandable. Comments are needed by humans, not by the computer. As far as the computer is concerned, comments do nothing.

There are two kinds of comments. An end-of-line comment begins with the character % and ends at the end of the current line. A bracketed comment is any sequence of characters not including comment bracketssurrounded by comment brackets /* and */. Bracketed comments may cross line boundaries.

For example, we can add comments in the program mini.t as following:
 
 

% This is the first Turing program written by me

put "Hi" /* Cause the screen display Hi. */
 
 

As far as the computer is concerned, this is the same program as the program mini.t.
 
 

7.14.2.8. KEYWORDS

In the program mini.t, put is called a keyword. Other keywords serve a variety of purposes. They have a specific meaning to Turing and cannot be used as variable names. For example, the keyword put causes the computer output something.

 The following is a list of keywords in Turing:
 
 

all and array assert begin

bind body boolean case collection

const decreasing div else elsif

end enum exit export false

fcn for forward free function

get if import in init

int invariant label loop mod

module new not of opaque

open or pervasive pointer post

pre proc procedure put read

real record result return seek

set skip string tag tell

then to true type union

var when write
 
 

7.14.3. VARIBLES AND IDENTIFIERS

The information we need are stored in some locations in the memory of the computer. Each location has its own unique address. We use a name to identify a particular memory location instead of referring the actual address. The memory location is called a variable. The name standing for it is called an identifier. The actual information stored in the memory location is called the value of the variable.
 
 

Each memory location is arranged to hold a particular type of information. This is called the data type of a variable. For example, we can have an integer variable which is set up to hold an integer, a real variable to hold a real number, and a character string variable to hold a character string. The value of a variable can be changed from time to time, but the type of a variable can never be changed.
 
 

An identifier consists of a sequence of at most 50 letters, digits, and underscores beginning with a letter; all these characters are significant in distinguishing identifiers. Upper and lower case letters are considered to be distinct in identifiers. Note that a keyword can not be used to identify a variable.
 
 

7.14.3.1. DECLARATIONS - DATA TYPES

After giving identifier to a variable, we must let the compiler know this so that it can associate the identifier with memory location suitable for the particular data type which they will hold. This is done by the means of a declaration.
 
 

The form for a variable declaration is:
 
 

var identifierList : dataType
 
 

where var is the keyword used for variable declarations,

identifierList is a list of one or more identifiers separated by commas,

 : a colon precedes the data type,

dataType specifies a particular data type.
 
 

Standard data types are:
 
 

int for integer numbers

real for floating point numbers

string[(length)] for character strings (default length is 255 characters)

boolean for the boolean values of "true" or "false"
 
 

If there is more than one identifier in a declaration statement, the identifiers should be separated by commas. For example, to declare that variables named a and b are integer variables we write
 
 

var a, b: int
 
 

Or, the variables could also be declared individually, as:
 
 

var a: int

var b: int
 
 

When a variable is declared as `string', e.g.
 
 

var name: string
 
 

a memory space for 255 characters is reserved. We can specify a smaller space by adding a number in parentheses after the keyword string.

For example:
 
 

var name: string(30)
 
 

reserves a space that can hold a maximum of 30 characters. Note that keywords can not be declared since they cannot be used as identifiers.
 
 

The following program illustrates the declarations of 'num1' and 'num2', identifiers of type 'integer', and 'the_sum', identifier of type 'real'.
 
 

% File name: average.t

% This is a simple little program to average 2 numbers
 
 

var num1, num2: int

var the_sum: real
 
 

put "This program will average 2 numbers."

put "Enter 2 numbers, separated by a space:"

get num1, num2

the_sum := (num1 + num2) / 2

put "The average is ", the_sum
 
 

The boolean type is used for values that are either true or false. The following example determines if the string s contains a period. found is declared as a boolean variable and assigned the value false. After the for loop, found will be true if there is a period in s.
 
 

% File name: period.t

% This is a simple little program to determine if a string

% contains a period.
 
 

var s : string

var found : boolean := false
 
 

put "Please input a string: "

get s
 
 

for i: 1..length(s)

if s(i) = "." then

found := true

end if

end for
 
 

if found = true then

put "The string contains a period"

else

put "The string doesn't contain a period"

end if
 
 

The true-false value of an expression can be assigned to a boolean variable. In the following example, the value of the expression 'mark>=60' is determinated by the value of 'mark'. If 'mark' is greater than or equal to 60, the value of the expression is true and hence the boolean variable 'success' is assigned the value true. Otherwise 'success' has the value false. Since assignment has lower precedence than '>=', there is no need to bracket the expression 'mark>=60'.

% File name: mark.t

% This program checks a series of marks entered from the

% keyboard to see if everyone has passed.
 
 

var success: boolean := false

var continuing := true %This implies the type is boolean

var mark : int
 
 

loop

put "Please a mark (enter -1 to end): "

get mark

exit when (mark < 0 ) or (mark > 100)

success := mark >= 60 %Assign the true-false value

%of 'mark>=60' to 'success'

continuing := continuing and success

end loop
 
 

if continuing = true then

put "Everyone passed"

else

put "Sorry, not everyone passed"

end if
 
 

The keyword for a data type is generally used in a variable declaration. However, an identifier can be associated with a data type and then the identifier can be used in place of the keyword for the data type. This association (identifier with a data type) is accomplished with the type declaration. The general form for a type declaration is:
 
 

type identifier : dataType
 
 

For example:
 
 

type mark_type : int

var mark : mark_type
 
 

This is equivalent to:
 
 

var mark : int
 
 

Suppose you had created a program with several variables, all relating to marks, and had declared them all using mark_type as the data type. If you then wanted to change all of these variables to type "real", you would only have to change one line in your program. i.e.
 
 

type mark_type : real
 
 

This would cause all mark type variables to be declared as real instead of integer.
 
 

7.14.3.2. ASSIGNMENT STATEMENTS

Variables can be assigned value by assignment statements. The form is
 
 

identifier := expression
 
 

Note that the identifier must have been already declared. The expression can contain constants and/or arithmetic expressions. The keywords true and false can also be used in the assignment of values to boolean type variables.

Here are some examples.
 
 

x := 5 % single constant in expressions

y := 300

z := 300 - 5 % arithmetic operator in expression

b := true % boolean keyword in expression

Variables can be used in the expression to assign value to the identifier. For example
 
 

x := 5 % constants in expression

y := 30

z := y - x % variables in expression

will give the value 25 to the variable z. Here is another example
 
 

k := 1

k := k + 1
 
 

After the execution of the first line, k has the value 1. After the execution of the second line, k has the value 2. When the statement k := k + 1 is executed, the value stored in the location named by k is added to the integer 1 and the sum is then stored back to the same location.
 
 

Let us write a program using the assignment statement.
 
 

% File name: assignment.t

% This is a Turing program using assignment statement
 
 

% declare name as a string, not more than 20 characters

var name: string(20)
 
 

name := "Tony" % assign value to the variable name.

put "Hi, ", name
 
 

The output of this program will be
 
 

Hi, Tony
 
 

A variable declaration statement can be combined with an assignment statement. This is often done when it is desirable to initialize a variable. For example, the statements:
 
 

var a: int

var token : boolean

a := 0

token := true
 
 

could be replaced by:
 
 

var a: int := 0

var token : boolean := true
 
 

In general, the format for a declaration with an assignment is:
 
 

var identifier : dataType := value
 
 

7.14.3.3. CONSTANTS

Identifiers can also take on constant values. In this case, the assignment, using the keyword "const", is of the form:
 
 

const identifier : = expression
 
 

A typical example is a constant used for the value of pi, for example,
 
 

const PI := 3.1416
 
 

Often, all of the letters in the identifier for a constant are capitalized by a programmer, to distinguish the identifier from a variable. Once defined, a constant can be used in arithmetic expressions just like a variable.
 
 

Example:
 
 

% File name: c_area.t

% Program to compute the area of a circle
 
 

var c_radius : int

var c_area : real

const PI := 3.1416
 
 

put "Input circle radius: "

get c_radius

c_area := PI * (c_radius ** 2)

put "Circle area is: ", c_area
 
 

The run of this program might appear as:
 
 

Input circle radius:

10 [return]

Circle area is: 314.16

7.14.3.4. STRING EXPRESSIONS

The positions of characters in a string are all numbered from the left. We can use position numbers to specify a substring which is a part of the string. A substring is specified by following the identifier with a pair of parentheses which enclose the range of character positions to be included in the substring. The start position is separated from the end position by two periods. i.e.
 
 

Substring Specification:

 string_name ( start_position ..end_position )
 
 

Note: "*" can be used to denote the last character position. Let's look at an example.

%File name: name.t
 
 

var name: string(20)

name := "Tony Franklin"

put name(6 .. 13)
 
 

name(6 .. 13) specifies a substring of characters starting at the 6th position in 'name' and ending at the 13th position.
 
 

The output will be:

Franklin
 
 

The position of the last character in a string can be represented by an asterisk. For example name(6 .. *) is the same as name(6 .. 20). Using an asterisk, the second last position is represented as *-1, the third last position is represented as *-2, and so on.
 
 

Make sure the range of a substring does not go beyond the range of the string itself.
 
 

Just as there are number expressions, there are also string expressions. In string expressions, + stands for the concatenation operation, which joins two strings together.
 
 

String Concatenation:
 
 

string1 + string2
 
 

For example,
 
 

"Hi, " + "Tony"
 
 

has the value "Hi, Tony".
 
 

7.14.3.5. ARRAYS

The general form for an array declaration is:
 
 

var array_name : array 1 .. last_element

[ , 1 .. last_element] of dataType

[ := init ( value, ... value ) ]
 
 

The last_element could be a number or a variable; however, if a variable is used, it must have been assigned a value before the array declaration. An array can be initialized at declaration time, or later in the program.
 
 

Suppose we have a list of the names of students. We could give this list a name, say, student. For the first student name in the list, we could identify it as student(1), the second as student(2), and so on. This list is an array and the number enclosed in parentheses is the index of the array.
 
 

Suppose we have 20 students and each student's name is a character string variable no more than 20 characters. We could use a declaration
 
 

var student: array 1 .. 20 of string(20)
 
 

In this declaration, the range (1 to 20) of the array is given after the keyword array. To access the 20 character string associated with the second student name, you would use the reference:

student(2)
 
 

Suppose now we have a table instead of a single list. For example:
 
 

12 34 29 76

32 3 36 5

86 32 54 1
 
 

This table is a two-dimensional array of integers Let us give this table an arbitrary name, say, intTable. Then intTable can be declared as following
 
 

var intTable: array 1 .. 3, 1 .. 4 of int
 
 

The first range 1 .. 3 gives the number of rows in the array, the second 1 .. 4 the columns.
 
 

To initialize an array in a declaration, we must give a value for each element in the array. This can be done with individual assignment statements, or, elements can be given values at the same time as they are declared. These values, separated by commas and enclosed in parentheses, follow the keyword init. For example
 
 

var name: array 1..2 of string(5) :=

init("Smith","Sarah")
 
 

For two-dimensional array, we initialize it row by row, as in:
 
 

var intTable: array 1 .. 3, 1 .. 4 of int :=

init(12, 34, 29, 76,

32, 3, 36, 5,

86, 32, 54, 1)
 
 

The ends of the range of a subscript are called the bounds of the array. In the preceding examples, the bounds are known before running the program. If these valus are not know until run times, the array is said to be a dynamic array. The following is an example. In this example, dyn: is a dynamic array, its upper bound is a variable n. The value of n is unknown until it is input by a user.
 
 

% File name: grade.t

% program to use a dynamic array
 
 

var n: int % The number of students

var sum: real := 0 % Initialize sum with 0

put "How many students? "

get n
 
 

% use a dynamic array of n real numbers

var dyn: array 1 .. n of real

for i: 1 .. n

put "enter the grade for student ", i

get dyn(i)

sum := sum + dyn(i)

end for

put "The average grade is ", sum / n
 
 

7.14.3.6. RECORDS

In an array, each entry is of the same data type. If entries are of different data types, record should be used. A record consists of a number of fields which may have different data types.
 
 

The general form for declaring a record is:
 
 

var record_name

record

field_1 : dataType

.

.

field_n : dataType

end record
 
 

A field reference is made by: record_name. field_name (A dot separates the record name from the field name). Example:
 
 

var student:

record

studentName: string(20)

mark: int

end record
 
 

In this example, student is the name of the record, while studentName and mark are the names of fields. Note that the fields have different data types. A reference to a mark would be: student.mark - a dot separates the record name from the field name.
 
 

7.14.3.7. COLLECTIONS

A collection is similar to an array in which elements are referred to by indexes. However, elements in a collection must be referred to by pointers. A pointer is an address of an object in memory. Here is how to declare a collection and a pointer:
 
 

var collection_name : collection ofdataType

var pointer_name : pointer tocollection_name
 
 

The first line declares a collection. The second line declares a pointer associated with that collection. You would use the pointer with the collection name, as you would an index with an array name. i.e. collection_name(pointer_name)
 
 

When a collection is declared it contains no elements. Elements are created by the new statement:
 
 

new collection_name, pointer_name
 
 

This statement assigns space to a new element c and sets pointer p locate this space. If we want to delete an element, we use the following statement:

free collection_name, pointer_name
 
 

For example :
 
 

% File name: collection.t

% An example showing how to create an element in a collecton
 
 

var c: collection of string % Declare a collection of

% the type string

var p: pointer to c % An index for c

new c,p % Create element of

% collection c

c(p) := "Andropov" % Set value of element to

% the word "Andropov"

var s: string := c(p) % Access the element

put "The element is : "..

put s % Display the element

free c,p % Delete element of c
 
 

7.14.4. INPUT AND OUTPUT

Information entered into a computer for processing is called input, the results of the processing is called output. Input can come from a keyboard or a file stored on a disk. Output can be sent to the screen, a printer, or to be stored in a disk file.

7.14.4.1. STANDARD OUTPUT

The output to the screen is called standard output. It is produced by a put statement. The general form is:
 
 

put data_item[:width] [,data_item[:width] ]

For example,
 
 

put 4,"Tony"
 
 

The output of the preceding statement would be the two data items "4", and "Tony":
 
 

4Tony
 
 

Note that explicit string constants are displayed without the quotation marks.

Formatted Output

Integers, real numbers, and explicit strings are generally displayed in fields just large enough to hold them. You can specify a minimum field width for the item to be displayed. This is done by writing a colon after the item and giving the size of the field immediately. For example,
 
 

put 4:10,"Tony":10
 
 

will output:
 
 

_________4Tony______
 
 

A blank line can be left by the following statement
 
 

put ""
 
 

Two blanks can be left by:
 
 

put skip
 
 

where skip is a keyword that can be placed in a list of output items to cause a new line to be started.
 
 

Often a put statement is used to issue a prompt to a user. The program run is more readable if the cursor remains at the end of the prompt rather than going to the beginning of a new line. Putting two dots at the end of a `put' statement facilitates this function. For example:
 
 

put "Input circle radius: " ..
 
 

The 2 dots at the end of this line would cause the cursor to remain at the end of the prompt. Be sure to include a space before the closing quotation mark so that the user's entry will not `run into' the prompt when the program is run.
 
 

7.14.4.2. STANDARD INPUT

The input from a keyboard is called standarrd input. It is produced by a get statement. The general form is:
 
 

get variable [ : width ] [,variable [ : width ]]

For example,
 
 

get x
 
 

will read a number that is entered on the keyboard and store it in the variable named x.
 
 

A string of characters can be input as a unit which we call a token. Here is an example
 
 

var text: string

put "Enter a string, please."

get text

put text
 
 

Execution will be like this
 
 

Enter a string, please.

"Hi, Tony." [return]

Hi, Tony.
 
 

The second line is what you enter on the keyboard. Notice that it is enclosed with quotes. However, if the token to be entered contains no blanks, you need not to use quotes. A token without quotes must be separated from other items by either blanks or a return.
 
 

We can also limit the number of characters to be input in a string. This is done by adding a colon and a number after the get statement. For example In the following statement,
 
 

get text:8
 
 

only the first 8 characters will be entered. If you want an entire line to be input into a string variable, an asterisk is used instead of a number. For example the statement
 
 

get text:*
 
 

will input the entire line into the variable text. Quotes are not necessary when inputting a fixed number of characters or an entire line at a time.

 Let us look at a complete program:
 
 

% File name: c_area.t

% Program to compute the area of a circle
 
 

var c_radius : int

var c_area : real

const PI := 3.1416
 
 

put "Input circle radius: " ..

get c_radius

c_area := PI * (c_radius ** 2)

put "Circle area is: ", c_area
 
 

The run of this program might appear as:
 
 

Input circle radius: 10 [return]

Circle area is: 314.16

7.14.4.3. FILE I/O

Input and output can be files on the disks. There are two kinds of files, text files and binary files. Text files consist of characters and these characters can be directly displayed on the screen. Binary files store information in the internal form used inside the computer. Text files are input and output by the get and put statement, while binary files requires the read and write statement.
 
 

When you want to access disk files you use the keyword open. The general form for the file open statement is:
 
 

open: stream_number, "file_name", io_capability
 
 

where:

 stream_number is a previously declared integer variable, its value is assigned by the open statement

 file_name is the name of the disk file

 io_capability is get or read for read, or put or write for write.

The io_capabilty also includes seek and mod. mod stands for modify here, which is different from the modulo operator mod. Refer to the Turing reference manual for details. If a file can not be opened, the corresponding stream number will be assigned the number 0. To check that if a file is opened correctly, an assert statement can be used. The statement:
 
 

assert stream_number not= 0
 
 

causes the program to terminate if the file could not be opened. If the condition in the assertion is not true at the time the assert statement is reached during execution, an error message will be displayed and the execution will cease.

To read from the input stream you include the following statement:
 
 

get: stream_number, list of input items
 
 

The predefined function eof can be used to determine if the end of the file has been reached. eof returns the boolean value true when all items from the file have been read (See program average.t for an example). The syntax for using eof is:
 
 

eof(stream_number )
 
 

To write to the output stream you include the following statement:
 
 

put: stream_number, list of output items
 
 

Files are automatically closed at the end of execution but if you want to read a file that you have just written it must be closed and then reopened for reading. To close a file we would use:
 
 

close: stream_number
 
 

Here is an example to read from a disk file called grades and write to a file called average.
 
 

% File name: average2.t

% Read from the "grades" file and

% write to the "average" file

var streamNumberIn: int

var streamNumberOut: int

var a, b : int
 
 

open: streamNumberIn, "grades", get

assert streamNumberIn not= 0
 
 

open: streamNumberOut, "average", put

assert streamNumberOut not= 0
 
 

loop

exit when eof(streamNumberIn)

get: streamNumberIn, a, b

put: streamNumberOut, ( (a + b) / 2)

end loop

close: streamNumberIn

close: streamNumberOut
 
 

7.14.5. CONTROL FLOW IN PROGRAMS

The normal flow of control in a program is sequential: statements are executed one after another until the last statement is reached. This kind of flow of control is called the sequence structure. In this section, we will show two ways of altering this order. One involves the repeating of sequences of statements; the other involves a selection between alternative paths. The first is called a loop or repetition, the second a selection. All programs can be created from these three basic control structures: sequence, repetition, andselection.
 
 

7.14.5.1. COUNTED LOOPS

A statement that will produce repetition is the counted loop or for loop. The general form is:
 
 

for [ decreasing ] index: start_count .. end_count

statement(s)

end for
 
 

The index, or counter, does not have to be formally declared in the program. Turing automatically defines it as an integer variable. An index is "local" to the for loop i.e. the index is only valid within the scope of the for loop. The following is an example:
 
 

% File name: sum20a.t

% Calculate the sum of 20 integers
 
 

var sum, mark : int

% Note the index, i, does not need to be declared

put "Enter 20 integers, please"

sum := 0

for i: 1 .. 20

get mark

sum := sum + mark

end for

put "The sum is ", sum
 
 

Line 2 and line 3 are the statements that we want to repeat, called the body of the loop. Statements in the body are indented to improve readability. The body of the loop is prefaced by:
 
 

for i: 1 .. 20
 
 

and followed by:
 
 

end for
 
 

where i identifies an index and is used to count the number of times the body is executed. i is automatically declared as an integer. 1 .. 20 is the range of the index i. First, i is set to 1 and the loop body is executed. After the first execution, control of the flow is sent back to the for from the end for. At this time, the index is increased by 1 and the loop body is executed again. This procedure repeats until i equals to the final value 20. At that time, control goes out of the loop to the next statement after the end for.
 
 

The index is not necessarily started at 1. We could have, for example:
 
 

for i: 12 .. 20
 
 

Here i starts at 12 and goes up to 20.

We can also count backwards by -1. If we write:
 
 

for decreasing i: 20 .. 1

body of loop

end for
 
 

the body of the loop will be executed with the index i taking the values 20,19, 18, ..., 1.
 
 

The counted loop can be terminated by an exit when statement. Here is an example.
 
 

% File name: sum20b.t

% Calculate the sum of at most 20 positive integers.

var sum, mark : int

% Note the index, i, does not need to be declared

put "Enter 20 positive integers, please."

sum := 0

for i: 1 .. 20

get mark

exit when mark <= 0

sum := sum + mark

end for

put "The sum is ", sum
 
 

7.14.5.2. CONDITIONAL LOOPS

The form of conditional loop is:
 
 

loop

statement(s)

exit when condition

statement(s)

end loop
 
 

The repetition of the body in the loop is terminated when the condition is true, otherwise the control goes to the next statement after the exit when statement. An exit statement is used to stop the execution of a loop or for statement. A loop may contain more than one exit when statement. These statements can be placed anywhere in the loop. Here is an example:
 
 

% File name: classsize.t
 
 

var class_size : int

put "Enter your Class Size: " ..

loop

get class_size

exit when class_size > 0

put "ERROR: class size must be > zero: " ..

end loop

put "class size is ", class_size
 
 

7.14.5.3. SELECTION - IF STATEMENTS

The basic form of a selection statement is
 
 

if condition then

statements

else

statements

end if
 
 

When the condition following the keyword if is true the statements following the keyword then are executed. If the condition is false the statements following the keyword else are executed. Here is an example:
 
 

% File name: age.t

var age : int

var retire : boolean
 
 

put "Please enter your age"

get age
 
 

if age > 65 then

retire := true

else

retire := false

end if
 
 

% Some code here
 
 

put "Thank you."
 
 

The basic form of a three-way selection statement is
 
 

if condition1 then

statement1

elsif condition2 then

statement2

else

statement3

end if
 
 

7.14.5.4. SELECTION - CASE STATEMENTS

The case statement is used to select from more than two alternatives. The basic form is
 
 

case expression of

label case-label1: statement1

label case-label2: statement2

...

label case-labeln: statementn

end case
 
 

Each case-label must be an integer constant, otherwise we cannot use a case statement. The case statement selects exactly one of the labeled alternatives: if the value of the expression equals to that of a case-label, the corresponding statement is executed.

If we are not sure whether or not the value of the expression is within that of all the case-labels, we can put a label keyword without a case-label value specified. For example:

 (begin form )

 case expression of

label case-label1: statement1

label case-label2: statement2

...

label case-labeln: statementn

label: statement

end case
 
 

The label with no specified value is like the else part of an if statement and must be the last label in the case statement. This last label defines the default action i.e. the action that is to be taken if the case expression does not correspond to any of the case-labels. Here is an example:
 
 

% File name: menu.t
 
 

put "****************************************************"

put " 1. Enter an item "

put " 2. Search an item "

put " 3. Print list "

put " 4. Delete an item "

put " 5. Quit "

put "****************************************************"
 
 

var choice : int

put " Enter your choice: " ..

get choice

case choice of

label 1: put "Enter an item "

lavel 2: put "Search an item "

label 3: put "Print list "

label 4: put "Delete an item "

label 5: put "Quit "

label: put "erroneous entry"

end case
 
 

A particular alternative in a case statement can have more than one case-label
 
 

case expression of

label case-label1, case-label2: statement1

...

label case-label3: statement3

end case