{%%%%%%%%% Copyright (c) 2016 Trevor Blight All rights reserved. %%%%%%%%%

     demo program for pan, the pascal analyser

}

program tpan(output);

var
   i : integer;
   x : real;


{test uninitialised varaibles}
procedure uninit;
label 1;
var
   c : char;
   pc : ^char;
   x : real;
   i : integer;   {shadows global variable i}
   r : record
          b : boolean;
          a : (red, orange, green);
       end;
   a : array[1..5] of char;
   s : set of char;

{tricky - this function & r.b initialise each other (supposedly)
 also, the return value of the function might not be assigned a value}
   function f: boolean;
   begin
      if r.b then
         f := true;
   end; { f }

begin
   writeln( 'i has no initial value: ', i:1 );

   if i = 0 then
      writeln('pc^ has no initial value: ''', pc^, '''');

   if r.b then
      writeln( 'r.b has no initial value: ', r.b );

   with r do begin
      b := f;
      writeln( 'r.a has no initial value: ', ord(r.a) );
   end;

   if a[2] = '6' then
      writeln( 'a[2] has no initial value: ''', a[2], '''' );

   a[2] := '6';
   if a[3] = '6' then
      writeln( 'a[3] has no initial value: ''', a[3], '''' );

   if 's' in s then
      writeln( 'set s has no initial value' );

   c := c;  {initialised to itself !!}
   writeln( 'c has no initial value: ''', c, '''' );

   goto 1;
   x := 22.2;
1:
  writeln( 'x has no initial value: ' , x:1:1 );


end; { uninit }


{test uninitialised varaibles
 this function is never called, so uninitialised variables are optimised out
 and no uninitialised variables are reported
}
procedure uninit0;
var
   c : char;
   i : integer;   {shadows global variable i}
begin
   writeln( 'i has no initial value: ', i:1 );

   c := c;  {initialised to itself !!}
   writeln( 'c has no initial value: ''', c, '''' );
end; { uninit0 }

{test unused }
procedure testUnused;

var
   ui : integer;
   ub : boolean;
   uc : char;
   ux : real;

   procedure p(up:real);
   var
      ui : integer;
      ub : boolean;
      uc : char;
      ux : real;
      ur : record
              x : real;
              i : integer;
           end;
   begin
      with ur do
         writeln('up is unused');
   end; { p }

begin
   p(ux); {ux used here, but parameter is unused}
   writeln('unused variables ui, ub, uc, ux');
end; { testUnused }


{test unused but set variable & parameters}
procedure testUnusedSet;

var
   ui : integer;
   ub : boolean;
   uc : array[1..9, 1..9] of char;
   ux : real;
   uy : real;

   procedure p(up:real);
   var
      ui : integer;
      ub : boolean;
      uc : char;
      ux : real;
   begin
      writeln('up is unused');
   end; { p }

begin
   p(ux);
   ux := 13;
   ub := true;
   ui := 14;
   uc[1][1] := uc[1][2]; {used uninitialised}
   p(uy); {uy used here, but parameter is unused}
   p(15);
   writeln('unused variables ui, ub, uc, ux');
end; { testUnusedSet }


procedure testothers;
var
   i,j : integer;
   x   : real;
begin
   if (j = 0) or (j=1) and (i<=0) then
      if i = 0 then
         writeln
      else
         writeln('dangling else');

   j := maxint;
   if x = 13.7 then begin   { comparing real nrs }
      i := (j div 112) * 113;  {overflow}
      j := j + 1;              {overflow}
   end;
   writeln('overflow test, j is ', j:1);
   writeln('overflow test, i is ', i:1);


   {empty body tests}
   while (x > 0) and (x < 0) do;
   if x = 0 then;
   for i := 0 to 6 do;
   repeat until (x > 0) and (x < 0);

end; { testothers }

function f:integer;
begin
   if i > 0 then
      f := i;
end; { f }

begin

   uninit;
   testUnused;
   testUnusedSet;
   testothers;

   {all global variables, including i are initialised to 0!!}
   writeln;
   if i >= f then
      writeln( 'pan test, global i is ', i:1 );
   if x >= 0 then
      writeln( 'pan test, global x is ', x:1:1 );
end.

{%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end of tpan.pas %%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
