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.
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:
otherwise instead of else.
Borland Pascal
case c of 'A' : ; 'B' : ; else ...; end;Extended Pascal
case c of 'A' : ; 'B' : ; otherwise ...; end;
otherwise clause and char c had
the value 'C', you got an error (note, this would be unnoticed in
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.
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.
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.
const i:integer = 0;to:
var i : integer value 0;
type MyInteger = integer value 0; var i : MyInteger;All variables of type MyInteger are automatically initialized to 0 when created.
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.
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;
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.
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.
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.