Intermediate Code for Procedures
Procedures and their
implementation will be discussed at length in Chapter 7, along with the
run-time management of storage for names. We use the term function in this
section for a procedure that returns a value. We briefly discuss function
declarations and three-address code for function calls. In three-address code,
a function call is unraveled into the evaluation of parameters in prepa-ration
for a call, followed by the call itself. For simplicity, we assume that
parameters are passed by value; parameter-passing methods are discussed in
Section 1.6.6.
Example 6.25 : Suppose that a is
an array of integers, and that f is a function from integers to integers. Then,
the assignment
The first two lines compute the
value of the expression a [ i ] into temporary t 2 , as discussed in Section
6.4. Line 3 makes t2 an actual parameter for the call on line 4 of f with one
parameter. Line 5 assigns the value returned by the function call to t 3 . Line
6 assigns the returned value to n.
The productions in Fig. 6.52
allow function definitions and function calls. (The syntax generates unwanted
commas after the last parameter, but is good enough for illustrating
translation.) Nonterminals D and T generate declara-tions and types,
respectively, as in Section 6.3. A function definition gener-ated by D consists of keyword define, a return
type, the function name, for-mal parameters in parentheses and a function body
consisting of a statement. Nonterminal F
generates zero or more formal parameters, where a formal pa-rameter consists of
a type followed by an identifier. Nonterminals S and E generate
statements and expressions, respectively. The production for S adds a statement that returns the
value of an expression. The production for E
adds function calls, with actual parameters generated by A. An actual parameter is an expression.
Function definitions and function
calls can be translated using concepts that have already been introduced in
this chapter.
Function types. The type of a
function must encode the return type and the types of the formal parameters.
Let void be a special type that represents no parameter or no return type. The
type of a function pop() that returns an integer is therefore "function
from void to integer." Function types can be represented by using a
constructor fun applied to the return type and an ordered list of types for the
parameters.
Symbol tables. Let s be the top
symbol table when the function definition is reached. The function name is
entered into s for use in the rest of the program. The formal parameters of a
function can be handled in analogy with field names in a record (see Fig. 6.18.
In the production for D, after seeing define and the function name, we push s
and set up a new symbol table
Env.push(top)] top = new
Env(top);
Call the new symbol table, t.
Note that top is passed as a parameter in n e w Env(top), so the new symbol
table t can be linked to the previous one, s. The new table t is used to
translate the function body. We revert to the previous symbol table s after the
function body is translated.
• Type checking. Within expressions, a function is
treated like any other operator. The
discussion of type checking in Section 6.5.2 therefore carries over, including
the rules for coercions. For example, i f / i s a function with a parameter of
type real, then the integer 2 is coerced to a real in the call
( 2 ) .
Function calls. When generating three-address
instructions for a function call id(E, E,... , E), it is sufficient to
generate the three-address instruc-tions for evaluating or reducing the
parameters E to addresses, followed
by a param instruction for each parameter. If we do not want to mix the
parameter-evaluating instructions with the param instructions, the attribute
E.addr for each expression E can be saved in a data structure
such as a queue. Once all the
expressions are translated, the param in-structions can be generated as the
queue is emptied.
The procedure is such an important and frequently
used programming con-struct that it is imperative for a compiler to good code
for procedure calls and returns. The run-time routines that handle procedure
parameter passing, calls, and returns are part of the run-time support package.
Mechanisms for run-time support are discussed in Chapter 7.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.