[comp.lang.pascal] TP problem

jjoshua@topaz.rutgers.edu (Jonathan Joshua) (11/05/87)

	Here's the deal..

type dirct = (n,s,e,w,ne,se,sw,nw) ;
var v : dirct ;

v is a variable with an ennumerated type, right?

readln(v) ;

gives an I/O not allowed error. I am using turbo pascal.
Am I doing something wrong or do I need a REAL compiler?

Any help SOON would be greatly appreciated.
-- 
|o|  Jonathan Joshua       rutgers!{unirot!jjosh,topaz.rutgers.edu!jjoshua} |o|
|o|  Rutgers University      Delphi : bunnyhutch / Compuserve : 73637,254   |o|
|o|                                                                         |o|
|o|  "Anything is possible except skiing through a revolving door." -Mur+*4;YQ[F

dmw3@ur-tut.UUCP (David M Walsh Jr.) (11/05/87)

In article <16249@topaz.rutgers.edu> jjoshua@topaz.rutgers.edu (Jonathan Joshua) writes:
>
>	Here's the deal..
>
>type dirct = (n,s,e,w,ne,se,sw,nw) ;
>var v : dirct ;
>
>v is a variable with an ennumerated type, right?
>
>readln(v) ;
>
>gives an I/O not allowed error. I am using turbo pascal.
>Am I doing something wrong or do I need a REAL compiler?
>
>-- 
>|o|  Jonathan Joshua       rutgers!{unirot!jjosh,topaz.rutgers.edu!jjoshua} |o|
>|o|  Rutgers University      Delphi : bunnyhutch / Compuserve : 73637,254   |o|

Yes you are doing something wrong.  Readln(); gets characters and the only
change it makes is to go from the chars to numbers.  If you have ever tried
this:  var b:boolean; readln(b);  you will get the same error.

The fix is simple, add the following:

var s:string;  {you do have strings don't you?:-) }

begin
  readln(s);
  if s='n' then v:=n else
    if s='s' then v:=s else
     if s='w' then v:=w else ...

end;

Well, It's not pretty and I'm sure that someone somewhere will yell at me for
doing that, but it WILL work, and that's what every programmer wants, a
working program, right?  :-) :-)

Good luck.

Dave Walsh - an old Apple ][+ hacker, trying to be a Mac hacker
           residing at University of Rochester

mail:  rochester!ur-tut!dmw3 or dmw3@tut.cc.rochester.edu.UUCP

Disclaimer:  Oh, I don't really need one anyways...I'm crazy.

fulton@comet.dec.com (Cathy Fulton -- CXO Technical Training) (11/06/87)

jjoshua writes :
 
>	Here's the deal..
> 
>type dirct = (n,s,e,w,ne,se,sw,nw) ;
>var v : dirct ;
> 
>v is a variable with an ennumerated type, right?
> 
>readln(v) ;
> 
>gives an I/O not allowed error. I am using turbo pascal.
>Am I doing something wrong or do I need a REAL compiler?
> 
>Any help SOON would be greatly appreciated.


From "Introduction to PASCAL and Structured Design" by Dale/Orshalick :

"Since user-defined types have meaning only within the program, we cannot
read them in or write them out."  (Note that for Dale/Orshalick, "user-
defined" is an alias for "enumerated.")

It is the exception for a Pascal compiler to provide I/O for enumerated
types.  It is not part of the language definition.  One semester I did a
project in Pascal on a SUN running Unix, and I was really suprised when I
was able to directly write out enumerated types - I thought it was pretty
neat.  But, the compiler did warn me that that was a "non-standard feature;"
this is further evidence that such a capability is exceptional.

- Cathy

uucp: ...decwrl!comet.dec.com!fulton
ARPA: fulton@comet.dec.com

fsbrn@BRL.ARPA (VLD/LTTB) (11/09/87)

Haah,

According to "Programming in Pascal" by Grogono (my favorite Pascal
text):

"Unfortunately, it is not possible in standard Pascal to read or write
a scalar [enumerated] value directly."  (page 127)

Assuming you are writing to a text file, how should the enumerated
value be written so that it could be read in again by another program?
If you are writing to a non-text file, say a file of a user-defined
record type, then the enumerated value may be written as a byte whose
value is the "index" number of the item within its enumerated set.
(That sounds confusing; it simply stores ORD(value).)  Now if any
write of an enumerated value wrote an integer, then you could read it
in as a different enum; eg, write ORD(first_member_set1) and then read
it back into a variable of a different type.  Definitely apples and
oranges here.

A brief scan thru my TP 3.0 manual didn't turn up any specific mention
of this problem, so I assume TP follows the standard here.  A
workaround (TP-specific) is the following:
  write(ord(enum_variable));   { when you need to store the enum value }

  read(int_variable);          { read integer and convert to enum value }
  enum_variable := enum_type(int_variable);

See page 65 for further details and a nice example.

                                        dsw, fferd
                                        Fred S. Brundick
                                        USABRL, APG, MD.
                                        <fsbrn@brl.arpa>

lowey@sask.UUCP (Kevin Lowey) (11/09/87)

In article <16249@topaz.rutgers.edu>, jjoshua@topaz.rutgers.edu (Jonathan Joshua) writes:
> 
> v is a variable with an ennumerated type, right?

     right

> readln(v) ;
> gives an I/O not allowed error. I am using turbo pascal.
> Am I doing something wrong or do I need a REAL compiler?

  As far as I know, PASCAL only accepts input from the console into 
STRING (array of char), integer, or real types.  All other types (arrays, 
records, enumerated types, and any other type you define) can only be written
to and read from files.

  To do what you want, you will have to input a character from the keyboard,
then use a case statement to assign the correct variable to the enumerated
type depending upon the value of the character.

  Internally, the enumerated type is stored as an integer (or some variant 
like BYTE), so you may be able to enter a number from the keyboard, but I 
doubt it.

______________________________________________________________________________
| Kevin Lowey                    |The above is the personal opinion of Kevin |
| University of Saskatchewan     |Lowey.  It does not reflect the position of|
| Computing Services             |the University of Saskatchewan in any way. |
| SaskTel: (306) 966-4826        |                                           |
| Bitnet:LOWEY@SASK. (preferred) |I am in no way affiliated with any of the  |
| UUCP:    ihnp4!sask!lowey.uucp |above mentioned companies other than U of S|
|________________________________|___________________________________________|

Robert_V._Muckley.henr801E@Xerox.COM (11/12/87)

 Jonathan Joshua of Rutgers University writes:


>   I am using turbo pascal.  Am I doing something wrong or do I need a
>   REAL compiler?


First of all, Turbo Pascal is a brand name and, as such, deserves to be 
capitalized.  

Secondly, Turbo Pascal *is* a REAL compiler.

rxb@rayssdb.RAY.COM (Richard A. Brooks) (11/13/87)

In article <936@sask.UUCP>, lowey@sask.UUCP (Kevin Lowey) writes:
> In article <16249@topaz.rutgers.edu>, jjoshua@topaz.rutgers.edu (Jonathan Joshua) writes:
> > 
> > v is a variable with an ennumerated type, right?
> 
>      right
> 
> > readln(v) ;
> > gives an I/O not allowed error. I am using turbo pascal.
> > Am I doing something wrong or do I need a REAL compiler?
> 
>   As far as I know, PASCAL only accepts input from the console into 
> STRING (array of char), integer, or real types.  All other types (arrays, 
> records, enumerated types, and any other type you define) can only be written
> to and read from files.

But a writeln(v) will give you the same error!!!!

 Try this:
program TEST;

type
  ON_OFF    = (ON,OFF);

var
  v 	    = ON_OFF;

begin
	readln(v);
	writeln('Switch is now ',v);
end.

	Upon compiling the above, you will recieve an I/O not 
	allowed error at the "readln(v)" and the "writeln(v)",
	if the readln is removed.

	TP does NOT allow you to read or write ennumerated types 
	to the screen!!! Is this so in 4.0?? I know you can change
	types, but what a pain. 


-- 
Richard Brooks      {allegra, gatech, ihnp4, linus, raybed2}!rayssd!rayssdb!rxb
Raytheon Service Company              // When everyone is out to get you  //
Portsmouth, Rhode Island 	     // Paranoia is just good thinking ! //

swarbric@tramp.Colorado.EDU (SWARBRICK FRANCIS JOHN) (11/16/87)

Wierd, the only enumerated type that you can output is boolean.  You can't
input a boolean var, though.

enped@conexch.UUCP (Eric Pederson) (11/19/87)

In article <1808@rayssdb.RAY.COM> Richard A. Brooks writes:
>In article <936@sask.UUCP>, Kevin Lowey writes:
>> In article <16249@topaz.rutgers.edu>, Jonathan Joshua writes:
>> > 
>> > [ the preceeding discussion about enumerated type I/O ]
>> [...]
> Try this:
>program TEST;
>
>type
>  ON_OFF    = (ON,OFF);
>var
>  v 	    = ON_OFF;
>begin
>	readln(v);
>	writeln('Switch is now ',v);
>end.
>
>	Upon compiling the above, you will recieve an I/O not 
>	allowed error at the "readln(v)" and the "writeln(v)",
>	if the readln is removed.
>
>	TP does NOT allow you to read or write ennumerated types 
>	to the screen!!! Is this so in 4.0?? I know you can change
>	types, but what a pain. 
>

Right.  PASCAL (not just TP) does not define I/O of structured or enumerated
types to TEXT files (file of char) which input and output are.

This is because the implementation details of these types are supposed to
be hidden from the user.  The user doesn't neccessarily care what gets
written out to a FILE OF anythingelse (that is anything other than char). 

In addition, if you write a FILE OF anythingelse with an object program
compiled by one Pascal compiler, that same file is not neccessarily
readable by object programs compiled by different Pascal compilers.

For example, VARs of type ON_OFF are (in TP) stored in one byte.  The value
of that byte is 0 for ON and 1 for off.  A common mistake for programmers
not used to enumerated types is to assume that "writeln(v)" will produce
"ON" or "OFF" on the output file.  To accomplish this, the compiler would
have to keep the actual character names of every enumerated type in the
object program, wasting lotsa space, and complicating the TEXT library
I/O routines.  For non-TEXT I/O the program will just read and write the
single byte.

Basically, structured and enumerated types are restricted from TEXT
I/O.  The workaround is either using ord() to convert the enumerated
type to an integer or to write out a TEXTable value based on the
enumerated type.

TP's structured typed constants make this really easy:

type ON_OFF = (ON,OFF);
     onoffarr = array[ON_OFF] of string[10];
     { or [ON..OFF] }

const onoffnames: onoffarr = ( 'ON','OFF' );

var v: ON_OFF;

begin
    ...
    writeln(ord(v),' ',onoffnames[v]);
end.

---
Eric Pederson
HBUHSD 714 964 3339

enped@conexch.UUCP (Eric Pederson) (12/02/87)

In article <1808@rayssdb.RAY.COM> Richard A. Brooks writes:
>In article <936@sask.UUCP>, Kevin Lowey writes:
>> In article <16249@topaz.rutgers.edu>, Jonathan Joshua writes:
>> >
>> > [ the preceeding discussion about enumerated type I/O ]
>> [...]
> Try this:
>program TEST;
>
>type
>  ON_OFF    = (ON,OFF);
>var
>  v         = ON_OFF;
>begin
>    readln(v);
>    writeln('Switch is now ',v);
>end.
>
>    Upon compiling the above, you will recieve an I/O not
>    allowed error at the "readln(v)" and the "writeln(v)",
>    if the readln is removed.
>
>    TP does NOT allow you to read or write ennumerated types
>    to the screen!!! Is this so in 4.0?? I know you can change
>    types, but what a pain.
>

Right.  PASCAL (not just TP) does not define I/O of structured or enumerated
types to TEXT files (file of char) which input and output are.

This is because the implementation details of these types are supposed to
be hidden from the user.  The user doesn't neccessarily care what gets
written out to a FILE OF anythingelse (that is anything other than char).

In addition, if you write a FILE OF anythingelse with an object program
compiled by one Pascal compiler, that same file is not neccessarily
readable by object programs compiled by different Pascal compilers.

For example, VARs of type ON_OFF are (in TP) stored in one byte.  The value
of that byte is 0 for ON and 1 for off.  A common mistake for programmers
not used to enumerated types is to assume that "writeln(v)" will produce
"ON" or "OFF" on the output file.  To accomplish this, the compiler would
have to keep the actual character names of every enumerated type in the
object program, wasting lotsa space, and complicating the TEXT library
I/O routines.  For non-TEXT I/O the program will just read and write the
single byte.

Basically, structured and enumerated types are restricted from TEXT
I/O.  The workaround is either using ord() to convert the enumerated
type to an integer or to write out a TEXTable value based on the
enumerated type.

TP's structured typed constants make this really easy:

type ON_OFF = (ON,OFF);
     onoffarr = array[ON_OFF] of string[10];
     { or [ON..OFF] }

const onoffnames: onoffarr = ( 'ON','OFF' );

var v: ON_OFF;

begin
    ...
    writeln(ord(v),' ',onoffnames[v]);
end.

---
Eric Pederson
HBUHSD 714 964 3339

shankar@hpclscu.HP.COM (Shankar Unni) (12/19/87)

>
>In article <1808@rayssdb.RAY.COM> Richard A. Brooks writes:
>>In article <936@sask.UUCP>, Kevin Lowey writes:
>>> In article <16249@topaz.rutgers.edu>, Jonathan Joshua writes:
>>> >
>>> > [ the preceeding discussion about enumerated type I/O ]
>>> [...]
>> Try this:
>>program TEST;
>>
>>type
>>  ON_OFF    = (ON,OFF);
>>var
>>  v         = ON_OFF;
>>begin
>>    readln(v);
>>    writeln('Switch is now ',v);
>>end.
>>
>>    Upon compiling the above, you will recieve an I/O not
>>    allowed error at the "readln(v)" and the "writeln(v)",
>>    if the readln is removed.
>

Eric Pedersen replies:

>......                        To accomplish this, the compiler would
>have to keep the actual character names of every enumerated type in the
>object program, wasting lotsa space, and complicating the TEXT library
>I/O routines.

Well, a few compilers (decent ones, btw) written for larger machines DO 
support this feature exactly as you describe (a table is dumped somewhere
for each enumerated type for which I/O is requested). And yes, the code
generated for the I/O *is* a little gnarly. But boy! is it worth it!! Input
may not be too important (and may be counter-productive, because user typos
will not be handled too gracefully), but output is certainly useful, if for
nothing else but for debugging purposes.

Shankar Unni.
...!hplabs!hpda!shankar