Compilation Units and the Scope of Objects
Following Pascal conventions, all objects in an EQUEL/Pascal program are local to the scope in which they are declared and are visible in any nested scopes unless hidden by an intermediate redeclaration.
Constant, label, type, and variable names are local to the closest enclosing Pascal compilation unit. EQUEL/Pascal compilation units include programs, modules, procedures, and functions. The objects visible in their scopes include objects that are visible in the parent scope, formal parameters (if applicable), and local declarations. As in Pascal, once the preprocessor has exited the scope, the variables are no longer visible and cannot be referenced.
Note that compilation units that use EQUEL statements must be declared to EQUEL. This is accomplished by preceding the unit's header and its begin and end statements with the ## mark.
EQUEL does not support Pascal inherited environments, except for the special case of the EQUEL environment. For more information, see
The Inherit Attribute.
Predeclared Identifiers
EQUEL predeclares all the standard Pascal types and constants, which are listed in
Data Types and Constants) in a scope enclosing the entire program. You should not redefine any of these identifiers because the runtime library expects the standard definitions.
Compilation Unit Syntax
The following sections describe the compilation unit syntax.
The Program Unit
The syntax for an EQUEL/Pascal program definition is:
program program_name [(identifier {, identifier})];
[declarations]
begin
[statements]
end.
where declarations can include any of the following:
label label_declarations
const constant_declarations
type type_declarations
var variable_declarations
procedures
functions
host_code
For a detailed description of the various types of declarations, see
Declaration Syntax.
Syntax Notes:
1. The program_name and the identifiers are not processed by EQUEL.
2. The various declaration sections can appear in any order and can be repeated.
3. The label declaration section is allowed only for compatibility with earlier versions of Ingres.
The Module Unit
The syntax for an EQUEL/Pascal module definition is:
module module_name [(identifier {, identifier})];
[declarations]
end.
where
declarations are the same as those for program units (see above). For a detailed description of the various types of declarations, see
Declaration Syntax.
Syntax Notes:
1. The module_name and the identifiers are not processed by EQUEL.
2. The various declaration sections can appear in any order and can be repeated.
## module ExternalVars;
## var
## CurFormName, CurFieldName, CurColName :
## varying[12] of Char;
## CurTableRow : Integer;
## end.
The Procedure
The syntax for an EQUEL/Pascal procedure is:
procedure procedure_name [(formal_parameters)];
[declarations]
begin
[statements]
end;
Syntax Notes:
1. The procedure_name is not processed by EQUEL.
2. Formal parameters and variables declared in a procedure are visible to the procedure and to any nested blocks.
## procedure AppendRow( name : varying[ub] of Char;
## age : Integer;
## salary : Real );
## begin
## APPEND TO emp (#name = name, #age = age,
## salary = salary)
## end;
The Function
The syntax for an EQUEL/Pascal function is:
function function_name [(formal_parameters)] : return_type_name
[declarations]
begin
[statements]
end;
Syntax Notes:
1. The function_name is not processed by EQUEL.
2. Formal parameters and variables declared in a function are visible to the function and to any nested blocks.
4. EQUEL does not allow function calls to replace variables in executable statements. Therefore, EQUEL need not know the return_type_name.
The following is an example of a function:
## function WasError( errorBuf : varying[ub] of
## Char ) : Boolean;
## const
## EquelNoError = 0;
## var
## errNum : Integer;
## begin
## INQUIRE_EQUEL (errNum = error)
if errNum = EquelNoError then
begin
errorBuf := ' ';
WasError := FALSE;
end else
begin
SetErrorBuf( errNum, errorBuf );
WasError := TRUE;
end;
## end;
The Scope of Objects
As mentioned above, constants, variables and types are visible in the block in which they are declared. Objects can be redeclared only in a nested scope, such as in a nested procedure, but not in the same scope.
Note that you can declare record components with the same name if they are in different record types. The following example declares two records, each of which has the components "firstname" and "lastname":
## type
## Child = record
## firstname: varying[20] of Char;
## lastname: varying[20] of Char;
## age: Integer;
## end;
## Mother = record
## firstname: varying[20] of Char;
## lastname: varying[20] of Char;
## num_child: 1..10;
## children: array[1..10] of Child;
## end;
The following example shows several different declarations of the variable "a_var," illustrating how the same name can be redeclared in nested and parallel scopes, each time referring to a different type:
## procedure Proc_A(a_var: type_1);
## procedure Proc_B;
## var
## a_var: type_2;
## begin
{A_var is of type_2}
## end;
## function Func_C(a_var: type_3) : Integer;
## begin
{Var is of type_3}
## end;
## begin
{A_var is of type_1}
## end;
Take special care when using variables with a declare cursor statement. The scope of the variables used in such a statement must also be valid in the scope of the open statement for that same cursor. The preprocessor actually generates the code for the declare at the point that the open is issued, and at that time, evaluates any associated variables.
For example, in the following program fragment, even though the variable "number" is valid to the preprocessor at the point of the declare cursor statement, it is not a valid variable name for the Pascal compiler at the point that the open is issued.
## procedure Init_Cursor; { Example contains an error }
## var
## number: Integer;
## begin
{ Cursor declaration includes reference to "number" }
## declare cursor c1 for
## retrieve (employee.name, employee.age)
## where employee.num = number
...
## end; { Init_Cursor }
## procedure Process_Cursor;
## var
## ename: varying[15] of char;
## eage: Integer;
## begin
{ Opening the cursor evaluates invalid "number" }
## open cursor c1
## retrieve cursor c1 (ename, eage)
...
## end; { Process_Cursor }