
/* Multiplication with a loop */
proc fact1 (a:int) returns (b:int) 
var c:int;
begin
  if (a<=1) then
    b = 1;
  else
    c = a - 1;
    c = fact1(c);
    b = 0;
    while (c>0) do
      b = b+a;
      c = c-1;
    done;
  endif
  ;
end

/* Multiplication with a procedure call.
   Permuting the arguments change the result */
proc mul (a:int, b:int) returns (c:int)
var t: int;
begin
  c = 0;
  t = b;
  while (t>0) do
    c = c+a;
    t = t-1;
  done 
  ;
end
proc fact2 (a:int) returns (b:int) 
var c:int;
begin
  if (a<=1) then
    b = 1;
  else
    c = a - 1;
    c = fact2(c);
    b = mul(c,a);
  endif
  ;
end

/* Direct Multiplication.
   Changing the order of the arguments changes the result */
proc fact3 (a:int) returns (b:int) 
var c:int;
begin
  if (a<=1) then
    b = 1;
  else
    c = a - 1;
    c = fact3(c);
    b = c*a;
  endif
  ;
end

var
y:int,z:int;

begin
y = 1;
while true do
  z = fact1(y);
  z = fact2(y);
  z = fact3(y);
  y = y+1;
done;
end
