
(run "


% Tests all variations of the call-by specifier.
% Set the parameters to f as specified below.
let
  a = 0
  b = 0
  c = 0
in
  let

    % Returns the number of times it has been called.
    g1 =
      let
        count = 0
      in
        proc ()
          begin
            set count = add1(count);
            count
          end

    % Returns the number of times it has been called.
    g2 =
      let
        count = 0
      in
        proc ()
          begin
            set count = add1(count);
            count
          end

    % Tests the call-by specifiers of its arguments.
    f = 
      proc (x, y, z, h1, h2)
        begin
          % Testing lazy evaluation on h1 by not using it.

          % Testing call-by-name/need on h2 by using it multiple times.
          h2;
          h2;
          h2;

          % Testing whether y is call-by-value-result by setting the value
          % of x according to b's value.  Since y called with b below,
          % call-by-reference would change the value of b in the first statement,
          % but call-by-value-result would not change the value of b since
          % it copies the parameter value during the procedure call.
          set y = 10;
          set x = b;

          % Testing whether z is call-by-value by updating a parameter's value.
          set z = 10
        end

    m = 0
    n = 0
  in
    begin
      (f  ref a  ref b  value-result c  name (g1)  name (g2));

      % Values of variables after call above when they have call-by specifier.
      % Keep a as type ref for this table to work.
      %
      % when b has type  a has value
      % ---------------  -----------
      % value               0
      % value-result        0
      % ref                10
      % name               10
      % need               10
      %
      % when c has type  c has value
      % ---------------  -----------
      % value               0
      % value-result       10
      % ref                10
      % name               10
      % need               10
      %
      % when (g1) has type  (g1) has value
      % ------------------  --------------
      % value                   2
      % value-result            2
      % ref                     2
      % name                    1
      % need                    1
      %
      % when (g2) has type  (g2) has value
      % ------------------  --------------
      % value                   2
      % value-result            2
      % ref                     2
      % name                    4
      % need                    2


      % Check that the sum is correct according to the tables above.
      +(+(a,c), +((g1),(g2)))

    end

")

