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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,e5fae12a81834f90 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-02-22 05:08:04 PST Path: supernews.google.com!sn-xit-03!supernews.com!cyclone2.usenetserver.com!news-out.usenetserver.com!howland.erols.net!cpk-news-hub1.bbnplanet.com!news.gtei.net!news-FFM2.ecrc.net!news.iks-jena.de!lutz From: lutz@iks-jena.de (Lutz Donnerhacke) Newsgroups: comp.lang.ada Subject: Re: AdaYY wish list from current projects Date: 22 Feb 2001 13:02:10 GMT Organization: IKS GmbH Jena Distribution: world Message-ID: References: <96ulad$r9e$1@belenus.iks-jena.de> <87u25nnfer.fsf@deneb.enyo.de> NNTP-Posting-Host: taranis.iks-jena.de Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit User-Agent: slrn/0.9.6.3 (Linux) Xref: supernews.google.com comp.lang.ada:5433 Date: 2001-02-22T13:02:10+00:00 List-Id: * Florian Weimer wrote: >lutz@belenus.iks-jena.de (Lutz Donnerhacke) writes: >> I have three sad problems (and a bonus problem) from my current projects. >> If they can fixed by a compiler it would be very fine: >> >> Problem 1: Pointer of component => Pointer to aggregate >> >> In order to mixin a generic list with head nodes not mixed into any other >> user defined structure I'd need to link not the base data but the mixin >> itself. Doing so I need to regenerate the whole aggregate pointer from >> a pointer of a component. Current (not tested) implementation: > >For limited types, there is another approach: > > type Mix_In_Type (Ref : access Mixed) is tagged limited private; Unfortunly this does increase the space requirments significantly. OTOH it does not address the problem, because I'd like to have a small RAM area containing only list heads. So I'd instantiate head : Mix_In_Type(Null); or anything like this? Hmm. Seems to work using additional pointers :-( >It appears that Ada is not suitable for this kind of design. Very bad. I'd like to suggest a language feature in order to solve this. >> Problem 2: Defining Byte_Order of record representations >> >> My low level networking application has to deal with low and big endian >> values on the net I want to handle with record representations clauses >> in order to get the benefits of compiler generated I/O functions. > >For my OpenPGP implementation, I've written my own stream I/O >functions. That's certainly the way to go if you don't need a >specific in-memory representation. Unfortunly I have to deal with memory mapped I/O (i.e. network cards) >I don't think an additional attribute is really necessary. Instead, >vendors could provide packages like Interfaces.Little_Endian and >Interfaces.Big_Endian which contain the Integer_* and Unsigned_* >types from package Interfaces, with the corresponding in-memory and >stream representation. If you make these types private and provide >conversion functions, you can implement these packages even yourself. You miss the point. Providing such packages does not allow the compiler to generate good maschine code. function t return Boolean is type Uplevel_Discriminator is (Bla, Blubb); for Uplevel_Discriminator use (Bla => 16#732#, Blubb => 16#7791#); type example is record port : Uplevel_Discriminator; end record; for example use record port at 17 range 0 .. 15; end record; for example'Bit_Order use Low_Order_First; -- bit numbering for example'Byte_Order use Little_Endian; -- bit chunk order for example'Address use 16#A00000#; begin case example.port is when Bla => return true; when Blubb => return false; end case; end t; May result in the following (hypothetic) code: .t FF FE 43 11 00 A0 00 32 07 LE CMP (A00011), 732 02 NEG Z BE 0B JNZ t_fin FF FE 43 11 00 A0 00 91 77 LE CMP (A00011), 7791 BE 01 JZ t_error .t_fin 99 RET .t_error .. Exception handling .. Without Byte_Order = Big_Endian the following code might appear: .t 43 00 A0 00 11 07 32 CMP (A00011), 732 02 NEG Z BE 0B JNZ t_fin 43 00 A0 00 11 77 91 CMP (A00011), 7791 BE 01 JZ t_error .t_fin 99 RET .t_error .. Exception handling .. Using a conversion package the code would look like this: with Endianess, Unchecked_Conversion; function t return Boolean is type Uplevel_Discriminator is (Bla, Blubb); for Uplevel_Discriminator use (Bla => 16#732#, Blubb => 16#7791#); function To_UpDisc is new Unchecked_Conversion (Endianess.Uint16, Uplevel_Discriminator); type example is record port : Endianess.Uint16; end record; for example use record port1 at 17 range 0 .. 15; end record; -- Avoid specification of Bit_Order to enshure compiling for example'Address use 16#A00000#; begin case To_UpDisc ( Endianess.From_Low (example.port)) is when Bla => return true; when Blubb => return false; end case; end t; resulting in the (inlined) code: .t PUSH A1 COPY (A00011), A1 EXCH A1 CMP A1, 732 ... which might be optimized (due to the use of constants) to: .t PUSH A1 COPY (A00011), A1 CMP A1, 3207 ... which might be optimized further to: .t CMP (A00011), 3207 ... which is similar to the original (unoptimized) code, but quite harder to get. It's always better to generate good code in the first place instead of trying to deduct it from a bad one. >> Problem 3: Static expressions of discriminants in record representations >> >> Trying to may a simple data structure like a Pascal string is not >> possible with Ada95. > >The following seems to work in some cases. > > subtype Pascal_Length is Integer range 0 .. 255; > > type Pascal_String (Length : Pascal_Length) is record > Data : String (1 .. Length); > end record; > pragma Pack (Pascal_String); *Gna* And now remove the limitation, that the discriminants have to appear first. Even better: Try to write a program, which derivates the type from a pointer.