here are three new sections for the "programmer's guide to GPC" (see
`info -f gpc -n programming'). Comments/improvements/etc. welcome.
--
Peter Gerwinski, Essen, Germany,
http://home.pages.de/~Peter.Gerwinski/
Maintainer GNU Pascal -
http://home.pages.de/~GNU-Pascal/ - gpc-980511
PGP key on request - 6C 94 45 BE 28 A4 96 - 0E CC E9 12 47 25 82 75
Fight the SPAM and UBE! -
http://spam.abuse.net/ -
http://maps.vix.com/
@c ============================================================================
@node Schemata
@section Schema Types
@cindex schemata
@cindex types, schema
Schemata are types that depend on a variable, called ``discriminant''.
They are an ISO-10206 Extended Pascal extension.
@smallexample
Type
RealArray ( n: Integer ) = array [ 1..n ] of Real;
@end smallexample
The type @samp{RealArray} in this example is called a Schema with the
discriminant @samp{n}. To declare a variable of such a type, write
@cindex Foo
@smallexample
Var
Foo: RealArray ( 42 );
@end smallexample
Schema-typed variables ``know'' about their discriminants. They can
be accessed just like record fields:
@smallexample
writeln ( Foo.n ); (* yields 42 *)
@end smallexample
While types of variables must always have specified discriminants (which
may be other variables), @emph{pointers} to schema variables may be
without a discriminant:
@cindex Bar
@smallexample
Type
RealArrayPtr = ^RealArray;
Var
Bar: RealArrayPtr;
@end smallexample
When applying @samp{New} to such a pointer, you must specify the
intended value of the discriminant as a parameter:
@smallexample
New ( Bar, 137 );
@end smallexample
As a GNU extension, the above can also be written as
@smallexample
Bar:= New ( RealArrayPtr, 137 );
@end smallexample
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.)
To finish this section, here is a somewhat exotic example:
@smallexample
Type
ColorType = ( red, green, blue );
ColoredInteger ( Color: ColorType ) = Integer;
@end smallexample
A @samp{ColoredInteger} behaves just like an ordinary integer, but
it has an additional property @samp{Color} which can be accessed like
a record field.
@smallexample
Var
Foo: ColoredInteger ( green );
[...]
Foo:= 7;
if Foo.Color = red then
inc ( Foo, 2 )
else
Foo:= Foo div 3;
@end smallexample
@c ============================================================================
@node Pointer arithmetics
@section Pointer Arithmetics
@cindex pointer arithmetics
GPC allows to increment, decrement, compare, and subtract pointers or to use
them in @samp{for} loops just like the C language.
@smallexample
Var
A: array [ 1..7 ] of Char;
p, q: ^Char;
i: Integer;
[...]
for p:= @@A [ 1 ] to @@A [ 7 ] do
p^:= 'x';
q:= @@A [ 3 ];
while p > q do
begin
p^:= 'y';
dec ( p );
end (* while *);
i:= q - p;
@end smallexample
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
(@samp{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.
@c ============================================================================
@node Type casts
@section Type Casts
@cindex type casts
In some cases, especially when interfacing with other languages,
Pascal's strong typing can be an obstacle. To temporarily circumvent
this, GPC (and other Pascal compilers) defines explicit ``type casts''.
To convert a value of one data type to another type, use the target type
as a ``function'':
@cindex Foo
@cindex Bar
@smallexample
Type
CharPtr = ^Char;
CharArray = array [ 0..99 ] of Char;
CharArrayPtr = ^CharArray;
Var
Foo: CharPtr;
Bar: CharArrayPtr;
[...]
Foo:= CharPtr ( Bar );
@end smallexample
Beware: Explicit type casts might have unexpected effects on different
platforms since you cannot rely on a specific way the data is stored.
If it is possible to avoid type casts (which holds for most cases), you
should do that. For instance in the example above, you can make
@samp{Foo} point to the first char in the array @samp{Bar^}:
@smallexample
Foo:= @@Bar^ [ 0 ];
@end smallexample
When dealing with objects (see @ref{OOP}), it is often necessary---and
safe---to cast a pointer to an object to a pointer of a ``bigger''
(derivated) object. In future releases, GPC will provide an operator
@samp{as} for a safer approach to this problem.
See also: @ref{absolute}.
@c ============================================================================