Access to Non-local Names:
- In some cases, when a procedure refer to variables that are not local to it, then such variables are called nonlocal variables
- There are two types of scope rules, for the non-local names. They are
Static
scope
Dynamic
scope
Static Scope or Lexical
Scope
- Lexical scope is also called static scope. In this type of scope, the scope is verified by examining the text of the program.
- Examples: PASCAL, C and ADA are the languages that use the static scope rule.
- These languages are also called block structured languages
Block
- A block defines a new scope with a sequence of statements that contains the local data declarations. It is enclosed within the delimiters.
Example:
{
Declaration statements
……….
}
- The beginning and end of the block are specified by the delimiter. The blocks can be in nesting fashion that means block B2 completely can be inside the block B1
- In a block structured language, scope declaration is given by static rule or most closely nested loop
- At a program point, declarations are visible
The
declarations that are made inside the procedure
The
names of all enclosing procedures
The
declarations of names made immediately within such procedures
- The displayed image on the screen shows the storage for the names corresponding to particular block
- Thus, block structure storage allocation can be done by stack
Lexical Scope for Nested
Procedure
- If a procedure is declared inside another procedure then that procedure is known as nested procedure
- A procedure pi, can call any procedure, i.e., its direct ancestor or older siblings of its direct ancestor
Procedure
main
Procedure
P1
Procedure
P2
Procedure
P3
Procedure
P4
Nesting Depth:
- Lexical scope can be implemented by using nesting depth of a procedure. The procedure of calculating nesting depth is as follows:
The
main programs nesting depth is ‘1’
When a
new procedure begins, add ‘1’ to nesting depth each time
When
you exit from a nested procedure, subtract ‘1’ from depth each time
The
variable declared in specific procedure is associated with nesting depth
Static Scope or
Lexical Scope
- The lexical scope can be implemented using access link and displays.
Access Link:
- Access links are the pointers used in the implementation of lexical scope which is obtained by using pointer to each activation record
- If procedure p is nested within a procedure q then access link of p points to access link or most recent activation record of procedure q
Example: Consider the following piece of code and the
runtime stack during execution of the program
program
test;
var a:
int;
procedure
A;
var d:
int;
{
a
:= 1,
}
procedure
B(i: int);
var b :
int;
procedure
C;
var k :
int;
{
A;
}
{
if(i<>0) then B(i-1)
else
C;
}
{
B(1);
}
Displays:
- If access links are used in the search, then the search can be slow
- So, optimization is used to access an activation record from the direct location of the variable without any search
- Display is a global array d of pointers to activation records, indexed by lexical nesting depth. The number of display elements can be known at compiler time
- d[i] is an array element which points to the most recent activation of the block at nesting depth (or lexical level)
- A nonlocal X is found in the following manner:
- Use one array access to find the activation record containing X. if the most-closely nested declaration of X is at nesting depth I, the d[i] points to the activation record containing the location for X
- Use relative address within the activation record
Example:
How to maintain
display information?
- When a procedure is called, a procedure ‘p’ at nesting depth ‘i’ is setup:
Save
value of d[i] in activation record for ‘p’
‘I’ set
d[i] to point to new activation record
- When a ‘p’ returns:
Reset
d[i] to display value stored
Where can display be maintained?
- Registers
- In statically allocated memory (data segment)
- Store display or control stack and create a new copy on each entry