From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=BAYES_00,INVALID_DATE, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!mailrus!tut.cis.ohio-state.edu!husc6!linus!mbunix!eachus From: eachus@mitre-bedford.ARPA (Robert Eachus) Newsgroups: comp.lang.ada Subject: Re: Ada exceptions Summary: Ada Syntax (and style) corrections Keywords: Ada exceptions Message-ID: <39817@linus.UUCP> Date: 12 Sep 88 16:10:10 GMT References: <8957@swan.ulowell.edu> <5701@utah-cs.UUCP> <4055@freja.dk> Sender: news@linus.UUCP Reply-To: eachus@mitre-bedford.arpa (Robert I. Eachus) Organization: The MITRE Corporation, Bedford, Mass. List-Id: 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...