The declaration section contains declarations or definitions of
constants, labels, user-defined data types, variables, and
user-defined functions and procedures. In addition, only
modules can contain initialization and finalization sections.
Each appears in a subsection introduced by a VSI Pascal reserved
word.
These sections appear after the header and before the executable
section (if any). The TO BEGIN DO and TO END DO sections can
appear only in modules and can appear only once within a module.
The remaining sections can appear in programs, modules,
functions, or procedures; they can appear more than once and in
any order in a single declaration section. If you use one kind
of section more than once in a declaration section, be sure to
declare types, variables, and constants before you use them in
subsequent sections.
If you want to apply the HIDDEN attribute to all of the data in
a declaration section, place the HIDDEN attribute immediately
preceding the section header, as follows:
[HIDDEN] CONST
Pi = 3.14
.
.
.
1 – Label Declaration
A label is a tag that makes an executable statement accessible
to a GOTO statement.
Syntax:
LABEL
{label},...;
The 'label' is a decimal integer between 0 and MAXINT or a
symbolic name. When declaring several labels, you can specify
them in any order.
Example:
LABEL 0, 6656, 778, 4352;
2 – Const Declaration
A CONST section defines symbolic constants by associating
identifiers with compile-time expressions.
Syntax:
CONST
{constant-identifier = constant-expression};...
The 'constant-identifier' is the identifier of the symbolic
constant being defined.
The 'constant-expression' is any legal compile-time expression.
The VSI Pascal compiler must be able to evaluate all of the
components of a compile-time expression when it compiles the
program.
Example:
CONST
Year = 1981;
Month = 'January'
Almost_Pi = 22.0/7.0;
Lie = FALSE;
Untruth = Lie;
This CONST section defines five symbolic constants. 'Year' is
declared to be the numeric value '1981'; 'Month' is declared to
be the string constant 'January'; 'Almost_Pi' is declared to be
the result of '22.0' divided by '7.0'; 'Lie' is declared to be
the Boolean value 'FALSE'; and 'Untruth' is declared to be of
type 'Lie.'
3 – Module Initialization
The TO BEGIN DO section allows you to specify a statement, in a
module, that is to be executed before the executable section of
the main program.
Syntax:
TO BEGIN DO statement;
The 'statement' is a VSI Pascal statement.
The TO BEGIN DO section can only appear in modules, can only
appear once in a module, and must appear as the last section in
the declaration section. (If appearing together, the TO BEGIN
DO section must precede the TO END DO section at the end of the
declaration section.)
As a general rule, if a program or module inherits an
environment file, the initialization section in the inherited
module must be executed before the initialization section in the
program or module that inherited it. If a module or program
inherits more than one module that contains an initialization
section, the order of execution of the inherited modules cannot
be determined.
Example:
MODULE X( INPUT, OUTPUT );
VAR
Debug : Boolean;
PROCEDURE Test(...); {Executable section...}
TO BEGIN DO
BEGIN
WRITE( 'Debug Module x? ' );
READLN( Debug );
END;
END.
This TO BEGIN DO section contains statements that write a string
and test the validity of the Debug variable.
4 – Module Finalization
The TO END DO section allows you to specify a statement, in a
module, to be executed after the executable section of the main
program.
Syntax:
TO END DO statement;
The 'statement' is a VSI Pascal statement.
The TO END DO section can only appear in modules, can only
appear once in a module, and must appear as the last section in
the declaration section (if appearing together, the TO BEGIN DO
section must precede the TO END DO section at the end of the
declaration section).
Example:
MODULE File_Output;
VAR
Out_File : TEXT;
t : TIMESTAMP;
PROCEDURE Test(...); {Executable section...}
TO BEGIN DO
OPEN( Out_File, 'foo.dat' );
END;
TO END DO
BEGIN
GETTIMESTAMP( t );
WRITELN( 'foo.dat closed at', TIME( t ) );
CLOSE( Out_File );
END;
END.
This TO END DO section contains statements that print the file
name and closing time.
5 – Type Declaration
A TYPE section introduces the name and set of values for a
user-defined type or schema definition and has one of the
following forms:
Syntax:
TYPE
{type-identifier = [[attribute-list]] type-denoter}
[[VALUE initial-state-specifier]];...
TYPE
{schema-declaration} [[VALUE initial-state-specifier]]
The 'type-identifier' is the identifier of the type being
defined.
The 'attribute-list' is one or more optional identifiers that
provide additional information about the type-denoter.
The 'type-denoter' is any legal Pascal type syntax.
The 'schema-declaration' is the declaration of a schema type.
The 'initial-state-specifier' is a compile-time expression that
is assignment compatible with a variable of the TYPE identifier
being defined. VSI Pascal initializes all variables declared to
be of this type with the constant value or values provided
(unless there is an overriding initial-state specifier in the
variable declaration).
Pascal requires that all user-defined type identifiers (except
base types of pointers) be defined before they are used in the
definitions of other types. A base type must be defined before
the end of the TYPE section in which it is first mentioned.
Example:
TYPE
Entertainment = ( dinner, movie, theater, concert );
Week_end = ( sat, sun ) VALUE sat;
Hours_worked = ARRAY[mon .. fri] OF INTEGER;
Salary = ARRAY[1 .. 50] OF REAL;
Salary_template( upper_bound : integer ) =
ARRAY [1..upper_bound] of REAL;
Pay = salary;
Ptr_to_hits = ^Hits;
Hits = RECORD
Title, Artist, Composer : VARYING[30] OF CHAR;
Weeks_on_chart : INTEGER;
First_version : Boolean;
END;
VAR
Week1, Week2 : Week_end;
Week3 : Week_end VALUE sun;
Salary_type2 : Salary_template( x );
In this example, 'Week1' and 'Week2' have initial values of sat,
as specified in the TYPE definition of 'Week_end'. 'Week3' has
an initial value of sun, because an initial value specified in
the variable declaration overrides any initial value specified
in the type definition. The 'Salary_template' schema has actual
discriminants of x, which indicates that the upper boundary of
'Salary_type2' will be determined at run time by a variable or
function call.
6 – Variable Declaration
A VAR section declares variables and associates each variable
with an identifier, a type, and optionally an initial value.
Syntax:
VAR
{{variable-identifier},... : [[attribute-list]] type-denoter
[[ {:= | VALUE} initial-state-specifier]]};...
The 'variable-identifier' is the identifier of the variable
being declared.
The 'attribute-list' is one or more optional identifiers that
provide additional information about the variable.
The 'type-denoter' is any legal Pascal type syntax.
The 'initial-state-specifier' is any constant expression that is
assignment compatible with the variable identifier. The
variable is initialized to this expression. See the "HP Pascal
Language Reference Manual" for the rules that apply to the use
of initial-state specifiers on variables.
You can use either the assignment operator (:=) or the reserved
word VALUE. However, if you require portable code, you should
use VALUE.
Example:
TYPE
Hours_worked = ARRAY [1..10] OF INTEGER;
VAR
Answer, Rumor : Boolean;
Temp : INTEGER VALUE 60;
Grade : 'A'..'D';
Weekly_hours : Hours_worked VALUE [1..3 : 7; OTHERWISE 5];
This VAR section declares five variables. The variables
'Answer' and 'Rumor' are both Boolean variables; 'Temp' is an
integer variable initialized with the value 60; 'Grade' is of a
character subrange type consisting of the characters
'A','B','C', and 'D'; 'Weekly_hours' is declared to be of the
user-defined array type 'Hours_worked' and is initialized with a
constructor of integers.
7 – Value Declaration
If you choose, you can use the VALUE section as a VSI Pascal
extension that initializes ordinal, real, array, record, set,
and string variables. (If you require portable code, use the
VALUE reserved word in either TYPE definitions or VAR
declarations.) The exact form of an initialization depends on
the type of the variable being initialized.
Syntax:
VALUE
{variable-identifier := constant-expression};...
The 'variable-identifier' is the name of the variable to be
initialized. You can initialize a variable or variable
component only once in the VALUE section. Any variables
appearing in the VALUE section must appear in a previous VAR
section.
The 'constant-expression' is any constant expression that is
assignment compatible with the variable identifier.
Unlike other declaration sections, the VALUE section can appear
only in a program or module declaration section. You cannot use
the VALUE declaration section in procedures or functions. If
you wish to initialize variables in procedures and functions,
use an initial-state specifier (by using the VALUE reserved word
in either the TYPE or VAR section).
You can assign values to complete structured variables or to a
single component of that variable.
Example:
VAR
School : Record
Class : Record
Grades : Char;
Order : Integer;
End;
Passed : Boolean;
End;
VALUE
School := (('B', 14), TRUE);
The constructor of School specifies a constant value of the
correct type for each field in the record.
8 – Routine Declaration
The basic algorithm for a program can usually be divided into
relatively simple, repetitive tasks. In Pascal, you can code
each task separately as a routine; that is, as either a
procedure or a function. A procedure contains one or more
statements to be executed once the procedure is called. A
function contains one or more statements to be executed once the
function is called; in addition, functions return a single
value.
A routine call executes all statements in the body of the
declared routine. You must declare a routine before you can
call it. In addition, function calls return a single value.
Syntactically, procedure calls are statements, and function
calls are expressions. You can call routines in the executable
section of a program or in the body of another routine.
Syntax:
[[attribute-list]]
PROCEDURE routine-identifier [[formal-parameter-list]];
{ [[declaration-section]] BEGIN {statement};... END |
{EXTERN
EXTERNAL
FORTRAN
FORWARD} }
Syntax:
[[attribute-list]]
FUNCTION routine-identifier [[formal-parameter-list]]
: [[attribute-list]] result-type-id;
{ [[declaration-section]] BEGIN {statement};... END |
{EXTERN
EXTERNAL
FORTRAN
FORWARD} }
The 'attribute-list' is one or more optional identifiers that
provide additional information about the type-denoter.
The 'routine-identifier' is the name of the routine. If you use
the routine-identifier within the routine body (with the
exception of assigning a value to the routine-identifier of a
function), the result is a recursive call to the routine. The
routine-identifier of a procedure can be redeclared in the
procedure's declaration-section. The routine-identifier of a
function cannot be redeclared in the function's
declaration-section; however, it can be redeclared in any nested
routines within the function's declaration-section.
The 'formal-parameter-list' is a comma list of the routine's
formal parameters. A procedure can have as many as 255 formal
parameters; depending on the function return value, some
functions are limited to 254 formal parameters. Optionally, you
can specify a mechanism specifier and an attribute list for each
parameter.
The 'declaration-section' can include all sections except TO
BEGIN DO, TO END DO, and VALUE sections. Data specified in this
declaration section is local to the routine and to any nested
routines; you can redeclare identifiers that are declared in an
outer block. You cannot redeclare a formal parameter identifier
to be a local variable in the routine.
The 'statement' is any VSI Pascal statement. In a function
executable section, there must be at least one statement of the
following form:
routine-identifier := result
The 'routine-identifier' is the name of the function.
The 'result' is a value of either an ordinal, real, structured,
or pointer type that VAX Pascal returns when function is called.
This value must be of the same type as the result-type-id, and
cannot be a file type or a structured type with a file
component.
'EXTERN', 'EXTERNAL', 'FORTRAN', and 'FORWARD' are predeclared
identifiers that direct VSI Pascal to find the body of the
routine elsewhere. The EXTERN, EXTERNAL, and FORTRAN
identifiers declare routines that are independently compiled by
VSI Pascal or that are written in other languages. In VSI
Pascal, these identifiers are equivalent. Although not part of
the Pascal standard, many Pascal compilers only accept the
FORTRAN identifier for external routines actually written in
FORTRAN; if portability is a concern, you may wish to use
FORTRAN only for external FORTRAN routines.
The 'result-type-id' is the type specification of the function
return value. The function's result must be of this data type.
This type cannot be a file type or a structured type with a file
component.
Example:
PROCEDURE Read_Write( VAR A : INTEGER );
This declares a procedure, 'Read_Write', which takes one
variable parameter, 'A'.
Example:
FUNCTION Counter( VAR Instring, Outstring : VARYING[10] OF CHAR;
VAR Valid : Boolean ) : INTEGER;
This declares a function, 'Counter', which takes three variable
parameters, 'Instring', 'Outstring', and 'Valid' and returns an
INTEGER value.
8.1 – formal_parameter_list
A formal parameter is located in the header of the routine
declaration, and consists of input parameters, output
parameters, and routine parameters. A routine uses input
parameters to obtain values; it uses output parameters to return
values; and it uses routine parameters to call another routine
named by a formal parameter.
The formal parameter establishes the semantics, the data type,
and the required passing mechanism of the parameter. See the
"HP Pascal Language Reference Manual" for more information on
parameter passing mechanisms.
Syntax:
[[({ {value-parameter-spec | variable-parameter-spec |
routine-parameter-spec | foreign parameter-spec} };...)]]
The specific format depends on the semantics (value, variable,
routine, or foreign) of the formal parameter you are declaring.
A formal value parameter represents a local variable within the
called routine. When you specify value semantics, the address
of the actual parameter is passed to the called routine, which
then copies the value from the specified address to its own
local storage. The routine then uses this copy. The copy is
not retained when control returns to the calling block.
Therefore, if the called routine assigns a new value to the
formal parameter, the change is not reflected in the value of
the actual parameter.
Syntax:
{identifier},... : [[attribute-list]]
{type-id | conformant-parameter-syntax |
undiscriminated-schema-name}
[[:= [[mechanism-specifier]] default-value]]
A formal variable parameter represents another name for a
variable in the calling block. It is preceded by the reserved
word VAR. When you specify variable semantics, the address of
the actual parameter is passed to the called routine. In
contrast to value semantics, the called routine directly
accesses the actual parameter. Thus, the routine can assign a
new value to the formal parameter during execution and the
changed value is reflected immediately in the calling block (the
value of the actual parameter changes).
Syntax:
VAR {identifier},... : [[attribute-list]]
{type-id | conformant-parameter-syntax |
undiscriminated-schema-name}
[[:= [[mechanism-specifier]] default-value]]
To write a routine that invokes another routine whose effect is
not determined until the program is executed, use routine
parameters. To declare a procedure or a function as a formal
parameter to another routine, you must include a complete
routine heading in the formal parameter list. You can also
associate a foreign mechanism specifier and a default value with
a formal procedure or function parameter.
Syntax:
[[attribute-list]] PROCEDURE procedure-id [[formal-parameter-list]]
[[ := [[mechanism-specifier]] default-value ]]
or
[[attribute-list]] FUNCTION function-id [[formal-parameter-list]] :
[[attribute-list]] result-type-id
[[ := [[mechanism-specifier]] default-value ]]
When declaring an external routine (one written in a language
other than Pascal) that is called by a VSI Pascal routine, you
must specify not only the correct semantics but the correct
mechanism as well. To allow you to obtain these passing
mechanisms, VSI Pascal provides foreign mechanism specifiers and
the passing mechanism attributes.
See the "HP Pascal Language Reference Manual" for complete
details on formal parameter semantics.
8.1.1 – identifier
The 'identifier' is the name of the formal parameter. Multiple identifiers must be separated with commas.
8.1.2 – attribute_list
The 'attribute-list' is one or more optional identifiers which provide information about the formal parameter.
8.1.3 – mechanism_specifier
VSI Pascal provides the foreign mechanism specifiers %IMMED, %REF, %DESCR, and %STDESCR, which precede a formal parameter in the declaration of an external routine. If the formal parameter does not represent a routine, the mechanism specifier must precede the parameter name. If the formal parameter represents a routine, the specifier must precede the reserved word PROCEDURE or FUNCTION in the parameter declaration. In addition, it is possible to use the passing mechanism attributes [IMMEDIATE] and [REFERENCE] in a formal parameter's attribute list to obtain the same behavior as %IMMED or %REF, respectively. A %REF or [REFERENCE] formal parameter requires actual parameters to be passed by reference. %REF or [REFERENCE] implies variable semantics unless the actual parameter is an expression; in that case, it implies foreign value semantics. An %IMMED or [IMMEDIATE] formal parameter requires actual parameters to be passed with the by immediate value mechanism and always implies value semantics. %IMMED or [IMMEDIATE] cannot be used on formal parameters of type VARYING, or on conformant array and conformant VARYING parameters. A %DESCR formal parameter requires actual parameters to be passed with the by descriptor mechanism and interprets the semantics as %REF or [REFERENCE] does. A %STDESCR formal parameter requires actual parameters to be passed with the by string descriptor mechanism. An actual parameter variable of type PACKED ARRAY OF CHAR implies variable semantics. An actual parameter expression of either type PACKED ARRAY OF CHAR or type VARYING OF CHAR implies foreign value semantics. You cannot use %STDESCR on formal procedure and function parameters.
8.1.4 – type_id
A type identifier is the type identifier of the parameters in this parameter section.
8.1.5 – undiscriminated_schema_name
The name of an undiscriminated schema type. If you have a user-defined, formal parameter of an undiscriminated schema type, the corresponding actual parameter must be discriminated from the same schema type as that of the formal parameter. When you pass a string expression to a formal, value parameter of type STRING, the actual parameter's current length (not its declared maximum length) becomes both the maximum length and the current length of the formal parameter.
8.1.6 – conformant_parameter
A conformant parameter is a syntax of a conformant array or a
conformant VARYING parameter that represents a set of types that
are identical except for their bounds. The bounds of a
conformant parameter are determined each time a corresponding
actual parameter is passed. The bounds of an actual parameter
are available within the routine through identifiers declared in
the schema. A conformant parameter can only appear within a
formal parameter list.
The form of a conformant array parameter is as follows:
ARRAY [{lower-bound-id .. upper-bound-id :
[[attribute-list]] index-type-id};...]
OF [[attribute-list]] {type-id | conformant-parameter-syntax}
PACKED ARRAY [lower-bound-id .. upper-bound-id :
[[attribute-list]] index-type-id]
OF [[attribute-list]] type-id
The form of a conformant VARYING parameter is as follows:
VARYING [upper-bound-id] OF [[attribute-list]] CHAR
The 'lower-bound-id' is an identifier that represents the lower
bound of the conformant array's index.
The 'upper-bound-id' is an identifier that represents the upper
bound of the conformant array's index.
The 'attribute-list' is one or more optional identifiers that
provide additional information about the conformant array.
The 'index-type-id' is the type identifier of the index, which
must denote an ordinal type.
The 'type-id' is the type identifier of the array components,
which can denote any type.
8.1.7 – default_value
VSI Pascal allows you to supply default values for formal parameters. Using default parameter values, you do not need to pass actual parameters. Also, you can specify an actual parameter in the position of a formal parameter whose default value you want to override. This value can be any constant value of the type. It must be a legal actual parameter for the kind of formal parameter with which the default is associated. The default-value is evaluated when the routine is declared.
8.2 – block
A block is a declaration section and an executable section.
Programs, modules, and routines are structured in blocks. A
declaration section can contain routine blocks nested within the
outer program or module block; routine blocks can also be nested
within other routines.
Syntax:
[[declaration-section]]
BEGIN
{statement};...
END
The declaration section contains data definitions and
declarations, and nested routine declarations that are local to
the enclosing block. The executable section contains the
statements that specify the block's actions. You can exit from
a block with the last executable statement of the block, which
causes normal termination, or with a GOTO statement, which
transfers control to an outer block.
8.3 – directive
A directive is the alternative to a block in a routine
declaration. A directive provides the compiler with information
about either a routine whose heading is declared separately from
its body (indicated by the FORWARD directive) or a routine that
is external to the Pascal program (indicated by the EXTERNAL,
EXTERN or FORTRAN directives). To specify a directive, include
it immediately after the routine heading and follow it with a
semicolon. The following describes the two classes of
directives.
o The FORWARD directive indicates a routine whose block is
specified in a subsequent part of the same procedure and
function section, allowing you to call a routine before you
specify its routine body. As an extension, VSI Pascal will
allow the body to be in a different declaration part. If
the body and heading are specified in different procedure
and function sections, a FORWARD declared function should
not be used as an actual discriminant to a schema type.
When you specify the body of the routine in subsequent code,
include only the FUNCTION or PROCEDURE predeclared
identifier, the routine-identifier, and the body of the
routine. Do not repeat the formal-parameter, the
attribute-list, or the result-type-id.
o The EXTERNAL, EXTERN and FORTRAN directives indicate that a
routine is external to a Pascal program. They are used to
declare independently compiled Pascal routines written in
other languages. For portability reasons, the FORTRAN
directive should only be used for external routines written
in FORTRAN.