This is ../p/doc/info/gpc.info, produced by makeinfo version 4.0 from
gpc.texi.

INFO-DIR-SECTION GNU programming tools
START-INFO-DIR-ENTRY
* GPC: (gpc).                   The GNU Pascal Compiler.
END-INFO-DIR-ENTRY
INFO-DIR-SECTION Individual utilities
START-INFO-DIR-ENTRY
* GPC: (gpc)Invoking GPC.       The GNU Pascal Compiler.
END-INFO-DIR-ENTRY

   This file documents the GNU Pascal Compiler.

   Copyright (C) 1988-2002 Free Software Foundation, Inc.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the sections entitled "GNU General Public License", "The GNU
Project", "The GNU Manifesto" and "Funding for Free Software" are
included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that the sections entitled "GNU General Public
License", "The GNU Project", "The GNU Manifesto" and "Funding for Free
Software" and this permission notice, may be included in translations
approved by the Free Software Foundation instead of in the original
English.


File: gpc.info,  Node: Main Branch Integer Types,  Next: Integer Types with Specified Size,  Prev: Natural Integer Types,  Up: Integer Types

The Main Branch of Integer Types
................................

   `Integer', `Cardinal', and `Word' define the three "main branches"
of GPC's integer types. You won't always be able to deal with the
natural size; sometimes something smaller or longer will be needed.
Especially when interfacing with libraries written in other languages
such as C, you will need equivalents for their integer types.

   The following variants of `Integer', `Cardinal' and `Word' are
guaranteed to be compatible to the integer types of GNU C. The sizes
given, however, are _not_ guaranteed. They are just typical values
currently used on most platforms, but they may be actually shorter or
increase in the future.

signed         unsigned     also unsigned    GNU C equivalent            size in bits
                                                                         (typically)
ByteInt        ByteCard     Byte             [un]signed char              8
ShortInt       ShortCard    ShortWord        [unsigned] short int        16
Integer        Cardinal     Word             [unsigned] int              32
MedInt         MedCard      MedWord          [unsinged] long int         32
LongInt        LongCard     LongWord         [unsinged] long long int    64
--             SizeType     --               size_t                      32
PtrDiffType    --           --               ptrdiff_t                   32
PtrInt         PtrCard      PtrWord          --                          32

   Since we don't know whether `LongInt' will always remain the
"longest" integer type available - maybe GNU C will get `long long long
int', one day, which we will support as `LongLongInt' - we have added
the synonym `LongestInt' for the longest available singed integer type,
and the same holds for `LongestCard' and `LongestWord'.


File: gpc.info,  Node: Integer Types with Specified Size,  Next: Integer Types and Compatibility,  Prev: Main Branch Integer Types,  Up: Integer Types

Integer Types with Specified Size
.................................

   In some situations you will need an integer type of a well-defined
size. For this purpose, GNU Pascal provides three families of signed
and unsinged integer types. The type

     Integer (42)

is guaranteed to have a precision of 42 bits. In a realistic context,
you will most often give a power of two as the number of bits, and the
machine you will need it on will support variables of that size. If
this is the case, the specified precision will simultaneously be the
amount of storage needed for variables of this type.

   In short: If you want to be sure that you have a signed integer with
32 bits width, write `Integer (32)', not just `Integer' which might be
bigger. The same works with `Cardinal' and `Word' if you need unsigned
integer types of well-known size.

   This way, you _can't_ get a higher precision than that of
`LongestInt' or `LongestCard' (see *Note Main Branch Integer Types::).
If you need higher precision, you can look at the `GMP' unit (*note
GMP::) which provides integer types with arbitrary precision, but their
usage is different from normal integer types.


File: gpc.info,  Node: Integer Types and Compatibility,  Next: Summary of Integer Types,  Prev: Integer Types with Specified Size,  Up: Integer Types

Integer Types and Compatibility
...............................

   If you care about ISO compliance, _only_ use `Integer' and subranges
of `Integer'.

   Some of GPC's non-ISO integer types exist in Borland Pascal, too:
`Byte', `ShortInt', `Word', and `LongInt'. The sizes of these types,
however, are not the same as in Borland Pascal. Even for `Byte' this is
not guaranteed (while probable, though).

   When designing GNU Pascal, we thought about compatibility to Borland
Pascal. Since GNU Pascal is (at least) a 32-bit compiler, `Integer'
_must_ have (at least) 32 bits. But what to do with `Word'? Same size
as `Integer' (like in BP) or 16 bits (like in BP)? We decided to make
`Word' the "natural-sized" unsigned integer type, thus making it (at
least) 32 bits wide. Similarly, we decided to give `LongInt' twice the
size of `Integer' (like in BP) rather than making it 32 bits wide (like
in BP). So `LongInt' has 64 bits, and `ShortInt' has 16 bits on the
IA32 platform.

   On the other hand, to increase compatibility to Borland Pascal and
Delphi, GPC provides the alias name `Comp' for `LongInt' (64 bits on
IA32) and `SmallInt' for `ShortInt' (16 bits on IA32). Note that BP
treats `Comp' as a "real" type and allows assignments like `MyCompVar
:= 42.0'. Since we don't consider this a feature, GPC does not copy
this behaviour.


File: gpc.info,  Node: Summary of Integer Types,  Prev: Integer Types and Compatibility,  Up: Integer Types

Summary of Integer Types
........................

   Here is a summary of all integer types defined in GPC. The sizes and
ranges are only _typical_ values, valid on some, but not all platforms.
Compatibility to GNU C however _is_ guaranteed.

*Note ByteInt::
     signed 8-bit integer type, `-128..128',
     compatible to `signed char' in GNU C.

*Note Byte: ByteCard
     unsigned 8-bit integer type, `0..255',
     compatible to `unsigned char' in GNU C.

*Note ShortInt::
     signed 16-bit integer type, `-32768..32767',
     compatible to `short int' in GNU C.

*Note ShortWord: ShortCard
     unsigned 16-bit integer type, `0..65535',
     compatible to `unsigned short int' in GNU C.

*Note Integer::
     signed 32-bit integer type, `-2147483648..2147483647',
     compatible to `int' in GNU C.

*Note Word: Cardinal
     unsigned 32-bit integer type, `0..4294967295',
     compatible to `unsigned int' in GNU C.

*Note MedInt::
     signed 32-bit integer type, `-2147483648..2147483647',
     compatible to `long int' in GNU C.

*Note MedWord: MedCard
     unsigned 32-bit integer type, `0..4294967295',
     compatible to `unsigned long int' in GNU C.

*Note LongInt::
     signed 64-bit integer type,
     `-9223372036854775808..9223372036854775807',
     compatible to `long long int' in GNU C.

*Note LongWord: LongCard
     unsigned 64-bit integer type, `0..18446744073709551615',
     compatible to `unsigned long long int' in GNU C.

*Note LongestInt::
     signed 64-bit integer type,
     `-9223372036854775808..9223372036854775807'.

*Note LongestWord: LongestCard
     unsigned 64-bit integer type, `0..18446744073709551615'.

*Note Comp::
     signed 64-bit integer type,
     `-9223372036854775808..9223372036854775807'.

*Note SmallInt::
     signed 16-bit integer type, `-32768..32767'.

*Note SizeType::
     integer type (usually unsigned) to represent the size of objects
     in memory

*Note PtrDiffType::
     signed integer type to represent the difference between two
     positions in memory

*Note PtrInt::
     signed integer type of the same size as a pointer

*Note PtrWord: PtrCard
     unsigned integer type of the same size as a pointer

   To specify the number of bits, use

`Integer (N)'
     signed N-bit integer type.

`Cardinal (N)'
     unsigned N-bit integer type.

`Word (N)'
     unsigned N-bit integer type.

     program IntegerTypesDemo (Output);
     
     var
       ByteVar: Byte;
       ShortIntVar: ShortInt;
       Foo: MedCard;
       Big: LongestInt;
     
     begin
       ShortIntVar := 1000;
       Big := MaxInt * ShortIntVar;
       ByteVar := 127;
       Foo := 16#deadbeef
     end.

   See also: *Note Subrange Types::.


File: gpc.info,  Node: Real Types,  Next: String Types,  Prev: Integer Types,  Up: Data Types

Built-in Real (Floating Point) Types
------------------------------------

   GPC has three built-in floating point types to represent real
numbers. Each of them is available under two names (for compatibility
to other compilers and languages).

   For most purposes, you will always use `Real' which is the only one
of them that is part of Standard and Extended Pascal. If memory
constraints apply, you might want to choose `ShortReal' for larger
arrays. On the other hand, if high precision is needed, you can use
`LongReal'. When interfacing with libraries written in other languages
such as C, you will need the equivalents for their real types.

   Note that not all machines support longer floating point types, so
`LongReal' is the same as `Real' on these machines. Also, some machines
may support a longer type, but not do all arithmetic operations (e.g.
the `Sin' function, *Note Sin::) in a precision higher than that of
`Real'. If you need higher precision, you can look at the `GMP' unit
(*note GMP::) which provides rational and real numbers with arbitrary
precision, but their usage is different from normal real types.

   The following real types are guaranteed to be compatible to the real
types of GNU C. The sizes given, however, are _not_ guaranteed.  They
are just typical values used on any IEEE compatible floating point
hardware, but they may be different on some machines.

type name    alternative name    GNU C equivalent    size in bits (typically)
ShortReal    Single              float               32
Real         Double              double              64
LongReal     Extended            long double         80


File: gpc.info,  Node: String Types,  Next: Character Types,  Prev: Real Types,  Up: Data Types

Strings Types
-------------

   There are several ways to use strings in GNU Pascal. One of them is
the use of the intrinsic string type `String' which is a predefined
schema type. The schema discriminant of this type holds the maximal
length, which is of type Integer, so values up to `MaxInt' can be
specified. For `String', an assignment is defined. There are many
built-in functions and procedures for comfortable strings handling.

   @@ ???? String procedures and functions.

   Another way to use strings is to use arrays of type `Char'. For
these, an intrinsic assignment is defined as well. Besides, `String'
and `Char' are assignment compatible. The preferred way, however, is
`String' because of the numerous possibilities for string handling.


File: gpc.info,  Node: Character Types,  Next: File Types,  Prev: String Types,  Up: Data Types

Character Types
---------------

   Character types are a special case of ordinal types. See *Note
Ordinal Types::


File: gpc.info,  Node: File Types,  Next: Boolean (Intrinsic),  Prev: Character Types,  Up: Data Types

File Types
----------

   Files are used to store data permanently, normally on hard drives or
floppies. There are tree types of files available: text files, typed
and untyped files.

   Text files are used to store text in them, where typed files are
used to store many entries of the same type in them, e.g.  addresses.
Text files and typed files are accessible by `Read' and `Write'
operations and do not need the parameter `BlockSize' in `Reset' or
`Rewrite'.  On the other hand, untyped files are used to store any type
of information in them but you need to use `BlockWrite' or `BlockRead'
to store or retrieve data out of this file.

     var
       F1: Text;   { a textfile }
       F2: file of Real;   { a typed filed used to store real values in it }
       F3: File;   { an untyped file }

See also
--------

   *Note File Routines::, *Note Write::, *Note Read::, *Note
BlockRead::, *Note BlockWrite::, *Note Reset::, *Note Rewrite::


File: gpc.info,  Node: Boolean (Intrinsic),  Next: Pointer (Intrinsic),  Prev: File Types,  Up: Data Types

Boolean (Intrinsic)
-------------------

   The intrinsic Boolean represents boolean values, i.e. it can only
assume true and false (which are predefined constants). This type
corresponds to the enumerated type
     type
       Boolean = (False, True);
   Since it is declared this way, it follows:
     Ord (False) = 0
     Ord (True) = 1
     False < True
    There are four intrinsic logical operators. The logical `and',
`or' and `not'. In Borland Pascal and GNU Pascal, there is  a logical
"exclusive or" `xor'.

See also
--------

   *Note Enumerated Types::, *Note and::, *Note or::, *Note not::,
*Note xor::


File: gpc.info,  Node: Pointer (Intrinsic),  Next: Type Definition Possibilities,  Prev: Boolean (Intrinsic),  Up: Data Types

Pointer (Intrinsic)
-------------------

   The intrinsic Pointer Type is a so-called unspecified or typeless
pointer (i.e. a pointer which does not point to any type but holds
simply a memory address).

See also
--------

   *Note Pointer Types::, *Note nil::


File: gpc.info,  Node: Type Definition Possibilities,  Next: Machine-dependent Type Implementation,  Prev: Pointer (Intrinsic),  Up: Data Types

Type Definition Possibilities
-----------------------------

* Menu:

* Subrange Types::     Packed and non-packed Subranges
* Enumerated Types::   Enumerated Types
* Array Types::        Fields (Array Types)
* Record Types::       Structured Types (Record Types)
* Variant Records::    Record Types with Varying Fields
* Schema Types::       Schema Types
* Set Types::          Set Types
* Pointer Types::      Pointer Types
* Procedural Types::   Procedures Types
* Object Types::       Types for Object-Oriented Programming
* Type Initializers::  Types Carrying an Initial Value for Variables
* Restricted Types::   Hiding Internal Information about Types


File: gpc.info,  Node: Subrange Types,  Next: Enumerated Types,  Up: Type Definition Possibilities

Subrange Types
..............

   GNU Pascal supports Standard Pascal's subrange types:

     program SubrangeDemo;
     type
       MonthInt = 1 .. 12;
       Capital = 'A' .. 'Z';
       ControlChar = ^A .. ^Z;  { `^A' = `Chr (1)' is a BP extension }
     begin
     end.
   Also possible: Subranges of enumerated types:
     program EnumSubrangeDemo;
     type
       { This is an enumerated type. }
       Days = (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
     
       { This is a subrange of `Days'. }
       Working = Mon .. Fri;
     
     begin
     end.

   To increase performance, variables of such a type are aligned in a
way which makes them fastest to access by the CPU. As a result, `1 ..
12' occupies 4 bytes of storage on an IA32 CPU.

   For the case you want to save storage at the expense of speed, GPC
provides a `packed' variant of these as an extension:

     program PackedSubrangeDemo;
     type
       MonthInt = packed 1 .. 12;
     begin
     end.

   A variable of this type occupies the shortest possible (i.e.,
addressable) space in memory - one byte on an IA32 compatible CPU.

   See also: *Note packed::.


File: gpc.info,  Node: Enumerated Types,  Next: Array Types,  Prev: Subrange Types,  Up: Type Definition Possibilities

Enumerated Types
................

     type
       ENUM TYPE IDENTIFIER = (NAME IDENTIFIER, ..., NAME IDENTIFIER);

   An enumerated type defines a range of elements which are referred to
by identifiers. Enumerated types are ordered by occurence in the
identifier list. So, they can be used as index types in an array
definition, and it is possible to define subranges of them. Since they
are ordered, they can be compared to one another. The intrinsic function
`Ord' applied to NAME IDENTIFIER returns the number of occurence in the
identifier list (beginning with zero), `Pred' and `Succ' return the
predecessor and successor of NAME IDENTIFIER.

See also
--------

   *Note Array Types::, *Note Subrange Types::, *Note Ord::, *Note
Pred::, *Note Succ::


File: gpc.info,  Node: Array Types,  Next: Record Types,  Prev: Enumerated Types,  Up: Type Definition Possibilities

Array Types
...........

     type
       ARRAY TYPE IDENTIFIER = array [INDEX TYPE] of ELEMENT TYPE
   or
     type
       ARRAY TYPE IDENTIFIER = array [INDEX TYPE, ..., INDEX TYPE] of ELEMENT TYPE

   The reserved word `array' defines an array type. INDEX TYPE has to
be an ordinal type, subrange type or an enumerated type, where several
index types, separated by commata, are allowed. ELEMENT TYPE is an
arbitrary type. An element of an array is accessed by ARRAY TYPE
VARIABLE [INDEX NUMBER]. The upper and lower index bounds can be
determined by the intrinsic functions `High' and `Low'.

     type
       IntArray = array [1 .. 20] of Integer;
       Foo      = array [(Mo, Tu, We, Th, Fr, Sa, Su)] of Char;
       Bar      = array [0 .. 9, 'a' .. 'z', (Qux, Glork1, Fred)] of Real;
       Baz1     = array [1 .. 10] of IntArray;
       { equal (but declared differently): }
       Baz2     = array [1 .. 10, 1 .. 20] of Integer;

See also
--------

   *Note High::, *Note Low::


File: gpc.info,  Node: Record Types,  Next: Variant Records,  Prev: Array Types,  Up: Type Definition Possibilities

Record Types
............

     type
       RECORD TYPE IDENTIFIER = record
         FIELD IDENTIFIER: TYPE DEFINITION;
         ...
         FIELD IDENTIFIER: TYPE DEFINITION;
       end;

   or, with a variant part,

     type
       RECORD TYPE IDENTIFIER = record
         FIELD IDENTIFIER: TYPE DEFINITION;
         ...
         FIELD IDENTIFIER: TYPE DEFINITION;
       case bar: VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
       end;

   or, without a variant selector field,

     type
       RECORD TYPE IDENTIFIER = record
         FIELD IDENTIFIER: TYPE DEFINITION;
         ...
         FIELD IDENTIFIER: TYPE DEFINITION;
       case VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
       end;

   The reserved word `record' defines a structure of fields.  Records
can be `packed' to save memory usage at the expense of speed.

   The reserved word `record' and record types are defined in ISO-7185
Pascal. According to ISO Pascal, the variant type must be an
identifier. GNU Pascal, like UCSD and Borland Pascal, also allows a
subrange here.

   A record field is accessed by RECORD TYPE VARIABLE . FIELD IDENTIFIER

   See also: *Note packed::, *Note case Statement::.


File: gpc.info,  Node: Variant Records,  Next: Schema Types,  Prev: Record Types,  Up: Type Definition Possibilities

Variant Records
...............

   GPC supports variant records like in EP and BP. The following
construction is not allowed in Extended Pascal, but in BP and GPC:

     program BPVariantRecordDemo;
     
     type
       PersonRec = record
         Age: Integer;
       case EyeColor: (Red, Green, Blue, Brown) of
         Red, Green : (WearsGlasses: Boolean);
         Blue, Brown: (LengthOfLashes: Integer);
       end;
     
     begin
     end.

   In EP, the variant field needs a type identifier, which, of course,
also works in GPC:

     program EPVariantRecordDemo;
     
     type
       EyeColorType = (Red, Green, Blue, Brown);
     
       PersonRec = record
         Age: Integer;
       case EyeColor: EyeColorType of
         Red, Green : (WearsGlasses: Boolean);
         Blue, Brown: (LengthOfLashes: Integer);
       end;
     
     begin
     end.


File: gpc.info,  Node: Schema Types,  Next: Set Types,  Prev: Variant Records,  Up: Type Definition Possibilities

EP's Schema Types including `String'
....................................

   Schemata are types that depend on one or more variables, called
"discriminants". They are an ISO-10206 Extended Pascal feature.

     type
       RealArray (n: Integer) = array [1 .. n] of Real;
       Matrix (n, m: PositiveInteger) = array [1 .. n, 1 .. m] of Integer;

   The type `RealArray' in this example is called a Schema with the
discriminant `n'.

   To declare a variable of such a type, write:

     var
       Foo: RealArray (42);

   The discriminants of every global or local schema variable are
initialized at the beginning of the procedure, function or program
where the schema variable is declared.

   Schema-typed variables "know" about their discriminants.
Discriminants can be accessed just like record fields:

     program Schema1Demo;
     type
       PositiveInteger = 1 .. MaxInt;
       RealArray (n: Integer) = array [1 .. n] of Real;
       Matrix (n, m: PositiveInteger) = array [1 .. n, 1 .. m] of Integer;
     
     var
       Foo: RealArray (42);
     
     begin
       WriteLn (Foo.n)  { yields 42 }
     end.

   Schemata may be passed as parameters. While types of schema
variables must always have specified discriminants (which may be other
variables), formal parameters (by reference or by value) may be of a
schema type without specified discriminant. In this, the actual
parameter may posses any discriminant. The discriminants of the
parameters get their values from the actual parameters.

   Also, _pointers_ to schema variables may be declared without a
discriminant:

     program Schema2Demo;
     type
       RealArray (n: Integer) = array [1 .. n] of Real;
       RealArrayPtr = ^RealArray;
     var
       Bar: RealArrayPtr;
     begin
     end.

   When applying `New' to such a pointer, you must specify the intended
value of the discriminant as a parameter:

     New (Bar, 137)

   As a GNU Pascal extension, the above can also be written as

     Bar := New (RealArrayPtr, 137)

   The allocated variable behaves like any other schema variable:

     program Schema3Demo;
     type
       RealArray (n: Integer) = array [1 .. n] of Real;
       RealArrayPtr = ^RealArray;
     var
       Bar: RealArrayPtr;
       i: Integer;
     begin
       Bar := New (RealArrayPtr, 137);
       for i := 1 to Bar^.n do
         Bar^[i] := 42
     end.

   Since the schema variable "knows" its size, pointers to schemata can
be disposed just like other pointers:

     Dispose (Bar)

   Schemata are not limited to arrays. They can be of any type that
normally requires constant values in its definition, for instance
subrange types, or records containing arrays etc. (Sets do not yet
work.)

   References to the schema discriminants are allowed, and the `with'
statement is also allowed, so one can say:

     program SchemaWithDemo;
     type
       RealArray (n: Integer) = array [1 .. n] of Real;
     var
       MyArray: RealArray (42);
     begin
       WriteLn (MyArray.n);  { writes 42 }
       with MyArray do
         WriteLn (n);        { writes 42 }
     end.

   Finally, here is a somewhat exotic example. Here, a `ColoredInteger'
behaves just like an ordinary integer, but it has an additional
property `Color' which can be accessed like a record field.

     program SchemaExoticDemo;
     
     type
       ColorType = (Red, Green, Blue);
       ColoredInteger (Color: ColorType) = Integer;
     
     var
       Foo: ColoredInteger (Green);
     
     begin
       Foo := 7;
       if Foo.Color = Red then
         Inc (Foo, 2)
       else
         Foo := Foo div 3
     end.

   An important schema is the predefined `String' schema (according to
Extended Pascal). It has one predefined discriminant identifier
`Capacity'. GPC implements the `String' schema as follows:

     type
       String (Capacity: Cardinal) = record
         Length: 0 .. Capacity;
         Chars: packed array [1 .. Capacity + 1] of Char
       end;

   The `Capacity' field may be directly referenced by the user, the
`Length' field is referenced by a predefined string function `Length
(Str)' and contains the current string length.  `Chars' contains the
chars in the string. The `Chars' and `Length' fields cannot be directly
referenced by a user program.

   If a formal value parameter is of type `String' (with or without
discriminant), the actual parameter may be either a `String' schema, a
fixed string (character array), a single character, a string literal or
a string expression. If the actual parameter is a `String' schema, it
is copied for the parameter in the usual way. If it is not a schema, a
`String' schema is created automatically, the actual parameter is
copied to the new variable and the `Capacity' field of the new variable
is set to the length of the actual parameter.

   Actual parameters to `var' parameters of type `String' must be
`String' schemata, not string literals or character arrays.

     program StringDemo (Output);
     
     type
       SType = String (10);
       SPtr  = ^String;
     
     var
       Str : SType;
       Str2: String (100000);
       Str3: String (20) value 'string expression';
       DStr: ^String;
       ZStr: SPtr;
       Len : Integer value 256;
       Ch  : Char value 'R';
     
     { `String' accepts any length of strings }
     procedure foo (z: String);
     begin
       WriteLn ('Capacity: ', z.Capacity);
       WriteLn ('Length  : ', Length (z));
       WriteLn ('Contents: ', z);
     end;
     
     { Another way to use dynamic strings }
     procedure Bar (SLen: Integer);
     var
       LString: String (SLen);
       FooStr: type of LString;
     begin
       LString := 'Hello world!';
       Foo (LString);
       FooStr := 'How are you?';
       Foo (FooStr);
     end;
     
     begin
       Str  := 'KUKKUU';
       Str2 := 'A longer string variable';
       New (DStr, 1000);  { Select the string Capacity with `New' }
       DStr^ := 'The maximum length of this is 1000 chars';
       New (ZStr, Len);
       ZStr^ := 'This should fit here';
       Foo (Str);
       Foo (Str2);
       Foo ('This is a constant string');
       Foo ('This is a ' + Str3);
       Foo (Ch);  { A char parameter to string routine }
       Foo ('');  { An empty string }
       Foo (DStr^);
       Foo (ZStr^);
       Bar (10000);
     end.

   In the above example, the predefined procedure `New' was used to
select the capacity of the strings. Procedure `Bar' also has a string
whose size depends of the parameter passed to it and another string
whose type will be the same as the type of the first string, using the
`type of' construct.

   All string and character types are compatible as long as the
destination string is long enough to hold the source in assignments.
If the source string is shorter than the destination, the destination
is automatically blank padded if the destination string is not of
string schema type.


File: gpc.info,  Node: Set Types,  Next: Pointer Types,  Prev: Schema Types,  Up: Type Definition Possibilities

Set Types
.........

     SET TYPE IDENTIFIER = set of SET ELEMENT TYPE;

   SET TYPE IDENTIFIER is a set of elements from SET ELEMENT TYPE which
is either an ordinal type, an enumerated type or a subrange type.  Set
element representatives are joined together into a set by brackets:
     [SET ELEMENT, ..., SET ELEMENT]
   `[]' indicates the empty set, which is compatible with all set types.
Note: Borland Pascal restricts the maximal set size (i.e. the range of
the set element type) to 256, GNU Pascal has no such restriction.  The
number of elements a set variable is holding can be determined by the
intrinsic set function Card (which is a GNU Pascal extension, in
Extended Pascal and Borland Pascal you can use SizeOf instead but note
the element type size in bytes, then) to the set.  There are four
intrinsic binary set operations: the union `+', the intersection `*'
and the difference `-'. The symmetric difference `><' is an Extended
Pascal extension.

See also
--------

   *Note Card::, *Note SizeOf::


File: gpc.info,  Node: Pointer Types,  Next: Procedural Types,  Prev: Set Types,  Up: Type Definition Possibilities

Pointer Types
.............

     POINTER TYPE IDENTIFIER = ^TYPE IDENTIFIER;

   A pointer of the type POINTER TYPE IDENTIFIER holds the address at
which data of the type TYPE IDENTIFIER is situated.  Unlike other
identifier declarations, where all identifiers in definition part have
to be declared before, in a pointer type declaration TYPE IDENTIFIER
may be declared after POINTER TYPE IDENTIFIER. The data pointed to is
accessed by `POINTER TYPE VARIABLE^'. To mark an unassigned pointer,
the `nil' constant (which stands for "not in list") has to be assigned
to it, which is compatible with all pointer types.

     type
       ItselfFoo = ^ItselfFoo;  { possible but senseless }
     
       PInt      = ^Integer;    { Pointer to an Integer }
     
       PNode     = ^TNode;      { Linked list }
       TNode     = record
         Key     : Integer;
         NextNode: PNode;
       end;
     
     var
       Foo, Bar: PInt;
     
     begin
       Foo := Bar;  { Modify address which foo is holding }
       Foo^ := 5;   { Access data foo is pointing to }
     end.

   GPC also suports pointers to procedures or function and calls
through them. This is a non-standard feature.

     program ProcPtrDemo (Output);
     
     type
       ProcPtr = ^procedure (Integer);
     
     var
       PVar: ProcPtr;
     
     procedure WriteInt (i: Integer);
     begin
       WriteLn ('Integer: ', i : 1)
     end;
     
     begin
       { Let PVar point to function WriteInt }
       PVar := @WriteInt;
     
       { Call the function by dereferencing the function pointer }
       PVar^ (12345)
     end.

   See also: *Note Pointer (Intrinsic)::.


File: gpc.info,  Node: Procedural Types,  Next: Object Types,  Prev: Pointer Types,  Up: Type Definition Possibilities

Procedural and Functional Types
...............................

   For procedures without a parameter list:
     PROCEDURE TYPE IDENTIFIER = procedure NAME IDENTIFIER;
   or functions:
     FUNCTION TYPE IDENTIFIER =
            function NAME IDENTIFIER: FUNCTION RESULT TYPE;

   For procedures with a parameter list:
     PROCEDURE TYPE IDENTIFIER =
            procedure NAME IDENTIFIER (PARAMETER LIST);
   or functions:
     FUNCTION TYPE IDENTIFIER =
            function NAME IDENTIFIER (PARAMETER LIST): FUNCTION RESULT TYPE;

   Procedural types can be used as procedures or functions
respectively, but also a value can be assigned to them. Procedural
types are a Borland Pascal extension.  In Borland Pascal, FUNCTION
RESULT TYPE can only be one of these types: ordinal types, enumerated
types, real types, pointer types, the intrinsic Boolean, or the
intrinsic String. In GNU Pascal every function result type for
procedural types is allowed.

   BP has procedural and functional types:

     type
       CompareFunction = function (Key1, Key2: String): Integer;
     
     function Sort (Compare: CompareFunction);
     begin
       ...
     end;

   Standard Pascal has procedural and functional parameters:

     function Sort (function Compare (Key1, Key2: String): Integer);
     begin
       ...
     end;

   Both ways have pros and cons, e.g. in BP you can save, compare,
trade, etc. procedural values, or build arrays of them, while the SP
way does not require a type declaration and prevents problems with
uninitialized or invalid pointers (which in BP will usually crash the
program).

   GPC supports both ways. An important feature of Standard Pascal (but
not BP) that GPC also supports is the possibility to pass _local_
routines as procedural or functional parameters, even if the called
routine is declared far remote. The called routine can then call the
passed local routine and it will have access to the original caller's
local variables.

     program LocalProceduralParameterDemo;
     
     procedure CallProcedure (procedure Proc);
     begin
       Proc
     end;
     
     procedure MainProcedure;
     var LocalVariable: Integer;
     
       procedure LocalProcedure;
       begin
         WriteLn (LocalVariable)
       end;
     
     begin
       LocalVariable := 42;
       CallProcedure (LocalProcedure)
     end;
     
     begin
       MainProcedure
     end.

   See also: *Note The Procedure::, *Note The Function::, *Note
Subroutine Parameter List Declaration::, *Note Procedure Call::.


File: gpc.info,  Node: Object Types,  Next: Type Initializers,  Prev: Procedural Types,  Up: Type Definition Possibilities

Object Types
............

   Object types are used to encapsulate data and methods.  Furthermore,
they implement a mechanism for inheritance.

See also
--------

   *Note OOP::


File: gpc.info,  Node: Type Initializers,  Next: Restricted Types,  Prev: Object Types,  Up: Type Definition Possibilities

Initial values to type denoters
...............................

   A type may be initialized to a value of expression when it is
declared, like a variable, as in:

     program TypeVarInitDemo;
     type
       Int10   = Integer value 10;
       FooType = Real;
       MyType  = Char value Pred ('A');
       EType   = (a, b, c, d, e, f, g) value d;
     
     const
       Answer = 42;
     
     var
       ii : Int10;                    { Value of ii set to 10 }
       ch : MyType  value Pred ('z');
       aa : Integer value Answer + 10;
       foo: FooType value Sqr (Answer);
       e1 : EType;                    { value set to d }
       e2 : EType value g;            { value set to g }
     begin
     end.

   Extended Pascal requires the type initializers to be constant
expressions. GPC allows any valid expression.

   Note, however, that the expressions that affect the size of storage
allocated for objects (e.g. the length of arrays) may contain variables
only inside functions or procedures.

   GPC evaluates the initial values used for the type when an
identifier is declared for that type. If a variable is declared with a
type-denoter that uses a type-name which already has an initial value
the latter initialization has precedence.

   @@ GPC does not know how to calculate constant values for math
functions in the runtime library at compile time, e.g. `Exp (Sin
(2.4567))', so you should not use these kind of expressions in object
size expressions. (Extended Pascal allows this.)


File: gpc.info,  Node: Restricted Types,  Prev: Type Initializers,  Up: Type Definition Possibilities

Restricted Types
................

   GPC supports `restricted' types, defined in Extended Pascal. A value
of a restricted type may be passed as a value parameter to a formal
parameter possessing its underlying type, or returned as the result of
a function. A variable of a restricted type may be passed as a variable
parameter to a formal parameter possessing the same type or its
underlying type. No other operations, such as accessing a component of
a restricted type value or performing arithmetic, are possible.

     program RestrictedDemo;
     
     type
       UnrestrictedRecord = record
         a: Integer;
       end;
       RestrictedRecord = restricted UnrestrictedRecord;
     
     var
       r1: UnrestrictedRecord;
       r2: RestrictedRecord;
       i: restricted Integer;
       k: Integer;
     
     function AccessRestricted (p: UnrestrictedRecord): RestrictedRecord;
     var URes: UnrestrictedRecord;
     begin
       { The parameter is treated as unrestricted, even though the actual
         parameter may be a restricted object }
       URes.a := p.a;
       { It is allowed to assign a return value }
       AccessRestricted := URes;
     end;
     
     begin
       r1.a := 354;
     
       { Assigning a restricted return value to a restricted object }
       { @@ Verify if this should really be allowed????? }
       r2 := AccessRestricted (r1);
     
       { Passing a restricted object to unrestericted formal parameter is ok }
       r2 := AccessRestricted (r2);
     
       {$ifdef BUG}
       { *** The following statements are not allowed *** }
       k := r2.a;      { field access (reading) }
       r2.a := 100;    { field access (writing) }
       r1 := r2;       { assignment source is restricted }
       r2 := r1;       { assignment target is restricted }
       r1 := AccessRestricted (r2); { assigning a restricted return
                                      value to an unrestricted object }
       i  := 16#ffff;  { assignment target is restricted }
       k  := i + 2;    { arithmetic with restricted value }
       {$endif}
     end.


File: gpc.info,  Node: Machine-dependent Type Implementation,  Prev: Type Definition Possibilities,  Up: Data Types

Machine-dependent Type Implementation
-------------------------------------

* Menu:

* Endianness::       How Integer Types are Stored on Different Machines
* Alignment::        How Variables are Placed in Memory


File: gpc.info,  Node: Endianness,  Next: Alignment,  Up: Machine-dependent Type Implementation

Endianness
..........

   Endianness means the order in which the bytes of a value larger than
one byte are stored in memory. This affects, e.g., integer values and
pointers while, e.g., arrays of single-byte characters are not
affected. The GPC `String' schema, however, contains `Capacity' and
`Length' fields before the character array.  These fields are integer
values larger than one byte, so the `String' schema _is_ affected by
endianness.

   Endianness depends on the hardware, especially the CPU. The most
common forms are:

   * "Little-endian"

     Little-endian machines store the least significant byte on the
     lowest memory address (the word is stored "little-end-first").

     E.g., if the 32 bit value `$deadbeef' is stored on memory address
     `$1234' on a little-endian machine, the following bytes will
     occupy the memory positions:

     Address       Value
     $1234         $ef
     $1235         $be
     $1236         $ad
     $1237         $de

     Examples for little-endian machines are IA32 and compatible
     microprocessors and Alpha processors.

   * "Big-endian"

     Big-endian machines store the most significant byte on the lowest
     memory address (the word is stored "big-end-first").

     E.g., if the 32 bit value `$deadbeef' is stored on memory address
     `$1234' on a big-endian machine, the following bytes will occupy
     the memory positions:

     Address       Value
     $1234         $de
     $1235         $ad
     $1236         $be
     $1237         $ef

     Examples for big-endian machines are the Sparc and Motorola m68k
     CPU families and most RISC processors. Big-endian byte order is
     also used in the Internet protocols.


   _Note:_ There are processors which can run in both little-endian and
big-endian mode, e.g. the MIPS processors. A single program, however,
(unless it uses special machine code instructions) will always run in
one endianness.

   Under normal circumstances, programs do not need to worry about
endianness, the CPU handles it by itself. Endianness becomes important
when exchanging data between different machines, e.g.  via binary files
or over a network. To avoid problems, one has to choose the endianness
to use for the data exchange. E.g., the Internet uses big-endian data,
and most known data formats have a specified endianness (usually that
of the CPU on which the format was originally created). If you define
your own binary data format, you're free to choose the endianness to
use.

   To deal with endianness, GPC predefines the symbol
`__BYTES_LITTLE_ENDIAN__' on little-endian machines and
`__BYTES_BIG_ENDIAN__' on big-endian machines. Besides, the Run Time
System defines the constant `BytesBigEndian' as False on little-endian
machines and True on big-endian machines.

   There are also the symbols `__BITS_LITTLE_ENDIAN__',
`__BITS_BIG_ENDIAN__', `__WORDS_LITTLE_ENDIAN__',
`__WORDS_BIG_ENDIAN__' and the constants `BitsBigEndian' and
`WordsBigEndian' which concern the order of bits within a byte (e.g.,
in packed records) or of words within multiword-numbers, but these are
usually less important.

   The Run Time System also contains a number of routines to convert
endianness and to read or write data from/to binary files in a given
endianness, independent of the CPU's endianness. These routines are
described in the RTS reference (*note Run Time System::), under
`endianness'. The demo program `endiandemo.pas' contains an example on
how to use these routines.


File: gpc.info,  Node: Alignment,  Prev: Endianness,  Up: Machine-dependent Type Implementation

Alignment
.........

   (Under construction.)  @@ ????


File: gpc.info,  Node: Operators,  Next: Parameters,  Prev: Data Types,  Up: Programming

Operators
=========

   GNU Pascal supports all operators of ISO Pascal and Borland Pascal.
In addition, you can define your own operators according to the
Pascal-SC (PXSC) syntax.

* Menu:

* Built-in Operators::
* User-defined Operators::


File: gpc.info,  Node: Built-in Operators,  Next: User-defined Operators,  Up: Operators

Built-in Operators
------------------

   The following table lists all built-in GNU Pascal operators, ordered
by precedence: `<' etc. have the lowest precedence, `not' etc. the
highest. As usual, the precedence of operators can be superseded with
parentheses.

   In an assignment statement, `:=' has lower precedence than all
operators. (This is rather obvious from the syntax of assignment
statements, and is merely noted for programmers familiar with C where
`=' is an operator.)

     <    =    >    in   <>   >=   <=
     +    -    or   +<   -<   +>   ->
     *    /    div  mod  and  shl  shr  xor  *<   /<   *>   />
     pow  **   ><
     not  &    @

   The Pascal-SC (PXSC) operators `+<', `-<', `+>', `->', `*<', `/<',
`*>', and `/>' are not yet implemented into GNU Pascal but may be
defined by the user (see below).


File: gpc.info,  Node: User-defined Operators,  Prev: Built-in Operators,  Up: Operators

User-defined Operators
----------------------

   GNU Pascal allows the (re-)definition of binary operators according
to the Pascal-SC (PXSC) syntax. The following vector addition example
illustrates how to do this:

     program OperatorDemo;
     
     type
       Vector3 = record
         x, y, z: Real;
       end;
     
     var
       a, b, c: Vector3 = (1, 2, 3);
     
     operator + (u, v: Vector3) w: Vector3;
     begin
       w.x := u.x + v.x;
       w.y := u.y + v.y;
       w.z := u.z + v.z;
     end;
     
     begin
       c := a + b
     end.

   Between the closing parenthesis of the argument list and the result
variable (`w' in the above example), GPC allows an optional equal sign.
This is not allowed in PXSC, but it is consistent with Extended
Pascal's function return variable definitions, where the equal sign is
obligatory (but also optional in GPC).

   The argument types needn't be equal, and the name of the operator
may be an identifier instead of a known symbol. You cannot define _new_
symbols in GPC.

   The PXSC operators `+>', `+<', etc. for exact numerical calculations
currently are not implemented in GPC, but you can define them. Also,
the other real-type operators do _not_ meet the requirements of PXSC; a
module which fixes that would be a welcome contribution.


File: gpc.info,  Node: Parameters,  Next: Pointer Arithmetics,  Prev: Operators,  Up: Programming

Procedure And Function Parameters
=================================

* Menu:

* Protected Parameters::  Parameters declared as `protected' or `const'
* Conformant Arrays::     The Standard way to pass arrays of variable size
* Open Arrays::           BP's alternative to Conformant Arrays


File: gpc.info,  Node: Protected Parameters,  Next: Conformant Arrays,  Up: Parameters

Parameters declared as `protected' or `const'
---------------------------------------------

   All the following works in GPC:

     procedure Foo (protected a, b, c: Integer);    { 3 arguments }
     procedure Foo (a, b, c, protected: Integer);   { 4 arguments }
     procedure Foo (a, b, protected, c: Integer);   { 4 arguments }
     procedure Foo (protected: Integer);            { 1 argument  }
     procedure Foo (var protected: Integer);        { 1 argument  }
     procedure Foo (protected protected: Integer);  { 1 argument  }

   Furthermore, GPC supports `const', according to BP, which is
equivalent to either `protected' or `protected var', up to the
compiler's discretion.


File: gpc.info,  Node: Conformant Arrays,  Next: Open Arrays,  Prev: Protected Parameters,  Up: Parameters

The Standard way to pass arrays of variable size
------------------------------------------------

   @@ (Under construction.)

   A feature of Standard Pascal level 1.


File: gpc.info,  Node: Open Arrays,  Prev: Conformant Arrays,  Up: Parameters

BP's alternative to Conformant Arrays
-------------------------------------

   Borland Pascal "open array" formal parameters are implemented into
GPC. Within the function body, they have integer type index with lower
bound 0.

   In constrast to conformant arrays (which are not supported by BP),
open arrays allow any ordinal type as the index of the actual parameter
(which is useful, e.g., if you want to be able to pass values of any
enumeration type). However, they lose information about the lower bound
(which is a problem, e.g., if you want to return information to the
caller that relates to the actual array index, like the function
`IOSelect' in the Run Time System does).


File: gpc.info,  Node: String Slice Access,  Next: Type Casts,  Prev: Pointer Arithmetics,  Up: Programming

Accessing parts of strings (and other arrays)
=============================================

   GPC allows the access of parts ("slices") of strings as defined in
Extended Pascal. For example:

     program StringSliceDemo;
     
     const
       HelloWorld = 'Hello, world!';
     
     begin
       WriteLn (HelloWorld[8 .. 12])  { yields `world' }
     end.

   As an extension, it also allows write access to a string slice:

     program SliceWriteDemo;
     
     var
       s: String (42) = 'Hello, world!';
     
     begin
       s[8 .. 12] := 'folks';
       WriteLn (s)  { yields `Hello, folks!' }
     end.

   As a further extension, GPC allows slice access also to non-string
arrays. However, the usefulness of this feature is rather limited
because of Pascal's strict type checking rules: If you have, e.g., an
`array [1 .. 10] of Integer' and take a slice `[1 .. 5]' of it, it will
not be compatible to another `array [1 .. 5] of Integer' because
distinct array types are not compatible in Pascal, even if they look
the same.

   However, array slice access can be used in connection with
conformant or open array parameters. See the program
`arrayslicedemo.pas' (in the `demos' directory) for an example.


File: gpc.info,  Node: Pointer Arithmetics,  Next: String Slice Access,  Prev: Parameters,  Up: Programming

Pointer Arithmetics
===================

   GPC allows to increment, decrement, compare, and subtract pointers
or to use them in `for' loops just like the C language.

   GPC implements the address operator `@' (a Borland Pascal extension).

     program PointerArithmeticDemo;
     var
       a: array [1 .. 7] of Char;
       p, q: ^Char;
       i: Integer;
     
     {$X+} { We need extended syntax for pointer arithmetic }
     
     begin
       for p := @A[1] to @A[7] do
         p^ := 'x';
     
       p := @A[7];
       q := @A[3];
       while p > q do
         begin
           p^ := 'y';
           Dec (p)
         end;
     
       p := @A[7];
       q := @A[3];
       i := q - p;    { yields 4 }
     end.

   Incrementing a pointer by one means to increment the address it
contains by the size of the variable it is pointing to. For typeless
pointers (`Pointer'), the address is incremented by one instead.

   Similar things hold when decrementing a pointer.

   Subtracting two pointers yields the number of variables pointed to
between both pointers, i.e. the difference of the addresses divided by
the size of the variables pointed to. The pointers must be of the same
type.

