* Ada for Data Processing? @ 1996-10-02 0:00 William Frye 1996-10-03 0:00 ` Alan Brain 0 siblings, 1 reply; 6+ messages in thread From: William Frye @ 1996-10-02 0:00 UTC (permalink / raw) Is there any one out there whoe can point me towards information and/or tools to take some of the pain out of doing DP work in Ada. Some very common DP situations (e.g. reading in variable format records with "discriminats that are two or more characters long) seem very difficult in Ada. (I have just recently started working in an Ada DP environment without report writing tools already established.) ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Ada for Data Processing? 1996-10-02 0:00 Ada for Data Processing? William Frye @ 1996-10-03 0:00 ` Alan Brain 1996-10-05 0:00 ` Keith Thompson 0 siblings, 1 reply; 6+ messages in thread From: Alan Brain @ 1996-10-03 0:00 UTC (permalink / raw) William Frye wrote: > > Is there any one out there whoe can point me towards information and/or > tools to take some of the pain out of doing DP work in Ada. Some > very common DP situations (e.g. reading in variable format records > with "discriminats that are two or more characters long) seem very > difficult in Ada. (I have just recently started working in an Ada > DP environment without report writing tools already established.) Hmmm.. this seems odd to me, it's one of the easier things in Ada-83. Here's the absolutely-guarenteed-to-work-always method. Let's assume you have a 2000 Char record, written by a COBOL, RPG or Assembler program, way back when. First, read the thing into a buffer of type BYTE_ARRAY, ie stick it in a typeless buffer defined only as a whole heap of consecutive memory. Second, use (Shock Horror) UNCHECKED_CONVERSION on the first discriminant. Third, do an assignment to the non-representation-clause-defined base type, and catch any exceptions raised. (How's that again?...See below for example fragments) Type TRAFFIC_LIGHT_TYPE is (Red, Yellow, Green); Type REPRESENTED_TRAFFIC_LIGHT_TYPE is new TRAFFIC_LIGHT_TYPE; for REPRESENTED_TRAFFIC_LIGHT_TYPE'SIZE use 16; for REPRESENTED_TRAFFIC_LIGHT_TYPE use ( RED => 16#FE00, YELLOW => 16#00FF, GREEN => 16#EE77); TARGET : TRAFFIC_LIGHT_TYPE; SOURCE : REPRESENTED_TRAFFIC_LIGHT_TYPE; begin -- do the unchecked conversion to SOURCE here -- -- .. PARANOIA_BLOCK: begin TARGET := TRAFFIC_LIGHT_TYPE(SOURCE); exception when CONSTRAINT_ERROR => -- your data is definitely bad -- etc end PARANOIA_BLOCK; .. end Note that if you had the record stored as "RE", "YE", "GR" then it might be a better idea to write a simple function that converts the character representation into a hex code, not strictly neccessary but would improve readability. Another bananaskin is that some older compilers may insist on no more than 8 bits for enumerated types. But even then, the 'SIZE clause above should over-ride that. Why use a seperate "represented" type for anything coming over I/O? Firstly, efficiency. The compiler will pick the most eficient representation for the machine. In the general case, this will not be the same as the data representation on the line/disk. Secondly, you may well have a different representation depending on the device. For example the char string "RE" on the disk may translate into 2#100 for the traffic light controller. You use the same base type - Traffic Light Type - in either case, but convert to different derived types for I/O. Thirdly, if the data comes from outside the system DON'T TRUST IT. Until you've done some operation - such as a simple type conversion and assignment - the UNCHECKED conversion is just that. If the data says "YE" when it's supposed to be "RE", both being valid values, you're out of luck (at least until you do similar assignments later on). But if it says "&Z" then you know it's crap. Maybe shifted left 1 bit by a hardware glitch, maybe corrupted, maybe just not adhering to the spec. I know whereof I speak, I've had exactly this problem. Any more tips, will be glad to give. ---------------------- <> <> How doth the little Crocodile | Alan & Carmel Brain| xxxxx Improve his shining tail? | Canberra Australia | xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM ---------------------- o OO*O^^^^O*OO o oo oo oo oo By pulling Maerklin Wagons, in 1/220 Scale ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Ada for Data Processing? 1996-10-03 0:00 ` Alan Brain @ 1996-10-05 0:00 ` Keith Thompson 1996-10-11 0:00 ` Alan Brain 0 siblings, 1 reply; 6+ messages in thread From: Keith Thompson @ 1996-10-05 0:00 UTC (permalink / raw) In <32546043.1BF3@dynamite.com.au> Alan Brain <aebrain@dynamite.com.au> writes: [...] > Type TRAFFIC_LIGHT_TYPE is (Red, Yellow, Green); > Type REPRESENTED_TRAFFIC_LIGHT_TYPE is new TRAFFIC_LIGHT_TYPE; > for REPRESENTED_TRAFFIC_LIGHT_TYPE'SIZE use 16; > for REPRESENTED_TRAFFIC_LIGHT_TYPE use > ( RED => 16#FE00, YELLOW => 16#00FF, GREEN => 16#EE77); The values given in an enumeration representation clause must satisfy the predefined ordering relationship of the type (RM95-13.4(6)). > TARGET : TRAFFIC_LIGHT_TYPE; > SOURCE : REPRESENTED_TRAFFIC_LIGHT_TYPE; > > begin > > -- do the unchecked conversion to SOURCE here -- > -- .. > > PARANOIA_BLOCK: > > begin > TARGET := TRAFFIC_LIGHT_TYPE(SOURCE); > exception > when CONSTRAINT_ERROR => -- your data is definitely bad > -- etc > end PARANOIA_BLOCK; > > .. > end If Source contains an invalid value, I don't think there's any guarantee that the conversion will raise Constraint_Error. In fact, one could argue that Program_Error makes more sense (assuming the error is detected at all). -- Keith Thompson (The_Other_Keith) kst@thomsoft.com <*> TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products 10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2706 FIJAGDWOL ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Ada for Data Processing? 1996-10-05 0:00 ` Keith Thompson @ 1996-10-11 0:00 ` Alan Brain 1996-10-11 0:00 ` Ken Garlington 1996-10-11 0:00 ` Robert Dewar 0 siblings, 2 replies; 6+ messages in thread From: Alan Brain @ 1996-10-11 0:00 UTC (permalink / raw) Keith Thompson wrote: > > In <32546043.1BF3@dynamite.com.au> Alan Brain <aebrain@dynamite.com.au> writes: > > for REPRESENTED_TRAFFIC_LIGHT_TYPE use > > ( RED => 16#FE00, YELLOW => 16#00FF, GREEN => 16#EE77); > > The values given in an enumeration representation clause must satisfy > the predefined ordering relationship of the type (RM95-13.4(6)). ..which is what I get for not compiling my code fragments before sending. Ta for spotting this. I really should have seen it myself, it's one of my more common coding errors found in the 1st pass. > > TARGET : TRAFFIC_LIGHT_TYPE; > > SOURCE : REPRESENTED_TRAFFIC_LIGHT_TYPE; > > > > begin > > > > -- do the unchecked conversion to SOURCE here -- > > -- .. > > > > PARANOIA_BLOCK: > > > > begin > > TARGET := TRAFFIC_LIGHT_TYPE(SOURCE); > > exception > > when CONSTRAINT_ERROR => -- your data is definitely bad > > -- etc > > end PARANOIA_BLOCK; > > > > .. > > end > > If Source contains an invalid value, I don't think there's any guarantee > that the conversion will raise Constraint_Error. In fact, one could > argue that Program_Error makes more sense (assuming the error is detected > at all). Why? How is this different from any other checked conversion? I see your point about Program_Error, but would hate to be the guy writing the compiler code to produce this. But a Constraint_Error is reasonable; and to write a compiler so as not to do such a check in this instance would be more work than leaving the check in. I don't have my LRM handy, but can you see how the wording re Constraint_Error would not apply here? I can't. ---------------------- <> <> How doth the little Crocodile | Alan & Carmel Brain| xxxxx Improve his shining tail? | Canberra Australia | xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM ---------------------- o OO*O^^^^O*OO o oo oo oo oo By pulling Maerklin Wagons, in 1/220 Scale ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Ada for Data Processing? 1996-10-11 0:00 ` Alan Brain @ 1996-10-11 0:00 ` Ken Garlington 1996-10-11 0:00 ` Robert Dewar 1 sibling, 0 replies; 6+ messages in thread From: Ken Garlington @ 1996-10-11 0:00 UTC (permalink / raw) Alan Brain wrote: [snip] > > > -- do the unchecked conversion to SOURCE here -- > > > -- .. > > > > > > PARANOIA_BLOCK: > > > > > > begin > > > TARGET := TRAFFIC_LIGHT_TYPE(SOURCE); > > > exception > > > when CONSTRAINT_ERROR => -- your data is definitely bad > > > -- etc > > > end PARANOIA_BLOCK; > > > > > > .. > > > end > > > > If Source contains an invalid value, I don't think there's any guarantee > > that the conversion will raise Constraint_Error. [snip] > > Why? How is this different from any other checked conversion? I don't know for sure, but I suspect the answer is related to the following Ada 83 problem: type Widget is range 1 .. 10; function Unchecked_Widget is new Unchecked_Conversion (Natural, Widget); Foo : Widget := Unchecked_Widget(0); if Foo not in Widget'Range then raise Some_Error; end if; Some compilers would not raise Some_Error, since Foo was expected to always be in the range of its own type -- thus, the "if" statement was optimized away. Since the assignment to Foo was erroneous in Ada 83 (as well as Ada 95, apparently), this was not a compiler bug. In Ada 95, of course, you should be able to write if not Foo'Valid then raise Some_Error; end if; although technically this is not guaranteed to work for this particular example either. (The AARM recommends doing the common sense thing here, however.) > I see your > point about Program_Error, but would hate to be the guy writing the > compiler code to produce this. But a Constraint_Error is reasonable; and > to write a compiler so as not to do such a check in this instance would > be more work than leaving the check in. It depends on how the compiler generates the code. For example, I see code like the following fairly often. Using no particular assembly syntax: Load Register_1, SOURCE -- put contents of SOURCE into a register Test Register_1, 16#00FF# -- compare register contents to 16#00FF# If_Equal, YELLOW -- jump to label YELLOW if register=16#00FF# Test Register_1, 16#EE77# If_Equal, GREEN Store 16#0#, TARGET -- set TARGET to representation of RED GoTo NEXT -- move on to next Ada instruction YELLOW: Store 16#1#, TARGET GoTo NEXT GREEN: Store 16#2#, TARGET NEXT: <something else> So long as all three of the enums in the type for SOURCE are in the type for TARGET, this will be the code. If one or more enums are missing from TARGET, then the appropriate store(s) would usually be replaced by a call to the exception handler, but no additional checks would be required. Note that only two compares are required to process the three enum values. It would require the generation of an additional test and jump to separate RED from the invalid bit patterns, as follows: Load Register_1, SOURCE -- put contents of SOURCE into a register Test Register_1, 16#00FF# -- compare register contents to 16#00FF# If_Equal, YELLOW -- jump to label YELLOW if register=16#00FF# Test Register_1, 16#EE77# If_Equal, GREEN Test Register_1, 16#FE00# -- new test If_Not_Equal, ERROR -- new jump (could be PROGRAM_ERROR) Store 16#0#, TARGET -- set TARGET to representation of RED GoTo NEXT -- move on to next Ada instruction YELLOW: Store 16#1#, TARGET GoTo NEXT GREEN: Store 16#2#, TARGET NEXT: <something else> If invalid bit patterns can only be generated via erroneous constructs, then the compiler vendor can generate less code by assuming that only three bit patterns exist in SOURCE. -- LMTAS - "Our Brand Means Quality" For more info, see http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Ada for Data Processing? 1996-10-11 0:00 ` Alan Brain 1996-10-11 0:00 ` Ken Garlington @ 1996-10-11 0:00 ` Robert Dewar 1 sibling, 0 replies; 6+ messages in thread From: Robert Dewar @ 1996-10-11 0:00 UTC (permalink / raw) Alan said "Why? How is this different from any other checked conversion? I see your point about Program_Error, but would hate to be the guy writing the compiler code to produce this. But a Constraint_Error is reasonable; and to write a compiler so as not to do such a check in this instance would be more work than leaving the check in. I don't have my LRM handy, but can you see how the wording re Constraint_Error would not apply here? I can't." Program_Error is always the more appropriate reaction to a case where erroneous or bounded error execution is detected by the generated code. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~1996-10-11 0:00 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1996-10-02 0:00 Ada for Data Processing? William Frye 1996-10-03 0:00 ` Alan Brain 1996-10-05 0:00 ` Keith Thompson 1996-10-11 0:00 ` Alan Brain 1996-10-11 0:00 ` Ken Garlington 1996-10-11 0:00 ` Robert Dewar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox