* converting (limited) private types?
@ 1992-09-26 2:40 munnari.oz.au!yoyo.aarnet.edu.au!news.adelaide.edu.au!cs.adelaide.edu.au!
0 siblings, 0 replies; 4+ messages in thread
From: munnari.oz.au!yoyo.aarnet.edu.au!news.adelaide.edu.au!cs.adelaide.edu.au! @ 1992-09-26 2:40 UTC (permalink / raw)
HACK ALERT! What follows is not for the squeamish.
Last night I got bored by the old Jimmy Stewart movie in the box,
so I turned my mind to a problem that has been bugging me a bit.
I am in the process of writing up the user manual for my LL1 parser
generator, written in 100% pure Ada of course, which interfaces with
an aflex-generated scanner. (and quite nice it is too - handles Pascal
quite well, and if some kind soul has an LL1ish Ada grammar I would love
to put the damned thing through its paces properly :-) )
Getting on to the advanced topics, I want to tell the user how to
handle "include" files, if the language they are dealing with is so
silly as to use them :-). The way I would normally do this in the case
where file inclusion can be nested would be to have a stack of files.
Trouble is, file types in Ada are limited private. So you can't assign
to objects of the type. So you can't make a stack of them.
While pondering this, an evil thought came into my head. Before succumbing
to my better feelings, I quickly dialled up the university and tried the
following:
with text_io; use text_io;
with unchecked_conversion;
procedure file_conv is
type conv is array(1..file_type'size) of boolean;
pragma pack(conv);
function to_conv is new unchecked_conversion(file_type,conv);
function to_file is new unchecked_conversion(conv,file_type);
a_file : file_type;
a_conv : conv;
begin
open(a_file,out_file,"foo_bar");
set_output(a_file);
put_line("this should not be seen");
a_conv := to_conv(a_file);
set_output(standard_output);
put_line("This should be seen");
set_output(to_file(a_conv));
put_line("This should not be seen either");
set_output(standard_output);
put_line("This should also be seen");
-- close(to_file(a_conv));
end;
Of course, the commented out call to close won't work, since it takes
an in out file parameter. The rest of it, perhaps surprisingly, does.
What I want to know is:
(1) APART from any righteous feelings about breaking the language's
privacy mechanism, are there any good reasons for not doing something
like this?
(2) Is there a better way to do it, one which does not rely on this
sort of hack?
(3) How can I close the damned file? (I've thought of a really disgusting
way, which oddly enough should be reasonably portable, but I certainly won't
publish it on the net.)
I would be grateful for advice. I won't be grateful for flames, but I can stand
them. :-)
--
#######################################################################
# Andrew Dunstan # There's nothing good or bad #
# Department of Computer Science # but thinking makes it so. #
# University of Adelaide # #
# South Australia # - Shakespeare #
# net: andrewd@cs.adelaide.edu.au # #
#######################################################################
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: converting (limited) private types?
@ 1992-09-26 21:08 Dave Marshall
0 siblings, 0 replies; 4+ messages in thread
From: Dave Marshall @ 1992-09-26 21:08 UTC (permalink / raw)
In article <1a0ijeINNfei@huon.itd.adelaide.edu.au>, andrewd@cs.adelaide.edu.au
(Andrew Dunstan) writes:
[some stuff deleted]
> Trouble is, file types in Ada are limited private. So you can't assign
> to objects of the type. So you can't make a stack of them.
>
> While pondering this, an evil thought came into my head. Before succumbing
> to my better feelings, I quickly dialled up the university and tried the
> following:
>
> with text_io; use text_io;
> with unchecked_conversion;
> procedure file_conv is
>
Ack! A totally UNJUSTIFIED use of UNCHECKED_CONVERSION! Flagellate yourself
thrice daily for a week.
[remainder of evil program deleted]
>
> What I want to know is:
>
> (1) APART from any righteous feelings about breaking the language's
> privacy mechanism, are there any good reasons for not doing something
> like this?
Yes. Don't used UNCHECKED_CONVERSION if you don't have to.
>
> (2) Is there a better way to do it, one which does not rely on this
> sort of hack?
Yes. Access types. A simple example follows at the end of this response.
>
> (3) How can I close the damned file? (I've thought of a really disgusting
> way, which oddly enough should be reasonably portable, but I certainly won't
> publish it on the net.)
Maybe that's for the best. :) [No chops-busting intended.]
What follows is my trivial example of using access types to keep track of
limited private types. In it, I keep an array of FILE_TYPE while I create
files, write to them, and close them. Creating a stack package, or even
using some other generic stack package, ought to be equally trivial.
Here it is:
with TEXT_IO;
procedure FILE_TEST is
type FILE_POINTER is access TEXT_IO.FILE_TYPE;
type POINTERS is array ( INTEGER range <>) of FILE_POINTER;
MY_ARRAY : POINTERS(1..5);
SOME_NAMES : constant array (INTEGER range 1..5) of STRING(1..8) :=
( "myfile.1",
"myfile.2",
"myfile.3",
"myfile.4",
"myfile.5");
begin
for I in MY_ARRAY'RANGE loop
MY_ARRAY(I) := new TEXT_IO.FILE_TYPE;
TEXT_IO.PUT_LINE( "Creating file" & INTEGER'IMAGE(I));
TEXT_IO.CREATE ( MY_ARRAY(I).all, NAME => SOME_NAMES(I));
end loop;
for J in MY_ARRAY'RANGE loop
TEXT_IO.PUT_LINE ( "Writing to file" & INTEGER'IMAGE(J));
TEXT_IO.PUT_LINE ( MY_ARRAY(J).all, "I am file" & INTEGER'IMAGE(J));
end loop;
for K in MY_ARRAY'RANGE loop
TEXT_IO.PUT_LINE ( "Closing file" & INTEGER'IMAGE(K));
TEXT_IO.CLOSE ( MY_ARRAY(K).all);
end loop;
end FILE_TEST;
Apologies to purists everywhere who take offense at my sloppiness in the
declarative section. Have a nice day.
--
Dave Marshall
dmarshal@stars.reston.unisys.com
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: converting (limited) private types?
@ 1992-09-27 20:07 cis.ohio-state.edu!news.sei.cmu.edu!ae
0 siblings, 0 replies; 4+ messages in thread
From: cis.ohio-state.edu!news.sei.cmu.edu!ae @ 1992-09-27 20:07 UTC (permalink / raw)
andrewd@cs.adelaide.edu.au (Andrew Dunstan) asks about a stack of items
of type Text_IO.File_Type, which is limited private.
It would be hard to do if you are using a stack package. However, if
you implement the stack as an array and an index (probably reasonable in
your case), just open the file right into the stack. Leaving out a lot,
like this:
File_Stack: array(0..File_Stack_Max) of Text_IO.File_Type;
Current_File: integer := 0; -- Current item in File_Stack
...
-- Opening intial file
Text_IO.Open(File_Stack(Current_File), Text_IO.In_File, ...
-- Reading the file (can be simplified with Set_Input)
Text_IO.Get_Line(File_Stack(Current_File), ...
-- Processing %include (or whatever)
Current_File := Current_File + 1;
Text_IO.Open(File_Stack(Current_File), Text_IO.In_File, ...
...
-- process the file
...
Text_IO.Close(File_Stack(Current_File));
Current_File := Current_File - 1;
You can easily fill in the details.
Art Evans
----------------------------------------------
Arthur Evans, Jr, PhD Ada Consultant
461 Fairview Road
Pittsburgh PA 15238-1933
412-963-0839
ae@sei.cmu.edu
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: converting (limited) private types?
@ 1992-09-29 20:00 Robert I. Eachus
0 siblings, 0 replies; 4+ messages in thread
From: Robert I. Eachus @ 1992-09-29 20:00 UTC (permalink / raw)
The most elegant way to solve this problem, and I do it every
time I have to do a lot of text file manipulation is to take your
favorite text editor and edit the specification of TEXT_IO. I usually
change the name to NICE_IO and build in whatever processing is
necessary to print out meaningful error messages when opening a file
fails, etc. In your case, redefine FILE_TYPE as a private type, and
then make it an access to TEXT_IO.FILE_TYPE. (If FILE_TYPE is already
an access type, there is an obvious optimization...I won't tell.)
Now write the body for the most part as calls through to TEXT_IO.
Slather pragma INLINE around liberally and you are ready to start
cooking. If you want to be a little more adventurous add functions
PUSH_CURRENT_IN, etc. to the package. See how easy that was? :-)
Seriously this does turn out to be a long term timesaver, since I
can and do add dozens of mixed output procedures, GET functions, etc.
to the mix.
--
Robert I. Eachus
with STANDARD_DISCLAIMER;
use STANDARD_DISCLAIMER;
function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~1992-09-29 20:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1992-09-26 21:08 converting (limited) private types? Dave Marshall
-- strict thread matches above, loose matches on Subject: below --
1992-09-29 20:00 Robert I. Eachus
1992-09-27 20:07 cis.ohio-state.edu!news.sei.cmu.edu!ae
1992-09-26 2:40 munnari.oz.au!yoyo.aarnet.edu.au!news.adelaide.edu.au!cs.adelaide.edu.au!
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox