Was this helpful?
Compilation Units and the Scope of Variables
Type names and variable names are local to the closest enclosing Ada compilation unit. EQUEL/Ada compilation units include procedures, functions, package bodies and declaration blocks, all of which can be declared to EQUEL. The objects visible in the scopes include objects that are visible in the parent scope, formal parameters (if applicable) and local declarations. You cannot use the dotted notation to refer to hidden or ambiguous objects by prefixing the object with a subprogram or package name.
As in Ada, once the preprocessor has exited the scope, the variables are no longer visible and cannot be referenced. The Ada package specification is an exception to this visibility rule, because all the package specification contents are visible outside of the package.
The Package Specification
The syntax for an EQUEL/Ada package specification is:
package package_name is
              
[declarations]
end [package_name];
Syntax Notes:
1. Package_names on the package and end statements are not processed and are not compared for equivalence, as required by Ada.
2. You cannot qualify objects in the package specification with any package names.
3. Variables declared in package specifications are global to the parent scope of the specification. This is true even for objects declared in the private section.
When EQUEL reads a package specification, no matter whether it is declared in the same file or included by means of the EQUEL include statement, the contents of the package become visible immediately afterwards. EQUEL behaves as though there were the implicit Ada statements:
with package_name; use package_name;
The use of the EQUEL include statement actually generates the Ada with and use clauses, using the file name as the package name. The preprocessor generates these statements and assumes global visibility of package specification contents, because it does not read Ada library units. This restriction indicates that two package specifications declared at the same scope level cannot declare two objects with the same name. Note that when a package specification is nested in another compilation unit or package specification, it does not create a new scope level. The following example will generate an error because of the redeclaration of the object "ptr":
## package Stack is
## stack_max: constant := 50;
## ptr: Integer range 1..stack_max;
## stack_arr: array(1..stack_max) of Integer;
## end Stack;

## package Employees is
## ename_arr: array(1..1000) of String(1..20);
## ptr: Integer range 1..1000;
## end Employees;
If a package specification declares several types and variables that will be used with various subprograms and package bodies, you should put the specification in a file by itself and use the EQUEL include statement. The include statement will re-read the original text file and behave as though you had issued the appropriate Ada with and use clauses. For more information on the EQUEL include statement, see Include File Processing.
If you do not use the EQUEL include statement, you must explicitly issue the Ada with and use clauses. The following example declares two variables inside a package specification. In a single file are two procedures, which must both be preceded by the with and use clauses:
## package Vars is
## var1: Integer;
## var2: String(1..3);
## end Vars37
## with Vars; use Vars; -- Explicit Ada visibility clauses
## procedure Read_Vars is
## begin                -- EQUEL Statements that retrieve var1 and var2
## end Read_Vars;

with Vars; use Vars;    -- Explicit Ada visibility clauses

## procedure Write_Vars is
## begin                -- EQUEL Statements that append var1 and var2
## end Write_Vars;
The Package Body
The syntax for an EQUEL/Ada package body is:
package body package_name is
              
[declarations]
[begin
              
statements]
end [package_name];
Syntax Notes:
1. Package_names on the package body and end statements are not processed and are not compared for equivalence, as required by Ada.
2. You cannot qualify objects in the package specification with any package names.
3. Variables declared in a package body are visible to the package body and to any nested blocks.
4. If the package body requires knowledge of the package specification, you must make the specification known to EQUEL. This can be done either by including the specification's file by means of the EQUEL include statement, or by including the text of the specification in the EQUEL source file. EQUEL does not assume knowledge of the package specification with the same name as the body.
5. EQUEL does not process separate compilation units and, consequently, does not allow the Ada separate clause.
The Procedure
The syntax for an EQUEL/Ada procedure is:
procedure proc_name [(formal_parameters)is
              
[declarations]
begin
              
statements
end [proc_name];
Syntax Notes:
1. Proc_names on the procedure and end statements are not processed
and are not compared for equivalence, as required by Ada.
2. Formal parameters and variables declared in a procedure are visible to the procedure and to any nested blocks.
3. Formal parameters and their syntax are described in the section on variable declarations.
The Function
The syntax for an EQUEL/Ada function is:
function func_name [(formal_parameters)return result_type is
              
[declarations]
begin
              
statements
end [func_name];
Syntax Notes:
1. Func_names on the function and end statements are not processed and are not compared for equivalence, as required by Ada.
2. EQUEL need not know the result_type, because EQUEL does not allow the use of functions in place of variables in executable statements.
3. Formal parameters and variables declared in a function are visible to the function and to any nested blocks.
4. Formal parameters and their syntax are described in the section on variable declarations.
The Declaration Block
The syntax for an EQUEL/Ada declaration block is:
declare
              
declarations
begin
              
statements
end [block_name];
Syntax Notes:
1. Block_name is not processed and is not compared for equivalence against any block labels (if used).
2. Variables declared in a declaration block are visible to the declaration block and to any nested blocks.
Variable and Type Scope
As mentioned above, variables and types are visible in the block in which they are declared, unless they are declared in a package specification, in which case they are globally visible. Variables can be redeclared only in a nested scope, such as in a declaration block or a nested procedure. Variables cannot be redeclared in the same scope. For example, the following two enumerated type declarations in the same scope will cause a redeclaration of the overloaded literal "UNDEFINED":
## type Question is (SIMPLE, DIFFICULT, UNDEFINED);
## type Answer is (WRONG, RIGHT, SORT_OF, UNDEFINED);
Note that you can declare record components with the same name but different record types. The following example declares two records, each of which has the components "firstname" and "lastname":
## type Child is
## record
##     firstname: String(1..15);
##     lastname: String(1..20);
##     age: Integer;
## end record;

## type Some_Childs is array(1..10) of Child;

## type Mother is
## record
##     firstname: String(1..15);
##     lastname: String(1..20);
##     num_child: Integer range 1..10;
##     children: Some_Childs;
## end record;
The following example shows several different declarations of the variable "var," illustrating how the same object can be redeclared in nested and parallel scopes, each time referring to a different type:
## with equel;

## procedure Proc_A(var: type_1) is

-- Will be used even when this particular "var" is hidden
## proc_a_var: type_1 renames var;

## procedure Proc_B is
##   var: type_2;
## begin   
   -- Var is of type_2
## end Proc_B;
## function Func_C(var: type_3) return Integer is
## begin

  -- Var is of type_3
  -- Note that you cannot refer to Proc_A.var
  -- but you can refer to proc_a_var of type_1.
## end Func_C;

## begin
     -- Var is of type_1

## declare
## var: type_4;
## begin
   -- Var is of type_4;
## end;

-- Var is of type_1

## end Proc_A;
Take special care when using variables with a declare cursor statement. 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 Ada compiler at the point that the open is issued.
## package Bad_Cursor is 
        --This example contains an error

## procedure Init_Csr is
## number: Integer;
## begin

-- Cursor declaration includes reference to "number"
## declare cursor c1 for
##    retrieve (employee.name, employee.age)
##      where employee.num = number

...

## end Init_Csr;
## procedure Process_Csr is
## ename: String(1..15);
## eage: Integer;
## begin
   -- Opening the cursor evaluates invalid "number"
## open cursor c1

## retrieve cursor c1 (ename, eage)

...

## end Process_Csr;

## end Bad_Cursor;
Last modified date: 11/28/2023