CASE for RECORD type is not supported

TYPE
Item_List_Cell = RECORD CASE INTEGER OF
1: ( { Normal Cell }
Buffer_Length : [WORD] 0…65535;
Item_Code : [WORD] 0…65535;
Buffer_Addr : UInt32;
Return_Addr : UInt32
);
2:( { Terminator }
Terminator : UInt32
);
END;

Item_List_Template(Count:INTEGER) = ARRAY [1..Count] OF Item_List_Cell;

This code is used in many Pascal compiler; why not in Oxygene, it’s like a killer for us.
a) BORLAND Turbo Pascal has it (read from programmers manuals),
b) OpenVMS Pascal has it (see code fragment above),
c) LAZARUS FreePascal has it (just tested), and
d) GNU Pascal has it (just tested).

  1. example

program Project1;
type
tMyPlace = record
x,y: Real;
case Art: Boolean of
true: (place : String[40]);
false: (myplace : String[20],
PLZ : Integer;
Address : String[30]:wink:
end;

begin
end.

complies with BORLAND, Free Pascal, GNU Pascal …

Having overlapped fields on .NET is possible but limited, which is why we don’t support the case syntax. On .NET you can’t overlap managed types (like strings) with other types, nor can you do string[40]. On Java records aren’t supported at all (we do support the syntax and the way records behave when assigning instances, but underneath it’s all classes). At this moment I can’t see much advantage to supporting the syntax and feature given the limitations of java and .NET.

What is your end purpose for this structure? Is it meant to be read from a file like was common in Turbo Pascal with blockread or as a good way to store different data dependent on the flag? If so 3 classes would probably work better:

type
tMyPlace = public abstract class
public
  x,y: Real;
  property Art: Boolean read ; abstract;
end;

tMyTruePlace = public class(tMyPlace)
public
  place: String;
  property Art: Boolean read true; override;
end;

tMyFalsePlace = public class(tMyPlace)
public
  myplace : String;
  plz: Integer;
  Address: string;
  property Art: Boolean read false; override;
end;

If you read one more time the first part of my mail, then you can see that an array type is defined and later used to define a variable with of an array of such records of a demanded size. The size of the arry depends on the system servie call to make. The array-records are filled with parameters for the system service call and the whould construct is then used like a descriptor toward system service calls in openVMS Pascal and other OpenVMS languages.

In regard to our code port from OpenVMS Pascal to Oxygene, until now we just use this constructs to call OpenVMS system services. Now we have to re-implement our system service wrappers to make them use Windows 7 system services. If it would be only for system services I wont call up here. But our legacy code has lot’s of such constructs.

I know, using a class I can do it in Oxygene. But using an existing syntax on a larger huge code port project is also an important factor paying off if you get the rigth Pascal. Here we have to weigth aspects of Pascals, get pros and cons, risks and chances of it and then select the Pascal based on a formal wighted evaluation.

Hello,
I’ve never used it in Oxygene, but does something like this work?

namespace ClassLibrary1;

interface

  uses
    System.Runtime.InteropServices;

  type
    [StructLayout (LayoutKind.Explicit)]
    tMyPlace  = public record
    public
      [FieldOffset ( 0)] x : Real;
      [FieldOffset ( 8)] y : Real;
      [FieldOffset (16)] Art : Boolean;
      [FieldOffset (20)] place : String;
      [FieldOffset (20)] myplace : String;
      [FieldOffset (24)] PLZ : Integer;
      [FieldOffset (28)] Address : String;
    end;
  
implementation

end.

You should really be careful when calculating field offsets, but it should work.

Patrick

yes, that works given we know the exact size of a given type which is different from Pascal to Pascal. Hopefully it is fix once we have defined it using the sizeOf( type) function.