Previous Next Contents Index Doc Set Home


Program Declarations

5


This chapter describes Pascal program declarations. It contains the following sections:

Declarations

page 77

Procedure and Function Headings

page 84


Declarations

This section describes the label, constant, type, variable, and define declarations. Procedure and function declarations are described in Chapter 6, "Built-In Procedures and Functions."

Label Declaration

The label declaration defines labels, which are used as the target of goto statements.

Comments

In Pascal, you can use both identifiers and integers as labels. Using identifiers as labels makes your code easier to read.

Example

The Pascal program, label.p

program return_example;

{ This program demonstrates the use of the
  label declaration. }

var
    i: integer;

procedure test;
label
    error_negative_value, error_bad_values, error_value_too_big;
begin
    if i < 0 then
      goto error_negative_value
    else if (i = 2) or (i = 3) then
      goto error_bad_values
    else if i > 100 then
      goto error_value_too_big;
    return;
error_negative_value:
    writeln('Value of i must be greater than 0.');
    return;
error_bad_values:
    writeln('Illegal value of i:  2 or 3.');
    return;
error_value_too_big:
    writeln('Value of i too large.');
    return
end; { test }

begin { main procedure }
    write('Enter value for i:  ');
    readln(i);
    test
end. { return_example }

The commands to compile and execute label.p

hostname% pc label.p
hostname% a.out
Enter value for i: 101
Value of i too large.

Constant Declaration

The constant declaration defines constants, values that do not change during program execution.

The value of expression can be a compile-time evaluable expression. It can contain any of the following:

Example

This constant declaration defines six valid constants.

const
	x = 75;
	y = 85;
	month = 'November';
	lie = false;
	result = (x + y) / 2.0;
	answer = succ(sqrt(5+4));

Type Declaration

The type declaration describes and names types used in variable, parameter, and function declarations.

Unlike standard Pascal, in Pascal, you can define universal pointer types and procedure and function pointer types in the type declaration.

Example

This type declaration defines opaque_pointers as a universal pointer and routines as a function pointer.

type
	lowints = 0..100;
	primary_colors = (red, yellow, blue);
	opaque_pointers = univ_ptr;
	routines = function(i: integer): boolean;
	capital_letters = set of 'A'..'Z';
	digits = set of lowints;
	char_array = array[1..10] of char;
	record_type = record
		name: char_array;
		age : integer;
	end;

Variable Declaration

The variable declaration declares variables.

In the variable declaration, you can specify the variable scope, attributes, and initial values. In most cases, you do not have a variable declaration that has both a variable scope and a variable attribute, because these are different ways for doing similar things.

Scope

The scope of a variable is either private or public.

You can also use the define/extern declaration to declare a variable as public, and the static attribute to declare a variable as private. See Appendix A, "Overview of Pascal Extensions," for information on define/extern.

Variables in the var declaration section of a program default to public when you compile your program without the -xl option. When you compile your program with -xl, variables default to private.

This code declares both public and private variables.

public var
	total: single := 100.00;
	quantity: integer16 := 25;

private var
	score: integer16 := 99;

Attributes

The variable attributes determine how to allocate the variable and its scope. They include static, extern, and define.

static

A static variable is a variable that is private in scope and which is allocated statically. A global variable declared as static is equivalent to a variable that has been declared private. Pascal generates a compile-time error if you attempt to declare a global variable as both static and public.

When you declare a local variable as static, the variable retains its value after the program exits the procedure in which it is declared. You can only initialize a local variable, that is, a variable declared in a procedure, in the var declaration if you also declare it as static.

The Pascal program, static.p

program static_example;

{ This program demonstrates the use of the
  static variable attribute. }

var
    i: integer;

procedure count;

var
    number_of_times_called: static integer := 0;

begin
    number_of_times_called := number_of_times_called + 1;
   writeln('Call number: ', number_of_times_called)
end; { count }

begin { main program }
    for i := 1 to 4 do begin
      count
    end
end. { static_example }

The commands to compile and execute static.p

hostname% pc static.p
hostname% a.out
Call number: 1
Call number: 2
Call number: 3
Call number: 4

extern
The extern attribute is used to declare a variable that is not allocated in the current module or program unit, but is a reference to a variable allocated in another unit. You cannot initialize extern variables. See the Pascal 4.2 User's Guide, which describes separately compiled programs and modules; it also contains examples of the extern attribute.

define
The define attribute is used to declare a variable that is allocated in the current module and whose scope is public. define is especially useful for declaring variables with the -xl option, which makes global variables private by default. See the Pascal 4.2 User's Guide for an example of this attribute.

Initialization
You can initialize real, integer, boolean, character, set, record, array, and pointer variables in the var declaration. You cannot initialize a local variable (a variable in the var declaration of a procedure or function) unless you declare it as static.

This example shows how to initialize a variable in the var declaration.

var
	x: array[1..5, 1..3] of real := [[* of 0.0], [* of 0.0]];
	year, zeta: integer := 0;
	sunny: boolean := false;
	c1: char := 'g';
	citrus: set of fruit := [orange, lemon, lime];
	name: array[1..11] of char := 'Rembrandt';

This code correctly declares the variables x, y, windy, and grade in procedure miscellaneous as static.

procedure miscellaneous;

var
	x: static integer16 := maxint;
	y: static single := 3.9;
	windy: static boolean := true;
	grade: static char := 'C';

Define Declaration

The define declaration controls the allocation of variables.

Comments

The value of identifier must correspond to either a variable or procedure or function identifier. If identifier corresponds to a variable, it must have a matching variable declaration with the extern attribute. The define declaration nullifies the meaning of extern: it allocates the variable in the current program or module unit.

If identifier corresponds to a procedure or a function, it nullifies a previous extern procedure/function declaration; this means that you must define the procedure/function thereafter.

You can initialize variables, but not procedures and functions, in the define declaration. Identifiers in the define declaration are always public.

Example

See the chapter on separate compilation in the Pascal 4.2 User's Guide for examples of the define declaration.


Procedure and Function Headings

This section discusses the visibility, parameters, the type identifier, functions, and options for procedure and function headings.

Visibility

You can declare a procedure or function at the outer block level as either public or private.

When a procedure or function is public, you can reference that routine in another program or module unit. Declaring a routine as private restricts its accessibility to the current compilation unit.

You can also use the define/extern declaration to declare a procedure or function as public, and the internal routine option to declare a routine as private. For more information on the define/extern declaration, see Appendix A, "Overview of Pascal Extensions."

Top-level procedures and functions declared in a program default to public when you compile your program without the -xl option. When you compile your program with -xl, all top-level routines declared in the program become private.

Nested procedures and functions are always private; it is illegal to declare a nested routine as public.

Procedures and functions declared within a module unit are always public. For additional information on modules, see the Pascal 4.2 User's Guide.

This code fragment declares both public and private functions and procedures.

public procedure average(s,t: single);

private procedure evaluate(n : integer);

public function big (quart : integer16;
			    cost : single) : single;

private function simple (x, y : boolean) : integer16;

Parameter List

Pascal supplies the parameter types in, out, in out, var, value, and univ.

Parameters: in, out, and in out

The in, out, and in out parameters are extensions to the standard, which are used to specify the direction of parameter passing:

in

Indicates that the parameter can only pass a value into the routine. The parameter is, in effect, a read-only variable. You cannot assign a value to an in parameter, nor can you pass an in parameter as an argument to another procedure that expects a var, out, or in out argument.

out

Indicates that the parameter is used to pass values out of the routine. In effect, declaring a parameter as out informs the compiler that the parameter has no initial value, and that assignments to the parameter are retained by the caller.

in out

Indicates that the parameter can both take in values and pass them back out. An in out parameter is equivalent to a var parameter.

Example

The Pascal program, in_out.p. The procedure compute_area reads in the length and width and outputs result. The procedure multiply_by_two reads in result, multiplies it by two and returns the modified value.

program in_out_example(input, output);

{ This program, which finds the area of a rectangle,
  demonstrates the use of the in, out, and in out
  parameters. }

var
    length, width, result: real;

{ Find area given length and width. }
procedure compute_area(in length: real; in width: real;
                       out result: real);

begin
    result := length * width
end; { compute_area } { compute_area }


{ Multiply the area by two. }
procedure multiply_by_two(in out result: real);

begin
    result := result * 2
end; { multiply_by_two } { multiply_by_two }


begin { main program }
    write('Enter values for length and width:  ');
    readln(length, width);
    compute_area(length, width, result);
    writeln('The area is ', result: 5: 2, '.');
    multiply_by_two(result);
    writeln('Twice the area is ', result: 5: 2, '.')
end. { in_out_example }

The commands to compile and execute in_out.p. This example shows the program output when you input a length of 4 and a width of 5.

hostname% pc in_out.p
hostname% a.out
Enter values for length and width: 4 5
The area is 20.00.
Twice the area is 40.00.

var Parameters

With standard conformance options (-s, -V0, -V1), var parameters are the same in standard Pascal and Pascal. By default, the Apollo-like var compatibility approach applies: actual and formal records and arrays should be of the same type; other types of var must be of the same length.

For example, all pointer types are compatible to univ_ptr, and vice versa. See "Universal Pointer" on page 42. Subranges -128...127 and 0...127 are also var-compatible.

Value Parameters

Value parameters are the same in standard Pascal and Pascal.

univ Parameters

The nonstandard univ parameter type is actually a modifier used before data types in formal parameter lists to turn off type checking for that parameter. You can use it with any type of parameter except conformant array, procedure, or function parameters.

univ is used as follows:

procedure somename (var firstparam: univ integer);

You could then call this procedure with a parameter of any type. You should always declare a univ parameter as either in, out, in out, or var.

univ is most often used for passing arrays, where you can call a procedure or function with different array sizes. In that case, you generally would pass another parameter that gives the actual size of the array, as follows:

type
	real_array = array[1..100] of real;

procedure receive(size: integer;
			var theArray: univ real_array);

var
	n: integer;

begin
	 for n:= 1 to size do
		.
		.
		.

Type Identifier

In Pascal, a function may represent a structure, such as a set, array, or record. In standard Pascal, a function can only represent the simple types of value, ordinal, or real.

Functions Returning Structured-Type Results

If a Pascal function returns the result of a structured type, for example, an array, a record, a string, or some combination of these, you can construct or update the result, component-by-component, using assignments of the form:

F S1 ... SN := E
where:

Standard Pascal allows assignments to the whole function result variable only, that is, F:= E, which may not be feasible or efficient enough, since you may have to declare and initialize extra structured-type variables.

Example 1: A Function That Returns Strings

When declaring functions that return strings (arrays of chars) and varying strings, you can specify the result by an assignment. For example:

F:= 'The answer: 12 miles'
where F is the function. However, sometimes you may want to obtain the string result by modifying some of the characters of an existing string (variable or parameter). In the following example, you may want to substitute a string for the string XX.

program String_Function_Example;
type s1 = array [1..20] of char;
    s2 = array [1..2 ] of char;

function f(x:s2):s1;
begin
  f := 'The answer: XX miles';
  f[13]:=x[1];
  f[14]:=x[2];
end;

var r: s2;
    s: s1;
begin
   r:='12';
   s:=f(r);

   writeln(s)
end.

In general, an identifier of a function f returning a string can be used in an assignment of the kind:

f[i]:=c
for specifying the i'th byte of the function result. This Pascal extension can be used both for strings and varying strings.

Example 2: A Function that Returns Arrays of Records
(Complex Vector Addition)

program complex_vectors;
	
type
		complex = record re, im: real end;
		compl_vect = array [1..10] of complex;
		
function add (var a, b: compl_vect): compl_vect;
var i: integer;
begin
		for i:= 1 to 10 do
		begin
			add[i].re:= a[i].re + b[i].re;
			add[i].im:= a[i].im + b[i].im;
		end;
end; { add }
	
var V1, V2, V3: compl_vect;
begin
		...
		V1:= add (V2, V3);
		...
end. { complex_vectors }

Options

Pascal supplies the standard forward routine option and the nonstandard options, extern, external, internal, variable, and nonpascal.

forward

The forward option is the same in Pascal and standard Pascal.

extern and external

The extern and external options indicate that the procedure or function is defined in a separate program or module. extern and external allow the optional specification of the source language of the procedure or function. For more information on these options, see the chapter on separate compilation in the Pascal 4.2 User's Guide.

internal

The internal option makes the procedure or function local to that module. Specifying the internal option is the same as declaring the procedure or function as private. Pascal generates an error message if you attempt to declare a public procedure or function as internal.

variable

Using the variable option, you can pass a procedure or function a smaller number of actual arguments than the number of formal arguments defined in the routine. The actual arguments must match the formal parameters types. You cannot pass a larger number of actual arguments than formal arguments.

Example

The Pascal program, variable.p, passes either two or three actual arguments to the procedure, calculate_total, depending on the user input.

program variable_example(input, output);

{ This program demonstrates the use of the
  variable routine option. }

const
    tax_rate = 0.07;
    shipping_fee = 2.50;

var
    price: single;
    resident: char;
    total: single;

function calculate(count: integer16; price: single;
                   tax: single): single;
                   options(variable);

begin
    if count = 2 then 
      calculate := price + tax + shipping_fee
    else 
      calculate := price + shipping_fee
end; { calculate }

begin { main program }
    write('Please enter the price:  ');
    readln(price);
	 writeln('California residents must add local sales tax.');
     write('Are you a California resident?  Enter y or n:  ');
    readln(resident);
    if resident = 'y' then 
      total := calculate(2, price, tax_rate * price)
    else 
      total := calculate(1, price);
    writeln('Your purchase amounts to $', total: 5: 2, '.')
end. { variable_example }

The commands to compile and execute variable.p

hostname% pc variable.p
hostname% a.out
Please enter the price: 10.00
California residents must add local sales tax.
Are you a California resident? Enter y or n: y
Your purchase amounts to $13.20.
hostname% a.out
Please enter the price: 10.00
California residents must add local sales tax.
Are you a California resident? Enter y or n: n
Your purchase amounts to $12.50.

nonpascal

Pascal supports nonpascal as a routine option when you compile your program with the -xl option. nonpascal declares non-Pascal routines when you are porting Apollo DOMAIN programs written in DOMAIN Pascal, FORTRAN, or C.

nonpascal passes arguments by reference. If the argument is a variable, nonpascal passes its address. If the argument is a constant or expression, nonpascal makes a copy on the caller's stack and passes the address of the copy.


Previous Next Contents Index Doc Set Home