Morfik Pascal Data Types and Variables

In this article we will take a closer look at the available data types in Morfik Pascal, how to create new ones and how to use them in declaring variables and constants.


Data Types

In Morfik Pascal, every time you declare a variable you must tell the compiler what its type is. The type of a variable defines what values it can assume and what operations can be performed on it during program execution.

A type declaration specifies an identifier for the type. It is through this identifier that the type will be referenced throughout the application.

There are several different major kinds of data types. In this chapter we will review each of these kinds in detail.

Simple Types

Simple types define ordered sets of values. Let us go through the simple types that are available to Morfik Pascal and see how these can be an important factor in making your code clearer and more elegant.

Note: It is important to note that some of the functions designed to work with ordinal data types are not available to browser side code.

Ordinal Types

Ordinal types represent a sub set of the Simple types. All simple types which are not floating point numeric types are ordinal types which have a one to one mapping to an element of a sub set of the set of Integer values (ℤ).

Integer Types

Morfik Pascal offers a wide choice of Integer types. You will probably find one of them suitable for each special need. The following table shows each of the integer types which are available on the server side of your application with the range of values it can store and the format in which the value is stored.


Type Value Range Format
Shortint -128 .. 127 Signed 8 bits
Smallint -32768 .. 32767 Signed 16 bits
Longint -2147483648 .. 2147483647 Signed 32 bits
Byte 0 .. 255 Unsigned 8 bits
Word 0 .. 65535 Unsigned 16 bits
Integer -2147483648 .. 2147483647 Signed 32 bits
Cardinal 0 .. 4294967295 Unsigned 32 bits
Int64 -9.2*1018 .. 9.2*1018 Signed 64 bits
LongWord 0 .. 4294967295 Unsigned 32 bits


Due to the limitations of the data types which are supported by the JavaScript engine inside the browsers a few of these types are not available in the browser side of your application. The following table lists the Integer types available to the browser side of your application.


Type Value Range Format
Smallint -32768 .. 32767 Signed 16 bits
Longint -2147483648 .. 2147483647 Signed 32 bits
Byte 0 .. 255 Unsigned 8 bits
Word 0 .. 65535 Unsigned 16 bits
Integer -2147483648 .. 2147483647 Signed 32 bits


Note that if you declare a variable of one of the unsupported types on the browser side of your application, Morfik will generate a compiler error for it.


Note: It is important to realize that the browser side of your application, written with Morfik Pascal, will be compiled into JavaScript for runtime execution. Because of this, JavaScript supported types define what can or cannot be supported on the browser side.
For numeric data, JavaScript has only one data type which is the equivalent of a floating point Double. All the supported data types on the browser side must be contained within the range of values covered by a Double.

Character Type

The Char data type is used to store a single character. The character encoding which will be used is selected when you create your project.

The Char type is an ordinal type since there is a numeric value associated with each character that is represented in the type. You can obtain this value and the set of characters is ordered by it.

Enumerated Types

Enumerated types define ordered sets by enumerating the identifiers that represent its elements. The order of the elements in the set is the same in which they were declared. The presence of an identifier in the list of elements of an enumerated type is, basically, equivalent to the declaration of a constant of that type. In Listing 1 there is an example of an enumerated type which declares an element for day of week and a test sub routine showing how this type can be used.


Listing 1 – The '''DaysOfTheWeek 'enumerated type.

Type
  DaysOfTheWeek = (Sunday, Monday, Tuesday, Wednesday,
                   Thursday, Friday, Saturday);
 
Procedure test
Var 
  ADay : DaysOfTheWeek;
      // ...
  ADay := Monday;
      // ...
  Case ADay Of
    Monday: ShowMessage('Monday');
    Tuesday: ShowMessage('Tuesday');
    Wednesday: ShowMessage('Wednesday');
    Thursday: ShowMessage('Thursday');
    Friday: ShowMessage('Friday');
  End;
  // ...
End;


All enumerated type elements have a corresponding numeric value, with the first element in the enumerated type having the value of 0 and all remaining elements having a value equals to its predecessor plus one.

Note: On the server side of your application you can use the Pred and Succ functions to obtain the previous and next values in an enumerated type. You can also apply the Ord function to obtain the numeric value of an enumerated type variable.
These functions are not available on the browser side of the application. Similar behavior to that of these functions can be obtained however. For example, in order to obtain the next day in the DaysOfTheWeek set, instead of the Succ function you could use code such as this:
day := DaysOfTheWeek(Integer(day) + 1);
More about the converting between types can be found under the topic of Typecasting in this chapter.

Boolean Type

The Boolean type is a special, pre-defined, enumerated type which is defined in the System module of the Morfik Framework. The declaration is the equivalent of the following Morfik Pascal enumerated type declaration:

Type
  Boolean = (False, True);


Note: Since Boolean is an enumerated value it is also an ordinal type with False having the value of zero and True the value of one. On the server side of your application you can apply the Ord function to obtain the numeric value of a Boolean variable.

Subrange Types

Subrange types define ranges of values within other ordinal types. We can, for example, define a subrange type called WeekDays as being a range from the DaysOfTheWeek enumerated type that is shown in Listing 1, as an example of enumerated types. The following is an example of what such a declaration would look like:

Type 
  WeekDays = Monday..Friday;


A variable whose type has been declared as being a Subrange type will have all the properties and characteristics of the base type of the Subrange, but will only accept values which fall within the specified range.

Floating Point Types

Floating point data types are sub ranges of the set of Real Numbers. Morfik Pascal supports several different floating point types, each of them stored in a different manner/format. The following is a table of the supported data types and their capacities.


Type Range Significant Digits Size in Bytes
Single 1.5*10-45 .. 3.4*1038 7-8 4
Double 5.0*10-324 .. 1.7*10308 15-16 8
Extended 1.9*10-4951 .. 1.1*104932 19-20 10
Currency -922337203685477.5808 .. 922337203685477.5807 19-20 8


Please note that Morfik Pascal uses different division operators, as mentioned in chapter 2, for integer ("div") and floating point types ("/").


Note: It is important to realize that the browser side of your application, written with Morfik Pascal, will be compiled into JavaScript for runtime execution. Because of this, JavaScript supported types define that can or cannot be supported on the browser side.
For numeric data, JavaScript has only one data type which is the equivalent of a floating point Double. All the supported data types on the browser side must be contained within the range of values covered by a Double.

String Type

The string type is used to store a list of characters as if to store a word or a sentence. We can think of this type as an ordered list of characters since the composing characters are stored in the precise order in which they were stored. The following are examples of declaring variables of the string type.

Var
  Str : String;
  Str2 : String = 'Hello!  This is a string!';


You can assign values to a string variable by assigning it a list of characters surrounded by a pair of the single quotes character. Since single quotes are used to delimit the characters that are being assigned to the string variable, having a single quote character within the character list becomes a problem as the compiler would interpret it as being the end of the character list. To work around this small problem, Morfik Pascal uses the same method as most other Pascal language compilers, to repeat the single quote char indicating that it is to be interpreted literally and not as a delimiter. The following is an example of how to embed a single quote in the value assigned to a string variable:

Var
  s1 : String = 'this is a '' single quote';

String Constants

You can declare simple string constants or typed string constants. Typed Constants are functionally equivalent to initialized variables.

Use two single quotes to represent a single quote within a string. You can also use the # symbol followed by an unsigned integer constant from 0 to 255 (decimal or hexadecimal) that denotes the corresponding ASCII character.

The following are some samples of string constant declarations.

Const
  Str1 = 'Hello';
  Str2 : string = 'Don''t do it';
  Multiline = 'First line'#13#10'Second line';

Structured Types

Structured types are types which store more than one atomic value. This essentially means that we are storing more than one value within a single variable. Morfik Pascal allows you to create structured types which have other structured types within their definition.

Arrays

Arrays are a structured data type which holds a fixed number of elements of a same type, called the base type. Arrays are ordered lists and can be accessed by a numeric index which will refer to one specific entry in the array. Morfik Pascal allows any range of numbers to be specified as the indexer of the array. The following are some sample declarations for arrays types in Morfik Pascal:

    Type 
      TZeroBasedIntegerArray = array[0..10] of integer;
      TOneBasedIntegerArray = array[1..10] of integer;


In the first declaration we are actually specifying an array with eleven elements numbered from zero to ten.

The following are some sample declarations of Array variables in Morfik Pascal:

    Var 
      A1 : TZeroBasedIntegerArray;
      A2 : ToneBasedIntegerArray;
      A4 : array[2..6] of integer;


Notice that you can directly define a variable as being an array or define it as being of a pre-defined array type such as the ones presented in this topic.

Once the array variables have been declared you can access the individual array elements by indexing the variable with the appropriate value such as shown in the following example:

    A1[0] := 1;
    A2[1] := 10;

Records

Record is the name we give to structured types which allow us to store multiple elements of information, with different data types, within a single variable. The declaration of a record includes an identifier for the type and identifiers and types for each of the elements that compose the structure. Frequently the component elements of a record are referred to as fields, much as instance variables of a class are. The following is an example of a record declaration:

Type 
  TPersonalData = record
    Name : String;
    Phone : String;
  End;


Records can also be declared with an added "packed" modifier which instructs the compiler to optimize memory usage, instead of prioritizing performance. The previous declaration would then be as follows, if we added the packed modifier.

Type 
  TPersonalData = packed record
    Name : String;
    Phone : String;
  End;


You can access a field of a record by using the same "." (dot) notation which is used for objects as show in the following example:

  Procedure test;
    Var
      Client1 : TPersonalData;
  Begin
    //... 
    Client1.Name := 'John';
    //...
  End;

Classes

Classes are structured types very similar to structures, in many ways. Classes however can "inherit" fields from other classes and can have procedures and functions as elements.

Type  
  TPersonalData = class
    Name : String;
    Phone : String;
 
    Procedure ChangeName(ANewName : String); virtual;
    Procedure ChangePhone(ANewPhone : String); virtual;
 
  End;


We will see classes in much greater detail in Chapter 5 – Object Oriented Programming with Morfik Pascal.

Sets

This type, defined by the Set keyword is exactly what its name implies – a set of values which consists of a subset of the values that can be assumed by the base type.

Morfik Pascal not only implements this type, but a full range of operations which can be handled on this data type.

The following is a declaration of a Set data type which is based on integer type:

  Type 
    TIntegerSet = Set Of integer;


Literal values can be assigned to Set variables in a very simple and straightforward manner, as shown in the following example:


Listing 2 – Set declarations and operations

Unit Sets;
 
Uses SystemUtilities;
 
Interface 
 
Type 
  TByteSet = Set Of Byte;
 
Var
  S1 : TByteSet;
 
Implementation
 
Procedure Go;
var
  S2 : Set Of Byte;
Begin
    //...
    S1 := [1,2];
    S2 := S1 + [1,3];
    S2 := S1 - [1,3];
    S2 := S1 * [1,3];
    //...
    If S1 >= S2 then ShowMessage('superset');
    If S1 =  S2 then ShowMessage('equal');
    If S1 <> S2 then ShowMessage('unequal');
    If 3  In S2 then ShowMessage('member');
End;
 
End.


Note: The Set type allows the usage of operators which treat Sets in a special way. In this example you can see Sets being added together or subtracted from one another.
These set operations will result in new sets which will hold all the elements of the two sets, in case of addition or a set with the elements of S1 which are not in S2, in case of subtraction, for example.

File Types

File types represents a linear sequence of values saved into a file. File types are available only on the server side of a Morfik application.

Typed Files

File types are declared with a base type which can be just about any fixed size type that can be declared in Morfik, leaving out other File types and dynamically allocated types such as classes and pointer types. This data type is frequently referred to as a "typed file" since it references a particular data type (the base type).


Listing 3 – Usage of the a typed file data type.

Unit FileTypes;
 
Interface
 
type
  TIntegerFile = File Of integer;
 
var F1 : TintegerFile;
 
Implementation
 
Procedure Go;
Var
   F2 : File Of Integer;
Begin
    AssignFile(F1, 'c:\test.int');
    Rewrite(F1);
    Write(F1, 9);
    CloseFile(F1);
End;
 
End.

Binary Files

You can also work with binary files, which could be considered a special case of the Type Files where the base type is Byte. These files are normally used for lower level I/O operations and everything that goes in and out of them is seen as nothing more than a stream of bytes. The following would be a declaration of such a binary file.

  Var
    MyFile : File of byte;

Pointers

Pointers store the memory address of other variables. Most of the time pointer variables will hold the address of a dynamically allocated variable.

The following are examples of pointer type declarations, which reference different data types, including a structure.

Type 
  TPersonalInfo = Record
    Name : String;
    Phone : String;
  End;
 
  TPersonalInfoList = array[1..10] of TPersonalInfo;
 
  PInteger = ^Integer;
  PCliente = ^TPersonalInfo;
  PClientes = ^TPersonalInfoList;


Notice that pointer data types use the caret "^" symbol to indicate that they are actually a reference to a variable which actually holds a value of the base type used in declaring the pointer.

Listing 4 – Example of pointer usage.

Unit Pointers;
 
Interface
//The next line declares a pointer to an Integer variable
 
Type 
  PInteger = ^Integer;
 
Var
  Ptr1 : PInteger; 
 
Implementation
 
Procedure Test;
Var
  I1, I2 : Integer;
  Ptr2 : ^Integer;
Begin
    I1 := 1;
    I2 := 2;
    Ptr1 := @I1; //Assign to variable Ptr1 the address of I1
    Ptr2 := @I2; //Assign to variable Ptr2 the address of I2
    //The next line Assigns to I1 the sum of I1 and I2
    I1 := Ptr1^ + Ptr2^
End;
 
End.


Note: In the example in listing 4 variables Ptr1 is declared as being of type PInteger and Ptr2 is defined as ^Integer. These types are essentially the same since PInteger is declared as being ^Integer.

The Pointer Type

In Morfik Pascal you can declare a variable as being of a type called Pointer. The pointer type is a generic type, not bound to any base type. It holds a memory address and makes no assumptions about what is stored in that memory position. The following is an example of a Pointer type variable.

  Var
    Ptr : Pointer;

Nil

When a Pointer type variable needs to be "empty" or null, Morfik Pascal provides a predefined value called Nil. Nil is essentially a Null pointer, a pointer that does not point to any memory location.

Procedural Types

A procedural type is essentially the same thing as pointer to a function or to a method. Procedural types are very useful; in fact it is through them that the Morfik Framework handles events generated by the controls in Forms.

The way in which you declare a procedural type is very similar to writing the header of a function or sub routine, as you can see in the following example:

  Type
   TNotifyEvent = procedure(Sender : TObject) of object;
   FuncType = procedure(Str : string);


In Listing 5 you can see an example of how to declare procedural types, how to assign values to them and how to use them in calling a function.

Listing 5 – Example of delegate usage.

Unit FunctionTypes;
 
uses SystemUtilities;
 
Interface
 
Type
  TestClass = class 
  Public
    Procedure TestProc(Sender : TObject);
  End; 
 
  TNotifyEvent1 = procedure(Sender : TObject) of object;
  FuncType = procedure(Str : String);
 
Implementation
 
Procedure TestClass.TestProc(Sender: TObject);
Begin
    //...
End;
 
Procedure MsgFunc(Str : String);
Begin
    ShowMessage(Str);
End;
 
Var
  N1 : TNotifyEvent1;
 
Procedure Test;
Var
  T : TestClass;
  N2 : procedure(Sender : TObject) of object;
  MsgProc : FuncType;
Begin
    N1 := T.TestProc;
    N2 := T.TestProc;
    MsgProc := MsgFunc;
    MsgProc('Hello');
End;
 
End.


In two variables declared in the example in Listing 5, you can see that the first one as the keywords "of object" added at the end of the line. The same is true of the procedural local variable declared inside the Test function. Procedural types declared with "of object" are references to methods, while those declared without it are references to common procedures or functions.

Variables

A variable is an identifier (a name, if you will) that we assign to a specific memory location whose content can be altered. Variables can be defined as being of a standard or user-defined data type.

Variable Declarations

In Morfik Pascal variable declarations must come at the start of a procedure, function or method. All variables must be declared before the first line of code which is part of the body of the function or method.

Variables can be declared one at a time or several at a time. The following sample shows you both styles of declarations.

  Var
    Int1 : integer;
    Int2 : integer;
    Str1, Str2, Str3 : string;

Variables can also be declared with their initial values as shown in the following example.

  Var
    Int3 : integer = 10;
    Str4 : string = 'Hello';


Note: Initialized variable declarations will not work for local variables if you have selected to use Delphi as your backend platform compiler. In this case you can only have global initialized variables.

Variable declarations can have inline structured type declarations in them as can be seen in the following example.

  Var
   APerson : record 
               Name : string;
               Phone : string;
   End;

Qualifiers

A reference to a variable may contain one ore more qualifiers which alter the meaning of the identifier. Qualifiers may assume several different forms and in your contact with Morfik Pascal through out this guide you have already had contact with them. Some examples of using qualifiers are:

  • prefixing a structure or class name to a member name,
  • using the "." (dot) notation,
  • indexing arrays and
  • dereferencing pointer variables.

You can see some usages of qualifiers in the following sample:

  Var
    TestObj : TestClass;
  //...
    N1 := TestObj.Name;
    A2[1] := 10;
    I1 := Ptr1^ + Ptr2^;


In all the cases shown in the sample, the meaning of an identifier is changed by a prefix, and index or an operator (caret (^) – dereferencing operator).

Typecasts

Typecasts are a way to tell the compiler that you want it to temporarily treat a variable as if it were of a different type. Typecasts can be accomplished using the name of the type you want the compiler to consider as the type of the variable as if it were a function. The following is a small sample of using a typecast to convert an integer to a pointer and a pointer to an integer.

Procedure test;
Var
  P : Pointer;
  I : Integer;
Begin
  I := Integer(P);
  P := Pointer(I);
  //...
End;


Note: No verification is done by the compiler regarding the properness of a typecast. It is presumed that the developer knows what he is doing when a typecast is requested.

Helper Methods

Morfik Pascal allows all language types to receive the addition of Helper Methods. Helper Methods are, essentially, functions which are associated with the type and are available for calling through a variable or a reference to a type.

Creating a Helper Method

Adding a Helper Method to a type is actually quite simple and can be done from anywhere in the code where the type is within scope. The following is an example of adding a Method called ToXString to the Integer data type. This method will return the string representation of the integer value, with an upper case "X" in front of it.

Function Integer.ToXString: string;
Begin
    Result := 'X'+ Self.ToString;
End;


Notice that this Method makes use of another Helper Method of the Integer data type, the ToString method.

An extensive list of Helper Methods has been introduced into the Morfik Framework in Morfik 2.

Wrapping it up

Morfik Pascal has a complete and sophisticated system for handling data types. In most respects, while programming in Morfik Pascal and experienced Pascal Developer, should feel right at home in working with Morfik Pascal.


Related Topics

See Also

Back to top