MPL Documentation

Modern Pascal Data Types

Data types of an entity (for example variables and constants) define the meaning, constraints, possible values, functions and mode of storage associated with it. Integer, float (a.k.a. real), Boolean and character types are referred to as standard types or native types. Data types can be categorized as scalar, pointer and structured data types, a type identifier's scope doesn't include itself
except for pointer types.

Scalar Standard

Scalar User Defined

Pointer

Structured

Integer types

Pronounced /in-tij-%u0259r/ is a noun, means a whole number; a number that is not a fraction. In Modern Pascal, there are 4 sizes of integer, 8bit, 16bit, 32bit and 64bit used to hold whole number values from the subrange minimum to the maximums below:

Type Minimum Maximum Format
 Byte  0  255  unsigned 8-bit
 Shortint  -128  127  signed 8-bit
 Word  0  65,535  unsigned 16-bit
 Smallint  -32,768  32,767  signed 16-bit
 Cardinal  0  4,294,967,295  unsigned 32-bit
 LongWord  0  4,294,967,295  unsigned 32-bit
 Integer  -2,147,483,648  2,147,483,647  signed 32-bit
 Longint  -2,147,483,648  2,147,483,647  signed 32-bit
 LargeWord  0  18,446,744,073,709,551,615  unsigned 64-bit
 UInt64  0  18,446,744,073,709,551,615  unsigned 64-bit
 Int64  -9,223,372,036,854,775,808  9,223,372,036,854,775,807  signed 64-bit
 LargeInt  -9,223,372,036,854,775,808  9,223,372,036,854,775,807  signed 64-bit
       

Float types

Short for floating-point notation, denotes a mode of representing numbers as two sequences of bits, one representing the whole number and the other determines the fraction. A value's floating-point notation normally comprises three values-M, B, and E-such that M x BE = N, where B is always 2, and both M and E are integral values within the float type's range. These M and E values further prescribe the float type's range and precision. In Modern Pascal, there are 3 sizes of float, 4byte, 8byte and 10byte used to hold number values from the minimum to the maximums below:

Type Minimum Maximum Significant Digits Format
 Single  1.5E-45  1.5E-45  7 to 8 places  4-byte
 Double  5.0E-324  1.7E308  15 to 16 places  8-byte
 Extended  1.9E-4932  1.1E4932  19 to 20 places  10-byte
 Currency  -922337203685477.5808  922337203685477.5807  19 to 20 places  8-byte
         

Character types

Char's set of values are characters, ordered according to the extended's ASCII character set. The function call Ord(Ch), where Ch is a Char value, returns Ch's ordinality. A string constant of length 1 can denote a constant character value. Any character value can be generated with the standard function Chr. In Modern Pascal, there are 3 distinct types of character types, single, wide and unicode. There are two distinct versions of these 3 times, single and multiple character collections or strings.

Type Minimum Maximum Format
 AnsiChar  #0  #255  1-byte
 Char  #0  #255  1-byte
 WideChar  #0#0  #255#255  2-byte UTF-16
 UnicodeChar  #0#0    2-byte Limited
 AnsiString  #0  #255  0-byte to 255-bytes
 String  #0  #255  0-byte to 4 Gig
 WideString  #0#0  #255#255  0-byte to 4 Gig
 UnicodeString  #0#0    0-byte to 4 Gig
 PAnsiChar  #0  #255  Unlimited
 PChar  #0#0  #255#255  Unlimited
 PWideChar  #0#0  #255#255  Unlimited
       

Boolean types

There are four predefined Boolean types: Boolean, ByteBool, WordBool, and LongBool. Boolean values are denoted by the predefined constant identifiers False and True. They are different memory sizes for memory alignment, but contain true and false, or 0 for false and non-zero for true.

Boolean and ByteBool variables occupy one byte, a WordBool variable occupies two bytes (one word), and a LongBool variable occupies four bytes (two words). Boolean is the preferred type and uses the least memory; ByteBool, WordBool, and LongBool exist primarily to provide compatibility with other languages and the Windows environment.

A Boolean variable can assume the ordinal values a and 1 only, but variables of type ByteBool, WordBool, and LongBool can assume other ordinal values. An expression of type ByteBool, WordBool, or LongBool is considered False when its ordinal value is zero, and True when its ordinal value is nonzero. Whenever a ByteBool, WordBool, or LongBool value is used in a context where a Boolean value is expected, the compiler will automatically generate code that converts any nonzero value to the value True.

Type Minimum Maximum Ord(True) Format
 Boolean  False  True  Any non-zero  1-byte
 ByteBool  False  True  Any non-zero  1-byte
 WordBool  False  True  Any non-zero  2-Byte
 LongBool  False  True  Any non-zero  4-byte
         

Enumerated types

In Modern Pascal enumerated types are a special way of creating your own variable types. Enumerated types define ordered sets of values by enumerating the identifiers that denote these values. Their ordering follows the sequence the identifiers are enumerated in.

Type Enumerators
 Direction  (North, East, South, West)
 Days  (monday, tuesday, wednesday, thursday, friday, saturday, sunday)
   

Subrange types

In Modern Pascal subrange types are a range values from an ordinal type. A subrange type is a range of values from an ordinal type called the host type. The definition of a subrange type specifies the smallest and the largest value in the subrange. To define a subrange type, you must specify its limiting values, minimum to maximum. Subrange types can also be of the above enumeration types. To avoid errors you should initialize a variable of Range type to it's default, the compiler does not do this.

Type Range
 Longint  -$80000000..$7FFFFFFF
 Byte  0..255
   
 WeekDays  monday..friday
 WeekEnd  saturday..sunday
   

Pointer type

In Modern Pascal a variable of the pointer type references an address in memory, where the data of another variable may be stored. Pointers are a type, which means that they point to a particular kind of data. From a character type, to a structured record type and even an instance of an object structure or class type.

Type Of Syntax(es)
 Pointer  any address and size in memory GetMem(Var,2048), Var:=AllocMem(2048)
 ^Type  Type, used for heap allocation of instance of type New(Var)
 Instance  of a class Var.Init;
     

Structured types

A structured type is a type that can hold multiple values in one variable. Structured types can be nested to unlimited levels.

Types
 array type
 record type
 class type
 set type
 

Static Arrays

Static Arrays have a fixed number of components of one type, the component type. Static arrays are predefined number of elements of a specified type. Modern Pascal supports multidimensional arrays written in long form. The component type follows the word of.

Static Array Multidimensional Static Array
 Var A:Array [0..6] of Integer;  Var A:Array [0..6] of Array[0..9] of Integer;
 Var S:Array [1..5] of String;  Var S:Array [1..5] of Array[1..3] of String;
 Const Pass=5; Fail=3;  
 Var Points:Array[Fail..Pass] of Integer;  Var A:Array[0..6] of Array[0..4] of Array[0..9] of Integer;
   

Dynamic Arrays

Dynamic Arrays are similar to static arrays as far a the component type, however, they are useful when you do not know the upper limit in advance. Using the SetLength() command you can dynamically increase and decrease the size of the zero based array.

Dynamic Array Multidimensional Dynamic Array
 Var A:Array of Integer;  Var A:Array of Array of Integer;
 Var S:Array of String;  Var S:Array of Array of String;
   
 SetLength(A,10);  SetLength(A,10); SetLength(A[0],10);
 SetLength(S,10);  SetLength(S,10); SetLength(S[0],10);
   

Defined Dynamic Arrays

Functions cannot return the definition array of type, however, these predefined type macros can be returned as function results.

Defined Array Type Equivalent Dynamic Array Definition
 TBooleanArray;  Array of Boolean;
 TByteBoolArray;  Array of ByteBool;
 TWordBoolArray;  Array of WordBool;
 TLongBoolArray;  Array of LongBool;
 TByteArray;  Array of Byte;
 TCharArray;  Array of Char;
 TWideCharArray;  Array of WideChar;
 TUnicodeCharArray;  Array of UnicodeChar;
 TWordArray;  Array of Word;
 TSmallIntArray;  Array of SmallInt;
 TLongWordArray;  Array of LongWord;
 TIntegerArray;  Array of Integer;
 TLongIntArray;  Array of LongInt;
 TLargeWordArray;  Array of LargeWord;
 TLargeIntArray;  Array of LargeInt;
 TInt64Array;  Array of Int64;
 TSingleArray;  Array of Single;
 TDoubleArray;  Array of Double;
 TExtendedArray;  Array of Extended;
 TCurrencyArray;  Array of Currency;
 TStringArray;  Array of String;
   

Record Types

Records are the complementary structure to an array. Where an array is a collection of like types, record types can be a collection of many different data types. Of course, you can also have an array of your record type. Records provide a well organized way of managing groups of data fields. A few data types are added as pointers (4 or 8 byte addresses) to the actual data, for example a record with an element of the type String will show sizeof(record_type) of either 4 or 8 (depending upon 32bit or 64bit platforms). This is important to remember when you store and retrieve records with these types - you will lose the data. You can avoid this issue by using string[84]; for example to store length byte 84 characters, which is much like using the type array[0..84] of char; where the 0th byte you put in a char(length).

Modern Pascal supports fixed records and records with variant parts. The variant part must be the last element in the record definition. The optional identifier in the union statement serves to access the variant field value, which otherwise would be invisible to the programmer. It can be used to see which variant is active at a certain time. In effect, it introduces a new field in the record.

By default, Modern Pascal will align each element on either 4 byte or 8 byte addresses in memory to achieve optimal access for performance. However, you may want to store these records to disk for example, and to reduce unnecessary padding to disk you can use the keyword Packed Record instead of Record to define no alignment.

program HelloRecordWorld;
uses display;

type
   UserRec=Record
      Name:String[55];
      PwrdSHA1:String[40];
      Verified:Boolean;
      Age:Byte;
   End;
   StoredUserRec=Packed Record
      Name:String[55];
      PwrdSHA1:String[40];
      Verified:Boolean;
      Age:Byte;
   End;

(* Here the main program block starts *)
begin
   WriteLn('Unpacked used ',SizeOf(UserRec),' bytes.');    // displays 102
   WriteLn('Packed used ',SizeOf(StoredUserRec),' bytes.');// displays 99
   Readkey;
end.

Set Types

Modern Pascal supports the set types as defined years ago in Turbo Pascal. Each of the elements of the set's type must be of the target type. Where Target type can be any ordinal type with a range between 0 (zero) and 255. A set can contain at most 255 elements. Sets are another way in which Pascal is unique from other languages. Whereas, enumerated types allow a variable to have one and only one value at a time, sets allow you to have any combination of given values. None, One, Multiples or All.

A set therefore holds a set of indicators, again up to 255 indicators (or elements). At first this may sound a little tricky to understand, however, it may help if you think of sets as a dynamic array of the elements from an enumerated type, and a boolean of true it is in this set or false it is not.

program HelloSetWorld;
uses display

type
   Days=(Sun=0, Mon, Tue, Wed, Thr, Fri, Sat);
   DaysWorked=Set of Days;

var
   Schedule:DaysWorked;

begin
   Schedule:=[Mon, Wed, Thr, Fri];
   Writeln('This week I work 9-5 on ',Schedule);
   Schedule =[Tue];
   Schedule-=[Thr];
   Writeln('Next week I work 9-5 on ',Schedule);
   ReadKey;
end.