Go to the first, previous, next, last section, table of contents.

# About Pascal and Extended Pascal languages

Pascal is a well-known programming language and hardly needs to be described here. Notice, however, that some people's idea of Pascal is affected by acquaintance with such products as Turbo Pascal which differ from the Pascal standard and provide a lot of nonstandard extensions (some of which are compatible with the Extended Pascal standard). Moreover, it is worth mentioning that the ISO Pascal standard defines two levels of the language, level 0 and level 1; the only difference between the levels is that level 1 supports the so-called conformant array schemas in parameter declarations.

Extended Pascal is a standardized language which contains so significant extensions to Pascal that it is best regarded as a new language. It is currently not very well known, and computer vendors do not seem to be eager to provide compilers for it. Thus, there is social need for GNU Pascal supporting Extended Pascal.

## A comparison of Borland Turbo Pascal with Extended Pascal

As mentioned earlier, Turbo Pascal does not conform to any of the Pascal standards. If you carefully chose a subset of unextended Pascal, you may be able to port code if you're lucky/careful.

To be fair, Turbo Pascal has some wonderful features that make it very powerful in the environments in which it runs. However, some of those features are of little use on non Windows/DOS platforms and probably are not good candidates for standardization.

There are several Turbo Pascal features which are semantically similar to features in unextended Pascal or Extended Pascal. Here is a list of mappings between Turbo Pascal features and Extended Pascal features:

- Case constructs
  1. Extended Pascal uses `otherwise` instead of `else`. Borland Pascal

         case c of
           'A' : ;
           'B' : ;
           else ...;
         end;

     Extended Pascal

         case c of
           'A' : ;
           'B' : ;
           otherwise ...;
         end;

  2. Missing cases cause Extended Pascal compilers to halt. In the case statement above if you had no `otherwise` clause and char c had the value 'C', you got an error (note, this would be unnoticed in Borland Pascal).
- Procedure and function types and variables Here is an area of subtle differences. Turbo Pascal has true procedure/function types but doesn't have standard Pascal's procedural/functional parameters. Borland Pascal

      type
        CompareFunction = function(Key1, Key2 : string) : integer;

      function Sort(Compare : CompareFunction);
      begin
        ...
      end;

  Extended Pascal

      function Sort(Compare : function(Key1, Key2 : string) : integer);
      begin
        ...
      end;

  Moving from Turbo Pascal to Extended Pascal might be difficult if the Turbo Pascal program saves, compares, trades, etc. procedure values. For example, an array of procedure values isn't possible in Extended Pascal. Moving the other way is a little easier as show by the above examples.
- Strings
  1. Borland Pascal's string type has a special case, namely `string` without a length meaning the same as `string[255]`. There is no default in Extended Pascal so you have to change all string types to `string(255)`. Example:

         var
           s : string;

     becomes:

         var
           s : string(255);

     Note also that you have to use parentheses instead of brackets.
  2. A nice pitfall is the pointer to string as in:

         type
           PString = ^String;

     In Extended Pascal this is a pointer to a schema type! Don't forget to translate this to:

         type
           string255 = string(255);
           PString = ^string255;

     If you indeed want to use String as a schema pointer you can define things like:

         type
           MyStr : ^String;
         begin
           New(MyStr, 1024);
         end;

     to allocate 1024 bytes of string space.
  3. As you could see above, Extended Pascal has no 255 byte limit for strings. It is however save to assume a limit of about 32000 bytes. At least Prospero's Extended Pascal limits strings to 32760 bytes. GNU Pascal seems to allow larger strings. DEC Pascal limits strings to 65535 bytes.
- Constant variables
  1. Extended Pascal translates Borland's gruesome:

         const
           i:integer = 0;

     to:

         var
           i : integer value 0;

  2. You can also assign initialization values to types. Like:

         type
           MyInteger = integer value 0;

         var
           i : MyInteger;

     All variables of type MyInteger are automatically initialized to 0 when created.
  3. Constant arrays of type string are translated from:

         const
           MyStringsCount = 5;
         type
           Ident = string[20];
         const
           MyStrings : array [1..MyStringsCount] of Ident = (
                         'EXPORT', 'IMPLEMENTATION', 'IMPORT', 'INTERFACE',
                         'MODULE');

     to:

         const
           MyStringsCount = 5;
         type
           Ident = string(20);
         var
           MyStrings : array [1..MyStringsCount] of Ident value [
             1:'EXPORT'; 2:'IMPLEMENTATION'; 3:'IMPORT';
             4:'INTERFACE'; 5:'MODULE'];

     There seem to be pros and cons to each style. Some folks don't like having to specify an index since it requires renumbering if you want to add a new item to the middle. However, if you index by an enumerated type, you might be able to avoid major renumbering by hand.
- Variant records The following construction is not allowed in Extended Pascal:

      type
        PersonRec = record
          Age : integer;
          case EyeColor : (Red, Green, Blue, Brown) of
            Red, Green : (Wears_Glasses : Boolean);
            Blue, Brown : (Length_of_lashes : integer);
          end;
        end;

  The variant field needs an explicit type. Code this as:

      type
        EyeColorType = (Red, Green, Blue, Brown);
        PersonRec = record
          Age : integer;
          case EyeColor : EyeColorType of
            Red, Green : (Wears_Glasses : Boolean);
            Blue, Brown : (Length_of_lashes : integer);
          end;
        end;

- Units
  1. You can translate units almost automatically to Extended Pascal Modules, taking into account some differences of course. Extended Pascal does not automatically export everything named in a module, but you have to create seperate export clauses. For example translate the following unit:

         unit A;

         interface

         uses
           B, C;

         procedure D;

         implementation

         procedure D;
         begin
         end;

         end.

     to this module:

         module A interface;

         export
           A = (D);

         import
           B;
           C;

         procedure D;

         end.

         module A implementation;

         procedure D;
         begin
         end;

         end.

     You can have one or more export clauses and the name of an export clause doesn't have to be equal to the name of the module. You also see in this example how to translate the Borland Pascal "uses" clause to the Extended Pascal "import" clause.
  2. Borland Pascal allows you to have code in a unit that is executed once, at startup, to initialize things. You can translate this to Extended Pascal's "to begin do ..end" structure. Borland Pascal

         unit A;

         interface

         implementation

         begin
           { do something }
         end.

     Extended Pascal

         module A interface;
         end.

         module A implementation;

         to begin do begin
           { do something }
         end;

         end.

     Extended Pascal also has a `"to end do .... end"` so you can translate `Exit` handlers also.
- Files Extended Pascal treats files quite differently as Borland Pascal. I'm not going to treat file pointers, Get and Put here, but instead I focus on special Extended Pascal features. In Borland Pascal you can read any text file as follows:

      var
        t : text;
        Line : string;
      begin
        Assign(t, 'MYTEXT.TXT');
        Reset(t);
        while not eof(t) do  begin
          readln(t, Line);
          writeln(Line);
        end;
      end;

  The `Assign` function associated the textfile `T` with the file `MYTEXT.TXT`. In Extended Pascal, files are considered entities external to your program. External entities, which don't need to be files, need to be bound to a variable your program. Any variable to which external entities can be bound needs to be declared bindable. So the variable declaration of t becomes:

      var
        t : bindable text;

  Extended Pascal has the bind function that binds a variable with an external entity. Here is an Extended Pascal procedure that emulates the Assign procedure in Turbo Pascal.

      procedure Assign(var t : text; protected Name : string);
      var
        b : BindingType;
      begin
        unbind (t);
        b := binding (t);
        b.Name := Name;
        bind (t, b);
        b := binding (t);
      end;

  Comments: the unbind procedure unbinds a bindable variable from its external entity. If it is not bound, nothing happens. The binding function initializes b. We call binding to set some fields of the BindingType record. Next we set the name field to the name of the file. Calling bind will bind t to the external entity. If we now call binding again, we get the current state of t's binding type. We can now check for example if the bind has succeeded by:

      if not b.bound then
        { do error processing }

  Note that Prospero's Pascal defaults to creating the file if it does not exists! You need to use Prospero's local addition of setting `b.existing` to `true` to work-around this. I've not worked with binary files enough, so no advice yet on how to access them, but you access them much the same. As last an example of getting the size of a file.

      function FileSize(filename : String) : LongInt;
      var
        f : bindable file [0..MaxInt] of char;
        b : BindingType;
      begin
        unbind(f);
        b := binding (f);
        b.Name := filename;
        bind(f, b);
        b := binding(f);
        SeekRead(f, 0);
        if empty(f)
          then  file_size := 0
          else  file_size := LastPosition(f) + 1;
        unbind(f);
      end(*file_size*);

  Prospero's Extended Pascal has a bug in this case. Replace the MaxInt in the type definition of f by a sufficiently large integer. GNU Pascal works correct in this case.

Go to the first, previous, next, last section, table of contents.