0% found this document useful (0 votes)
503 views3 pages

Procedure Calls in Compiler Design

This document discusses the importance of generating efficient code for procedure calls in compiler design, detailing the calling sequences and actions involved during procedure calls. It explains access links and displays for managing non-local names, highlighting the differences between static (lexical) and dynamic scoping. The document also outlines methods for implementing non-local access, including deep and shallow access techniques.

Uploaded by

Mamatha
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
503 views3 pages

Procedure Calls in Compiler Design

This document discusses the importance of generating efficient code for procedure calls in compiler design, detailing the calling sequences and actions involved during procedure calls. It explains access links and displays for managing non-local names, highlighting the differences between static (lexical) and dynamic scoping. The document also outlines methods for implementing non-local access, including deep and shallow access techniques.

Uploaded by

Mamatha
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Compiler Design Unit-5

Procedure Calls
The procedure is an important and frequently used programming construct that it is
imperative for a compiler to generate good code for procedure calls and returns. The run-time
routines that handle procedure argument passing, calls and returns are part of the run-time
support package.
Let us consider a grammar for a simple procedure call statement
(1) S->call id(Elist)
(2) Elist-> Elist , E
(3) Elist-> E
Calling Sequences:
The translation for a call includes a calling sequence, a sequence of actions taken on entry to and
exit from each procedure. The following are the actions that take place in a calling sequence:
 When a procedure call occurs, space must be allocated for the activation record of the
called procedure.
 The arguments of the called procedure must be evaluated and made available to the called
procedure in a known place.
 Environment pointers must be established to enable the called procedure to access data in
enclosing blocks.
 The state of the calling procedure must be saved so it can resume execution after the call.
 Also saved in a known place is the return address, the location to which the called routine
must transfer after it is finished.
 Finally a jump to the beginning of the code for the called procedure must be generated.
For example, consider the following syntax-directed translation
(1) S-> call id ( Elist )

{ for each item p on queue do emit (‘ param’ p );

emit (‘call’ [Link]) }


Here, the code for S is the code for Elist, which evaluates the arguments, followed by a
param p statement for each argument, followed by a call statement.

1
Compiler Design Unit-5

(2) Elist-> Elist , E


{ append [Link] to the end of queue }
(3) Elist-> E

{ initialize queue to contain only [Link] }


Here, queue is emptied and then gets a single pointer to the symbol table location for the
name that denotes the value of E.
Access Links and Displays for Non-Local Names
 An access link is a pointer to each activation record that obtains a direct implementation of
lexical scope for nested procedures. In other words, an access link is used to implement
lexically scoped language. An “access line” can be required to place data required by the
called procedure.
 An improved scheme for handling static links defined at various lexical levels is the
usage of a data structure called display. A display is an array of pointers to the
activation records. Display [0] contains a pointer to the activation record of the most
recent activation of a procedure defined at lexical level 0.
 The number of elements in the display array is given by the maximum level of nesting in the
input source program. In the display scheme of accessing the non-local variables defined in
the enclosing procedures, each procedure on activation stores a pointer to its activation
record in the display array at its lexical level.
 It saves the previous value at that location in the display array and restores it when the
procedure exits. The advantage of the display scheme is that the activation record of any
enclosing procedure at lexical level ‘n’ can be directly fetched using Display [n] as opposed
to traversing of the access links in the previous scheme.
There are two types of scope rules for the non-local names are as follows −
Static Scope or Lexical Scope
Lexical scope is known as static scope. In this type of scope, the scope is tested by determining
the text of the program. An example such as PASCAL, C and ADA are the languages that use
the static scope rule. These languages are also known as blockstructured languages.
Dynamic Scope

2
Compiler Design Unit-5

The dynamic scope allocation rules are used for non-block structured languages. In this type of
scoping, the non-local variables access refers to the non-local data which is declared in most
recently called and still active procedures. There are two methods to implement non-local
accessing under dynamic scoping are −
Deep Access − The basic concept is to keep a stack of active variables. Use control links instead
of access links and to find a variable, search the stack from top to bottom looking for the most
recent activation record that contains the space for desired variables. This method of accessing
nonlocal variables is called deep access. Since search is made “deep” in the stack, hence the
method is called deep access. In this method, a symbol table should be used at runtime.
Shallow Access − The idea to keep central storage and allot one slot for every variable name. If
the names are not created at runtime then the storage layout can be fixed at compile time.

You might also like