comp.lang.ada
 help / color / mirror / Atom feed
From: eachus@mitre-bedford.ARPA (Robert Eachus)
Subject: Re: Ada exceptions
Date: 12 Sep 88 16:10:10 GMT	[thread overview]
Message-ID: <39817@linus.UUCP> (raw)
In-Reply-To: 4055@freja.dk

In article <4055@freja.dk> carllp@freja.dk (Carl-Lykke Pedersen) writes:

>PL/1:
>     FACTORIAL: PROCEDURE;
>	DECLARE (N, F) FIXED FIN (31) INIT (1);
>	ON FINISH BEGIN;
>	  PUT LIST (N, "FACTORIAL =", F);
>	  PUT SKIP;
>	  N = N + 1;
>	  F = N * F;
>	  STOP;
>	  END;
>	STOP;
>     END FACTORIAL;

     I'm not sure what the PL/I example is trying to demonstrate, so I
won't try to rewrite it in PL/I, but it is very simple in Ada:

with TEXT_IO;
procedure FACTORIALS is
  type My_Int is range -2**31..2**31-1;
-- Since the program's behavior depends on 32 bit integers,
-- force a type and subtype with the range expected.
  N, F: My_Int := 1;
begin
  loop
    TEXT_IO.Put_Line(My_Int'IMAGE(N) & "FACTORIAL =" & My_Int'IMAGE(F));
    N := N + 1;
    F := F * N;
  end loop;
exception
  when others => TEXT_IO.Put_line("  That's all folks!");
end FACTORIALS;

>Ada:
>     function DIVIDE_CHECK(X, Y: REAL) return REAL is
>	begin
>	  if X = 0 then
>		raise SILLY;
>	  else X/Y;
>	  endif;
>	exception
>	  when NUMERIC_ERROR => return 0;
>	  when SILLY => return -1;
>     end;

>Sorry if the syntax isn't correct. I do not have an Ada-compiler (or a PL/1-
>compiler).

     There  is a missing  "return"   before  X/Y.   If  REAL is not an
integer type, the constants need to contain  decimal points.  There is
a syntactic problem  is much  more  subtle.  A  compiler is allowed to
generate code which computes  X/Y in a  type with wider range and then
convert the result to REAL. (This is  not  just a theoretical case, it
happens  all the  time with IEEE  floating  point.)   This  results in
CONSTRAINT_ERROR being raised   in some cases,   and NUMERIC_ERROR  in
others. There may also  be a programming mistake.   I assume that  you
want to raise SILLY  when  Y is zero,  but I'm not sure, since raising
SILLY when X is zero is certainly silly. :-)

     There  are also  two   problems of  style.   You surely  want the
function named  "/",  unless it  is generic,   and it is bad   form to
declare an exception like SILLY (you did intend to  declare it, didn't
you?) just to handle it locally. So:

  generic
    type REAL is digits <>;
    DIVIDE_BY_ZERO_RETURN_VALUE: in REAL := -1.0;
    OVERFLOW_RETURN_VALUE: in REAL := 0.0;
  function DIVIDE_WITH_ERROR_HANDLING (X, Y: REAL) return REAL is
  begin
    if Y = 0.0
    then return DIVIDE_BY_ZERO_RETURN_VALUE;
    else return X/Y;
    endif;
  exception
    when CONSTRAINT_ERROR | NUMERIC_ERROR => 
      return OVERFLOW_RETURN_VALUE;
  end DIVIDE_WITH_ERROR_HANDLING;

  -- Now it can be instantiated as follows.  I've changed the overflow
  -- default to show how it's done.

  function "/" is new Divide_with_Error_Handling
                 (Float, Overflow_return_value => Float'LAST);


					Robert I. Eachus

with STANDARD_DISCLAIMER;
use  STANDARD_DISCLAIMER;
function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...

      reply	other threads:[~1988-09-12 16:10 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1988-09-06 22:07 Real time environment w/ 300K+ lines? MFHorn
1988-09-07  9:01 ` Ada exceptions Daniel M Floyd
1988-09-07 22:28   ` Robert Eachus
1988-09-09 16:57   ` Carl-Lykke Pedersen
1988-09-12 16:10     ` Robert Eachus [this message]
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox