Homework 11, Parameter-passing and procedure activations

1. For each to the 4 parameter transition techniques discussed, give the output of the following program.

program p(output);
   var a,b,i: integer;
       c: array [1..4] of integer;
   procedure s(d,e,f: integer);
      begin
         d := 5; b := a+3; e := 3; i:= 1; f:= 20; c[i] := 200
      end;
   begin
      c[1] := 100; c[2] := 150; c[3] := 175; c[4] := 190;
      a := 10; b := 5; i := 2;
      s(a,i,c[i]);
      writeln(a,b,c[1],c[2],c[3],c[4])
   end.

2. We define a new parameter-passing technique, call-by-need, based on the notion of lazy evaluation. When a parameter is passed, it is not evaluated until the code of the called procedure actually needs the value. Then evaluation takes place, the result is stored in a temporary, and further references use the stored value. If Pascal adopted call-by-need parameters as its default parameter passing mechanism, what would the following program print?

program P(output);
   function R(A,B: integer): integer;
      begin
         if B = 0 then R := 0
         else R := R(A,B)
      end;
   begin
      writeln(R(R(1,1),R(0,0)))
   end.

3. The following program was written to exchange the values of two integer variables. If the parameter transmission mechanism were changed to by-name, is there a set of input variables whose values cannot be exchanged?

procedure Swap(var X,Y: integer);
   begin
      integer T;
      T := X; X := Y; Y := T
   end;

4. Give the least restrictive limits that can be placed on actual parameters so that call by name and call by reference give the same results.

5. What is the output of the following program if parameters are passed by name?

program P(output);
   var A: array [1..4] of integer;
       I, J: integer;
   procedure R(X,Y,Z: integer);
      begin
         I := I + 1;
         J := J + 2;
         X := X * Z;
         Y := 0
      end;
   procedure Q;
      var J,K: integer;
      begin
         J := 2;
         K := 3;
         R(A[I], A[J], J + K)
      end;
   begin
      for J := 1 to 4 do A[J] := 3;
      J := 1;
      I := 2;
      Q;
      writeln(A[1],A[2],A[3],A[4])
   end.

6. When a procedure is called, a compiler creates an activation record with information about where the procedure was called, what its parameters are, where the code of the procedure starts, etc.

When the last statement executed in the body of a procedure is a recursive call, the call is said to be tail recursive. A tail-recursive call can be replaced by a jump to the beginning of the procedure, thereby avoiding the overhead of a call and the allocation of additional stack memory.

Consider a block-structured language such as Pascal but without pointers. Discuss how by-value and by-reference parameter passing would be handled (without changing the semantics of the language) in an implementation of tail recursion optimization. Be sure to consider the cases where the actual parameter is a non-local variable, local variable, reference parameter, or value parameter. For any actual parameter/parameter passing scheme that can't be handled in the presence of tail recursion, explain why and give an example of a program which demonstrates the problem.

7. Calculate the output for the following program.

1  program Main(input, output);
2     var A: integer;
3     procedure P(var M: integer);
4       begin
5         M := M + 10;
6         writeln(M)
7       end;
8     procedure R (procedure X(var D: integer));
9       var B: integer;
10      procedure S(var C: integer);
11        begin
12          C := A + B + C;
13          X(C);
14          writeln(C)
15        end;
16      begin
17        A := A - 1;
18        B := A;
19        if B > 0 then R(S) else S(B);
20      end;
21    begin
22      A := 2;
23      R(P);
24      writeln(A)
25    end.

8. What outputs are produced by the following program if delete's parameters are passed by value, value-result, or reference?

program Main (output);
type elemptr = ^element;
     element = record
                  data: integer;
                  next: elemptr
               end;
var first, e, t : elemptr;
    i: integer;
procedure delete (p: elemptr);
  begin
    p^.next := p^.next^.next;
    p := nil;
  end;
procedure print (p: elemptr);
  begin
    write('start:');
    while p <> nil do begin
       write(p^.data);
       p := p^.next
    end;
    writeln
  end;
begin
   first := nil;
   for i := 1 to 3 do begin
      new(e); e^.data := i; e^.next := first; first := e
      end;
   print(first);
   t := first;
   delete(t^.next);
   print(first)
end.