This is 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, 1996-2000 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: Subroutine Parameter List Declaration,  Prev: The Operator,  Up: Subroutine Declaration

Subroutine Parameter List Declaration
.....................................

     PARAMETER; ...; PARAMETER

   Value parameters are declared this way:
     PARAMETER IDENTIFIER: PARAMETER TYPE
   where parameters of the same type be listed, separated by commata:
     PARAMETER IDENTIFIER, ..., PARAMETER IDENTIFIER: PARAMETER TYPE

   If `var' is specified before a parameter, which is an USCD extension,
the compiler is told to pass the argument by reference, i.e. the
parameter passed to is expected to be an L-value whose type is
PARAMETER TYPE if specified, else it is compatible with any type:
     var PARAMETER IDENTIFIER: PARAMETER TYPE
   or without type specification:
     var PARAMETER IDENTIFIER
   This declaration is necessary if the parameter is to be modified
within a block and to hold its value still after return. Otherwise, the
parameter remains unchanged after block exit, since it is passed by
value, and therefore it is called value parameter.

   A parameter of this kind is called variable parameter and
corresponds to an L-value pointer (to TYPE IDENTIFIER if specified).
As a Borland Pascal extension, there are also constant parameters which
are not allowed to be changed in the related statement part.  Like
variable parameters, the type needs not to be declared; in this case
PARAMETER IDENTIFIER is treated as a typeless parameter.
     const PARAMETER IDENTIFIER: PARAMETER TYPE
   or without any further type specification:
     const PARAMETER IDENTIFIER

   As an Extended Pascal extension, there is a way to declare procedural
parameters directly:
     procedure PARAMETER IDENTIFIER
   or without type specification:
     function PARAMETER IDENTIFIER: PARAMETER IDENTIFIER RESULT TYPE

   Example for parameter lists:
     procedure Foo (var Bar; var Baz: Integer; const Fred: Integer);
     
       procedure Glork1 (function Foo: Integer; procedure Bar (Baz: Integer));
       begin
         Bar (Foo)
       end;
     
     begin
       baz := Integer (Bar) + Fred
     end;


   *See also* *Note Data Types::


File: gpc.info,  Node: Statements,  Next: Modules and Units,  Prev: Subroutine Declaration,  Up: Source Structures

Statements
----------

* Menu:

* Assignment::
* begin end Compound Statement::
* if Statement::
* case Statement::
* for Statement::
* while Statement::
* repeat Statement::
* asm Inline::
* with Statement::
* goto Statement::
* Procedure Call::
* The Declaring Statement::
* Loop Control Statements::


File: gpc.info,  Node: Assignment,  Next: begin end Compound Statement,  Up: Statements

Assignment
..........

   The way an assignment looks like:
     L-VALUE := EXPRESSION;

   This statement assigns any valid expression to L-VALUE. Make sure
that the result of EXPRESSION is compatible with L-VALUE, otherwise an
compilation error is reported. The `:=' is called assignment operator.
As long as L-VALUE and EXPRESSION are type compatible, they are
assignment compatible for _any definable type_ as well.


File: gpc.info,  Node: begin end Compound Statement,  Next: if Statement,  Prev: Assignment,  Up: Statements

begin end Compound Statement
............................

   It looks like that:
     begin
       STATEMENT;
       STATEMENT;
       ...
       STATEMENT
     end

   This statement joins several STATEMENTS together into one compound
statement which is treated as a single statement by the compiler. The
finishing semicolon before `end' can be left out.


File: gpc.info,  Node: if Statement,  Next: case Statement,  Prev: begin end Compound Statement,  Up: Statements

if Statement
............

   This statement has the following look:
     if BOOLEAN EXPRESSION then
       STATEMENT
   or with an alternative statement:
     if BOOLEAN EXPRESSION then
       STATEMENT1
     else
       STATEMENT2

   The `if' ... `then' statement consists of a boolean expression and a
STATEMENT, which is conditionally executed if the evaluation of BOOLEAN
EXPRESSION yields true.

   If `if' ... `then' ... `else' is concerned, STATEMENT1 is executed
depending on BOOLEAN EXPRESSION being true, otherwise STATEMENT2 is
executed alternatively. Note: the statement before else _must not_
finish with a semicolon.


File: gpc.info,  Node: case Statement,  Next: for Statement,  Prev: if Statement,  Up: Statements

case Statement
..............

     case EXPRESSION of
       SELECTOR: STATEMENT;
       ...
       SELECTOR: STATEMENT;
     end
   or, with alternative statement sequence:
     case ORDINAL EXPRESSION of
       SELECTOR: STATEMENT;
       ...
       SELECTOR: STATEMENT;
     otherwise                   { ``else'' instead of ``otherwise'' allowed }
       STATEMENT;
       ...
       STATEMENT;
     end
   or, as part of the invariant `record' type definition:
     type
       foo = record
         FIELD DECLARATIONS
       case bar: VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
       end;
   or, without a variant selector field,
     type
       foo = record
         FIELD DECLARATIONS
       case VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
       end;

   The `case' statement compares the value of ORDINAL EXPRESSION to
each SELECTOR, which can be a constant, a subrange, or a list of them
separated by commata, being compatible with the result of ORDINAL
EXPRESSION.  Note: duplicate selectors or range crossing is not allowed
unless {$borland-pascal} is specified. In case of equality the
corresponding statement is executed. If `otherwise' is specified and no
appropriate selector matched the expression, the series of statements
following `otherwise' is executed. As a synonym for `otherwise', `else'
can be used. The semicolon before `otherwise' is optional.


   @@ ????  The expression _must_ match one of the selectors in order
to continue, unless an alternative statement series is specified.

   For `case' in a variant record type definition, see *Note Record
Types::.


   *See also* *Note if Statement::


File: gpc.info,  Node: for Statement,  Next: while Statement,  Prev: case Statement,  Up: Statements

for Statement
.............

   For ordinal index variables:
     for ORDINAL VARIABLE := INITIAL VALUE to FINAL VALUE do
       STATEMENT
   or
     for ORDINAL VARIABLE := INITIAL VALUE downto FINAL VALUE do
       STATEMENT

   For sets:
     for SET ELEMENT TYPE VARIABLE in SOME SET do
       STATEMENT

   For pointer index variables:
     for POINTER VARIABLE := INITIAL ADDRESS to FINAL ADDRESS do
       STATEMENT
   or
     for POINTER VARIABLE := INITIAL ADDRESS downto FINAL ADDRESS do
       STATEMENT

   The FOR statement is a control statement where an index variable
assumes every value of a certain range and for every value the index
variable assumes STATEMENT is executed. The range can be specified by
two bounds (which must be of the same type as the index variable, i.e.
ordinal or pointers) or by a set.


   For ordinal index variables: If `to' is specified, the index counter
is increased by one as long as INITIAL VALUE is less or equal to FINAL
VALUE, if `downto' is specified, it is decreased by one as long as
INITIAL VALUE is greater or equal to FINAL VALUE.


   For pointer index variables: If `to' is specified, the index counter
is increased by the size of the type the index variable points to (if
it is a typed pointer, otherwise by one if it is typeless) as long as
INITIAL ADDRESS is less or equal to FINAL ADDRESS, if `downto' is
specified, it is decreased by a corresponding value as long as INITIAL
ADDRESS is greater or equal to FINAL ADDRESS. Since gpc provides a flat
memory modell, all addresses are linear, so they can be compared.


   For sets: STATEMENT is executed with the index variable (which must
be ordinal and of the same type as the set elements) assuming every
element in SOME SET, however note that a set is a not-ordered structure.


   Note: A modification of the index variable may result in
unpredictable action.


   *See also* *Note Set Types::, *Note Pointer Arithmetics::, *Note
repeat Statement::, *Note for Statement::


File: gpc.info,  Node: while Statement,  Next: repeat Statement,  Prev: for Statement,  Up: Statements

while Statement
...............

   The while loop has the following form
     while BOOLEAN EXPRESSION do
       STATEMENT

   The `while' statement declares a loop which is executed while
BOOLEAN EXPRESSION is true. Since the terminating condition is checked
before execution of the loop body, STATEMENT may never be executed.


   *See also* *Note repeat Statement::, *Note for Statement::


File: gpc.info,  Node: repeat Statement,  Next: asm Inline,  Prev: while Statement,  Up: Statements

repeat Statement
................

     repeat
       STATEMENT;
       ...
       STATEMENT;
     until BOOLEAN EXPRESSION

   The `repeat' ... `until' statement declares a loop which is repeated
until BOOLEAN EXPRESSION is true. Since the terminating condition is
checked after execution of the loop body, the statement sequence is
executed at least once.


   *See also* *Note while Statement::, *Note for Statement::


File: gpc.info,  Node: asm Inline,  Next: with Statement,  Prev: repeat Statement,  Up: Statements

asm Inline
..........

   @@ ????
     asm (StatementList : String);

   The `asm' inline statement is a GNU extension. It requires its
paramenter to be AT&T-noted assembler statements, and therefore it is
not compatible with that one of Borland Pascal. STATEMENTLIST is a
string containing asm statements seperated by semicola.


File: gpc.info,  Node: with Statement,  Next: goto Statement,  Prev: asm Inline,  Up: Statements

with Statement
..............


File: gpc.info,  Node: goto Statement,  Next: Procedure Call,  Prev: with Statement,  Up: Statements

goto Statement
..............

   @@ ????  This statement looks like this:
     goto LABEL

   (Under construction.)


File: gpc.info,  Node: Procedure Call,  Next: The Declaring Statement,  Prev: goto Statement,  Up: Statements

Procedure Call
..............

     SUBROUTINE NAME;

   This statement calls the subroutine SUBROUTINE NAME which can either
be a procedure or, if GNU extended syntax is turned on, a function. In
this case, the return value is ignored.


File: gpc.info,  Node: The Declaring Statement,  Next: Loop Control Statements,  Prev: Procedure Call,  Up: Statements

The Declaring Statement
.......................

   This statement allows to declare a variable within a statement part.
It looks like this:
     var
       VARIABLE IDENTIFIER: TYPE IDENTIFIER;
   or
     var
       VARIABLE IDENTIFIER: TYPE DEFINITION;
   and with initializing value:
     var
       VARIABLE IDENTIFIER: TYPE IDENTIFIER value EXPRESSION;
   or
     var
       VARIABLE IDENTIFIER: TYPE DEFINITION value EXPRESSION;

   Unlike in declaration parts, the initializing EXPRESSION has not to
be a constant expression. Note that every declaring statement has to
start with `var'. The name space of VARIABLE IDENTIFIER extends from
its declaration to the end of the current matching statement sequence
(which can be a statement part (of the program, a function, a procedure
or an operator) or, within that part, a begin end compound statement, a
repeat loop, or the else branch of a case statement). This statement is
a GNU extension.


   *See also* *Note Type Definition::, *Note Data Types::


File: gpc.info,  Node: Loop Control Statements,  Prev: The Declaring Statement,  Up: Statements

Loop Control Statements
.......................

   These are
     Continue;
   and
     Break;

   These simple statements _must not_ occur outside a loop, i.e. a for,
while or repeat statement. `Continue' transfers control to the beginning
of the loop right by its call, `Break' exits the current loop turn and
continues loop execution.


File: gpc.info,  Node: Modules and Units,  Prev: Statements,  Up: Source Structures

Import Part and Module/Unit Concept
-----------------------------------

* Menu:

* Modules::   The source structure of ISO-10206 Extended Pascal Modules.
* Units::     The source structure of UCSD/Borland Pascal Units.


File: gpc.info,  Node: Modules,  Next: Units,  Up: Modules and Units

The Source Structure of ISO-10206 Extended Pascal Modules
.........................................................

   @@ Description missing here

   A module 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.

   Sample module code with separate `interface' and `implementation'
parts:

     module DemoModule interface;  { interface part }
     
     export DemoModule = (FooType, SetFoo, GetFoo);
     
     type
       FooType = Integer;
     
     procedure SetFoo (f : FooType);
     function  GetFoo : FooType;
     
     end.
     
     module DemoModule implementation;  { implementation part }
     
     import
       StandardInput;
       StandardOutput;
     
     var
       Foo : FooType;
     
     { Note: the effect is the same as a `forward' directive would have:
       parameter lists and return types are not allowed in the
       declaration of exported routines, according to EP. In GPC, they
       are allowed, but not required. }
     procedure SetFoo;
     begin
       Foo := f
     end;
     
     function GetFoo;
     begin
       GetFoo := Foo
     end;
     
     to begin do
       begin
         foo := 59;
         WriteLn ('Just an example of a module initializer. See comment below')
       end;
     
     to end do
       begin
         Foo := 0;
         WriteLn ('Goodbye')
       end;
     
     end.

   Alternatively the module interface and implementation may be
combined as follows:

     module DemoMod2; { Alternative method }
     
     export Catch22 = (FooType, SetFoo, GetFoo);
     
     type
       FooType = Integer;
     
     procedure SetFoo (f : FooType);
     function  GetFoo : FooType;
     
     end; { note: this end is required here, even if the
            module-block below would be empty. }
     
     var
       Foo : FooType;
     
     procedure SetFoo;
     begin
       Foo := f
     end;
     
     function GetFoo;
     begin
       GetFoo := Foo
     end;
     
     end.

   Either one of the two methods may be used like this:

     program ModuleDemo (Output);
     
     import DemoModule;
     
     begin
       SetFoo (999);
       WriteLn (GetFoo);
     end.

     program ModDemo2 (Output);
     
     import Catch22 in 'demomod2.pas';
     
     begin
       SetFoo (999);
       WriteLn (GetFoo);
     end.

   Somewhat simpler GPC modules are also supported. *Note:* This is not
supported in the Extended Pascal standard.

   This is a simpler module support that does not require exports,
imports, module headers etc.

   These non-standard simple GPC modules look like (does not have an
export part, does not have a separate module-block, does not use
import/export features.)

     module DemoMod3;
     
     type
       FooType = Integer;
     
     var
       Foo : FooType;
     
     procedure SetFoo (f : FooType);
     begin
       Foo := f
     end;
     
     function GetFoo : FooType;
     begin
       GetFoo := Foo;
     end;
     
     end.
     
     program ModDemo3 (Output);
     
     { Manually do the "import" from DemoMod3 }
     type
       FooType = Integer;
     
     procedure SetFoo (f : FooType); external;
     function  GetFoo : FooType;     external;
     
     begin
       SetFoo (999);
       WriteLn (GetFoo)
     end.

   Module initialization and finalization:

   The `to begin do' module initialization and `to end do' module
finalization constructs now work on _every_ target.

   By the way: The "GPC specific" module definition is almost identical
to the PXSC standard. With an additional keyword `global' which puts a
declaration into an export interface with the name of the module, it
will be the same. @@This is planned.


File: gpc.info,  Node: Units,  Prev: Modules,  Up: Modules and Units

The Source Structure of UCSD/Borland Pascal Units
.................................................

   A generic GNU Pascal unit looks like the following:

     unit NAME;
     
     interface
     
     IMPORT PART
     
     INTERFACE PART
     
     implementation
     
     IMPLEMENTATION PART
     
     INITIALIZATION PART
     
     end.

   The NAME of the unit should coincide with the name of the file with
the extension stripped. (If not, you can tell GPC the file name with
`uses foo in 'bar.pas'', see *Note uses::.)

   The IMPORT PART is either empty or contains a `uses' clause to
import other units. It may also consist of an ISO-style `import'
specification. Note that the implementation part is not preceeded by a
second import part in GPC (see *Note import::).

   The INTERFACE PART consists of constant, type, and variable
declarations, procedure and function headings which may be freely mixed.

   The IMPLEMENTATION PART is like the declaration part of a program,
but the headers of procedures and functions may be abbreviated:
Parameter lists and function return values may be omitted for
procedures and functions already declared in the interface part.

   The INITIALIZATION PART may be missing, or it may be a `begin'
followed by one or more statements, such that the unit has a statement
part between this `begin' and the final `end'. Alternatively, a unit
may have ISO-style module initializers and finalizers, see *Note to
begin do::, *Note to end do::.

   Note that GPC does _not_ yet check whether all interface
declarations are resolved in the same unit. Procedures and functions
which are in fact not used may be omitted, and/or procedures and
functions may be implemented somewhere else, even in a different
language. However, relying on a GPC bug (that will eventually be fixed)
is not a good idea, so this is not recommended.

   A unit exports everything declared in the interface section. The
exported interface has the name of the unit and is compatible with
Extended Pascal module interfaces since GPC uses the same code to
handle both.


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

Data Types
==========

* Menu:

* Type Definition::                         The Declaration Part
* Ordinal Types::                           Built-in Ordinal Types
* Integer Types::                           Built-in Integer Types
* Real Types::                              Built-in Real Types
* String Types::                            Built-in Character and String Types
* Character Types::                         Built-in Chararacter Types. See Ordinal Types
* File Types::                              Built-in Types for File Handling
* Boolean (Intrinsic)::                     Built-in Type for Boolean values.
* Pointer (Intrinsic)::                     The Intrinsic Pointer Type
* Type Definition Possibilities::           User-defined Types
* Machine-dependent Type Implementation::   Differences in Implementation


File: gpc.info,  Node: Type Definition,  Next: Ordinal Types,  Up: Data Types

Type Definition
---------------

   As described in *Note Type Declaration::, a type declaration part
looks like this:
     type
        TYPE IDENTIFIER = TYPE DEFINITION;
        ...
        TYPE IDENTIFIER = TYPE DEFINITION;
   where the left side is the type declaration and the right one the
type definition side. GNU Pascal offers variant possibilities to
implement highly specialized and problem-specific data types.


File: gpc.info,  Node: Ordinal Types,  Next: Integer Types,  Prev: Type Definition,  Up: Data Types

Ordinal Types
-------------

   An ordinal type is a range of whole numbers. It includes integer
types, character types and subrange types of them.

   A character type is represented by the intrinsic type `Char' which
can hold elements of the operating system's character set (usually
ASCII).  Conversion between character types and ordinal types is
possible with the intrinsic functions `Ord' and `Chr' or type casting
techniques.

     type
       Foo: Char;       { foo can hold a character }
       Num: '0' .. '9'; { Can hold decimal ciphers, is a subrange type of Char }

   *See also* *Note Ord::, *Note Chr::, *Note Type Casts::


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

Integer Types
-------------

   Besides `Integer', GNU Pascal supports a large zoo of integer types.
Some of them you will find in other compilers, too, but most are GNU
extensions, introduced for particular needs. Many of these types are
synonyms for each other. In total, GPC provides 20 built-in integer
types, plus seven families you can play with. (Four of these "families"
are signed and unsigned, packed and unpacked subrange types; the others
are explained below.)

* Menu:

* Natural Integer Types::
* Main Branch Integer Types::
* Integer Types with Specified Size::
* Integer Types and Compatibility::
* Summary of Integer Types::

   See also: *Note Subrange Types::.


File: gpc.info,  Node: Natural Integer Types,  Next: Main Branch Integer Types,  Up: Integer Types

The CPU's Natural Integer Types
...............................

   For most purposes, you will always use `Integer', a signed integer
type which has the "natural" size of such types for the machine. On
most machines GPC runs on, this is a size of 32 bits, so `Integer'
usually has a range of `-2147483648..2147483647' (see *Note Integer::).

   If you need an unsigned integer type, the "natural" choice is
`Cardinal', also called `Word'. Like `Integer', it has 32 bits on most
machines and thus a range of `0..4294967295' (see *Note Cardinal::,
*Note Word::).

   These natural integer types should be your first choice for best
performance. For instance on an Intel x86 CPU operations with `Integer'
usually work faster than operations with shorter integer types like
`ShortInt' or `ByteInt' (see below).


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

   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
Intel x86 platforms.

   On the other hand, to increase compatibility to Borland Pascal and
Delphi, GPC provides the alias name `Comp' for `LongInt' (64 bits on
Intel x86) and `SmallInt' for `ShortInt' (16 bits on Intel x86). 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'.

   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
----------

   @@ ???? I think that's something for someone who might know what he
is doing


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 Variing 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 Intel x86 compatible 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 Intel x86 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 variants of a variant record share one location in memory
(inside the record) and thus can be used to emulate type casting
without violating ISO-7185 Standard Pascal.

   The reserved word `record' and record types are defined in ISO-7185
Standard 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 *) Integer;
       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)::.

