Tom
Tom

Reputation: 79

How can I use WriteLn with an enum type?

I'm trying to make a custom data type for days of the week but I can't get it to write it. The compiler error says this:

[Error] hours.dpr(28): Illegal type in Write/Writeln statement

program hours;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TypeDay = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);

var day: TypeDay;

begin
     for day := Sun to Sat do
     begin
         writeln(day);
     end;
end.

It's in Delphi 7 on Windows.

Upvotes: 7

Views: 3415

Answers (5)

chikega
chikega

Reputation: 155

Interestingly enough, I'm able to use readLn with enum types in FPC (Lazarus), but will throw the same error (illegal type) as mentioned above in Delphi, Oxygene, PascalABC.Net...


    type
        beverage = (coffee, tea, milk, water, coke, limejuice);
    
    var
        drink : beverage;
    
    begin
         writeLn('Which drink do you want? ');
         writeLn('Here are the choices: coffee, tea, milk, water, coke, limejuice ');
         readLn(drink);
         writeLn('So you would like to drink ', drink, '.');
         readLn
    end. 

Upvotes: 0

You don't need to write Assembler for this; TypInfo include all that you need for do this (get the string associated to an enumerated value).

This code:

program hours;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  TypInfo;

type
  TypeDay = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);

var
  day: TypeDay;
  Str:String;

begin
     for day := Sun to Sat do begin
        Str := GetEnumName(TypeInfo(TypeDay),ord(day));
         writeln(Str);
     end;
end.

And this is the output:

alt text

Regards.

Upvotes: 16

Jeroen Wiert Pluimers
Jeroen Wiert Pluimers

Reputation: 24523

Enumerations are not strings, so you need to convert them.
For conversion, you can use the GetEnumName function from the Delphi TypInfo unit as explained at delphi.about.com.

--jeroen

Upvotes: 2

Arnaud Bouchez
Arnaud Bouchez

Reputation: 43043

You can use RTTI to write the enumerate names.

Here is an optimized function I wrote some time ago:

program hours;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function GetEnumName(aTypeInfo: pointer; aIndex: integer): PShortString;
asm // get enumerate name from RTTI
    or edx,edx
    movzx ecx,byte ptr [eax+1] // +1=TTypeInfo.Name
    mov eax,[eax+ecx+1+9+1] //BaseType
    mov eax,[eax]
    movzx ecx,byte ptr [eax+1]
    lea eax,[eax+ecx+1+9+4+1] // eax=EnumType.BaseType^.EnumType.NameList
    jz @0
@1: movzx ecx,byte ptr [eax]
    dec edx
    lea eax,eax+ecx+1 // next short string
    jnz @1
@0:
end;

type
  TypeDay = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);

var day: TypeDay;

begin
     for day := Sun to Sat do
     begin
         writeln(GetEnumName(TypeInfo(TypeDay),ord(day))^);
     end;
end.

But be warned that this version doesn't check for that aIndex to be in range.

Upvotes: 4

RRUZ
RRUZ

Reputation: 136431

Tom, Writeln does not support a Enum as parameter. you must call to the Ordfunction to get the ordinal representation. if you wanna show the names of your TypeDay you can write a code like this.

program hours;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TypeDay     = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);
const
  TypeDayStr  : Array[TypeDay] of string = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');

var day: TypeDay;

begin
     for day := Sun to Sat do
       writeln( Ord(day));

     for day := Sun to Sat do
       writeln( TypeDayStr[day]);

     Readln;
end.

Upvotes: 11

Related Questions