comp.lang.ada
 help / color / mirror / Atom feed
* 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