mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 05:49:14 +02:00
8527 lines
286 KiB
TeX
8527 lines
286 KiB
TeX
%
|
|
% $Id$
|
|
% This file is part of the FPC documentation.
|
|
% Copyright (C) 1997, by Michael Van Canneyt
|
|
%
|
|
% The FPC documentation is free text; you can redistribute it and/or
|
|
% modify it under the terms of the GNU Library General Public License as
|
|
% published by the Free Software Foundation; either version 2 of the
|
|
% License, or (at your option) any later version.
|
|
%
|
|
% The FPC Documentation is distributed in the hope that it will be useful,
|
|
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
% Library General Public License for more details.
|
|
%
|
|
% You should have received a copy of the GNU Library General Public
|
|
% License along with the FPC documentation; see the file COPYING.LIB. If not,
|
|
% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
% Boston, MA 02111-1307, USA.
|
|
%
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Preamble.
|
|
\input{preamble.inc}
|
|
\begin{latexonly}
|
|
\ifpdf
|
|
\pdfinfo{/Author(Michael Van Canneyt)
|
|
/Title(Standard units Reference Guide)
|
|
/Subject(Free Pascal Reference guide)
|
|
/Keywords(Free Pascal, Language, System Unit)
|
|
}
|
|
\fi
|
|
\end{latexonly}
|
|
|
|
%
|
|
% Settings
|
|
%
|
|
\makeindex
|
|
%
|
|
% Syntax style
|
|
%
|
|
\usepackage{syntax}
|
|
\input{syntax/diagram.tex}
|
|
%
|
|
% Start of document.
|
|
%
|
|
\begin{document}
|
|
\renewcommand{\hline}{\xspace}
|
|
\title{Free Pascal :\\ Reference guide.}
|
|
\docdescription{Reference guide for Free Pascal, version \fpcversion}
|
|
\docversion{1.9}
|
|
\input{date.inc}
|
|
\author{Micha\"el Van Canneyt}
|
|
\maketitle
|
|
\tableofcontents
|
|
\newpage
|
|
\listoftables
|
|
\newpage
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Introduction
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% About this guide
|
|
\section*{About this guide}
|
|
This document describes all constants, types, variables, functions and
|
|
procedures as they are declared in the system unit.
|
|
Furthermore, it describes all pascal constructs supported by \fpc, and lists
|
|
all supported data types. It does not, however, give a detailed explanation
|
|
of the pascal language. The aim is to list which Pascal constructs are
|
|
supported, and to show where the \fpc implementation differs from the
|
|
Turbo Pascal implementation.
|
|
\subsection*{Notations}
|
|
Throughout this document, we will refer to functions, types and variables
|
|
with \var{typewriter} font. Functions and procedures have their own
|
|
subsections, and for each function or procedure we have the following
|
|
topics:
|
|
\begin{description}
|
|
\item [Declaration] The exact declaration of the function.
|
|
\item [Description] What does the procedure exactly do ?
|
|
\item [Errors] What errors can occur.
|
|
\item [See Also] Cross references to other related functions/commands.
|
|
\end{description}
|
|
The cross-references come in two flavours:
|
|
\begin{itemize}
|
|
\item References to other functions in this manual. In the printed copy, a
|
|
number will appear after this reference. It refers to the page where this
|
|
function is explained. In the on-line help pages, this is a hyperlink,
|
|
which can be clicked to jump to the declaration.
|
|
\item References to Unix manual pages. (For linux and unix related things only) they
|
|
are printed in \var{typewriter} font, and the number after it is the Unix
|
|
manual section.
|
|
\end{itemize}
|
|
\subsection*{Syntax diagrams}
|
|
All elements of the pascal language are explained in syntax diagrams.
|
|
Syntax diagrams are like flow charts. Reading a syntax diagram means getting
|
|
from the left side to the right side, following the arrows.
|
|
When the right side of a syntax diagram is reached, and it ends with a single
|
|
arrow, this means the syntax diagram is continued on the next line. If
|
|
the line ends on 2 arrows pointing to each other, then the diagram is
|
|
ended.
|
|
|
|
Syntactical elements are written like this
|
|
\begin{mysyntdiag}
|
|
\synt{syntactical\ elements\ are\ like\ this}
|
|
\end{mysyntdiag}
|
|
Keywords which must be typed exactly as in the diagram:
|
|
\begin{mysyntdiag}
|
|
\lit*{keywords\ are\ like\ this}
|
|
\end{mysyntdiag}
|
|
When something can be repeated, there is an arrow around it:
|
|
\begin{mysyntdiag}
|
|
\begin{rep}[b] \synt{this\ can\ be\ repeated} \\ \end{rep}
|
|
\end{mysyntdiag}
|
|
When there are different possibilities, they are listed in columns:
|
|
\begin{mysyntdiag}
|
|
\begin{stack}
|
|
\synt{First\ possibility} \\
|
|
\synt{Second\ possibility}
|
|
\end{stack}
|
|
\end{mysyntdiag}
|
|
Note, that one of the possibilities can be empty:
|
|
\begin{mysyntdiag}
|
|
\begin{stack}\\
|
|
\synt{First\ possibility} \\
|
|
\synt{Second\ possibility}
|
|
\end{stack}
|
|
\end{mysyntdiag}
|
|
This means that both the first or second possibility are optional.
|
|
Of course, all these elements can be combined and nested.
|
|
|
|
\part{The Pascal language}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The Pascal language
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Pascal Tokens}
|
|
In this chapter we describe all the pascal reserved words, as well as the
|
|
various ways to denote strings, numbers, identifiers etc.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Symbols
|
|
\section{Symbols}
|
|
Free Pascal allows all characters, digits and some special ASCII symbols
|
|
in a Pascal source file.
|
|
\input{syntax/symbol.syn}
|
|
The following characters have a special meaning:
|
|
\begin{verbatim}
|
|
+ - * / = < > [ ] . , ( ) : ^ @ { } $ #
|
|
\end{verbatim}
|
|
and the following character pairs too:
|
|
\begin{verbatim}
|
|
<= >= := += -= *= /= (* *) (. .) //
|
|
\end{verbatim}
|
|
When used in a range specifier, the character pair \var{(.} is equivalent to
|
|
the left square bracket \var{[}. Likewise, the character pair \var{.)} is
|
|
equivalent to the right square bracket \var{]}.
|
|
When used for comment delimiters, the character pair \var{(*} is equivalent
|
|
to the left brace \var{\{} and the character pair \var{*)} is equivalent
|
|
to the right brace \var{\}}.
|
|
These character pairs retain their normal meaning in string expressions.
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Comments
|
|
\section{Comments}
|
|
\fpc supports the use of nested comments. The following constructs are valid
|
|
comments:
|
|
\begin{verbatim}
|
|
(* This is an old style comment *)
|
|
{ This is a Turbo Pascal comment }
|
|
// This is a Delphi comment. All is ignored till the end of the line.
|
|
\end{verbatim}
|
|
The following are valid ways of nesting comments:
|
|
\begin{verbatim}
|
|
{ Comment 1 (* comment 2 *) }
|
|
(* Comment 1 { comment 2 } *)
|
|
{ comment 1 // Comment 2 }
|
|
(* comment 1 // Comment 2 *)
|
|
// comment 1 (* comment 2 *)
|
|
// comment 1 { comment 2 }
|
|
\end{verbatim}
|
|
The last two comments {\em must} be on one line. The following two will give
|
|
errors:
|
|
\begin{verbatim}
|
|
// Valid comment { No longer valid comment !!
|
|
}
|
|
\end{verbatim}
|
|
and
|
|
\begin{verbatim}
|
|
// Valid comment (* No longer valid comment !!
|
|
*)
|
|
\end{verbatim}
|
|
The compiler will react with a 'invalid character' error when it encounters
|
|
such constructs, regardless of the \var{-So} switch.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Reserved words
|
|
\section{Reserved words}
|
|
Reserved words are part of the Pascal language, and cannot be redefined.
|
|
They will be denoted as {\sffamily\bfseries this} throughout the syntax
|
|
diagrams. Reserved words can be typed regardless of case, i.e. Pascal is
|
|
case insensitive.
|
|
We make a distinction between Turbo Pascal and Delphi reserved words, since
|
|
with the \var{-So} switch, only the Turbo Pascal reserved words are
|
|
recognised, and the Delphi ones can be redefined. By default, \fpc
|
|
recognises the Delphi reserved words.
|
|
\subsection{Turbo Pascal reserved words}
|
|
The following keywords exist in Turbo Pascal mode
|
|
\begin{multicols}{4}
|
|
\begin{verbatim}
|
|
absolute
|
|
and
|
|
array
|
|
asm
|
|
begin
|
|
break
|
|
case
|
|
const
|
|
constructor
|
|
continue
|
|
destructor
|
|
div
|
|
do
|
|
downto
|
|
else
|
|
end
|
|
file
|
|
for
|
|
function
|
|
goto
|
|
if
|
|
implementation
|
|
in
|
|
inherited
|
|
inline
|
|
interface
|
|
label
|
|
mod
|
|
nil
|
|
not
|
|
object
|
|
of
|
|
on
|
|
operator
|
|
or
|
|
packed
|
|
procedure
|
|
program
|
|
record
|
|
repeat
|
|
self
|
|
set
|
|
shl
|
|
shr
|
|
string
|
|
then
|
|
to
|
|
type
|
|
unit
|
|
until
|
|
uses
|
|
var
|
|
while
|
|
with
|
|
xor
|
|
\end{verbatim}
|
|
\end{multicols}
|
|
\subsection{Delphi reserved words}
|
|
The Delphi (II) reserved words are the same as the pascal ones, plus the
|
|
following ones:
|
|
\begin{multicols}{4}
|
|
\begin{verbatim}
|
|
as
|
|
class
|
|
except
|
|
exports
|
|
finalization
|
|
finally
|
|
initialization
|
|
is
|
|
library
|
|
on
|
|
property
|
|
raise
|
|
threadvar
|
|
try
|
|
\end{verbatim}
|
|
\end{multicols}
|
|
\subsection{\fpc reserved words}
|
|
On top of the Turbo Pascal and Delphi reserved words, \fpc also considers
|
|
the following as reserved words:
|
|
\begin{multicols}{4}
|
|
\begin{verbatim}
|
|
dispose
|
|
exit
|
|
false
|
|
new
|
|
true
|
|
\end{verbatim}
|
|
\end{multicols}
|
|
\subsection{Modifiers}
|
|
The following is a list of all modifiers. They are not exactly reserved
|
|
words in the sense that they can be used as identifiers, but in specific
|
|
places, they have a special meaning for the compiler.
|
|
\begin{multicols}{4}
|
|
\begin{verbatim}
|
|
absolute
|
|
abstract
|
|
alias
|
|
assembler
|
|
cdecl
|
|
default
|
|
export
|
|
external
|
|
far
|
|
far16
|
|
forward
|
|
fpccall
|
|
index
|
|
name
|
|
near
|
|
override
|
|
pascal
|
|
popstack
|
|
private
|
|
protected
|
|
public
|
|
published
|
|
read
|
|
register
|
|
safecall
|
|
saveregisters
|
|
softfloat
|
|
stdcall
|
|
virtual
|
|
write
|
|
\end{verbatim}
|
|
\end{multicols}
|
|
\begin{remark}
|
|
Predefined types such as \var{Byte}, \var{Boolean} and constants
|
|
such as \var{maxint} are {\em not} reserved words. They are
|
|
identifiers, declared in the system unit. This means that these types
|
|
can be redefined in other units. The programmer is, however, not
|
|
encouraged to do this, as it will cause a lot of confusion.
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Identifiers
|
|
\section{Identifiers}
|
|
Identifiers denote constants, types, variables, procedures and functions,
|
|
units, and programs. All names of things that are defined are identifiers.
|
|
An identifier consists of 255 significant characters (letters, digits and
|
|
the underscore character), from which the first must be an alphanumeric
|
|
character, or an underscore (\var{\_})
|
|
The following diagram gives the basic syntax for identifiers.
|
|
\input{syntax/identifier.syn}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Numbers
|
|
\section{Numbers}
|
|
Numbers are by default denoted in decimal notation.
|
|
Real (or decimal) numbers are written using engineering or scientific
|
|
notation (e.g. \var{0.314E1}).
|
|
|
|
For integer type constants, \fpc supports 4 formats:
|
|
\begin{enumerate}
|
|
\item Normal, decimal format (base 10). This is the standard format.
|
|
\item Hexadecimal format (base 16), in the same way as Turbo Pascal does.
|
|
To specify a constant value in hexadecimal format, prepend it with a dollar
|
|
sign (\var{\$}). Thus, the hexadecimal \var{\$FF} equals 255 decimal.
|
|
Note that case is insignificant when using hexadecimal constants.
|
|
\item As of version 1.0.7, Octal format (base 8) is also supported.
|
|
To specify a constant in octal format, prepend it with a ampersand (\&).
|
|
For instance 15 is specified in octal notation as \var{\&17}.
|
|
\item Binary notation (base 2). A binary number can be specified
|
|
by preceding it with a percent sign (\var{\%}). Thus, \var{255} can be
|
|
specified in binary notation as \var{\%11111111}.
|
|
\end{enumerate}
|
|
The following diagrams show the syntax for numbers.
|
|
\input{syntax/numbers.syn}
|
|
|
|
%%% !!!!!!!!!!!!
|
|
%%% For 2.0, the range has changed, and constants within
|
|
%%% a 64bit range are parsed as int64. and no longer
|
|
%%% as reals (except if they don't fit in int64!) !!!! - carl
|
|
\begin{remark}
|
|
It is to note that all decimal constants which do no fit within
|
|
the -2147483648..2147483647 range, are silently and automatically
|
|
parsed as real-type constants.
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Labels
|
|
\section{Labels}
|
|
Labels can be digit sequences or identifiers.
|
|
\input{syntax/label.syn}
|
|
\begin{remark}
|
|
Note that the \var{-Sg} switch must be specified before labels can be used.
|
|
By default, \fpc doesn't support \var{label} and \var{goto} statements.
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Character strings
|
|
\section{Character strings}
|
|
A character string (or string for short) is a sequence of zero or more
|
|
characters from the ASCII character set, enclosed by single quotes, and on 1
|
|
line of the program source.
|
|
A character set with nothing between the quotes (\var{'{}'}) is an empty
|
|
string.
|
|
\input{syntax/string.syn}
|
|
\chapter{Constants}
|
|
Just as in Turbo Pascal, \fpc supports both normal and typed constants.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Ordinary constants
|
|
\section{Ordinary constants}
|
|
Ordinary constants declarations are not different from the Turbo Pascal or
|
|
Delphi implementation.
|
|
\input{syntax/const.syn}
|
|
The compiler must be able to evaluate the expression in a constant
|
|
declaration at compile time. This means that most of the functions
|
|
in the Run-Time library cannot be used in a constant declaration.
|
|
Operators such as \var{+, -, *, /, not, and, or, div, mod, ord, chr,
|
|
sizeof, pi, int, trunc, round, frac, odd} can be used, however. For more
|
|
information on expressions, see \seec{Expressions}.
|
|
Only constants of the following types can be declared: \var{Ordinal types},
|
|
\var{Real types}, \var{Char}, and \var{String}.
|
|
The following are all valid constant declarations:
|
|
\begin{verbatim}
|
|
Const
|
|
e = 2.7182818; { Real type constant. }
|
|
a = 2; { Ordinal (Integer) type constant. }
|
|
c = '4'; { Character type constant. }
|
|
s = 'This is a constant string'; {String type constant.}
|
|
s = chr(32)
|
|
ls = SizeOf(Longint);
|
|
\end{verbatim}
|
|
Assigning a value to an ordinary constant is not permitted.
|
|
Thus, given the previous declaration, the following will result
|
|
in a compiler error:
|
|
\begin{verbatim}
|
|
s := 'some other string';
|
|
\end{verbatim}
|
|
|
|
Prior to version 1.9, \fpc did not correctly support 64-bit constants. As
|
|
of version 1.9, 64-bits constants can be specified.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Typed constants
|
|
\section{Typed constants}
|
|
Typed constants serve to provide a program with initialised variables.
|
|
Contrary to ordinary constants, they may be assigned to at run-time.
|
|
The difference with normal variables is that their value is initialised
|
|
when the program starts, whereas normal variables must be initialised
|
|
explicitly.
|
|
\input{syntax/tconst.syn}
|
|
Given the declaration:
|
|
\begin{verbatim}
|
|
Const
|
|
S : String = 'This is a typed constant string';
|
|
\end{verbatim}
|
|
The following is a valid assignment:
|
|
\begin{verbatim}
|
|
S := 'Result : '+Func;
|
|
\end{verbatim}
|
|
Where \var{Func} is a function that returns a \var{String}.
|
|
Typed constants are often used to initialize arrays and records. For arrays,
|
|
the initial elements must be specified, surrounded by round brackets, and
|
|
separated by commas. The number of elements must be exactly the same as
|
|
the number of elements in the declaration of the type.
|
|
As an example:
|
|
\begin{verbatim}
|
|
Const
|
|
tt : array [1..3] of string[20] = ('ikke', 'gij', 'hij');
|
|
ti : array [1..3] of Longint = (1,2,3);
|
|
\end{verbatim}
|
|
For constant records, each element of the record should be specified, in
|
|
the form \var{Field : Value}, separated by commas, and surrounded by round
|
|
brackets.
|
|
As an example:
|
|
\begin{verbatim}
|
|
Type
|
|
Point = record
|
|
X,Y : Real
|
|
end;
|
|
Const
|
|
Origin : Point = (X:0.0; Y:0.0);
|
|
\end{verbatim}
|
|
The order of the fields in a constant record needs to be the same as in the type declaration,
|
|
otherwise a compile-time error will occur.
|
|
|
|
\begin{remark}
|
|
It should be stressed that typed constants are initialized at program start.
|
|
This is also true for {\em local} typed constants. Local typed constants are
|
|
also initialized at program start. If their value was changed during previous
|
|
invocations of the function, they will retain their changed value, i.e. they
|
|
are not initialized each time the function is invoked.
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% resource strings
|
|
\section{Resource strings}
|
|
\label{se:resourcestring}
|
|
A special kind of constant declaration part is the \var{Resourestring}
|
|
part. This part is like a \var{Const} section, but it only allows
|
|
to declare constant of type string. This part is only available in the
|
|
\var{Delphi} or \var{objfpc} mode.
|
|
|
|
The following is an example of a resourcestring definition:
|
|
\begin{verbatim}
|
|
Resourcestring
|
|
|
|
FileMenu = '&File...';
|
|
EditMenu = '&Edit...';
|
|
\end{verbatim}
|
|
All string constants defined in the resourcestring section are stored
|
|
in special tables, allowing to manipulate the values of the strings
|
|
at runtime with some special mechanisms.
|
|
|
|
Semantically, the strings are like constants; Values can not be assigned to
|
|
them, except through the special mechanisms in the objpas unit. However,
|
|
they can be used in assignments or expressions as normal constants.
|
|
The main use of the resourcestring section is to provide an easy means
|
|
of internationalization.
|
|
|
|
More on the subject of resourcestrings can be found in the \progref, and
|
|
in the chapter on the \file{objpas} later in this manual.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Types
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Types}
|
|
All variables have a type. \fpc supports the same basic types as Turbo
|
|
Pascal, with some extra types from Delphi.
|
|
The programmer can declare his own types, which is in essence defining an identifier
|
|
that can be used to denote this custom type when declaring variables further
|
|
in the source code.
|
|
\input{syntax/typedecl.syn}
|
|
There are 7 major type classes :
|
|
\input{syntax/type.syn}
|
|
The last class, {\sffamily type identifier}, is just a means to give another
|
|
name to a type. This presents a way to make types platform independent, by
|
|
only using these types, and then defining these types for each platform
|
|
individually. The programmer that uses these units doesn't have to worry
|
|
about type size and so on. It also allows to use shortcut names for
|
|
fully qualified type names. e.g. define \var{system.longint} as
|
|
\var{Olongint} and then redefine \var{longint}.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Base types
|
|
\section{Base types}
|
|
The base or simple types of \fpc are the Delphi types.
|
|
We will discuss each separate.
|
|
\input{syntax/typesim.syn}
|
|
\subsection{Ordinal types}
|
|
With the exception of \var{int64}, \var{qword} and Real types,
|
|
all base types are ordinal types. Ordinal types have the following
|
|
characteristics:
|
|
\begin{enumerate}
|
|
\item Ordinal types are countable and ordered, i.e. it is, in principle,
|
|
possible to start counting them one bye one, in a specified order.
|
|
This property allows the operation of functions as \seep{Inc}, \seef{Ord},
|
|
\seep{Dec}
|
|
on ordinal types to be defined.
|
|
\item Ordinal values have a smallest possible value. Trying to apply the
|
|
\seef{Pred} function on the smallest possible value will generate a range
|
|
check error if range checking is enabled.
|
|
\item Ordinal values have a largest possible value. Trying to apply the
|
|
\seef{Succ} function on the largest possible value will generate a range
|
|
check error if range checking is enabled.
|
|
\end{enumerate}
|
|
\subsubsection{Integers}
|
|
A list of pre-defined integer types is presented in \seet{integerstyp}
|
|
%
|
|
\begin{table}[ht]
|
|
\caption{Predefined integer types}
|
|
\label{tab:integerstyp}
|
|
\begin{center}
|
|
\begin{tabular}{l}
|
|
%\begin{FPCltable}{l}{Predefined integer types}{integerstyp}
|
|
Name\\ \hline
|
|
Integer \\
|
|
Shortint \\
|
|
SmallInt \\
|
|
Longint \\
|
|
Longword \\
|
|
Int64 \\
|
|
Byte \\
|
|
Word \\
|
|
Cardinal \\
|
|
QWord \\
|
|
Boolean \\
|
|
ByteBool \\
|
|
LongBool \\
|
|
Char \\ \hline
|
|
\end{tabular}
|
|
\end{center}
|
|
\end{table}
|
|
%\end{FPCltable}
|
|
The integer types, and their ranges and sizes, that are predefined in
|
|
\fpc are listed in \seet{integersranges}. It is to note that
|
|
the \var{qword} and \var{int64} types are not true ordinals, so
|
|
some pascal constructs will not work with these two integer types.
|
|
\begin{FPCltable}{lcr}{Predefined integer types}{integersranges}
|
|
Type & Range & Size in bytes \\ \hline
|
|
Byte & 0 .. 255 & 1 \\
|
|
Shortint & -128 .. 127 & 1\\
|
|
Smallint & -32768 .. 32767 & 2\\
|
|
Word & 0 .. 65535 & 2 \\
|
|
Integer & either smallint, longint or int64 & size 2,4 or 8 \\
|
|
Cardinal & either word, longword or qword & size 2,4 or 8 \\
|
|
Longint & -2147483648 .. 2147483647 & 4\\
|
|
Longword & 0..4294967295 & 4 \\
|
|
Int64 & -9223372036854775808 .. 9223372036854775807 & 8 \\
|
|
QWord & 0 .. 18446744073709551615 & 8 \\ \hline
|
|
\end{FPCltable}
|
|
|
|
The \var{integer} type maps to the smallint type in the default
|
|
\fpc mode. It maps to either a longint or int64 in either Delphi or ObjFPC
|
|
mode. The \var{cardinal} type is currently always mapped to the
|
|
longword type. The definition of the \var{cardinal} and \var{integer}
|
|
types may change from one architecture to another and from one
|
|
compiler mode to another. They usually have the same size as the
|
|
underlying target architecture.
|
|
|
|
% This IS NOT TRUE, this is a 32-bit compiler, so the integer type
|
|
% will always be the same independently the CPU type.
|
|
%This is summarized in \seet{integer32type} for 32-bit processors
|
|
%(such as Intel 80x86, Motorola 680x0, PowerPC 32-bit, SPARC v7, MIPS32), and
|
|
%in \seet{integer64type} for 64-bit processors (such as Alpha AXP,
|
|
%SPARC v9 or later, Intel Itanium, MIPS64).
|
|
|
|
%\begin{FPCltable}{lcr}{\var{Integer} type mapping for 32-bit processors}{integer32type}
|
|
%Compiler mode & Range & Size in bytes \\ \hline
|
|
%<default> & -32768 .. 32767 & 2\\
|
|
%tp & -32768 .. 32767 & 2\\
|
|
%Delphi & -2147483648 .. 2147483647 & 4\\
|
|
%ObjFPC & -2147483648 .. 2147483647 & 4\\
|
|
%\end{FPCltable}
|
|
|
|
%\begin{FPCltable}{lcr}{\var{Integer} type mapping for 64-bit processors}{integer64type}
|
|
%Compiler mode & Range & Size in bytes \\ \hline
|
|
%<default> & -32768 .. 32767 & 2\\
|
|
%tp & -32768 .. 32767 & 2\\
|
|
%Delphi & -9223372036854775808 .. 9223372036854775807 & 8 \\
|
|
%ObjFPC & -9223372036854775808 .. 9223372036854775807 & 8 \\
|
|
%\end{FPCltable}
|
|
|
|
\fpc does automatic type conversion in expressions where different kinds of
|
|
integer types are used.
|
|
\subsubsection{Boolean types}
|
|
\fpc supports the \var{Boolean} type, with its two pre-defined possible
|
|
values \var{True} and \var{False}. It also supports the \var{ByteBool},
|
|
\var{WordBool} and \var{LongBool} types. These are the only two values that can be
|
|
assigned to a \var{Boolean} type. Of course, any expression that resolves
|
|
to a \var{boolean} value, can also be assigned to a boolean type.
|
|
\begin{FPCltable}{lll}{Boolean types}{booleantypes}
|
|
Name & Size & Ord(True) \\ \hline
|
|
Boolean & 1 & 1 \\
|
|
ByteBool & 1 & Any nonzero value \\
|
|
WordBool & 2 & Any nonzero value \\
|
|
LongBool & 4 & Any nonzero value \\ \hline
|
|
\end{FPCltable}
|
|
Assuming \var{B} to be of type \var{Boolean}, the following are valid
|
|
assignments:
|
|
\begin{verbatim}
|
|
B := True;
|
|
B := False;
|
|
B := 1<>2; { Results in B := True }
|
|
\end{verbatim}
|
|
Boolean expressions are also used in conditions.
|
|
|
|
\begin{remark}
|
|
In \fpc, boolean expressions are always evaluated in such a
|
|
way that when the result is known, the rest of the expression will no longer
|
|
be evaluated (Called short-cut evaluation). In the following example, the function \var{Func} will never
|
|
be called, which may have strange side-effects.
|
|
\begin{verbatim}
|
|
...
|
|
B := False;
|
|
A := B and Func;
|
|
\end{verbatim}
|
|
Here \var{Func} is a function which returns a \var{Boolean} type.
|
|
\end{remark}
|
|
|
|
\subsubsection{Enumeration types}
|
|
Enumeration types are supported in \fpc. On top of the Turbo Pascal
|
|
implementation, \fpc allows also a C-style extension of the
|
|
enumeration type, where a value is assigned to a particular element of
|
|
the enumeration list.
|
|
\input{syntax/typeenum.syn}
|
|
(see \seec{Expressions} for how to use expressions)
|
|
When using assigned enumerated types, the assigned elements must be in
|
|
ascending numerical order in the list, or the compiler will complain.
|
|
The expressions used in assigned enumerated elements must be known at
|
|
compile time.
|
|
So the following is a correct enumerated type declaration:
|
|
\begin{verbatim}
|
|
Type
|
|
Direction = ( North, East, South, West );
|
|
\end{verbatim}
|
|
The C style enumeration type looks as follows:
|
|
\begin{verbatim}
|
|
Type
|
|
EnumType = (one, two, three, forty := 40,fortyone);
|
|
\end{verbatim}
|
|
As a result, the ordinal number of \var{forty} is \var{40}, and not \var{3},
|
|
as it would be when the \var{':= 40'} wasn't present.
|
|
The ordinal value of \var{fortyone} is then {41}, and not \var{4}, as it
|
|
would be when the assignment wasn't present. After an assignment in an
|
|
enumerated definition the compiler adds 1 to the assigned value to assign to
|
|
the next enumerated value.
|
|
When specifying such an enumeration type, it is important to keep in mind
|
|
that the enumerated elements should be kept in ascending order. The
|
|
following will produce a compiler error:
|
|
\begin{verbatim}
|
|
Type
|
|
EnumType = (one, two, three, forty := 40, thirty := 30);
|
|
\end{verbatim}
|
|
It is necessary to keep \var{forty} and \var{thirty} in the correct order.
|
|
When using enumeration types it is important to keep the following points
|
|
in mind:
|
|
\begin{enumerate}
|
|
\item The \var{Pred} and \var{Succ} functions cannot be used on
|
|
this kind of enumeration types. Trying to do this anyhow will result in a
|
|
compiler error.
|
|
\item Enumeration types stored using a default size. This behaviour can be changed
|
|
with the \var{\{\$PACKENUM n\}} compiler directive, which
|
|
tells the compiler the minimal number of bytes to be used for enumeration
|
|
types.
|
|
For instance
|
|
\begin{verbatim}
|
|
Type
|
|
{$PACKENUM 4}
|
|
LargeEnum = ( BigOne, BigTwo, BigThree );
|
|
{$PACKENUM 1}
|
|
SmallEnum = ( one, two, three );
|
|
Var S : SmallEnum;
|
|
L : LargeEnum;
|
|
begin
|
|
WriteLn ('Small enum : ',SizeOf(S));
|
|
WriteLn ('Large enum : ',SizeOf(L));
|
|
end.
|
|
\end{verbatim}
|
|
will, when run, print the following:
|
|
\begin{verbatim}
|
|
Small enum : 1
|
|
Large enum : 4
|
|
\end{verbatim}
|
|
\end{enumerate}
|
|
More information can be found in the \progref, in the compiler directives
|
|
section.
|
|
\subsubsection{Subrange types}
|
|
A subrange type is a range of values from an ordinal type (the {\em host}
|
|
type). To define a subrange type, one must specify it's limiting values: the
|
|
highest and lowest value of the type.
|
|
\input{syntax/typesubr.syn}
|
|
Some of the predefined \var{integer} types are defined as subrange types:
|
|
\begin{verbatim}
|
|
Type
|
|
Longint = $80000000..$7fffffff;
|
|
Integer = -32768..32767;
|
|
shortint = -128..127;
|
|
byte = 0..255;
|
|
Word = 0..65535;
|
|
\end{verbatim}
|
|
Subrange types of enumeration types can also be defined:
|
|
\begin{verbatim}
|
|
Type
|
|
Days = (monday,tuesday,wednesday,thursday,friday,
|
|
saturday,sunday);
|
|
WorkDays = monday .. friday;
|
|
WeekEnd = Saturday .. Sunday;
|
|
\end{verbatim}
|
|
\subsection{Real types}
|
|
\fpc uses the math coprocessor (or emulation) for all its floating-point
|
|
calculations. The Real native type is processor dependant,
|
|
but it is either Single or Double. Only the IEEE floating point types are
|
|
supported, and these depend on the target processor and emulation options.
|
|
The true Turbo Pascal compatible types are listed in
|
|
\seet{Reals}.
|
|
\begin{FPCltable}{lccr}{Supported Real types}{Reals}
|
|
Type & Range & Significant digits & Size \\ \hline
|
|
Real & platform dependant & ??? & 4 or 8 \\
|
|
Single & 1.5E-45 .. 3.4E38 & 7-8 & 4 \\
|
|
Double & 5.0E-324 .. 1.7E308 & 15-16 & 8 \\
|
|
Extended & 1.9E-4951 .. 1.1E4932 & 19-20 & 10\\
|
|
Comp & -2E64+1 .. 2E63-1 & 19-20 & 8 \\
|
|
\end{FPCltable}
|
|
The \var{Comp} type is, in effect, a 64-bit integer and is not available
|
|
on all target platforms. To get more information on the supported types
|
|
for each platform, refer to the \progref.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Character types
|
|
\section{Character types}
|
|
\subsection{Char}
|
|
\fpc supports the type \var{Char}. A \var{Char} is exactly 1 byte in
|
|
size, and contains one character.
|
|
A character constant can be specified by enclosing the character in single
|
|
quotes, as follows : 'a' or 'A' are both character constants.
|
|
A character can also be specified by its ASCII
|
|
value, by preceding the ASCII value with the number symbol (\#). For example
|
|
specifying \var{\#65} would be the same as \var{'A'}.
|
|
Also, the caret character (\verb+^+) can be used in combination with a letter to
|
|
specify a character with ASCII value less than 27. Thus \verb+^G+ equals
|
|
\var{\#7} (G is the seventh letter in the alphabet.)
|
|
When the single quote character must be represented, it should be typed
|
|
two times successively, thus \var{''''} represents the single quote character.
|
|
|
|
\subsection{Strings}
|
|
\fpc supports the \var{String} type as it is defined in Turbo Pascal
|
|
(A sequence of characters with a specified length) and it
|
|
supports ansistrings as in Delphi.
|
|
To declare a variable as a string, use the following type specification:
|
|
\input{syntax/sstring.syn}
|
|
|
|
The meaning of a string declaration statement is interpreted differently
|
|
depending on the \var{\{\$H\}} switch. The above declaration can declare an
|
|
ansistrng or a short string.
|
|
|
|
Whatever the actual type, ansistrings and short strings can be used
|
|
interchangeably. The compiler always takes care of the necessary type
|
|
conversions. Note, however, that the result of an expression that contains
|
|
ansistrings and short strings will always be an ansistring.
|
|
|
|
\subsection{Short strings}
|
|
A string declaration declares a short string in the following cases:
|
|
|
|
\begin{enumerate}
|
|
\item If the switch is off: \var{\{\$H-\}}, the string declaration
|
|
will always be a short string declaration.
|
|
\item If the switch is on \var{\{\$H+\}}, and there is a length
|
|
specifier, the declaration is a short string declaration.
|
|
\end{enumerate}
|
|
The predefined type \var{ShortString} is defined as a string of length 255:
|
|
\begin{verbatim}
|
|
ShortString = String[255];
|
|
\end{verbatim}
|
|
|
|
If the size of the string is not specified, \var{255} is taken as a
|
|
default. The length of the string can be obtained with the \seef{Length}
|
|
standard runtime routine.
|
|
For example in
|
|
\begin{verbatim}
|
|
{$H-}
|
|
|
|
Type
|
|
NameString = String[10];
|
|
StreetString = String;
|
|
\end{verbatim}
|
|
\var{NameString} can contain a maximum of 10 characters. While
|
|
\var{StreetString} can contain up to 255 characters.
|
|
|
|
\subsection{Ansistrings}
|
|
Ansistrings are strings that have no length limit. They are reference
|
|
counted and null terminated. Internally, an ansistring is treated as
|
|
a pointer. This is all handled transparantly, i.e. they can be manipulated
|
|
as a normal short string. Ansistrings can be defined using the predefined
|
|
\var{AnsiString} type.
|
|
|
|
If the \var{\{\$H\}} switch is on, then a string definition using the
|
|
regular \var{String} keyword and that doesn't contain a length specifier,
|
|
will be regarded as an ansistring as well. If a length specifier is present,
|
|
a short string will be used, regardless of the \var{\{\$H\}} setting.
|
|
|
|
If the string is empty (\var{''}), then the internal pointer representation
|
|
of the string pointer is \var{Nil}. If the string is not empty, then the
|
|
pointer points to a structure in heap memory.
|
|
|
|
The internal representation as a pointer, and the automatic null-termination
|
|
make it possible to typecast an ansistring to a pchar. If the string is empty
|
|
(so the pointer is nil) then the compiler makes sure that the typecasted
|
|
pchar will point to a null byte.
|
|
|
|
Assigning one ansistring to another doesn't involve moving the actual
|
|
string. A statement
|
|
\begin{verbatim}
|
|
S2:=S1;
|
|
\end{verbatim}
|
|
results in the reference count of \var{S2} being decreased by one,
|
|
The referece count of \var{S1} is increased by one, and finally \var{S1}
|
|
(as a pointer) is copied to \var{S2}. This is a significant speed-up in
|
|
the code.
|
|
|
|
If the reference count reaches zero, then the memory occupied by the
|
|
string is deallocated automatically, so no memory leaks arise.
|
|
|
|
When an ansistring is declared, the \fpc compiler initially
|
|
allocates just memory for a pointer, not more. This pointer is guaranteed
|
|
to be nil, meaning that the string is initially empty. This is
|
|
true for local and global ansistrings or anstrings that are part of a
|
|
structure (arrays, records or objects).
|
|
|
|
This does introduce an overhead. For instance, declaring
|
|
\begin{verbatim}
|
|
Var
|
|
A : Array[1..100000] of string;
|
|
\end{verbatim}
|
|
Will copy 100,000 times \var{nil} into \var{A}. When \var{A} goes out of scope, then
|
|
the reference count of the 100,000 strings will be decreased by 1 for each
|
|
of these strings. All this happens
|
|
invisibly for the programmer, but when considering performance issues,
|
|
this is important.
|
|
|
|
Memory will be allocated only when the string is assigned a value.
|
|
If the string goes out of scope, then its reference count is automatically
|
|
decreased by 1. If the reference count reaches zero, the memory reserved for
|
|
the string is released.
|
|
|
|
If a value is assigned to a character of a string that has a reference count
|
|
greater than 1, such as in the following
|
|
statements:
|
|
\begin{verbatim}
|
|
S:=T; { reference count for S and T is now 2 }
|
|
S[I]:='@';
|
|
\end{verbatim}
|
|
then a copy of the string is created before the assignment. This is known
|
|
as {\em copy-on-write} semantics.
|
|
|
|
The \seef{Length} function must be used to get the length of an
|
|
ansistring.
|
|
|
|
To set the length of an ansistring, the \seep{SetLength} function must be used.
|
|
Constant ansistrings have a reference count of -1 and are treated specially.
|
|
|
|
Ansistrings are converted to short strings by the compiler if needed,
|
|
this means that the use of ansistrings and short strings can be mixed
|
|
without problems.
|
|
|
|
Ansistrings can be typecasted to \var{PChar} or \var{Pointer} types:
|
|
\begin{verbatim}
|
|
Var P : Pointer;
|
|
PC : PChar;
|
|
S : AnsiString;
|
|
|
|
begin
|
|
S :='This is an ansistring';
|
|
PC:=Pchar(S);
|
|
P :=Pointer(S);
|
|
\end{verbatim}
|
|
There is a difference between the two typecasts. When an empty
|
|
ansistring is typecasted to a pointer, the pointer wil be \var{Nil}. If an
|
|
empty ansistring is typecasted to a \var{PChar}, then the result will be a pointer to a
|
|
zero byte (an empty string).
|
|
|
|
The result of such a typecast must be used with care. In general, it is best
|
|
to consider the result of such a typecast as read-only, i.e. suitable for
|
|
passing to a procedure that needs a constant pchar argument.
|
|
|
|
It is therefore NOT advisable to typecast one of the following:
|
|
\begin{enumerate}
|
|
\item expressions.
|
|
\item strings that have reference count larger than 0.
|
|
(call uniquestring to ensure a string has reference count 1)
|
|
\end{enumerate}
|
|
|
|
\subsection{WideStrings}
|
|
Widestrings (used to represent unicode character strings) are implemented in much
|
|
the same way as ansistrings: reference counted, null-terminated arrays, only they
|
|
are implemented as arrays of \var{WideChars} instead of regular \var{Chars}.
|
|
A \var{WideChar} is a two-byte character (an element of a DBCS: Double Byte
|
|
Character Set). Mostly the same rules apply for \var{WideStrings} as for
|
|
\var{AnsiStrings}. The compiler transparantly converts WideStrings to
|
|
AnsiStrings and vice versa.
|
|
|
|
Similarly to the typecast of an Ansistring to a \var{PChar} null-terminated
|
|
array of characters, a WideString can be converted to a \var{PWideChar}
|
|
null-terminated array of characters.
|
|
Note that the \var{PWideChar} array is terminated by 2 null bytes instead of
|
|
1, so a typecast to a pchar is not automatic.
|
|
|
|
The compiler itself provides no support for any conversion from Unicode to
|
|
ansistrings or vice versa; 2 procedural variables are present in the system
|
|
unit which can be set to handle the conversion. For more information, see
|
|
the system units reference.
|
|
|
|
% Constant strings
|
|
\subsection{Constant strings}
|
|
|
|
To specify a constant string, it must be enclosed in single-quotes, just
|
|
as a \var{Char} type, only now more than one character is allowed.
|
|
Given that \var{S} is of type \var{String}, the following are valid assignments:
|
|
\begin{verbatim}
|
|
S := 'This is a string.';
|
|
S := 'One'+', Two'+', Three';
|
|
S := 'This isn''t difficult !';
|
|
S := 'This is a weird character : '#145' !';
|
|
\end{verbatim}
|
|
As can be seen, the single quote character is represented by 2 single-quote
|
|
characters next to each other. Strange characters can be specified by their
|
|
ASCII value.
|
|
The example shows also that two strings can be added. The resulting string is
|
|
just the concatenation of the first with the second string, without spaces in
|
|
between them. Strings can not be substracted, however.
|
|
|
|
Whether the constant string is stored as an ansistring or a short string
|
|
depends on the settings of the \var{\{\$H\}} switch.
|
|
|
|
% PChar
|
|
\subsection{PChar - Null terminated strings}
|
|
\fpc supports the Delphi implementation of the \var{PChar} type. \var{PChar}
|
|
is defined as a pointer to a \var{Char} type, but allows additional
|
|
operations.
|
|
The \var{PChar} type can be understood best as the Pascal equivalent of a
|
|
C-style null-terminated string, i.e. a variable of type \var{PChar} is a
|
|
pointer that points to an array of type \var{Char}, which is ended by a
|
|
null-character (\var{\#0}).
|
|
\fpc supports initializing of \var{PChar} typed constants, or a direct
|
|
assignment. For example, the following pieces of code are equivalent:
|
|
\begin{verbatim}
|
|
program one;
|
|
var p : PChar;
|
|
begin
|
|
P := 'This is a null-terminated string.';
|
|
WriteLn (P);
|
|
end.
|
|
\end{verbatim}
|
|
Results in the same as
|
|
\begin{verbatim}
|
|
program two;
|
|
const P : PChar = 'This is a null-terminated string.'
|
|
begin
|
|
WriteLn (P);
|
|
end.
|
|
\end{verbatim}
|
|
These examples also show that it is possible to write {\em the contents} of
|
|
the string to a file of type \var{Text}.
|
|
The \seestrings unit contains procedures and functions that manipulate the
|
|
\var{PChar} type as in the standard C library.
|
|
Since it is equivalent to a pointer to a type \var{Char} variable, it is
|
|
also possible to do the following:
|
|
\begin{verbatim}
|
|
Program three;
|
|
Var S : String[30];
|
|
P : PChar;
|
|
begin
|
|
S := 'This is a null-terminated string.'#0;
|
|
P := @S[1];
|
|
WriteLn (P);
|
|
end.
|
|
\end{verbatim}
|
|
This will have the same result as the previous two examples.
|
|
Null-terminated strings cannot be added as normal Pascal
|
|
strings. If two \var{PChar} strings mustt be concatenated; the functions from
|
|
the unit \seestrings must be used.
|
|
|
|
However, it is possible to do some pointer arithmetic. The
|
|
operators \var{+} and \var{-} can be used to do operations on \var{PChar} pointers.
|
|
In \seet{PCharMath}, \var{P} and \var{Q} are of type \var{PChar}, and
|
|
\var{I} is of type \var{Longint}.
|
|
\begin{FPCltable}{lr}{\var{PChar} pointer arithmetic}{PCharMath}
|
|
Operation & Result \\ \hline
|
|
\var{P + I} & Adds \var{I} to the address pointed to by \var{P}. \\
|
|
\var{I + P} & Adds \var{I} to the address pointed to by \var{P}. \\
|
|
\var{P - I} & Substracts \var{I} from the address pointed to by \var{P}. \\
|
|
\var{P - Q} & Returns, as an integer, the distance between 2 addresses \\
|
|
& (or the number of characters between \var{P} and \var{Q}) \\
|
|
\hline
|
|
\end{FPCltable}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Structured Types
|
|
\section{Structured Types}
|
|
A structured type is a type that can hold multiple values in one variable.
|
|
Stuctured types can be nested to unlimited levels.
|
|
\input{syntax/typestru.syn}
|
|
Unlike Delphi, \fpc does not support the keyword \var{Packed} for all
|
|
structured types, as can be seen in the syntax diagram. It will be mentioned
|
|
when a type supports the \var{packed} keyword.
|
|
In the following, each of the possible structured types is discussed.
|
|
\subsection{Arrays}
|
|
\fpc supports arrays as in Turbo Pascal, multi-dimensional arrays
|
|
and packed arrays are also supported, as well as the dynamic arrays of
|
|
Delphi:
|
|
\input{syntax/typearr.syn}
|
|
\subsubsection{Static arrays}
|
|
When the range of the array is included in the array definition, it is
|
|
called a static array. Trying to access an element with an index that is
|
|
outside the declared range will generate a run-time error (if range checking
|
|
is on). The following is an example of a valid array declaration:
|
|
\begin{verbatim}
|
|
Type
|
|
RealArray = Array [1..100] of Real;
|
|
\end{verbatim}
|
|
Valid indexes for accessing an element of the array are between 1 and 100,
|
|
where the borders 1 and 100 are included.
|
|
As in Turbo Pascal, if the array component type is in itself an array, it is
|
|
possible to combine the two arrays into one multi-dimensional array. The
|
|
following declaration:
|
|
\begin{verbatim}
|
|
Type
|
|
APoints = array[1..100] of Array[1..3] of Real;
|
|
\end{verbatim}
|
|
is equivalent to the following declaration:
|
|
\begin{verbatim}
|
|
Type
|
|
APoints = array[1..100,1..3] of Real;
|
|
\end{verbatim}
|
|
The functions \seef{High} and \seef{Low} return the high and low bounds of
|
|
the leftmost index type of the array. In the above case, this would be 100
|
|
and 1.
|
|
|
|
When static array-type variables are assigned to each other, the contents of the
|
|
whole array is copied. This is also true for multi-dimensional arrays:
|
|
\begin{verbatim}
|
|
program testarray1;
|
|
|
|
Type
|
|
TA = Array[0..9,0..9] of Integer;
|
|
|
|
var
|
|
A,B : TA;
|
|
I,J : Integer;
|
|
begin
|
|
For I:=0 to 9 do
|
|
For J:=0 to 9 do
|
|
A[I,J]:=I*J;
|
|
For I:=0 to 9 do
|
|
begin
|
|
For J:=0 to 9 do
|
|
Write(A[I,J]:2,' ');
|
|
Writeln;
|
|
end;
|
|
B:=A;
|
|
Writeln;
|
|
For I:=0 to 9 do
|
|
For J:=0 to 9 do
|
|
A[9-I,9-J]:=I*J;
|
|
For I:=0 to 9 do
|
|
begin
|
|
For J:=0 to 9 do
|
|
Write(B[I,J]:2,' ');
|
|
Writeln;
|
|
end;
|
|
end.
|
|
\end{verbatim}
|
|
The output will be 2 identical matrices.
|
|
|
|
\subsubsection{Dynamic arrays}
|
|
As of version 1.1, \fpc also knows dynamic arrays: In that case, the array
|
|
range is omitted, as in the following example:
|
|
\begin{verbatim}
|
|
Type
|
|
TByteArray : Array of Byte;
|
|
\end{verbatim}
|
|
When declaring a variable of a dynamic array type, the initial length of the
|
|
array is zero. The actual length of the array must be set with the standard
|
|
\var{SetLength} function, which will allocate the memory to contain the
|
|
array elements on the heap. The following example will set the length to
|
|
1000:
|
|
\begin{verbatim}
|
|
Var
|
|
A : TByteArray;
|
|
|
|
begin
|
|
SetLength(A,1000);
|
|
\end{verbatim}
|
|
After a call to \var{SetLength}, valid array indexes are 0 to 999: the array
|
|
index is always zero-based.
|
|
|
|
Note that the length of the array is set in elements, not in bytes of
|
|
allocated mmemory (although these may be the same). The amount of
|
|
memory allocated is the size of the array multiplied by the size of
|
|
1 element in the array. The memory will be disposed of at the exit of the
|
|
current procedure or function.
|
|
|
|
It is also possible to resize the array: in that case, as much of the
|
|
elements in the array as will fit in the new size, will be kept. The array
|
|
can be resized to zero, which effectively resets the variable.
|
|
|
|
At all times, trying to access an element of the array that is not in the
|
|
current length of the array will generate a run-time error.
|
|
|
|
Assignment of one dynamic array-type variable to another will let both
|
|
variables point to the same array. Contrary to ansistrings, an
|
|
assignment to an element of one array will be reflected in the
|
|
other:
|
|
\begin{verbatim}
|
|
Var
|
|
A,B : TByteArray;
|
|
|
|
begin
|
|
SetLength(A,10);
|
|
A[1]:=33;
|
|
B:=A;
|
|
A[1]:=31;
|
|
\end{verbatim}
|
|
After the second assignment, the first element in B will also contain 31.
|
|
|
|
It can also be seen from the output of the following example:
|
|
\begin{verbatim}
|
|
program testarray1;
|
|
|
|
Type
|
|
TA = Array of array of Integer;
|
|
|
|
var
|
|
A,B : TA;
|
|
I,J : Integer;
|
|
begin
|
|
Setlength(A,10,10);
|
|
For I:=0 to 9 do
|
|
For J:=0 to 9 do
|
|
A[I,J]:=I*J;
|
|
For I:=0 to 9 do
|
|
begin
|
|
For J:=0 to 9 do
|
|
Write(A[I,J]:2,' ');
|
|
Writeln;
|
|
end;
|
|
B:=A;
|
|
Writeln;
|
|
For I:=0 to 9 do
|
|
For J:=0 to 9 do
|
|
A[9-I,9-J]:=I*J;
|
|
For I:=0 to 9 do
|
|
begin
|
|
For J:=0 to 9 do
|
|
Write(B[I,J]:2,' ');
|
|
Writeln;
|
|
end;
|
|
end.
|
|
\end{verbatim}
|
|
The output will be a matrix of numbers, and then the same matrix, mirrorred.
|
|
|
|
Dynamic arrays are reference counted: if in one of the previous examples A
|
|
goes out of scope and B does not, then the array is not yet disposed of: the
|
|
reference count of A (and B) is decreased with 1. As soon as the reference
|
|
count reaches zero, the memory is disposed of.
|
|
|
|
It is also possible to copy and/or resize the array with the standard
|
|
\var{Copy} function, which acts as the copy function for strings:
|
|
\begin{verbatim}
|
|
program testarray3;
|
|
|
|
Type
|
|
TA = array of Integer;
|
|
|
|
var
|
|
A,B : TA;
|
|
I,J : Integer;
|
|
begin
|
|
Setlength(A,10);
|
|
For I:=0 to 9 do
|
|
A[I]:=I;
|
|
B:=Copy(A,3,9);
|
|
For I:=0 to 5 do
|
|
Writeln(B[I]);
|
|
end.
|
|
\end{verbatim}
|
|
The \var{Copy} function will copy 9 elements of the array to a new array.
|
|
Starting at the element at index 3 (i.e. the fourth element) of the array.
|
|
|
|
The \var{Low} function on a dynamic array will always return 0, and the
|
|
High function will return the value \var{Length-1}, i.e., the value of the
|
|
highest allowed array index. The \var{Length} function will return the
|
|
number of elements in the array.
|
|
\subsection{Record types}
|
|
\fpc supports fixed records and records with variant parts.
|
|
The syntax diagram for a record type is
|
|
\input{syntax/typerec.syn}
|
|
So the following are valid record types declarations:
|
|
\begin{verbatim}
|
|
Type
|
|
Point = Record
|
|
X,Y,Z : Real;
|
|
end;
|
|
RPoint = Record
|
|
Case Boolean of
|
|
False : (X,Y,Z : Real);
|
|
True : (R,theta,phi : Real);
|
|
end;
|
|
BetterRPoint = Record
|
|
Case UsePolar : Boolean of
|
|
False : (X,Y,Z : Real);
|
|
True : (R,theta,phi : Real);
|
|
end;
|
|
\end{verbatim}
|
|
The variant part must be last in the record. The optional identifier in the
|
|
case statement serves to access the tag field value, which otherwise would
|
|
be invisible to the programmer. It can be used to see which variant is
|
|
active at a certain time. In effect, it introduces a new field in the
|
|
record.
|
|
\begin{remark}
|
|
It is possible to nest variant parts, as in:
|
|
\begin{verbatim}
|
|
Type
|
|
MyRec = Record
|
|
X : Longint;
|
|
Case byte of
|
|
2 : (Y : Longint;
|
|
case byte of
|
|
3 : (Z : Longint);
|
|
);
|
|
end;
|
|
\end{verbatim}
|
|
\end{remark}
|
|
The size of a record is the sum of the sizes of its fields, each size of a
|
|
field is rounded up to a power of two. If the record contains a variant part, the size
|
|
of the variant part is the size of the biggest variant, plus the size of the
|
|
tag field type {\em if an identifier was declared for it}. Here also, the size of
|
|
each part is first rounded up to two. So in the above example,
|
|
\seef{SizeOf} would return 24 for \var{Point}, 24 for \var{RPoint} and
|
|
26 for \var{BetterRPoint}. For \var{MyRec}, the value would be 12.
|
|
If a typed file with records, produced by a Turbo Pascal program, must be read,
|
|
then chances are that attempting to read that file correctly will fail.
|
|
The reason for this is that by default, elements of a record are aligned at
|
|
2-byte boundaries, for performance reasons. This default behaviour can be
|
|
changed with the \var{\{\$PackRecords n\}} switch. Possible values for
|
|
\var{n} are 1, 2, 4, 16 or \var{Default}.
|
|
This switch tells the compiler to align elements of a record or object or
|
|
class that have size larger than \var{n} on \var{n} byte boundaries.
|
|
Elements that have size smaller or equal than \var{n} are aligned on
|
|
natural boundaries, i.e. to the first power of two that is larger than or
|
|
equal to the size of the record element.
|
|
The keyword \var{Default} selects the default value for the platform
|
|
that the code is compiled for (currently, this is 2 on all platforms)
|
|
Take a look at the following program:
|
|
\begin{verbatim}
|
|
Program PackRecordsDemo;
|
|
type
|
|
{$PackRecords 2}
|
|
Trec1 = Record
|
|
A : byte;
|
|
B : Word;
|
|
end;
|
|
|
|
{$PackRecords 1}
|
|
Trec2 = Record
|
|
A : Byte;
|
|
B : Word;
|
|
end;
|
|
{$PackRecords 2}
|
|
Trec3 = Record
|
|
A,B : byte;
|
|
end;
|
|
|
|
{$PackRecords 1}
|
|
Trec4 = Record
|
|
A,B : Byte;
|
|
end;
|
|
{$PackRecords 4}
|
|
Trec5 = Record
|
|
A : Byte;
|
|
B : Array[1..3] of byte;
|
|
C : byte;
|
|
end;
|
|
|
|
{$PackRecords 8}
|
|
Trec6 = Record
|
|
A : Byte;
|
|
B : Array[1..3] of byte;
|
|
C : byte;
|
|
end;
|
|
{$PackRecords 4}
|
|
Trec7 = Record
|
|
A : Byte;
|
|
B : Array[1..7] of byte;
|
|
C : byte;
|
|
end;
|
|
|
|
{$PackRecords 8}
|
|
Trec8 = Record
|
|
A : Byte;
|
|
B : Array[1..7] of byte;
|
|
C : byte;
|
|
end;
|
|
Var rec1 : Trec1;
|
|
rec2 : Trec2;
|
|
rec3 : TRec3;
|
|
rec4 : TRec4;
|
|
rec5 : Trec5;
|
|
rec6 : TRec6;
|
|
rec7 : TRec7;
|
|
rec8 : TRec8;
|
|
|
|
begin
|
|
Write ('Size Trec1 : ',SizeOf(Trec1));
|
|
Writeln (' Offset B : ',Longint(@rec1.B)-Longint(@rec1));
|
|
Write ('Size Trec2 : ',SizeOf(Trec2));
|
|
Writeln (' Offset B : ',Longint(@rec2.B)-Longint(@rec2));
|
|
Write ('Size Trec3 : ',SizeOf(Trec3));
|
|
Writeln (' Offset B : ',Longint(@rec3.B)-Longint(@rec3));
|
|
Write ('Size Trec4 : ',SizeOf(Trec4));
|
|
Writeln (' Offset B : ',Longint(@rec4.B)-Longint(@rec4));
|
|
Write ('Size Trec5 : ',SizeOf(Trec5));
|
|
Writeln (' Offset B : ',Longint(@rec5.B)-Longint(@rec5),
|
|
' Offset C : ',Longint(@rec5.C)-Longint(@rec5));
|
|
Write ('Size Trec6 : ',SizeOf(Trec6));
|
|
Writeln (' Offset B : ',Longint(@rec6.B)-Longint(@rec6),
|
|
' Offset C : ',Longint(@rec6.C)-Longint(@rec6));
|
|
Write ('Size Trec7 : ',SizeOf(Trec7));
|
|
Writeln (' Offset B : ',Longint(@rec7.B)-Longint(@rec7),
|
|
' Offset C : ',Longint(@rec7.C)-Longint(@rec7));
|
|
Write ('Size Trec8 : ',SizeOf(Trec8));
|
|
Writeln (' Offset B : ',Longint(@rec8.B)-Longint(@rec8),
|
|
' Offset C : ',Longint(@rec8.C)-Longint(@rec8));
|
|
end.
|
|
\end{verbatim}
|
|
The output of this program will be :
|
|
\begin{verbatim}
|
|
Size Trec1 : 4 Offset B : 2
|
|
Size Trec2 : 3 Offset B : 1
|
|
Size Trec3 : 2 Offset B : 1
|
|
Size Trec4 : 2 Offset B : 1
|
|
Size Trec5 : 8 Offset B : 4 Offset C : 7
|
|
Size Trec6 : 8 Offset B : 4 Offset C : 7
|
|
Size Trec7 : 12 Offset B : 4 Offset C : 11
|
|
Size Trec8 : 16 Offset B : 8 Offset C : 15
|
|
\end{verbatim}
|
|
And this is as expected. In \var{Trec1}, since \var{B} has size 2, it is
|
|
aligned on a 2 byte boundary, thus leaving an empty byte between \var{A}
|
|
and \var{B}, and making the total size 4. In \var{Trec2}, \var{B} is aligned
|
|
on a 1-byte boundary, right after \var{A}, hence, the total size of the
|
|
record is 3.
|
|
For \var{Trec3}, the sizes of \var{A,B} are 1, and hence they are aligned on 1
|
|
byte boundaries. The same is true for \var{Trec4}.
|
|
For \var{Trec5}, since the size of B -- 3 -- is smaller than 4, \var{B} will
|
|
be on a 4-byte boundary, as this is the first power of two that is
|
|
larger than it's size. The same holds for \var{Trec6}.
|
|
For \var{Trec7}, \var{B} is aligned on a 4 byte boundary, since it's size --
|
|
7 -- is larger than 4. However, in \var{Trec8}, it is aligned on a 8-byte
|
|
boundary, since 8 is the first power of two that is greater than 7, thus
|
|
making the total size of the record 16.
|
|
\fpc supports also the 'packed record', this is a record where all the
|
|
elements are byte-aligned.
|
|
Thus the two following declarations are equivalent:
|
|
\begin{verbatim}
|
|
{$PackRecords 1}
|
|
Trec2 = Record
|
|
A : Byte;
|
|
B : Word;
|
|
end;
|
|
{$PackRecords 2}
|
|
\end{verbatim}
|
|
and
|
|
\begin{verbatim}
|
|
Trec2 = Packed Record
|
|
A : Byte;
|
|
B : Word;
|
|
end;
|
|
\end{verbatim}
|
|
Note the \var{\{\$PackRecords 2\}} after the first declaration !
|
|
\subsection{Set types}
|
|
\fpc supports the set types as in Turbo Pascal. The prototype of a set
|
|
declaration is:
|
|
\input{syntax/typeset.syn}
|
|
Each of the elements of \var{SetType} must be of type \var{TargetType}.
|
|
\var{TargetType} can be any ordinal type with a range between \var{0} and
|
|
\var{255}. A set can contain maximally \var{255} elements.
|
|
The following are valid set declaration:
|
|
\begin{verbatim}
|
|
Type
|
|
Junk = Set of Char;
|
|
|
|
Days = (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
|
|
WorkDays : Set of days;
|
|
\end{verbatim}
|
|
Given this set declarations, the following assignment is legal:
|
|
\begin{verbatim}
|
|
WorkDays := [ Mon, Tue, Wed, Thu, Fri];
|
|
\end{verbatim}
|
|
The operators and functions for manipulations of sets are listed in
|
|
\seet{SetOps}.
|
|
\begin{FPCltable}{lr}{Set Manipulation operators}{SetOps}
|
|
Operation & Operator \\ \hline
|
|
Union & + \\
|
|
Difference & - \\
|
|
Intersection & * \\
|
|
Add element & \var{include} \\
|
|
Delete element & \var{exclude} \\ \hline
|
|
\end{FPCltable}
|
|
Two sets can be compared with the \var{<>} and \var{=} operators, but not
|
|
(yet) with the \var{<} and \var{>} operators.
|
|
The compiler stores small sets (less than 32 elements) in a Longint, if the
|
|
type range allows it. This allows for faster processing and decreases
|
|
program size. Otherwise, sets are stored in 32 bytes.
|
|
\subsection{File types}
|
|
File types are types that store a sequence of some base type, which can be
|
|
any type except another file type. It can contain (in principle) an infinite
|
|
number of elements.
|
|
File types are used commonly to store data on disk. Nothing prevents the programmer,
|
|
however, from writing a file driver that stores it's data in memory.
|
|
Here is the type declaration for a file type:
|
|
\input{syntax/typefil.syn}
|
|
If no type identifier is given, then the file is an untyped file; it can be
|
|
considered as equivalent to a file of bytes. Untyped files require special
|
|
commands to act on them (see \seep{Blockread}, \seep{Blockwrite}).
|
|
The following declaration declares a file of records:
|
|
\begin{verbatim}
|
|
Type
|
|
Point = Record
|
|
X,Y,Z : real;
|
|
end;
|
|
PointFile = File of Point;
|
|
\end{verbatim}
|
|
Internally, files are represented by the \var{FileRec} record, which is
|
|
declared in the DOS unit.
|
|
|
|
A special file type is the \var{Text} file type, represented by the
|
|
\var{TextRec} record. A file of type \var{Text} uses special input-output
|
|
routines.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Pointers
|
|
\section{Pointers}
|
|
\fpc supports the use of pointers. A variable of the pointer type
|
|
contains an address in memory, where the data of another variable may be
|
|
stored.
|
|
\input{syntax/typepoin.syn}
|
|
As can be seen from this diagram, pointers are typed, which means that
|
|
they point to a particular kind of data. The type of this data must be
|
|
known at compile time.
|
|
Dereferencing the pointer (denoted by adding \var{\^{}} after the variable
|
|
name) behaves then like a variable. This variable has the type declared in
|
|
the pointer declaration, and the variable is stored in the address that is
|
|
pointed to by the pointer variable.
|
|
Consider the following example:
|
|
\begin{verbatim}
|
|
Program pointers;
|
|
type
|
|
Buffer = String[255];
|
|
BufPtr = ^Buffer;
|
|
Var B : Buffer;
|
|
BP : BufPtr;
|
|
PP : Pointer;
|
|
etc..
|
|
\end{verbatim}
|
|
In this example, \var{BP} {\em is a pointer to} a \var{Buffer} type; while \var{B}
|
|
{\em is} a variable of type \var{Buffer}. \var{B} takes 256 bytes memory,
|
|
and \var{BP} only takes 4 bytes of memory (enough to keep an adress in
|
|
memory).
|
|
\begin{remark} \fpc treats pointers much the same way as C does. This means
|
|
that a pointer to some type can be treated as being an array of this type.
|
|
The pointer then points to the zeroeth element of this array. Thus the
|
|
following pointer declaration
|
|
\begin{verbatim}
|
|
Var p : ^Longint;
|
|
\end{verbatim}
|
|
Can be considered equivalent to the following array declaration:
|
|
\begin{verbatim}
|
|
Var p : array[0..Infinity] of Longint;
|
|
\end{verbatim}
|
|
The difference is that the former declaration allocates memory for the
|
|
pointer only (not for the array), and the second declaration allocates
|
|
memory for the entire array. If the former is used, the memory must be
|
|
allocated manually, using the \seep{Getmem} function.
|
|
The reference \var{P\^{}} is then the same as \var{p[0]}. The following program
|
|
illustrates this maybe more clear:
|
|
\begin{verbatim}
|
|
program PointerArray;
|
|
var i : Longint;
|
|
p : ^Longint;
|
|
pp : array[0..100] of Longint;
|
|
begin
|
|
for i := 0 to 100 do pp[i] := i; { Fill array }
|
|
p := @pp[0]; { Let p point to pp }
|
|
for i := 0 to 100 do
|
|
if p[i]<>pp[i] then
|
|
WriteLn ('Ohoh, problem !')
|
|
end.
|
|
\end{verbatim}
|
|
\end{remark}
|
|
\fpc supports pointer arithmetic as C does. This means that, if \var{P} is a
|
|
typed pointer, the instructions
|
|
\begin{verbatim}
|
|
Inc(P);
|
|
Dec(P);
|
|
\end{verbatim}
|
|
Will increase, respectively decrease the address the pointer points to
|
|
with the size of the type \var{P} is a pointer to. For example
|
|
\begin{verbatim}
|
|
Var P : ^Longint;
|
|
...
|
|
Inc (p);
|
|
\end{verbatim}
|
|
will increase \var{P} with 4.
|
|
Normal arithmetic operators on pointers can also be used, that is, the
|
|
following are valid pointer arithmetic operations:
|
|
\begin{verbatim}
|
|
var p1,p2 : ^Longint;
|
|
L : Longint;
|
|
begin
|
|
P1 := @P2;
|
|
P2 := @L;
|
|
L := P1-P2;
|
|
P1 := P1-4;
|
|
P2 := P2+4;
|
|
end.
|
|
\end{verbatim}
|
|
Here, the value that is added or substracted {\em is } multiplied by the
|
|
size of the type the pointer points to. In the previous
|
|
example \var{P1} will be decremented by 16 bytes, and
|
|
\var{P2} will be incremented by 16.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Forward type declarations
|
|
\section{Forward type declarations}
|
|
Programs often need to maintain a linked list of records. Each record then
|
|
contains a pointer to the next record (and possibly to the previous record
|
|
as well). For type safety, it is best to define this pointer as a typed
|
|
pointer, so the next record can be allocated on the heap using the \var{New}
|
|
call. In order to do so, the record should be defined something like this:
|
|
\begin{verbatim}
|
|
Type
|
|
TListItem = Record
|
|
Data : Integer;
|
|
Next : ^TListItem;
|
|
end;
|
|
\end{verbatim}
|
|
When trying to compile this, the compiler will complain that the
|
|
\var{TListItem} type is not yet defined when it encounters the \var{Next}
|
|
declaration: This is correct, as the definition is still being parsed.
|
|
|
|
To be able to have the \var{Next} element as a typed pointer, a 'Forward
|
|
type declaration' must be introduced:
|
|
\begin{verbatim}
|
|
Type
|
|
PListItem = ^TListItem;
|
|
TListItem = Record
|
|
Data : Integer;
|
|
Next : PTListItem;
|
|
end;
|
|
\end{verbatim}
|
|
When the compiler encounters a typed pointer declaration where the
|
|
referenced type is not yet known, it postpones resolving the reference later
|
|
on: The pointer definition is a 'Forward type declaration'. The referenced
|
|
type should be introduced later in the same \var{Type} block. No other block
|
|
may come between the definition of the pointer type and the referenced type.
|
|
Indeed, even the word \var{Type} itself may not re-appear: in effect it
|
|
would start a new type-block, causing the compiler to resolve all pending
|
|
declarations in the current block. In most cases, the definition of the
|
|
referenced type will follow immediatly after the definition of the pointer
|
|
type, as shown in the above listing. The forward defined type can be used in
|
|
any type definition following its declaration.
|
|
|
|
Note that a forward type declaration is only possible with pointer types and
|
|
classes, not with other types.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Procedural types
|
|
\section{Procedural types}
|
|
\fpc has support for procedural types, although it differs a little from
|
|
the Turbo Pascal implementation of them. The type declaration remains the
|
|
same, as can be seen in the following syntax diagram:
|
|
\input{syntax/typeproc.syn}
|
|
For a description of formal parameter lists, see \seec{Procedures}.
|
|
The two following examples are valid type declarations:
|
|
\begin{verbatim}
|
|
Type TOneArg = Procedure (Var X : integer);
|
|
TNoArg = Function : Real;
|
|
var proc : TOneArg;
|
|
func : TNoArg;
|
|
\end{verbatim}
|
|
One can assign the following values to a procedural type variable:
|
|
\begin{enumerate}
|
|
\item \var{Nil}, for both normal procedure pointers and method pointers.
|
|
\item A variable reference of a procedural type, i.e. another variable of
|
|
the same type.
|
|
\item A global procedure or function address, with matching function or
|
|
procedure header and calling convention.
|
|
\item A method address.
|
|
\end{enumerate}
|
|
Given these declarations, the following assignments are valid:
|
|
\begin{verbatim}
|
|
Procedure printit (Var X : Integer);
|
|
begin
|
|
WriteLn (x);
|
|
end;
|
|
...
|
|
Proc := @printit;
|
|
Func := @Pi;
|
|
\end{verbatim}
|
|
From this example, the difference with Turbo Pascal is clear: In Turbo
|
|
Pascal it isn't necessary to use the address operator (\var{@})
|
|
when assigning a procedural type variable, whereas in \fpc it is required
|
|
(unless the \var{-So} switch is used, in which case the address
|
|
operator can be dropped.)
|
|
\begin{remark} The modifiers concerning the calling conventions
|
|
must be the same as the declaration;
|
|
i.e. the following code would give an error:
|
|
\begin{verbatim}
|
|
Type TOneArgCcall = Procedure (Var X : integer);cdecl;
|
|
var proc : TOneArgCcall;
|
|
Procedure printit (Var X : Integer);
|
|
begin
|
|
WriteLn (x);
|
|
end;
|
|
begin
|
|
Proc := @printit;
|
|
end.
|
|
\end{verbatim}
|
|
Because the \var{TOneArgCcall} type is a procedure that uses the cdecl
|
|
calling convention.
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Variant types
|
|
\section{Variant types}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Definition
|
|
\subsection{Definition}
|
|
As of version 1.1, FPC has support for variants. For variant support to be
|
|
enabled, the \file{variants} unit must be included in every unit that uses
|
|
variants in some way. Furthermore, the compiler must be in \var{Delphi} or
|
|
\var{ObjFPC} mode.
|
|
|
|
The type of a value stored in a variant is only determined at runtime:
|
|
it depends what has been assigned to the to the variant. Almost any type
|
|
can be assigned to variants: ordinal types, string types, int64 types.
|
|
Structured types such as sets, records, arrays, files, objects and classes
|
|
are not assign-compatible with a variant, as well as pointers. Interfaces
|
|
and COM or CORBA objects can be assigned to a variant.
|
|
|
|
This means that the following assignments are valid:
|
|
\begin{verbatim}
|
|
Type
|
|
TMyEnum = (One,Two,Three);
|
|
|
|
Var
|
|
V : Variant;
|
|
I : Integer;
|
|
B : Byte;
|
|
W : Word;
|
|
Q : Int64;
|
|
E : Extended;
|
|
D : Double;
|
|
En : TMyEnum;
|
|
AS : AnsiString;
|
|
WS : WideString;
|
|
|
|
begin
|
|
V:=I;
|
|
V:=B;
|
|
V:=W;
|
|
V:=Q;
|
|
V:=E;
|
|
V:=En;
|
|
V:=D:
|
|
V:=AS;
|
|
V:=WS;
|
|
end;
|
|
\end{verbatim}
|
|
And of course vice-versa as well.
|
|
\begin{remark}
|
|
The enumerated type assignment is broken in the early 1.1 development series of the
|
|
compiler. It is expected that this is fixed soon.
|
|
\end{remark}
|
|
|
|
A variant can hold an an array of values: All elements in the array have the
|
|
same type (but can be of type 'variant'). For a variant that contains an
|
|
array, the variant can be indexed:
|
|
\begin{verbatim}
|
|
Program testv;
|
|
|
|
uses variants;
|
|
|
|
Var
|
|
A : Variant;
|
|
I : integer;
|
|
|
|
begin
|
|
A:=VarArrayCreate([1,10],varInteger);
|
|
For I:=1 to 10 do
|
|
A[I]:=I;
|
|
end.
|
|
\end{verbatim}
|
|
(for the explanation of \var{VarArrayCreate}, see \unitsref.)
|
|
|
|
Note that when the array contains a string, this is not considered an 'array
|
|
of characters', and so the variant cannot be indexed to retrieve a character
|
|
at a certain position in the string.
|
|
|
|
\begin{remark}
|
|
The array functionality is broken in the early 1.1 development series of the
|
|
compiler. It is expected that this is fixed soon.
|
|
\end{remark}
|
|
|
|
\subsection{Variants in assignments and expressions}
|
|
As can be seen from the definition above, most simple types can be assigned
|
|
to a variant. Likewise, a variant can be assigned to a simple type: If
|
|
possible, the value of the variant will be converted to the type that is
|
|
being assigned to. This may fail: Assigning a variant containing a string
|
|
to an integer will fail unless the string represents a valid integer. In the
|
|
following example, the first assignment will work, the second will fail:
|
|
\begin{verbatim}
|
|
program testv3;
|
|
|
|
uses Variants;
|
|
|
|
Var
|
|
V : Variant;
|
|
I : Integer;
|
|
|
|
begin
|
|
V:='100';
|
|
I:=V;
|
|
Writeln('I : ',I);
|
|
V:='Something else';
|
|
I:=V;
|
|
Writeln('I : ',I);
|
|
end.
|
|
\end{verbatim}
|
|
The first assignment will work, but the second will not, as \var{Something else}
|
|
cannot be converted to a valid integer value. An \var{EConvertError} exception
|
|
will be the result.
|
|
|
|
The result of an expression involving a variant will be of type variant again,
|
|
but this can be assigned to a variable of a different type - if the result
|
|
can be converted to a variable of this type.
|
|
|
|
Note that expressions involving variants take more time to be evaluated, and
|
|
should therefore be used with caution. If a lot of calculations need to be
|
|
made, it is best to avoid the use of variants.
|
|
|
|
When considering implicit type conversions (e.g. byte to integer, integer to
|
|
double, char to string) the compiler will ignore variants unless a variant
|
|
appears explicitly in the expression.
|
|
|
|
\subsection{Variants and interfaces}
|
|
|
|
\begin{remark}
|
|
Dispatch interface support for variants is currently broken in the compiler.
|
|
\end{remark}
|
|
|
|
Variants can contain a reference to an interface - a normal interface
|
|
(descending from \var{IInterface}) or a dispatchinterface (descending
|
|
from \var{IDispatch}). Variants containing a reference to a dispatch
|
|
interface can be used to control the object behind it: the compiler will use
|
|
late binding to perform the call to the dispatch interface: there will be no
|
|
run-time checking of the function names and parameters or arguments given to
|
|
the functions. The result type is also not checked. The compiler will simply
|
|
insert code to make the dispatch call and retrieve the result.
|
|
|
|
This means basically, that you can do the following on Windows:
|
|
\begin{verbatim}
|
|
Var
|
|
W : Variant;
|
|
V : String;
|
|
|
|
begin
|
|
W:=CreateOleObject('Word.Application');
|
|
V:=W.Application.Version;
|
|
Writeln('Installed version of MS Word is : ',V);
|
|
end;
|
|
\end{verbatim}
|
|
The line
|
|
\begin{verbatim}
|
|
V:=W.Application.Version;
|
|
\end{verbatim}
|
|
is executed by inserting the necessary code to query the dispatch interface
|
|
stored in the variant \var{W}, and execute the call if the needed dispatch
|
|
information is found.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Variables
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Variables}
|
|
\label{ch:Variables}
|
|
\section{Definition}
|
|
Variables are explicitly named memory locations with a certain type. When
|
|
assigning values to variables, the \fpc compiler generates machine code
|
|
to move the value to the memory location reserved for this variable. Where
|
|
this variable is stored depends on where it is declared:
|
|
|
|
\begin{itemize}
|
|
\item Global variables are variables declared in a unit or program, but not
|
|
inside a procedure or function. They are stored in fixed memory locations,
|
|
and are available during the whole execution time of the program.
|
|
\item Local variables are declared inside a procedure or function. Their
|
|
value is stored on the program stack, i.e. not at fixed locations.
|
|
\end{itemize}
|
|
|
|
The \fpc compiler handles the allocation of these memory locations
|
|
transparantly, although this location can be influenced in the declaration.
|
|
|
|
The \fpc compiler also handles reading values from or writing values to
|
|
the variables transparantly. But even this can be explicitly handled by the
|
|
programmer when using properties.
|
|
|
|
Variables must be explicitly declared when they are needed. No memory is
|
|
allocated unless a variable is declared. Using an variable identifier (for
|
|
instance, a loop variable) which is not declared first, is an error which
|
|
will be reported by the compiler.
|
|
|
|
\section{Declaration}
|
|
The variables must be declared in a variable declaration section of a unit
|
|
or a procedure or function. It looks as follows:
|
|
\input{syntax/vardecl.syn}
|
|
|
|
This means that the following are valid variable declarations:
|
|
\begin{verbatim}
|
|
Var
|
|
curterm1 : integer;
|
|
|
|
curterm2 : integer; cvar;
|
|
curterm3 : integer; cvar; external;
|
|
|
|
curterm4 : integer; external name 'curterm3';
|
|
curterm5 : integer; external 'libc' name 'curterm9';
|
|
|
|
curterm6 : integer absolute curterm1;
|
|
|
|
curterm7 : integer; cvar; export;
|
|
curterm8 : integer; cvar; public;
|
|
curterm9 : integer; export name 'me';
|
|
curterm10 : integer; public name 'ma';
|
|
|
|
curterm11 : integer = 1 ;
|
|
\end{verbatim}
|
|
|
|
The difference between these declarations is as follows:
|
|
\begin{enumerate}
|
|
\item The first form (\var{curterm1}) defines a regular variable. The
|
|
compiler manages everything by itself.
|
|
\item The second form (\var{curterm2}) declares also a regular variable,
|
|
but specifies that the assembler name for this variable equals the name
|
|
of the variable as written in the source.
|
|
\item The third form (\var{curterm3}) declares a variable which is located
|
|
externally: the compiler will assume memory is located elsewhere, and that
|
|
the assembler name of this location is specified by the name of the
|
|
variable, as written in the source. The name may not be specified.
|
|
\item The fourth form is completely equivalent to the third, it declares a
|
|
variable which is stored externally, and explicitly gives the assembler
|
|
name of the location. If \var{cvar} is not used, the name must be specified.
|
|
\item The fifth form is a variant of the fourth form, only the name of the
|
|
library in which the memory is reserved is specified as well.
|
|
\item The sixth form declares a variable (\var{curterm6}), and tells the compiler that it is
|
|
stored in the same location as another variable (\var{curterm1})
|
|
\item The seventh form declares a variable (\var{curterm7}), and tells the
|
|
compiler that the assembler label of this variable should be the name of the
|
|
variable (case sensitive) and must be made public. (i.e. it can be
|
|
referenced from other object files)
|
|
\item The eight form (\var{curterm8}) is equivalent to the seventh: 'public'
|
|
is an alias for 'export'.
|
|
\item The ninth and tenth form are equivalent: they specify the assembler
|
|
name of the variable.
|
|
\item the elevents form declares a variable (\var{curterm11}) and
|
|
initializes it with a value (1 in the above case).
|
|
\end{enumerate}
|
|
Note that assembler names must be unique. It's not possible to declare or
|
|
export 2 variables with the same assembler name.
|
|
|
|
\section{Scope}
|
|
Variables, just as any identifier, obey the general rules of scope.
|
|
In addition, initialized variables are initialized when they enter scope:
|
|
\begin{itemize}
|
|
\item Global initialized variables are initialized once, when the program starts.
|
|
\item Local initialized variables are initialized each time the procedure is
|
|
entered.
|
|
\end{itemize}
|
|
Note that the behaviour for local initialized variables is different from
|
|
the one of a local typed constant. A local typed constant behaves like a
|
|
global initialized variable.
|
|
|
|
\section{Properties}
|
|
A global block can declare properties, just as they could be defined in a
|
|
class. The difference is that the global property does not need a class
|
|
instance: there is only 1 instance of this property. Other than that, a
|
|
global property behaves like a class property. The read/write specifiers for
|
|
the global property must also be regular procedures, not methods.
|
|
The concept of a global property is specific to \fpc, and does not exist in
|
|
Delphi.
|
|
|
|
The concept of a global property can be used to 'hide' the location of the
|
|
value, or to calculate the value on the fly, or to check the values which
|
|
are written to the property.
|
|
|
|
The declaration is as follows:
|
|
\input{syntax/propvar.syn}
|
|
|
|
The following is an example:
|
|
\begin{verbatim}
|
|
{$mode objfpc}
|
|
unit testprop;
|
|
|
|
Interface
|
|
|
|
Function GetMyInt : Integer;
|
|
Procedure SetMyInt(Value : Integer);
|
|
|
|
Property
|
|
MyProp : Integer Read GetMyInt Write SetMyInt;
|
|
|
|
Implementation
|
|
|
|
Uses sysutils;
|
|
|
|
Var
|
|
FMyInt : Integer;
|
|
|
|
Function GetMyInt : Integer;
|
|
|
|
begin
|
|
Result:=FMyInt;
|
|
end;
|
|
|
|
Procedure SetMyInt(Value : Integer);
|
|
|
|
begin
|
|
If ((Value mod 2)=1) then
|
|
Raise Exception.Create('MyProp can only contain even value');
|
|
FMyInt:=Value;
|
|
end;
|
|
|
|
end.
|
|
\end{verbatim}
|
|
|
|
The read/write specifiers can be hidden by declaring them in another unit
|
|
which must be in the \var{uses} clause of the unit. This can be used to hide
|
|
the read/write access specifiers for programmers, just as if they were in a
|
|
\var{private} section of a class (discussed below). For the previous
|
|
example, this could look as follows:
|
|
\begin{verbatim}
|
|
{$mode objfpc}
|
|
unit testrw;
|
|
|
|
Interface
|
|
|
|
Function GetMyInt : Integer;
|
|
Procedure SetMyInt(Value : Integer);
|
|
|
|
Implementation
|
|
|
|
Uses sysutils;
|
|
|
|
Var
|
|
FMyInt : Integer;
|
|
|
|
Function GetMyInt : Integer;
|
|
|
|
begin
|
|
Result:=FMyInt;
|
|
end;
|
|
|
|
Procedure SetMyInt(Value : Integer);
|
|
|
|
begin
|
|
If ((Value mod 2)=1) then
|
|
Raise Exception.Create('Only even values are allowed');
|
|
FMyInt:=Value;
|
|
end;
|
|
|
|
end.
|
|
\end{verbatim}
|
|
The unit \file{testprop} would then look like:
|
|
\begin{verbatim}
|
|
{$mode objfpc}
|
|
unit testprop;
|
|
|
|
Interface
|
|
|
|
uses testrw;
|
|
|
|
Property
|
|
MyProp : Integer Read GetMyInt Write SetMyInt;
|
|
|
|
Implementation
|
|
|
|
end.
|
|
\end{verbatim}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Objects
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Objects}
|
|
\label{ch:Objects}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Declaration
|
|
\section{Declaration}
|
|
\fpc supports object oriented programming. In fact, most of the compiler is
|
|
written using objects. Here we present some technical questions regarding
|
|
object oriented programming in \fpc.
|
|
Objects should be treated as a special kind of record. The record contains
|
|
all the fields that are declared in the objects definition, and pointers
|
|
to the methods that are associated to the objects' type.
|
|
|
|
An object is declared just as a record would be declared; except that
|
|
now,procedures and functions can be declared as if they were part of the record.
|
|
Objects can ''inherit'' fields and methods from ''parent'' objects. This means
|
|
that these fields and methods can be used as if they were included in the
|
|
objects declared as a ''child'' object.
|
|
|
|
Furthermore, a concept of visibility is introduced: fields, procedures and functions
|
|
can be delcared as \var{public} or \var{private}. By default, fields and
|
|
methods are \var{public}, and are
|
|
exported outside the current unit. Fields or methods that are declared
|
|
\var{private} are only accessible in the current unit.
|
|
The prototype declaration of an object is as follows:
|
|
\input{syntax/typeobj.syn}
|
|
As can be seen, as many \var{private} and \var{public} blocks as needed can be
|
|
declared.
|
|
\var{Method definitions} are normal function or procedure declarations.
|
|
Fields cannot be declared after methods in the same block, i.e. the following
|
|
will generate an error when compiling:
|
|
\begin{verbatim}
|
|
Type MyObj = Object
|
|
Procedure Doit;
|
|
Field : Longint;
|
|
end;
|
|
\end{verbatim}
|
|
But the following will be accepted:
|
|
\begin{verbatim}
|
|
Type MyObj = Object
|
|
Public
|
|
Procedure Doit;
|
|
Private
|
|
Field : Longint;
|
|
end;
|
|
\end{verbatim}
|
|
because the field is in a different section.
|
|
|
|
\begin{remark}
|
|
\fpc also supports the packed object. This is the same as an object, only
|
|
the elements (fields) of the object are byte-aligned, just as in the packed
|
|
record.
|
|
The declaration of a packed object is similar to the declaration
|
|
of a packed record :
|
|
\begin{verbatim}
|
|
Type
|
|
TObj = packed object;
|
|
Constructor init;
|
|
...
|
|
end;
|
|
Pobj = ^TObj;
|
|
Var PP : Pobj;
|
|
\end{verbatim}
|
|
Similarly, the \var{\{\$PackRecords \}} directive acts on objects as well.
|
|
\end{remark}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Fields
|
|
\section{Fields}
|
|
Object Fields are like record fields. They are accessed in the same way as
|
|
a record field would be accessed : by using a qualified identifier. Given the
|
|
following declaration:
|
|
\begin{verbatim}
|
|
Type TAnObject = Object
|
|
AField : Longint;
|
|
Procedure AMethod;
|
|
end;
|
|
Var AnObject : TAnObject;
|
|
\end{verbatim}
|
|
then the following would be a valid assignment:
|
|
\begin{verbatim}
|
|
AnObject.AField := 0;
|
|
\end{verbatim}
|
|
Inside methods, fields can be accessed using the short identifier:
|
|
\begin{verbatim}
|
|
Procedure TAnObject.AMethod;
|
|
begin
|
|
...
|
|
AField := 0;
|
|
...
|
|
end;
|
|
\end{verbatim}
|
|
Or, one can use the \var{self} identifier. The \var{self} identifier refers
|
|
to the current instance of the object:
|
|
\begin{verbatim}
|
|
Procedure TAnObject.AMethod;
|
|
begin
|
|
...
|
|
Self.AField := 0;
|
|
...
|
|
end;
|
|
\end{verbatim}
|
|
One cannot access fields that are in a private section of an object from
|
|
outside the objects' methods. If this is attempted anyway, the compiler will complain about
|
|
an unknown identifier.
|
|
It is also possible to use the \var{with} statement with an object instance:
|
|
\begin{verbatim}
|
|
With AnObject do
|
|
begin
|
|
Afield := 12;
|
|
AMethod;
|
|
end;
|
|
\end{verbatim}
|
|
In this example, between the \var{begin} and \var{end}, it is as if
|
|
\var{AnObject} was prepended to the \var{Afield} and \var{Amethod}
|
|
identifiers. More about this in \sees{With}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Constructors and destructors
|
|
\section{Constructors and destructors }
|
|
\label{se:constructdestruct}
|
|
As can be seen in the syntax diagram for an object declaration, \fpc supports
|
|
constructors and destructors. The programmer is responsible for calling the
|
|
constructor and the destructor explicitly when using objects.
|
|
The declaration of a constructor or destructor is as follows:
|
|
\input{syntax/construct.syn}
|
|
A constructor/destructor pair is {\em required} if the object uses virtual methods.
|
|
In the declaration of the object type, a simple identifier should be used
|
|
for the name of the constuctor or destructor. When the constructor or destructor
|
|
is implemented, A qualified method identifier should be used,
|
|
i.e. an identifier of the form \var{objectidentifier.methodidentifier}.
|
|
\fpc supports also the extended syntax of the \var{New} and \var{Dispose}
|
|
procedures. In case a dynamic variable of an object type must be allocated
|
|
the constructor's name can be specified in the call to \var{New}.
|
|
The \var{New} is implemented as a function which returns a pointer to the
|
|
instantiated object. Consider the following declarations:
|
|
\begin{verbatim}
|
|
Type
|
|
TObj = object;
|
|
Constructor init;
|
|
...
|
|
end;
|
|
Pobj = ^TObj;
|
|
Var PP : Pobj;
|
|
\end{verbatim}
|
|
Then the following 3 calls are equivalent:
|
|
\begin{verbatim}
|
|
pp := new (Pobj,Init);
|
|
\end{verbatim}
|
|
and
|
|
\begin{verbatim}
|
|
new(pp,init);
|
|
\end{verbatim}
|
|
and also
|
|
\begin{verbatim}
|
|
new (pp);
|
|
pp^.init;
|
|
\end{verbatim}
|
|
In the last case, the compiler will issue a warning that the
|
|
extended syntax of \var{new} and \var{dispose} must be used to generate instances of an
|
|
object. It is possible to ignore this warning, but it's better programming practice to
|
|
use the extended syntax to create instances of an object.
|
|
Similarly, the \var{Dispose} procedure accepts the name of a destructor. The
|
|
destructor will then be called, before removing the object from the heap.
|
|
|
|
In view of the compiler warning remark, the following chapter presents the
|
|
Delphi approach to object-oriented programming, and may be considered a
|
|
more natural way of object-oriented programming.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Methods
|
|
\section{Methods}
|
|
Object methods are just like ordinary procedures or functions, only they
|
|
have an implicit extra parameter : \var{self}. Self points to the object
|
|
with which the method was invoked.
|
|
When implementing methods, the fully qualified identifier must be given
|
|
in the function header. When declaring methods, a normal identifier must be
|
|
given.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Method invocation
|
|
\section{Method invocation}
|
|
Methods are called just as normal procedures are called, only they have an
|
|
object instance identifier prepended to them (see also \seec{Statements}).
|
|
To determine which method is called, it is necessary to know the type of
|
|
the method. We treat the different types in what follows.
|
|
\subsubsection{Static methods}
|
|
Static methods are methods that have been declared without a \var{abstract}
|
|
or \var{virtual} keyword. When calling a static method, the declared (i.e.
|
|
compile time) method of the object is used.
|
|
For example, consider the following declarations:
|
|
\begin{verbatim}
|
|
Type
|
|
TParent = Object
|
|
...
|
|
procedure Doit;
|
|
...
|
|
end;
|
|
PParent = ^TParent;
|
|
TChild = Object(TParent)
|
|
...
|
|
procedure Doit;
|
|
...
|
|
end;
|
|
PChild = ^TChild;
|
|
\end{verbatim}
|
|
As it is visible, both the parent and child objects have a method called
|
|
\var{Doit}. Consider now the following declarations and calls:
|
|
\begin{verbatim}
|
|
Var ParentA,ParentB : PParent;
|
|
Child : PChild;
|
|
ParentA := New(PParent,Init);
|
|
ParentB := New(PChild,Init);
|
|
Child := New(PChild,Init);
|
|
ParentA^.Doit;
|
|
ParentB^.Doit;
|
|
Child^.Doit;
|
|
\end{verbatim}
|
|
Of the three invocations of \var{Doit}, only the last one will call
|
|
\var{TChild.Doit}, the other two calls will call \var{TParent.Doit}.
|
|
This is because for static methods, the compiler determines at compile
|
|
time which method should be called. Since \var{ParentB} is of type
|
|
\var{TParent}, the compiler decides that it must be called with
|
|
\var{TParent.Doit}, even though it will be created as a \var{TChild}.
|
|
There may be times when the method that is actually called should
|
|
depend on the actual type of the object at run-time. If so, the method
|
|
cannot be a static method, but must be a virtual method.
|
|
\subsubsection{Virtual methods}
|
|
To remedy the situation in the previous section, \var{virtual} methods are
|
|
created. This is simply done by appending the method declaration with the
|
|
\var{virtual} modifier.
|
|
Going back to the previous example, consider the following alternative
|
|
declaration:
|
|
\begin{verbatim}
|
|
Type
|
|
TParent = Object
|
|
...
|
|
procedure Doit;virtual;
|
|
...
|
|
end;
|
|
PParent = ^TParent;
|
|
TChild = Object(TParent)
|
|
...
|
|
procedure Doit;virtual;
|
|
...
|
|
end;
|
|
PChild = ^TChild;
|
|
\end{verbatim}
|
|
As it is visible, both the parent and child objects have a method called
|
|
\var{Doit}. Consider now the following declarations and calls :
|
|
\begin{verbatim}
|
|
Var ParentA,ParentB : PParent;
|
|
Child : PChild;
|
|
ParentA := New(PParent,Init);
|
|
ParentB := New(PChild,Init);
|
|
Child := New(PChild,Init);
|
|
ParentA^.Doit;
|
|
ParentB^.Doit;
|
|
Child^.Doit;
|
|
\end{verbatim}
|
|
Now, different methods will be called, depending on the actual run-time type
|
|
of the object. For \var{ParentA}, nothing changes, since it is created as
|
|
a \var{TParent} instance. For \var{Child}, the situation also doesn't
|
|
change: it is again created as an instance of \var{TChild}.
|
|
For \var{ParentB} however, the situation does change: Even though it was
|
|
declared as a \var{TParent}, it is created as an instance of \var{TChild}.
|
|
Now, when the program runs, before calling \var{Doit}, the program
|
|
checks what the actual type of \var{ParentB} is, and only then decides which
|
|
method must be called. Seeing that \var{ParentB} is of type \var{TChild},
|
|
\var{TChild.Doit} will be called.
|
|
The code for this run-time checking of the actual type of an object is
|
|
inserted by the compiler at compile time.
|
|
The \var{TChild.Doit} is said to {\em override} the \var{TParent.Doit}.
|
|
It is possible to acces the \var{TParent.Doit} from within the
|
|
var{TChild.Doit}, with the \var{inherited} keyword:
|
|
\begin{verbatim}
|
|
Procedure TChild.Doit;
|
|
begin
|
|
inherited Doit;
|
|
...
|
|
end;
|
|
\end{verbatim}
|
|
In the above example, when \var{TChild.Doit} is called, the first thing it
|
|
does is call \var{TParent.Doit}. The inherited keyword cannot be used in
|
|
static methods, only on virtual methods.
|
|
\subsubsection{Abstract methods}
|
|
An abstract method is a special kind of virtual method. A method can not be
|
|
abstract if it is not virtual (this is not obvious from the syntax diagram).
|
|
An instance of an object that has an abstract method cannot be created directly.
|
|
The reason is obvious: there is no method where the compiler could jump to !
|
|
A method that is declared \var{abstract} does not have an implementation for
|
|
this method. It is up to inherited objects to override and implement this
|
|
method. Continuing our example, take a look at this:
|
|
\begin{verbatim}
|
|
Type
|
|
TParent = Object
|
|
...
|
|
procedure Doit;virtual;abstract;
|
|
...
|
|
end;
|
|
PParent=^TParent;
|
|
TChild = Object(TParent)
|
|
...
|
|
procedure Doit;virtual;
|
|
...
|
|
end;
|
|
PChild = ^TChild;
|
|
\end{verbatim}
|
|
As it is visible, both the parent and child objects have a method called
|
|
\var{Doit}. Consider now the following declarations and calls :
|
|
\begin{verbatim}
|
|
Var ParentA,ParentB : PParent;
|
|
Child : PChild;
|
|
ParentA := New(PParent,Init);
|
|
ParentB := New(PChild,Init);
|
|
Child := New(PChild,Init);
|
|
ParentA^.Doit;
|
|
ParentB^.Doit;
|
|
Child^.Doit;
|
|
\end{verbatim}
|
|
First of all, Line 3 will generate a compiler error, stating that one cannot
|
|
generate instances of objects with abstract methods: The compiler has
|
|
detected that \var{PParent} points to an object which has an abstract
|
|
method. Commenting line 3 would allow compilation of the program.
|
|
\begin{remark}
|
|
If an abstract method is overridden, The parent method cannot be called
|
|
with \var{inherited}, since there is no parent method; The compiler
|
|
will detect this, and complain about it, like this:
|
|
\begin{verbatim}
|
|
testo.pp(32,3) Error: Abstract methods can't be called directly
|
|
\end{verbatim}
|
|
If, through some mechanism, an abstract method is called at run-time,
|
|
then a run-time error will occur. (run-time error 211, to be precise)
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Visibility
|
|
\section{Visibility}
|
|
For objects, 3 visibility specifiers exist : \var{private}, \var{protected} and
|
|
\var{public}. If a visibility specifier is not specified, \var{public}
|
|
is assumed.
|
|
Both methods and fields can be hidden from a programmer by putting them
|
|
in a \var{private} section. The exact visibility rule is as follows:
|
|
\begin{description}
|
|
\item [Private\ ] All fields and methods that are in a \var{private} block,
|
|
can only be accessed in the module (i.e. unit or program) that contains
|
|
the object definition.
|
|
They can be accessed from inside the object's methods or from outside them
|
|
e.g. from other objects' methods, or global functions.
|
|
\item [Protected\ ] Is the same as \var{Private}, except that the members of
|
|
a \var{Protected} section are also accessible to descendent types, even if
|
|
they are implemented in other modules.
|
|
\item [Public\ ] sections are always accessible, from everywhere.
|
|
Fields and metods in a \var{public} section behave as though they were part
|
|
of an ordinary \var{record} type.
|
|
\end{description}
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Classes
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Classes}
|
|
\label{ch:Classes}
|
|
In the Delphi approach to Object Oriented Programming, everything revolves
|
|
around the concept of 'Classes'. A class can be seen as a pointer to an
|
|
object, or a pointer to a record.
|
|
|
|
\begin{remark}
|
|
In earlier versions of \fpc it was necessary, in order to use classes,
|
|
to put the \file{objpas} unit in the uses clause of a unit or program.
|
|
{\em This is no longer needed} as of version 0.99.12. As of version 0.99.12
|
|
the \file{system} unit contains the basic definitions of \var{TObject}
|
|
and \var{TClass}, as well as some auxiliary methods for using classes.
|
|
The \file{objpas} unit still exists, and contains some redefinitions of
|
|
basic types, so they coincide with Delphi types. The unit will be loaded
|
|
automatically when the \var{-S2} or \var{-Sd} options are specified.
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Class definitions
|
|
\section{Class definitions}
|
|
The prototype declaration of a class is as follows :
|
|
\input{syntax/typeclas.syn}
|
|
As many \var{private}, \var{protected}, \var{published}
|
|
and \var{public} blocks as needed can be repeated.
|
|
Methods are normal function or procedure declarations.
|
|
As can be seen, the declaration of a class is almost identical to the
|
|
declaration of an object. The real difference between objects and classes
|
|
is in the way they are created (see further in this chapter).
|
|
The visibility of the different sections is as follows:
|
|
\begin{description}
|
|
\item [Private\ ] All fields and methods that are in a \var{private} block, can
|
|
only be accessed in the module (i.e. unit) that contains the class definition.
|
|
They can be accessed from inside the classes' methods or from outside them
|
|
(e.g. from other classes' methods)
|
|
\item [Protected\ ] Is the same as \var{Private}, except that the members of
|
|
a \var{Protected} section are also accessible to descendent types, even if
|
|
they are implemented in other modules.
|
|
\item [Public\ ] sections are always accessible.
|
|
\item [Published\ ] Is the same as a \var{Public} section, but the compiler
|
|
generates also type information that is needed for automatic streaming of
|
|
these classes. Fields defined in a \var{published} section must be of class type.
|
|
Array peroperties cannot be in a \var{published} section.
|
|
\end{description}
|
|
|
|
It is also possible to define class reference types:
|
|
\input{syntax/classref.syn}
|
|
Class reference types are used to create instances of a certain class, which
|
|
is not yet known at compile time, but which is specified at run time.
|
|
Essentially, a variable of a class reference type contains a pointer to the
|
|
VMT of the speficied class. This can be used to construct an instance of the
|
|
class corresponding to the VMT. The following example shows how it works:
|
|
\begin{verbatim}
|
|
Type
|
|
TComponentClass = Class of TComponent;
|
|
|
|
Function CreateComponent(AClass : TComponentClass; AOwner : TComponent) : TComponent;
|
|
|
|
begin
|
|
// ...
|
|
Result:=AClass.Create(AOwner);
|
|
// ...
|
|
end;
|
|
\end{verbatim}
|
|
More about instantiating a class can be found in the next section.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Class instantiation
|
|
\section{Class instantiation}
|
|
Classes must be created using their constructor. Remember that a class is a
|
|
pointer to an object, so when a variable of some class is declared, the
|
|
compiler just allocates a pointer, not the entire object. The constructor of
|
|
a class returns a pointer to an initialized instance of the object.
|
|
So, to initialize an instance of some class, one would do the following :
|
|
\begin{verbatim}
|
|
ClassVar := ClassType.ConstructorName;
|
|
\end{verbatim}
|
|
The extended syntax of \var{new} and \var{dispose} can be used to
|
|
instantiate and destroy class instances.
|
|
That construct is reserved for use with objects only.
|
|
Calling the constructor will provoke a call to \var{getmem}, to allocate
|
|
enough space to hold the class instance data.
|
|
After that, the constuctor's code is executed.
|
|
The constructor has a pointer to it's data, in \var{self}.
|
|
|
|
\begin{remark}
|
|
\begin{itemize}
|
|
\item The \var{\{\$PackRecords \}} directive also affects classes.
|
|
i.e. the alignment in memory of the different fields depends on the
|
|
value of the \var{\{\$PackRecords \}} directive.
|
|
\item Just as for objects and records, a packed class can be declared.
|
|
This has the same effect as on an object, or record, namely that the
|
|
elements are aligned on 1-byte boundaries. i.e. as close as possible.
|
|
\item \var{SizeOf(class)} will return 4, since a class is but a pointer to
|
|
an object. To get the size of the class instance data, use the
|
|
\var{TObject.InstanceSize} method.
|
|
\end{itemize}
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Methods
|
|
\section{Methods}
|
|
\subsection{invocation}
|
|
Method invocation for classes is no different than for objects. The
|
|
following is a valid method invocation:
|
|
\begin{verbatim}
|
|
Var AnObject : TAnObject;
|
|
begin
|
|
AnObject := TAnObject.Create;
|
|
ANobject.AMethod;
|
|
\end{verbatim}
|
|
\subsection{Virtual methods}
|
|
Classes have virtual methods, just as objects do. There is however a
|
|
difference between the two. For objects, it is sufficient to redeclare the
|
|
same method in a descendent object with the keyword \var{virtual} to
|
|
override it. For classes, the situation is different:
|
|
virtual methods {\em must} be overridden with the \var{override} keyword. Failing to do so,
|
|
will start a {\em new} batch of virtual methods, hiding the previous
|
|
one. The \var{Inherited} keyword will not jump to the inherited method, if
|
|
virtual was used.
|
|
|
|
The following code is {\em wrong}:
|
|
\begin{verbatim}
|
|
Type
|
|
ObjParent = Class
|
|
Procedure MyProc; virtual;
|
|
end;
|
|
ObjChild = Class(ObjPArent)
|
|
Procedure MyProc; virtual;
|
|
end;
|
|
\end{verbatim}
|
|
The compiler will produce a warning:
|
|
\begin{verbatim}
|
|
Warning: An inherited method is hidden by OBJCHILD.MYPROC
|
|
\end{verbatim}
|
|
The compiler will compile it, but using \var{Inherited} can
|
|
produce strange effects.
|
|
|
|
The correct declaration is as follows:
|
|
\begin{verbatim}
|
|
Type ObjParent = Class
|
|
Procedure MyProc; virtual;
|
|
end;
|
|
ObjChild = Class(ObjPArent)
|
|
Procedure MyProc; override;
|
|
end;
|
|
\end{verbatim}
|
|
This will compile and run without warnings or errors.
|
|
|
|
\subsection{Message methods}
|
|
New in classes are \var{message} methods. Pointers to message methods are
|
|
stored in a special table, together with the integer or string cnstant that
|
|
they were declared with. They are primarily intended to ease programming of
|
|
callback functions in several \var{GUI} toolkits, such as \var{Win32} or
|
|
\var{GTK}. In difference with Delphi, \fpc also accepts strings as message
|
|
identifiers.
|
|
|
|
Message methods that are declared with an integer constant can take only one
|
|
var argument (typed or not):
|
|
\begin{verbatim}
|
|
Procedure TMyObject.MyHandler(Var Msg); Message 1;
|
|
\end{verbatim}
|
|
The method implementation of a message function is no different from an
|
|
ordinary method. It is also possible to call a message method directly,
|
|
but this should not be done. Instead, the \var{TObject.Dispatch} method
|
|
should be used.
|
|
|
|
The \var{TOBject.Dispatch} method can be used to call a \var{message}
|
|
handler. It is declared in the \file{system} unit and will accept a var
|
|
parameter which must have at the first position a cardinal with the
|
|
message ID that should be called. For example:
|
|
\begin{verbatim}
|
|
Type
|
|
TMsg = Record
|
|
MSGID : Cardinal
|
|
Data : Pointer;
|
|
Var
|
|
Msg : TMSg;
|
|
|
|
MyObject.Dispatch (Msg);
|
|
\end{verbatim}
|
|
In this example, the \var{Dispatch} method will look at the object and all
|
|
it's ancestors (starting at the object, and searching up the class tree),
|
|
to see if a message method with message \var{MSGID} has been
|
|
declared. If such a method is found, it is called, and passed the
|
|
\var{Msg} parameter.
|
|
|
|
If no such method is found, \var{DefaultHandler} is called.
|
|
\var{DefaultHandler} is a virtual method of \var{TObject} that doesn't do
|
|
anything, but which can be overridden to provide any processing that might be
|
|
needed. \var{DefaultHandler} is declared as follows:
|
|
\begin{verbatim}
|
|
procedure defaulthandler(var message);virtual;
|
|
\end{verbatim}
|
|
|
|
In addition to the message method with a \var{Integer} identifier,
|
|
\fpc also supports a message method with a string identifier:
|
|
\begin{verbatim}
|
|
Procedure TMyObject.MyStrHandler(Var Msg); Message 'OnClick';
|
|
\end{verbatim}
|
|
|
|
The working of the string message handler is the same as the ordinary
|
|
integer message handler:
|
|
|
|
The \var{TOBject.DispatchStr} method can be used to call a \var{message}
|
|
handler. It is declared in the system unit and will accept one parameter
|
|
which must have at the first position a string with the message ID that
|
|
should be called. For example:
|
|
\begin{verbatim}
|
|
Type
|
|
TMsg = Record
|
|
MsgStr : String[10]; // Arbitrary length up to 255 characters.
|
|
Data : Pointer;
|
|
Var
|
|
Msg : TMSg;
|
|
|
|
MyObject.DispatchStr (Msg);
|
|
\end{verbatim}
|
|
In this example, the \var{DispatchStr} method will look at the object and
|
|
all it's ancestors (starting at the object, and searching up the class tree),
|
|
to see if a message method with message \var{MsgStr} has been
|
|
declared. If such a method is found, it is called, and passed the
|
|
\var{Msg} parameter.
|
|
|
|
If no such method is found, \var{DefaultHandlerStr} is called.
|
|
\var{DefaultHandlerStr} is a virtual method of \var{TObject} that doesn't do
|
|
anything, but which can be overridden to provide any processing that might be
|
|
needed. \var{DefaultHandlerStr} is declared as follows:
|
|
\begin{verbatim}
|
|
procedure DefaultHandlerStr(var message);virtual;
|
|
\end{verbatim}
|
|
|
|
In addition to this mechanism, a string message method accepts a \var{self}
|
|
parameter:
|
|
\begin{verbatim}
|
|
TMyObject.StrMsgHandler(Data : Pointer; Self : TMyObject);Message 'OnClick';
|
|
\end{verbatim}
|
|
When encountering such a method, the compiler will generate code that loads
|
|
the \var{Self} parameter into the object instance pointer. The result of
|
|
this is that it is possible to pass \var{Self} as a parameter to such a
|
|
method.
|
|
|
|
\begin{remark}
|
|
The type of the \var{Self} parameter must be of the same class
|
|
as the class the method is defined in.
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Properties
|
|
\section{Properties}
|
|
Classes can contain properties as part of their fields list. A property
|
|
acts like a normal field, i.e. its value can be retrieved or set, but it
|
|
allows to redirect the access of the field through functions and
|
|
procedures. They provide a means to associate an action with an assignment
|
|
of or a reading from a class 'field'. This allows for e.g. checking that a
|
|
value is valid when assigning, or, when reading, it allows to construct the
|
|
value on the fly. Moreover, properties can be read-only or write only.
|
|
The prototype declaration of a property is as follows:
|
|
\input{syntax/property.syn}
|
|
A \var{read specifier} is either the name of a field that contains the
|
|
property, or the name of a method function that has the same return type as
|
|
the property type. In the case of a simple type, this
|
|
function must not accept an argument. A \var{read specifier} is optional,
|
|
making the property write-only.
|
|
A \var{write specifier} is optional: If there is no \var{write specifier}, the
|
|
property is read-only. A write specifier is either the name of a field, or
|
|
the name of a method procedure that accepts as a sole argument a variable of
|
|
the same type as the property.
|
|
The section (\var{private}, \var{published}) in which the specified function or
|
|
procedure resides is irrelevant. Usually, however, this will be a protected
|
|
or private method.
|
|
Example:
|
|
Given the following declaration:
|
|
\begin{verbatim}
|
|
Type
|
|
MyClass = Class
|
|
Private
|
|
Field1 : Longint;
|
|
Field2 : Longint;
|
|
Field3 : Longint;
|
|
Procedure Sety (value : Longint);
|
|
Function Gety : Longint;
|
|
Function Getz : Longint;
|
|
Public
|
|
Property X : Longint Read Field1 write Field2;
|
|
Property Y : Longint Read GetY Write Sety;
|
|
Property Z : Longint Read GetZ;
|
|
end;
|
|
Var MyClass : TMyClass;
|
|
\end{verbatim}
|
|
The following are valid statements:
|
|
\begin{verbatim}
|
|
WriteLn ('X : ',MyClass.X);
|
|
WriteLn ('Y : ',MyClass.Y);
|
|
WriteLn ('Z : ',MyClass.Z);
|
|
MyClass.X := 0;
|
|
MyClass.Y := 0;
|
|
\end{verbatim}
|
|
But the following would generate an error:
|
|
\begin{verbatim}
|
|
MyClass.Z := 0;
|
|
\end{verbatim}
|
|
because Z is a read-only property.
|
|
What happens in the above statements is that when a value needs to be read,
|
|
the compiler inserts a call to the various \var{getNNN} methods of the
|
|
object, and the result of this call is used. When an assignment is made,
|
|
the compiler passes the value that must be assigned as a paramater to
|
|
the various \var{setNNN} methods.
|
|
Because of this mechanism, properties cannot be passed as var arguments to a
|
|
function or procedure, since there is no known address of the property (at
|
|
least, not always).
|
|
If the property definition contains an index, then the read and write
|
|
specifiers must be a function and a procedure. Moreover, these functions
|
|
require an additional parameter : An integer parameter. This allows to read
|
|
or write several properties with the same function. For this, the properties
|
|
must have the same type.
|
|
The following is an example of a property with an index:
|
|
\begin{verbatim}
|
|
{$mode objfpc}
|
|
Type TPoint = Class(TObject)
|
|
Private
|
|
FX,FY : Longint;
|
|
Function GetCoord (Index : Integer): Longint;
|
|
Procedure SetCoord (Index : Integer; Value : longint);
|
|
Public
|
|
Property X : Longint index 1 read GetCoord Write SetCoord;
|
|
Property Y : Longint index 2 read GetCoord Write SetCoord;
|
|
Property Coords[Index : Integer]:Longint Read GetCoord;
|
|
end;
|
|
Procedure TPoint.SetCoord (Index : Integer; Value : Longint);
|
|
begin
|
|
Case Index of
|
|
1 : FX := Value;
|
|
2 : FY := Value;
|
|
end;
|
|
end;
|
|
Function TPoint.GetCoord (INdex : Integer) : Longint;
|
|
begin
|
|
Case Index of
|
|
1 : Result := FX;
|
|
2 : Result := FY;
|
|
end;
|
|
end;
|
|
Var P : TPoint;
|
|
begin
|
|
P := TPoint.create;
|
|
P.X := 2;
|
|
P.Y := 3;
|
|
With P do
|
|
WriteLn ('X=',X,' Y=',Y);
|
|
end.
|
|
\end{verbatim}
|
|
When the compiler encounters an assignment to \var{X}, then \var{SetCoord}
|
|
is called with as first parameter the index (1 in the above case) and with
|
|
as a second parameter the value to be set.
|
|
Conversely, when reading the value of \var{X}, the compiler calls
|
|
\var{GetCoord} and passes it index 1.
|
|
Indexes can only be integer values.
|
|
Array propertie also exist. These are properties that accept an
|
|
index, just as an array does. Only now the index doesn't have to be an
|
|
ordinal type, but can be any type.
|
|
|
|
A \var{read specifier} for an array property is the name method function
|
|
that has the same return type as the property type.
|
|
The function must accept as a sole arguent a variable of the same type as
|
|
the index type. For an array property, one cannot specify fields as \var{read
|
|
specifiers}.
|
|
|
|
A \var{write specifier} for an array property is the name of a method
|
|
procedure that accepts two arguments: The first argument has the same
|
|
type as the index, and the second argument is a parameter of the same
|
|
type as the property type.
|
|
As an example, see the following declaration:
|
|
\begin{verbatim}
|
|
Type TIntList = Class
|
|
Private
|
|
Function GetInt (I : Longint) : longint;
|
|
Function GetAsString (A : String) : String;
|
|
Procedure SetInt (I : Longint; Value : Longint;);
|
|
Procedure SetAsString (A : String; Value : String);
|
|
Public
|
|
Property Items [i : Longint] : Longint Read GetInt
|
|
Write SetInt;
|
|
Property StrItems [S : String] : String Read GetAsString
|
|
Write SetAsstring;
|
|
end;
|
|
Var AIntList : TIntList;
|
|
\end{verbatim}
|
|
Then the following statements would be valid:
|
|
\begin{verbatim}
|
|
AIntList.Items[26] := 1;
|
|
AIntList.StrItems['twenty-five'] := 'zero';
|
|
WriteLn ('Item 26 : ',AIntList.Items[26]);
|
|
WriteLn ('Item 25 : ',AIntList.StrItems['twenty-five']);
|
|
\end{verbatim}
|
|
While the following statements would generate errors:
|
|
\begin{verbatim}
|
|
AIntList.Items['twenty-five'] := 1;
|
|
AIntList.StrItems[26] := 'zero';
|
|
\end{verbatim}
|
|
Because the index types are wrong.
|
|
Array properties can be declared as \var{default} properties. This means that
|
|
it is not necessary to specify the property name when assigning or reading
|
|
it. If, in the previous example, the definition of the items property would
|
|
have been
|
|
\begin{verbatim}
|
|
Property Items[i : Longint]: Longint Read GetInt
|
|
Write SetInt; Default;
|
|
\end{verbatim}
|
|
Then the assignment
|
|
\begin{verbatim}
|
|
AIntList.Items[26] := 1;
|
|
\end{verbatim}
|
|
Would be equivalent to the following abbreviation.
|
|
\begin{verbatim}
|
|
AIntList[26] := 1;
|
|
\end{verbatim}
|
|
Only one default property per class is allowed, and descendent classes
|
|
cannot redeclare the default property.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Interfaces
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Interfaces}
|
|
\label{ch:Interfaces}
|
|
\section{Definition}
|
|
As of version 1.1, FPC supports interfaces. Interfaces are an
|
|
alternative to multiple inheritance (where a class can have multiple
|
|
parent classes) as implemented for instance in C++. An interface is
|
|
basically a named set of methods and properties: A class that
|
|
{\em implements} the interface provides {\em all} the methods as
|
|
they are enumerated in the Interface definition. It is not possible for a
|
|
class to implement only part of the interface: it is all or nothing.
|
|
|
|
Interfaces can also be ordered in a hierarchy, exactly as classes:
|
|
An interface definition that inherits from another interface definition
|
|
contains all the methods from the parent interface, as well as the methods
|
|
explicitly named in the interface definition. A class implementing an
|
|
interface must then implement all members of the interface as well as the
|
|
methods of the parent interface(s).
|
|
|
|
An interface can be uniquely identified by a GUID (GUID is an acronym for
|
|
Globally Unique Identifier, a 128-bit integer guaranteed always to be
|
|
unique\footnote{In theory, of course.}. Especially on Windows systems, the
|
|
GUID of an interface can and must be used when using COM.
|
|
|
|
The definition of an Interface has the following form:
|
|
\input{syntax/typeintf.syn}
|
|
Along with this definition the following must be noted:
|
|
\begin{itemize}
|
|
\item Interfaces can only be used in \var{DELPHI} mode or in \var{OBJFPC}
|
|
mode.
|
|
\item There are no visibility specifiers. All members are public (indeed,
|
|
it would make little sense to make them private or protected).
|
|
\item The properties declared in an interface can only have methods as read and
|
|
write specifiers.
|
|
\item There are no constructors or destructors. Instances of interfaces
|
|
cannot be created directly: instead, an instance of a class implementing
|
|
the interface must be created.
|
|
\item Only calling convention modifiers may be present in the definition of
|
|
a method. Modifiers as \var{virtual}, \var{abstract} or \var{dynamic}, and
|
|
hence also \var{override} cannot be present in the definition of a interface
|
|
definition.
|
|
\end{itemize}
|
|
|
|
\section{Interface identification: A GUID}
|
|
An interface can be identified by a GUID. This is a 128-bit number, which is
|
|
represented in a text representation (a string literal):
|
|
\begin{verbatim}
|
|
['{HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH}']
|
|
\end{verbatim}
|
|
Each \var{H} character represents a hexadecimal number (0-9,A-F). The format
|
|
contains 8-4-4-4-12 numbers. A GUID can also be represented by the following
|
|
record, defined in the \file{objpas} unit (included automatically when in
|
|
\var{DELPHI} or \var{OBJFPC} mode:
|
|
\begin{verbatim}
|
|
PGuid = ^TGuid;
|
|
TGuid = packed record
|
|
case integer of
|
|
1 : (
|
|
Data1 : DWord;
|
|
Data2 : word;
|
|
Data3 : word;
|
|
Data4 : array[0..7] of byte;
|
|
);
|
|
2 : (
|
|
D1 : DWord;
|
|
D2 : word;
|
|
D3 : word;
|
|
D4 : array[0..7] of byte;
|
|
);
|
|
end;
|
|
\end{verbatim}
|
|
A constant of type TGUID can be specified using a string literal:
|
|
\begin{verbatim}
|
|
{$mode objfpc}
|
|
program testuid;
|
|
|
|
Const
|
|
MyGUID : TGUID = '{10101010-1010-0101-1001-110110110110}';
|
|
|
|
begin
|
|
end.
|
|
\end{verbatim}
|
|
Normally, the GUIDs are only used in Windows, when using COM interfaces.
|
|
More on this in the next section.
|
|
|
|
\section{Interfaces and COM}
|
|
When using interfaces on Windows which should be available to the COM
|
|
subsystem, the calling convention should be \var{stdcall} - this is not the
|
|
default \fpc calling convention, so it should be specified explicitly.
|
|
|
|
COM does not know properties. It only knows methods. So when specifying
|
|
property definitions as part of an interface definition, be aware that the
|
|
properties will only be known in the \fpc compiled program: other Windows
|
|
programs will not be aware of the property definitions. For this reason,
|
|
property definitions must always have interface methods as the read/write
|
|
specifiers.
|
|
|
|
\section*{Interface implementations}
|
|
When a class implements an interface, it should implement all methods of the
|
|
interface. If a method of an interface is not implemented, then the compiler
|
|
will give an error. For example:
|
|
\begin{verbatim}
|
|
Type
|
|
IMyInterface = Interface
|
|
Function MyFunc : Integer;
|
|
Function MySecondFunc : Integer;
|
|
end;
|
|
|
|
TMyClass = Class(TInterfacedObject,IMyInterface)
|
|
Function MyFunc : Integer;
|
|
Function MyOtherFunc : Integer;
|
|
end;
|
|
|
|
Function TMyClass.MyFunc : Integer;
|
|
|
|
begin
|
|
Result:=23;
|
|
end;
|
|
|
|
Function TMyClass.MyOtherFunc : Integer;
|
|
|
|
begin
|
|
Result:=24;
|
|
end;
|
|
\end{verbatim}
|
|
will result in a compiler error:
|
|
\begin{verbatim}
|
|
Error: No matching implementation for interface method
|
|
"IMyInterface.MySecondFunc:LongInt" found
|
|
\end{verbatim}
|
|
|
|
At the moment of writing, the compiler does not yet support providing
|
|
aliases for an interface as in Delphi. i.e. the following will not yet
|
|
compile:
|
|
\begin{verbatim}
|
|
ype
|
|
IMyInterface = Interface
|
|
Function MyFunc : Integer;
|
|
end;
|
|
|
|
TMyClass = Class(TInterfacedObject,IMyInterface)
|
|
Function MyOtherFunction : Integer;
|
|
// The following fails in FPC.
|
|
Function IMyInterface.MyFunc = MyOtherFunction;
|
|
end;
|
|
\end{verbatim}
|
|
This declaration should tell the compiler that the \var{MyFunc} method of
|
|
the \var{IMyInterface} interface is implemented in the \var{MyOtherFunction}
|
|
method of the \var{TMyClass} class.
|
|
|
|
\section{CORBA and other Interfaces}
|
|
COM is not the only architecture where interfaces are used. CORBA knows
|
|
interfaces, UNO (the OpenOffice API) uses interfaces, and Java as well.
|
|
These languages do not know the \var{IUnknown} interface used as the basis of
|
|
all interfaces in COM. It would therefore be a bad idea if an interface
|
|
automatically descended from \var{IUnknown} if no parent interface was
|
|
specified. Therefore, a directive \var{\{\$INTERFACES\}} was introduced in
|
|
\fpc: it specifies what the parent interface is of an interface, declared
|
|
without parent. More information about this directive can be found in the
|
|
\progref.
|
|
|
|
Note that COM interfaces are by default reference counted.
|
|
CORBA interfaces are not necessarily reference counted.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Expressions
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Expressions}
|
|
\label{ch:Expressions}
|
|
Expressions occur in assignments or in tests. Expressions produce a value,
|
|
of a certain type.
|
|
Expressions are built with two components: Operators and their operands.
|
|
Usually an operator is binary, i.e. it requires 2 operands. Binary operators
|
|
occur always between the operands (as in \var{X/Y}). Sometimes an
|
|
operator is unary, i.e. it requires only one argument. A unary operator
|
|
occurs always before the operand, as in \var{-X}.
|
|
|
|
When using multiple operands in an expression, the precedence rules of
|
|
\seet{OperatorPrecedence} are used.
|
|
\begin{FPCltable}{lll}{Precedence of operators}{OperatorPrecedence}
|
|
Operator & Precedence & Category \\ \hline
|
|
\var{Not, @} & Highest (first) & Unary operators\\
|
|
\var{* / div mod and shl shr as} & Second & Multiplying operators\\
|
|
\var{+ - or xor} & Third & Adding operators \\
|
|
\var{< <> < > <= >= in is} & Lowest (Last) & relational operators \\
|
|
\hline
|
|
\end{FPCltable}
|
|
When determining the precedence, the compiler uses the following rules:
|
|
\begin{enumerate}
|
|
\item In operations with unequal precedences the operands belong to the
|
|
operater with the highest precedence. For example, in \var{5*3+7}, the
|
|
multiplication is higher in precedence than the addition, so it is
|
|
executed first. The result would be 22.
|
|
\item If parentheses are used in an expression, their contents is evaluated
|
|
first. Thus, \var {5*(3+7)} would result in 50.
|
|
\end{enumerate}
|
|
|
|
\begin{remark}
|
|
The order in which expressions of the same precedence are evaluated is not
|
|
guaranteed to be left-to-right. In general, no assumptions on which expression
|
|
is evaluated first should be made in such a case.
|
|
The compiler will decide which expression to evaluate first based on
|
|
optimization rules. Thus, in the following expression:
|
|
\begin{verbatim}
|
|
a := g(3) + f(2);
|
|
\end{verbatim}
|
|
\var{f(2)} may be executed before \var{g(3)}. This behaviour is distinctly
|
|
different from \delphi or \tp.
|
|
|
|
If one expression {\em must} be executed before the other, it is necessary
|
|
to split up the statement using temporary results:
|
|
\begin{verbatim}
|
|
e1 := g(3);
|
|
a := e1 + f(2);
|
|
\end{verbatim}
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Expression syntax
|
|
\section{Expression syntax}
|
|
An expression applies relational operators to simple expressions. Simple
|
|
expressions are a series of terms (what a term is, is explained below), joined by
|
|
adding operators.
|
|
\input{syntax/expsimpl.syn}
|
|
The following are valid expressions:
|
|
\begin{verbatim}
|
|
GraphResult<>grError
|
|
(DoItToday=Yes) and (DoItTomorrow=No);
|
|
Day in Weekend
|
|
\end{verbatim}
|
|
And here are some simple expressions:
|
|
\begin{verbatim}
|
|
A + B
|
|
-Pi
|
|
ToBe or NotToBe
|
|
\end{verbatim}
|
|
Terms consist of factors, connected by multiplication operators.
|
|
\input{syntax/expterm.syn}
|
|
Here are some valid terms:
|
|
\begin{verbatim}
|
|
2 * Pi
|
|
A Div B
|
|
(DoItToday=Yes) and (DoItTomorrow=No);
|
|
\end{verbatim}
|
|
Factors are all other constructions:
|
|
\input{syntax/expfact.syn}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Function calls
|
|
\section{Function calls}
|
|
Function calls are part of expressions (although, using extended syntax,
|
|
they can be statements too). They are constructed as follows:
|
|
\input{syntax/fcall.syn}
|
|
The \synt{variable reference} must be a procedural type variable reference.
|
|
A method designator can only be used inside the method of an object. A
|
|
qualified method designator can be used outside object methods too.
|
|
The function that will get called is the function with a declared parameter
|
|
list that matches the actual parameter list. This means that
|
|
\begin{enumerate}
|
|
\item The number of actual parameters must equal the number of declared
|
|
parameters (unless default parameter values are used).
|
|
\item The types of the parameters must be compatible. For variable
|
|
reference parameters, the parameter types must be exactly the same.
|
|
\end{enumerate}
|
|
If no matching function is found, then the compiler will generate an error.
|
|
Depending on the fact of the function is overloaded (i.e. multiple functions
|
|
with the same name, but different parameter lists) the error will be
|
|
different.
|
|
There are cases when the compiler will not execute the function call in an
|
|
expression. This is the case when assigning a value to a procedural
|
|
type variable, as in the following example:
|
|
\begin{verbatim}
|
|
Type
|
|
FuncType = Function: Integer;
|
|
Var A : Integer;
|
|
Function AddOne : Integer;
|
|
begin
|
|
A := A+1;
|
|
AddOne := A;
|
|
end;
|
|
Var F : FuncType;
|
|
N : Integer;
|
|
begin
|
|
A := 0;
|
|
F := AddOne; { Assign AddOne to F, Don't call AddOne}
|
|
N := AddOne; { N := 1 !!}
|
|
end.
|
|
\end{verbatim}
|
|
In the above listing, the assigment to F will not cause the function AddOne
|
|
to be called. The assignment to N, however, will call AddOne.
|
|
A problem with this syntax is the following construction:
|
|
\begin{verbatim}
|
|
If F = AddOne Then
|
|
DoSomethingHorrible;
|
|
\end{verbatim}
|
|
Should the compiler compare the addresses of \var{F} and \var{AddOne},
|
|
or should it call both functions, and compare the result ? \fpc solves this
|
|
by deciding that a procedural variable is equivalent to a pointer. Thus the
|
|
compiler will give a type mismatch error, since AddOne is considered a
|
|
call to a function with integer result, and F is a pointer, Hence a type
|
|
mismatch occurs.
|
|
How then, should one compare whether \var{F} points to the function
|
|
\var{AddOne} ? To do this, one should use the address operator \var{@}:
|
|
\begin{verbatim}
|
|
If F = @AddOne Then
|
|
WriteLn ('Functions are equal');
|
|
\end{verbatim}
|
|
The left hand side of the boolean expression is an address. The right hand
|
|
side also, and so the compiler compares 2 addresses.
|
|
How to compare the values that both functions return ? By adding an empty
|
|
parameter list:
|
|
\begin{verbatim}
|
|
If F()=Addone then
|
|
WriteLn ('Functions return same values ');
|
|
\end{verbatim}
|
|
Remark that this behaviour is not compatible with Delphi syntax.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Set constructors
|
|
\section{Set constructors}
|
|
When a set-type constant must be entered in an expression, a
|
|
set constructor must be given. In essence this is the same thing as when a
|
|
type is defined, only there is no identifier to identify the set with.
|
|
A set constructor is a comma separated list of expressions, enclosed in
|
|
square brackets.
|
|
\input{syntax/setconst.syn}
|
|
All set groups and set elements must be of the same ordinal type.
|
|
The empty set is denoted by \var{[]}, and it can be assigned to any type of
|
|
set. A set group with a range \var{[A..Z]} makes all values in the range a
|
|
set element. If the first range specifier has a bigger ordinal value than
|
|
the second the set is empty, e.g., \var{[Z..A]} denotes an empty set.
|
|
The following are valid set constructors:
|
|
\begin{verbatim}
|
|
[today,tomorrow]
|
|
[Monday..Friday,Sunday]
|
|
[ 2, 3*2, 6*2, 9*2 ]
|
|
['A'..'Z','a'..'z','0'..'9']
|
|
\end{verbatim}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Value typecasts
|
|
\section{Value typecasts}
|
|
Sometimes it is necessary to change the type of an expression, or a part of
|
|
the expression, to be able to be assignment compatible. This is done through
|
|
a value typecast. The syntax diagram for a value typecast is as follows:
|
|
\input{syntax/tcast.syn}
|
|
Value typecasts cannot be used on the left side of assignments, as variable
|
|
typecasts.
|
|
Here are some valid typecasts:
|
|
\begin{verbatim}
|
|
Byte('A')
|
|
Char(48)
|
|
boolean(1)
|
|
longint(@Buffer)
|
|
\end{verbatim}
|
|
The type size of the expression and the size of the type cast must be the
|
|
same. That is, the following doesn't work:
|
|
\begin{verbatim}
|
|
Integer('A')
|
|
Char(4875)
|
|
boolean(100)
|
|
Word(@Buffer)
|
|
\end{verbatim}
|
|
This is different from Delphi or Turbo Pascal behaviour.
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The @ operator
|
|
\section{The @ operator}
|
|
The address operator \var{@} returns the address of a variable, procedure
|
|
or function. It is used as follows:
|
|
\input{syntax/address.syn}
|
|
The \var{@} operator returns a typed pointer if the \var{\$T} switch is on.
|
|
If the \var{\$T} switch is off then the address operator returns an untyped
|
|
pointer, which is assigment compatible with all pointer types. The type of
|
|
the pointer is \var{\^{}T}, where \var{T} is the type of the variable
|
|
reference.
|
|
For example, the following will compile
|
|
\begin{verbatim}
|
|
Program tcast;
|
|
{$T-} { @ returns untyped pointer }
|
|
|
|
Type art = Array[1..100] of byte;
|
|
Var Buffer : longint;
|
|
PLargeBuffer : ^art;
|
|
|
|
begin
|
|
PLargeBuffer := @Buffer;
|
|
end.
|
|
\end{verbatim}
|
|
Changing the \var{\{\$T-\}} to \var{\{\$T+\}} will prevent the compiler from
|
|
compiling this. It will give a type mismatch error.
|
|
By default, the address operator returns an untyped pointer.
|
|
Applying the address operator to a function, method, or procedure identifier
|
|
will give a pointer to the entry point of that function. The result is an
|
|
untyped pointer.
|
|
By default, the address operator must be used if a value must be assigned
|
|
to a procedural type variable. This behaviour can be avoided by using the
|
|
\var{-So} or \var{-S2} switches, which result in a more compatible Delphi or
|
|
Turbo Pascal syntax.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Operators
|
|
\section{Operators}
|
|
Operators can be classified according to the type of expression they
|
|
operate on. We will discuss them type by type.
|
|
\subsection{Arithmetic operators}
|
|
Arithmetic operators occur in arithmetic operations, i.e. in expressions
|
|
that contain integers or reals. There are 2 kinds of operators : Binary and
|
|
unary arithmetic operators.
|
|
Binary operators are listed in \seet{binaroperators}, unary operators are
|
|
listed in \seet{unaroperators}.
|
|
\begin{FPCltable}{ll}{Binary arithmetic operators}{binaroperators}
|
|
Operator & Operation \\ \hline
|
|
\var{+} & Addition\\
|
|
\var{-} & Subtraction\\
|
|
\var{*} & Multiplication \\
|
|
\var{/} & Division \\
|
|
\var{Div} & Integer division \\
|
|
\var{Mod} & Remainder \\ \hline
|
|
\end{FPCltable}
|
|
With the exception of \var{Div} and \var{Mod}, which accept only integer
|
|
expressions as operands, all operators accept real and integer expressions as
|
|
operands.
|
|
For binary operators, the result type will be integer if both operands are
|
|
integer type expressions. If one of the operands is a real type expression,
|
|
then the result is real.
|
|
As an exception : division (\var{/}) results always in real values.
|
|
\begin{FPCltable}{ll}{Unary arithmetic operators}{unaroperators}
|
|
Operator & Operation \\ \hline
|
|
\var{+} & Sign identity\\
|
|
\var{-} & Sign inversion \\ \hline
|
|
\end{FPCltable}
|
|
For unary operators, the result type is always equal to the expression type.
|
|
The division (\var{/}) and \var{Mod} operator will cause run-time errors if
|
|
the second argument is zero.
|
|
The sign of the result of a \var{Mod} operator is the same as the sign of
|
|
the left side operand of the \var{Mod} operator. In fact, the \var{Mod}
|
|
operator is equivalent to the following operation :
|
|
\begin{verbatim}
|
|
I mod J = I - (I div J) * J
|
|
\end{verbatim}
|
|
but it executes faster than the right hand side expression.
|
|
\subsection{Logical operators}
|
|
Logical operators act on the individual bits of ordinal expressions.
|
|
Logical operators require operands that are of an integer type, and produce
|
|
an integer type result. The possible logical operators are listed in
|
|
\seet{logicoperations}.
|
|
\begin{FPCltable}{ll}{Logical operators}{logicoperations}
|
|
Operator & Operation \\ \hline
|
|
\var{not} & Bitwise negation (unary) \\
|
|
\var{and} & Bitwise and \\
|
|
\var{or} & Bitwise or \\
|
|
\var{xor} & Bitwise xor \\
|
|
\var{shl} & Bitwise shift to the left \\
|
|
\var{shr} & Bitwise shift to the right \\ \hline
|
|
\end{FPCltable}
|
|
The following are valid logical expressions:
|
|
\begin{verbatim}
|
|
A shr 1 { same as A div 2, but faster}
|
|
Not 1 { equals -2 }
|
|
Not 0 { equals -1 }
|
|
Not -1 { equals 0 }
|
|
B shl 2 { same as B * 2 for integers }
|
|
1 or 2 { equals 3 }
|
|
3 xor 1 { equals 2 }
|
|
\end{verbatim}
|
|
\subsection{Boolean operators}
|
|
Boolean operators can be considered logical operations on a type with 1 bit
|
|
size. Therefore the \var{shl} and \var{shr} operations have little sense.
|
|
Boolean operators can only have boolean type operands, and the resulting
|
|
type is always boolean. The possible operators are listed in
|
|
\seet{booleanoperators}
|
|
\begin{FPCltable}{ll}{Boolean operators}{booleanoperators}
|
|
Operator & Operation \\ \hline
|
|
\var{not} & logical negation (unary) \\
|
|
\var{and} & logical and \\
|
|
\var{or} & logical or \\
|
|
\var{xor} & logical xor \\ \hline
|
|
\end{FPCltable}
|
|
\begin{remark} Boolean expressions are always evaluated with short-circuit
|
|
evaluation. This means that from the moment the result of the complete
|
|
expression is known, evaluation is stopped and the result is returned.
|
|
For instance, in the following expression:
|
|
\begin{verbatim}
|
|
B := True or MaybeTrue;
|
|
\end{verbatim}
|
|
The compiler will never look at the value of \var{MaybeTrue}, since it is
|
|
obvious that the expression will always be true. As a result of this
|
|
strategy, if \var{MaybeTrue} is a function, it will not get called !
|
|
(This can have surprising effects when used in conjunction with properties)
|
|
\end{remark}
|
|
|
|
\subsection{String operators}
|
|
There is only one string operator : \var{+}. It's action is to concatenate
|
|
the contents of the two strings (or characters) it stands between.
|
|
One cannot use \var{+} to concatenate null-terminated (\var{PChar}) strings.
|
|
The following are valid string operations:
|
|
\begin{verbatim}
|
|
'This is ' + 'VERY ' + 'easy !'
|
|
Dirname+'\'
|
|
\end{verbatim}
|
|
The following is not:
|
|
\begin{verbatim}
|
|
Var Dirname = Pchar;
|
|
...
|
|
Dirname := Dirname+'\';
|
|
\end{verbatim}
|
|
Because \var{Dirname} is a null-terminated string.
|
|
\subsection{Set operators}
|
|
The following operations on sets can be performed with operators:
|
|
Union, difference and intersection. The operators needed for this are listed
|
|
in \seet{setoperators}.
|
|
\begin{FPCltable}{ll}{Set operators}{setoperators}
|
|
Operator & Action \\ \hline
|
|
\var{+} & Union \\
|
|
\var{-} & Difference \\
|
|
\var{*} & Intersection \\ \hline
|
|
\end{FPCltable}
|
|
The set type of the operands must be the same, or an error will be
|
|
generated by the compiler.
|
|
\subsection{Relational operators}
|
|
The relational operators are listed in \seet{relationoperators}
|
|
\begin{FPCltable}{ll}{Relational operators}{relationoperators}
|
|
Operator & Action \\ \hline
|
|
\var{=} & Equal \\
|
|
\var{<>} & Not equal \\
|
|
\var{<} & Stricty less than\\
|
|
\var{>} & Strictly greater than\\
|
|
\var{<=} & Less than or equal \\
|
|
\var{>=} & Greater than or equal \\
|
|
\var{in} & Element of \\ \hline
|
|
\end{FPCltable}
|
|
Left and right operands must be of the same type. Only integer
|
|
and real types can be mixed in relational expressions.
|
|
Comparing strings is done on the basis of their ASCII code representation.
|
|
When comparing pointers, the addresses to which they point are compared.
|
|
This also is true for \var{PChar} type pointers. To compare the strings
|
|
the \var{Pchar} point to, the \var{StrComp} function
|
|
from the \file{strings} unit must be used.
|
|
The \var{in} returns \var{True} if the left operand (which must have the same
|
|
ordinal type as the set type, and which must be in the range 0..255) is an
|
|
element of the set which is the right operand, otherwise it returns \var{False}
|
|
\chapter{Statements}
|
|
\label{ch:Statements}
|
|
The heart of each algorithm are the actions it takes. These actions are
|
|
contained in the statements of a program or unit. Each statement can be
|
|
labeled and jumped to (within certain limits) with \var{Goto} statements.
|
|
This can be seen in the following syntax diagram:
|
|
\input{syntax/statement.syn}
|
|
A label can be an identifier or an integer digit.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Simple statements
|
|
\section{Simple statements}
|
|
A simple statement cannot be decomposed in separate statements. There are
|
|
basically 4 kinds of simple statements:
|
|
\input{syntax/simstate.syn}
|
|
Of these statements, the {\em raise statement} will be explained in the
|
|
chapter on Exceptions (\seec{Exceptions})
|
|
\subsection{Assignments}
|
|
Assignments give a value to a variable, replacing any previous value the
|
|
variable might have had:
|
|
\input{syntax/assign.syn}
|
|
In addition to the standard Pascal assignment operator (\var{ := }), which
|
|
simply replaces the value of the varable with the value resulting from the
|
|
expression on the right of the { := } operator, \fpc
|
|
supports some c-style constructions. All available constructs are listed in
|
|
\seet{assignments}.
|
|
\begin{FPCltable}{lr}{Allowed C constructs in \fpc}{assignments}
|
|
Assignment & Result \\ \hline
|
|
a += b & Adds \var{b} to \var{a}, and stores the result in \var{a}.\\
|
|
a -= b & Substracts \var{b} from \var{a}, and stores the result in
|
|
\var{a}. \\
|
|
a *= b & Multiplies \var{a} with \var{b}, and stores the result in
|
|
\var{a}. \\
|
|
a /= b & Divides \var{a} through \var{b}, and stores the result in
|
|
\var{a}. \\ \hline
|
|
\end{FPCltable}
|
|
For these constructs to work, the \var{-Sc} command-line switch must
|
|
be specified.
|
|
|
|
\begin{remark}
|
|
These constructions are just for typing convenience, they
|
|
don't generate different code.
|
|
Here are some examples of valid assignment statements:
|
|
\begin{verbatim}
|
|
X := X+Y;
|
|
X+=Y; { Same as X := X+Y, needs -Sc command line switch}
|
|
X/=2; { Same as X := X/2, needs -Sc command line switch}
|
|
Done := False;
|
|
Weather := Good;
|
|
MyPi := 4* Tan(1);
|
|
\end{verbatim}
|
|
\end{remark}
|
|
|
|
\subsection{Procedure statements}
|
|
Procedure statements are calls to subroutines. There are
|
|
different possibilities for procedure calls: A normal procedure call, an
|
|
object method call (fully qualified or not), or even a call to a procedural
|
|
type variable. All types are present in the following diagram.
|
|
\input{syntax/procedure.syn}
|
|
The \fpc compiler will look for a procedure with the same name as given in
|
|
the procedure statement, and with a declared parameter list that matches the
|
|
actual parameter list.
|
|
The following are valid procedure statements:
|
|
\begin{verbatim}
|
|
Usage;
|
|
WriteLn('Pascal is an easy language !');
|
|
Doit();
|
|
\end{verbatim}
|
|
\subsection{Goto statements}
|
|
\fpc supports the \var{goto} jump statement. Its prototype syntax is
|
|
\input{syntax/goto.syn}
|
|
When using \var{goto} statements, the following must be kept in mind:
|
|
\begin{enumerate}
|
|
\item The jump label must be defined in the same block as the \var{Goto}
|
|
statement.
|
|
\item Jumping from outside a loop to the inside of a loop or vice versa can
|
|
have strange effects.
|
|
\item To be able to use the \var{Goto} statement, the \var{-Sg} compiler
|
|
switch must be used.
|
|
\end{enumerate}
|
|
\var{Goto} statements are considered bad practice and should be avoided as
|
|
much as possible. It is always possible to replace a \var{goto} statement by a
|
|
construction that doesn't need a \var{goto}, although this construction may
|
|
not be as clear as a goto statement.
|
|
For instance, the following is an allowed goto statement:
|
|
\begin{verbatim}
|
|
label
|
|
jumpto;
|
|
...
|
|
Jumpto :
|
|
Statement;
|
|
...
|
|
Goto jumpto;
|
|
...
|
|
\end{verbatim}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Structured statements
|
|
\section{Structured statements}
|
|
Structured statements can be broken into smaller simple statements, which
|
|
should be executed repeatedly, conditionally or sequentially:
|
|
\input{syntax/struct.syn}
|
|
Conditional statements come in 2 flavours :
|
|
\input{syntax/conditio.syn}
|
|
Repetitive statements come in 3 flavours:
|
|
\input{syntax/repetiti.syn}
|
|
The following sections deal with each of these statements.
|
|
\subsection{Compound statements}
|
|
Compound statements are a group of statements, separated by semicolons,
|
|
that are surrounded by the keywords \var{Begin} and \var{End}. The
|
|
Last statement doesn't need to be followed by a semicolon, although it is
|
|
allowed. A compound statement is a way of grouping statements together,
|
|
executing the statements sequentially. They are treated as one statement
|
|
in cases where Pascal syntax expects 1 statement, such as in
|
|
\var{if ... then} statements.
|
|
\input{syntax/compound.syn}
|
|
\subsection{The \var{Case} statement}
|
|
\fpc supports the \var{case} statement. Its syntax diagram is
|
|
\input{syntax/case.syn}
|
|
The constants appearing in the various case parts must be known at
|
|
compile-time, and can be of the following types : enumeration types,
|
|
Ordinal types (except boolean), and chars. The expression must be also of
|
|
this type, or a compiler error will occur. All case constants must
|
|
have the same type.
|
|
The compiler will evaluate the expression. If one of the case constants
|
|
values matches the value of the expression, the statement that follows
|
|
this constant is executed. After that, the program continues after the final
|
|
\var{end}.
|
|
If none of the case constants match the expression value, the statement
|
|
after the \var{else} keyword is executed. This can be an empty statement.
|
|
If no else part is present, and no case constant matches the expression
|
|
value, program flow continues after the final \var{end}.
|
|
The case statements can be compound statements
|
|
(i.e. a \var{begin..End} block).
|
|
|
|
\begin{remark}
|
|
Contrary to Turbo Pascal, duplicate case labels are not
|
|
allowed in \fpc, so the following code will generate an error when
|
|
compiling:
|
|
\begin{verbatim}
|
|
Var i : integer;
|
|
...
|
|
Case i of
|
|
3 : DoSomething;
|
|
1..5 : DoSomethingElse;
|
|
end;
|
|
\end{verbatim}
|
|
The compiler will generate a \var{Duplicate case label} error when compiling
|
|
this, because the 3 also appears (implicitly) in the range \var{1..5}. This
|
|
is similar to Delphi syntax.
|
|
\end{remark}
|
|
The following are valid case statements:
|
|
\begin{verbatim}
|
|
Case C of
|
|
'a' : WriteLn ('A pressed');
|
|
'b' : WriteLn ('B pressed');
|
|
'c' : WriteLn ('C pressed');
|
|
else
|
|
WriteLn ('unknown letter pressed : ',C);
|
|
end;
|
|
\end{verbatim}
|
|
Or
|
|
\begin{verbatim}
|
|
Case C of
|
|
'a','e','i','o','u' : WriteLn ('vowel pressed');
|
|
'y' : WriteLn ('This one depends on the language');
|
|
else
|
|
WriteLn ('Consonant pressed');
|
|
end;
|
|
\end{verbatim}
|
|
\begin{verbatim}
|
|
Case Number of
|
|
1..10 : WriteLn ('Small number');
|
|
11..100 : WriteLn ('Normal, medium number');
|
|
else
|
|
WriteLn ('HUGE number');
|
|
end;
|
|
\end{verbatim}
|
|
\subsection{The \var{If..then..else} statement}
|
|
The \var{If .. then .. else..} prototype syntax is
|
|
\input{syntax/ifthen.syn}
|
|
The expression between the \var{if} and \var{then} keywords must have a
|
|
boolean return type. If the expression evaluates to \var{True} then the
|
|
statement following \var{then} is executed.
|
|
|
|
If the expression evaluates to \var{False}, then the statement following
|
|
\var{else} is executed, if it is present.
|
|
|
|
Be aware of the fact that the boolean expression will be short-cut evaluated.
|
|
(Meaning that the evaluation will be stopped at the point where the
|
|
outcome is known with certainty)
|
|
Also, before the \var {else} keyword, no semicolon (\var{;}) is allowed,
|
|
but all statements can be compound statements.
|
|
In nested \var{If.. then .. else} constructs, some ambiguity may araise as
|
|
to which \var{else} statement pairs with which \var{if} statement. The rule
|
|
is that the \var{else } keyword matches the first \var{if} keyword not
|
|
already matched by an \var{else} keyword.
|
|
For example:
|
|
\begin{verbatim}
|
|
If exp1 Then
|
|
If exp2 then
|
|
Stat1
|
|
else
|
|
stat2;
|
|
\end{verbatim}
|
|
Despite it's appearance, the statement is syntactically equivalent to
|
|
\begin{verbatim}
|
|
If exp1 Then
|
|
begin
|
|
If exp2 then
|
|
Stat1
|
|
else
|
|
stat2
|
|
end;
|
|
\end{verbatim}
|
|
and not to
|
|
\begin{verbatim}
|
|
{ NOT EQUIVALENT }
|
|
If exp1 Then
|
|
begin
|
|
If exp2 then
|
|
Stat1
|
|
end
|
|
else
|
|
stat2
|
|
\end{verbatim}
|
|
If it is this latter construct is needed, the \var{begin} and \var{end}
|
|
keywords must be present. When in doubt, it is better to add them.
|
|
|
|
The following is a valid statement:
|
|
\begin{verbatim}
|
|
If Today in [Monday..Friday] then
|
|
WriteLn ('Must work harder')
|
|
else
|
|
WriteLn ('Take a day off.');
|
|
\end{verbatim}
|
|
\subsection{The \var{For..to/downto..do} statement}
|
|
\fpc supports the \var{For} loop construction. A for loop is used in case
|
|
one wants to calculated something a fixed number of times.
|
|
The prototype syntax is as follows:
|
|
\input{syntax/for.syn}
|
|
\var{Statement} can be a compound statement.
|
|
When this statement is encountered, the control variable is initialized with
|
|
the initial value, and is compared with the final value.
|
|
What happens next depends on whether \var{to} or \var{downto} is used:
|
|
\begin{enumerate}
|
|
\item In the case \var{To} is used, if the initial value larger than the final
|
|
value then \var{Statement} will never be executed.
|
|
\item In the case \var{DownTo} is used, if the initial value larger than the final
|
|
value then \var{Statement} will never be executed.
|
|
\end{enumerate}
|
|
After this check, the statement after \var{Do} is executed. After the
|
|
execution of the statement, the control variable is increased or decreased
|
|
with 1, depending on whether \var{To} or \var{Downto} is used.
|
|
The control variable must be an ordinal type, no other
|
|
types can be used as counters in a loop.
|
|
|
|
\begin{remark}
|
|
Contrary to ANSI pascal specifications, \fpc first initializes
|
|
the counter variable, and only then calculates the upper bound.
|
|
\end{remark}
|
|
|
|
The following are valid loops:
|
|
\begin{verbatim}
|
|
For Day := Monday to Friday do Work;
|
|
For I := 100 downto 1 do
|
|
WriteLn ('Counting down : ',i);
|
|
For I := 1 to 7*dwarfs do KissDwarf(i);
|
|
\end{verbatim}
|
|
|
|
If the statement is a compound statement, then the \seep{Break} and
|
|
\seep{Continue} reserved words can be used to jump to the end or just
|
|
after the end of the \var{For} statement.
|
|
|
|
|
|
\subsection{The \var{Repeat..until} statement}
|
|
The \var{repeat} statement is used to execute a statement until a certain
|
|
condition is reached. The statement will be executed at least once.
|
|
The prototype syntax of the \var{Repeat..until} statement is
|
|
\input{syntax/repeat.syn}
|
|
This will execute the statements between \var{repeat} and \var{until} up to
|
|
the moment when \var{Expression} evaluates to \var{True}.
|
|
Since the \var{expression} is evaluated {\em after} the execution of the
|
|
statements, they are executed at least once.
|
|
Be aware of the fact that the boolean expression \var{Expression} will be
|
|
short-cut evaluated. (Meaning that the evaluation will be stopped at the
|
|
point where the outcome is known with certainty)
|
|
The following are valid \var{repeat} statements
|
|
\begin{verbatim}
|
|
repeat
|
|
WriteLn ('I =',i);
|
|
I := I+2;
|
|
until I>100;
|
|
repeat
|
|
X := X/2
|
|
until x<10e-3
|
|
\end{verbatim}
|
|
The \seep{Break} and \seep{Continue} reserved words can be used to jump to
|
|
the end or just after the end of the \var{repeat .. until } statement.
|
|
|
|
\subsection{The \var{While..do} statement}
|
|
A \var{while} statement is used to execute a statement as long as a certain
|
|
condition holds. This may imply that the statement is never executed.
|
|
The prototype syntax of the \var{While..do} statement is
|
|
\input{syntax/while.syn}
|
|
This will execute \var{Statement} as long as \var{Expression} evaluates to
|
|
\var{True}. Since \var{Expression} is evaluated {\em before} the execution
|
|
of \var{Statement}, it is possible that \var{Statement} isn't executed at
|
|
all. \var{Statement} can be a compound statement.
|
|
Be aware of the fact that the boolean expression \var{Expression} will be
|
|
short-cut evaluated. (Meaning that the evaluation will be stopped at the
|
|
point where the outcome is known with certainty)
|
|
The following are valid \var{while} statements:
|
|
\begin{verbatim}
|
|
I := I+2;
|
|
while i<=100 do
|
|
begin
|
|
WriteLn ('I =',i);
|
|
I := I+2;
|
|
end;
|
|
X := X/2;
|
|
while x>=10e-3 do
|
|
X := X/2;
|
|
\end{verbatim}
|
|
They correspond to the example loops for the \var{repeat} statements.
|
|
|
|
If the statement is a compound statement, then the \seep{Break} and
|
|
\seep{Continue} reserved words can be used to jump to the end or just
|
|
after the end of the \var{While} statement.
|
|
|
|
\subsection{The \var{With} statement}
|
|
\label{se:With}
|
|
The \var{with} statement serves to access the elements of a record
|
|
or object or class, without having to specify the name of the each time.
|
|
The syntax for a \var{with} statement is
|
|
\input{syntax/with.syn}
|
|
The variable reference must be a variable of a record, object or class type.
|
|
In the \var{with} statement, any variable reference, or method reference is
|
|
checked to see if it is a field or method of the record or object or class.
|
|
If so, then that field is accessed, or that method is called.
|
|
Given the declaration:
|
|
\begin{verbatim}
|
|
Type Passenger = Record
|
|
Name : String[30];
|
|
Flight : String[10];
|
|
end;
|
|
Var TheCustomer : Passenger;
|
|
\end{verbatim}
|
|
The following statements are completely equivalent:
|
|
\begin{verbatim}
|
|
TheCustomer.Name := 'Michael';
|
|
TheCustomer.Flight := 'PS901';
|
|
\end{verbatim}
|
|
and
|
|
\begin{verbatim}
|
|
With TheCustomer do
|
|
begin
|
|
Name := 'Michael';
|
|
Flight := 'PS901';
|
|
end;
|
|
\end{verbatim}
|
|
The statement
|
|
\begin{verbatim}
|
|
With A,B,C,D do Statement;
|
|
\end{verbatim}
|
|
is equivalent to
|
|
\begin{verbatim}
|
|
With A do
|
|
With B do
|
|
With C do
|
|
With D do Statement;
|
|
\end{verbatim}
|
|
This also is a clear example of the fact that the variables are tried {\em last
|
|
to first}, i.e., when the compiler encounters a variable reference, it will
|
|
first check if it is a field or method of the last variable. If not, then it
|
|
will check the last-but-one, and so on.
|
|
The following example shows this;
|
|
\begin{verbatim}
|
|
Program testw;
|
|
Type AR = record
|
|
X,Y : Longint;
|
|
end;
|
|
PAR = Record;
|
|
|
|
Var S,T : Ar;
|
|
begin
|
|
S.X := 1;S.Y := 1;
|
|
T.X := 2;T.Y := 2;
|
|
With S,T do
|
|
WriteLn (X,' ',Y);
|
|
end.
|
|
\end{verbatim}
|
|
The output of this program is
|
|
\begin{verbatim}
|
|
2 2
|
|
\end{verbatim}
|
|
Showing thus that the \var{X,Y} in the \var{WriteLn} statement match the
|
|
\var{T} record variable.
|
|
|
|
\begin{remark}
|
|
When using a \var{With} statement with a pointer, or a class, it is not
|
|
permitted to change the pointer or the class in the \var{With} block.
|
|
With the definitions of the previous example, the following illustrates
|
|
what it is about:
|
|
\begin{verbatim}
|
|
|
|
Var p : PAR;
|
|
|
|
begin
|
|
With P^ do
|
|
begin
|
|
// Do some operations
|
|
P:=OtherP;
|
|
X:=0.0; // Wrong X will be used !!
|
|
end;
|
|
\end{verbatim}
|
|
The reason the pointer cannot be changed is that the address is stored
|
|
by the compiler in a temporary register. Changing the pointer won't change
|
|
the temporary address. The same is true for classes.
|
|
\end{remark}
|
|
|
|
\subsection{Exception Statements}
|
|
\fpc supports exceptions. Exceptions provide a convenient way to
|
|
program error and error-recovery mechanisms, and are
|
|
closely related to classes.
|
|
Exception support is explained in \seec{Exceptions}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Assembler statements
|
|
\section{Assembler statements}
|
|
An assembler statement allows to insert assembler code right in the
|
|
pascal code.
|
|
\input{syntax/statasm.syn}
|
|
More information about assembler blocks can be found in the \progref.
|
|
The register list is used to indicate the registers that are modified by an
|
|
assembler statement in the assembler block. The compiler stores certain results in the
|
|
registers. If the registers are modified in an assembler statement, the compiler
|
|
should, sometimes, be told about it. The registers are denoted with their
|
|
Intel names for the I386 processor, i.e., \var{'EAX'}, \var{'ESI'} etc...
|
|
As an example, consider the following assembler code:
|
|
\begin{verbatim}
|
|
asm
|
|
Movl $1,%ebx
|
|
Movl $0,%eax
|
|
addl %eax,%ebx
|
|
end; ['EAX','EBX'];
|
|
\end{verbatim}
|
|
This will tell the compiler that it should save and restore the contents of
|
|
the \var{EAX} and \var{EBX} registers when it encounters this asm statement.
|
|
|
|
\fpc supports various styles of assembler syntax. By default, \var{AT\&T}
|
|
syntax is assumed for the 80386 and compatibles platform.
|
|
The default assembler style can be changed with the \var{\{\$asmmode xxx\}}
|
|
switch in the code, or the \var{-R} command-line option. More about this can
|
|
be found in the \progref.
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Using functions and procedures.
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Using functions and procedures}
|
|
\label{ch:Procedures}
|
|
\fpc supports the use of functions and procedures, but with some extras:
|
|
Function overloading is supported, as well as \var{Const} parameters and
|
|
open arrays.
|
|
|
|
\begin{remark} In many of the subsequent paragraphs the words \var{procedure}
|
|
and \var{function} will be used interchangeably. The statements made are
|
|
valid for both, except when indicated otherwise.
|
|
\end{remark}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Procedure declaration
|
|
\section{Procedure declaration}
|
|
A procedure declaration defines an identifier and associates it with a
|
|
block of code. The procedure can then be called with a procedure statement.
|
|
\input{syntax/procedur.syn}
|
|
See \sees{Parameters} for the list of parameters.
|
|
A procedure declaration that is followed by a block implements the action of
|
|
the procedure in that block.
|
|
The following is a valid procedure :
|
|
\begin{verbatim}
|
|
Procedure DoSomething (Para : String);
|
|
begin
|
|
Writeln ('Got parameter : ',Para);
|
|
Writeln ('Parameter in upper case : ',Upper(Para));
|
|
end;
|
|
\end{verbatim}
|
|
Note that it is possible that a procedure calls itself.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Function declaration
|
|
\section{Function declaration}
|
|
A function declaration defines an identifier and associates it with a
|
|
block of code. The block of code will return a result.
|
|
The function can then be called inside an expression, or with a procedure
|
|
statement, if extended syntax is on.
|
|
\input{syntax/function.syn}
|
|
The result type of a function can be any previously declared type.
|
|
contrary to Turbo pascal, where only simple types could be returned.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Parameter lists
|
|
\section{Parameter lists}
|
|
\label{se:Parameters}
|
|
When arguments must be passed to a function or procedure, these parameters
|
|
must be declared in the formal parameter list of that function or procedure.
|
|
The parameter list is a declaration of identifiers that can be referred to
|
|
only in that procedure or function's block.
|
|
\input{syntax/params.syn}
|
|
Constant parameters and variable parameters can also be \var{untyped}
|
|
parameters if they have no type identifier.
|
|
|
|
As of version 1.1, \fpc supports default values for both constant parameters
|
|
and value parameters, but only for simple types. The compiler must be in
|
|
\var{OBJFPC} or \var{DELPHI} mode to accept default values.
|
|
|
|
\subsection{Value parameters}
|
|
Value parameters are declared as follows:
|
|
\input{syntax/paramval.syn}
|
|
When parameters are declared as value parameters, the procedure gets {\em
|
|
a copy} of the parameters that the calling block passes. Any modifications
|
|
to these parameters are purely local to the procedure's block, and do not
|
|
propagate back to the calling block.
|
|
A block that wishes to call a procedure with value parameters must pass
|
|
assignment compatible parameters to the procedure. This means that the types
|
|
should not match exactly, but can be converted (conversion code is inserted
|
|
by the compiler itself)
|
|
|
|
Care must be taken when using value parameters: Value parameters makes heavy
|
|
use of the stack, especially when using large parameters. The total size of
|
|
all parameters in the formal parameter list should be below 32K for
|
|
portability's sake (the Intel version limits this to 64K).
|
|
|
|
Open arrays can be passed as value parameters. See \sees{openarray} for
|
|
more information on using open arrays.
|
|
|
|
For a parameter of a simple type (i.e. not a structured type), a default
|
|
value can be specified. This can be an untyped constant. If the function
|
|
call omits the parameter, the default value will be passed on to the
|
|
function. For dynamic arrays or other types that can be considered as
|
|
equivalent to a pointer, the only possible default value is \var{Nil}.
|
|
|
|
The following example will print 20 on the screen:
|
|
\begin{verbatim}
|
|
program testp;
|
|
|
|
Const
|
|
MyConst = 20;
|
|
|
|
Procedure MyRealFunc(I : Integer = MyConst);
|
|
|
|
begin
|
|
Writeln('Function received : ',I);
|
|
end;
|
|
|
|
begin
|
|
MyRealFunc;
|
|
end.
|
|
\end{verbatim}
|
|
|
|
\subsection{Variable parameters}
|
|
\label{se:varparams}
|
|
Variable parameters are declared as follows:
|
|
\input{syntax/paramvar.syn}
|
|
When parameters are declared as variable parameters, the procedure or
|
|
function accesses immediatly the variable that the calling block passed in
|
|
its parameter list. The procedure gets a pointer to the variable that was
|
|
passed, and uses this pointer to access the variable's value.
|
|
From this, it follows that any changes made to the parameter, will
|
|
propagate back to the calling block. This mechanism can be used to pass
|
|
values back in procedures.
|
|
Because of this, the calling block must pass a parameter of {\em exactly}
|
|
the same type as the declared parameter's type. If it does not, the compiler
|
|
will generate an error.
|
|
|
|
Variable and constant parameters can be untyped. In that case the variable has no type,
|
|
and hence is incompatible with all other types. However, the address operator
|
|
can be used on it, or it can be can passed to a function that has also an
|
|
untyped parameter. If an untyped parameter is used in an assigment,
|
|
or a value must be assigned to it, a typecast must be used.
|
|
|
|
File type variables must always be passed as variable parameters.
|
|
|
|
Open arrays can be passed as variable parameters. See \sees{openarray} for
|
|
more information on using open arrays.
|
|
|
|
Note that default values are not supported for variable parameters. This
|
|
would make little sense since it defeats the purpose of being able to pass a
|
|
value back to the caller.
|
|
|
|
\subsection{Out parameters}
|
|
\label{se:outparams}
|
|
Out parameters (output parameters) are declared as follows:
|
|
\input{syntax/paramout.syn}
|
|
The purpose of an \var{out} parameter is to pass values back to the calling
|
|
routine: The variable is passed by reference. The initial value of the
|
|
parameter on function entry is discarded, and should not be used.
|
|
|
|
If a variable must be used to pass a value to a function and retrieve data
|
|
from the function, then a variable parameter must be used. If only a value
|
|
must be retrieved, a \var{out} parameter can be used.
|
|
|
|
Needless to say, default values are not supported for \var{out} parameters.
|
|
|
|
\subsection{Constant parameters}
|
|
In addition to variable parameters and value parameters \fpc also supports
|
|
Constant parameters. A constant parameter as can be specified as follows:
|
|
\input{syntax/paramcon.syn}
|
|
A constant argument is passed by reference if it's size is larger than a
|
|
pointer. It is passed by value if the size is equal or is less then the
|
|
size of a native pointer.
|
|
This means that the function or procedure receives a pointer to the passed
|
|
argument, but it cannot be assigned to, this will result in a
|
|
compiler error. Furthermore a const parameter cannot be passed on to another
|
|
function that requires a variable parameter.
|
|
The main use for this is reducing the stack size, hence improving
|
|
performance, and still retaining the semantics of passing by value...
|
|
|
|
Constant parameters can also be untyped. See \sees{varparams} for more
|
|
information about untyped parameters.
|
|
|
|
As for value parameters, constant parameters can get default values.
|
|
|
|
Open arrays can be passed as constant parameters. See \sees{openarray} for
|
|
more information on using open arrays.
|
|
\subsection{Open array parameters}
|
|
\label{se:openarray}
|
|
\fpc supports the passing of open arrays, i.e. a procedure can be declared
|
|
with an array of unspecified length as a parameter, as in Delphi.
|
|
Open array parameters can be accessed in the procedure or function as an
|
|
array that is declared with starting index 0, and last element
|
|
index \var{High(paremeter)}.
|
|
For example, the parameter
|
|
\begin{verbatim}
|
|
Row : Array of Integer;
|
|
\end{verbatim}
|
|
would be equivalent to
|
|
\begin{verbatim}
|
|
Row : Array[0..N-1] of Integer;
|
|
\end{verbatim}
|
|
Where \var{N} would be the actual size of the array that is passed to the
|
|
function. \var{N-1} can be calculated as \var{High(Row)}.
|
|
Open parameters can be passed by value, by reference or as a constant
|
|
parameter. In the latter cases the procedure receives a pointer to the
|
|
actual array. In the former case, it receives a copy of the array.
|
|
In a function or procedure, open arrays can only be passed to functions which
|
|
are also declared with open arrays as parameters, {\em not} to functions or
|
|
procedures which accept arrays of fixed length.
|
|
The following is an example of a function using an open array:
|
|
\begin{verbatim}
|
|
Function Average (Row : Array of integer) : Real;
|
|
Var I : longint;
|
|
Temp : Real;
|
|
begin
|
|
Temp := Row[0];
|
|
For I := 1 to High(Row) do
|
|
Temp := Temp + Row[i];
|
|
Average := Temp / (High(Row)+1);
|
|
end;
|
|
\end{verbatim}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The array of const construct
|
|
\subsection{Array of const}
|
|
In Object Pascal or Delphi mode, \fpc supports the \var{Array of Const}
|
|
construction to pass parameters to a subroutine.
|
|
|
|
This is a special case of the \var{Open array} construction, where it is
|
|
allowed to pass any expression in an array to a function or procedure.
|
|
|
|
In the procedure, passed the arguments can be examined using a special
|
|
record:
|
|
\begin{verbatim}
|
|
Type
|
|
PVarRec = ^TVarRec;
|
|
TVarRec = record
|
|
case VType : Longint of
|
|
vtInteger : (VInteger: Longint);
|
|
vtBoolean : (VBoolean: Boolean);
|
|
vtChar : (VChar: Char);
|
|
vtExtended : (VExtended: PExtended);
|
|
vtString : (VString: PShortString);
|
|
vtPointer : (VPointer: Pointer);
|
|
vtPChar : (VPChar: PChar);
|
|
vtObject : (VObject: TObject);
|
|
vtClass : (VClass: TClass);
|
|
vtAnsiString : (VAnsiString: Pointer);
|
|
vtWideString : (VWideString: Pointer);
|
|
vtInt64 : (VInt64: PInt64);
|
|
end;
|
|
\end{verbatim}
|
|
Inside the procedure body, the array of const is equivalent to
|
|
an open array of TVarRec:
|
|
\begin{verbatim}
|
|
Procedure Testit (Args: Array of const);
|
|
|
|
Var I : longint;
|
|
|
|
begin
|
|
If High(Args)<0 then
|
|
begin
|
|
Writeln ('No aguments');
|
|
exit;
|
|
end;
|
|
Writeln ('Got ',High(Args)+1,' arguments :');
|
|
For i:=0 to High(Args) do
|
|
begin
|
|
write ('Argument ',i,' has type ');
|
|
case Args[i].vtype of
|
|
vtinteger :
|
|
Writeln ('Integer, Value :',args[i].vinteger);
|
|
vtboolean :
|
|
Writeln ('Boolean, Value :',args[i].vboolean);
|
|
vtchar :
|
|
Writeln ('Char, value : ',args[i].vchar);
|
|
vtextended :
|
|
Writeln ('Extended, value : ',args[i].VExtended^);
|
|
vtString :
|
|
Writeln ('ShortString, value :',args[i].VString^);
|
|
vtPointer :
|
|
Writeln ('Pointer, value : ',Longint(Args[i].VPointer));
|
|
vtPChar :
|
|
Writeln ('PCHar, value : ',Args[i].VPChar);
|
|
vtObject :
|
|
Writeln ('Object, name : ',Args[i].VObject.Classname);
|
|
vtClass :
|
|
Writeln ('Class reference, name :',Args[i].VClass.Classname);
|
|
vtAnsiString :
|
|
Writeln ('AnsiString, value :',AnsiString(Args[I].VAnsiStr
|
|
else
|
|
Writeln ('(Unknown) : ',args[i].vtype);
|
|
end;
|
|
end;
|
|
end;
|
|
\end{verbatim}
|
|
In code, it is possible to pass an arbitrary array of elements
|
|
to this procedure:
|
|
\begin{verbatim}
|
|
S:='Ansistring 1';
|
|
T:='AnsiString 2';
|
|
Testit ([]);
|
|
Testit ([1,2]);
|
|
Testit (['A','B']);
|
|
Testit ([TRUE,FALSE,TRUE]);
|
|
Testit (['String','Another string']);
|
|
Testit ([S,T]) ;
|
|
Testit ([P1,P2]);
|
|
Testit ([@testit,Nil]);
|
|
Testit ([ObjA,ObjB]);
|
|
Testit ([1.234,1.234]);
|
|
TestIt ([AClass]);
|
|
\end{verbatim}
|
|
|
|
If the procedure is declared with the \var{cdecl} modifier, then the
|
|
compiler will pass the array as a C compiler would pass it. This, in effect,
|
|
emulates the C construct of a variable number of arguments, as the following
|
|
example will show:
|
|
\begin{verbatim}
|
|
program testaocc;
|
|
{$mode objfpc}
|
|
|
|
Const
|
|
P : Pchar = 'example';
|
|
Fmt : PChar =
|
|
'This %s uses printf to print numbers (%d) and strings.'#10;
|
|
|
|
// Declaration of standard C function printf:
|
|
procedure printf (fm : pchar; args : array of const);cdecl; external 'c';
|
|
|
|
begin
|
|
printf(Fmt,[P,123]);
|
|
end.
|
|
\end{verbatim}
|
|
Remark that this is not true for Delphi, so code relying on this feature
|
|
will not be portable.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Function overloading
|
|
\section{Function overloading}
|
|
Function overloading simply means that the same function is defined more
|
|
than once, but each time with a different formal parameter list.
|
|
The parameter lists must differ at least in one of it's elements type.
|
|
When the compiler encounters a function call, it will look at the function
|
|
parameters to decide which one of the defined functions it should call.
|
|
This can be useful when the same function must be defined for different
|
|
types. For example, in the RTL, the \var{Dec} procedure could be
|
|
defined as:
|
|
\begin{verbatim}
|
|
...
|
|
Dec(Var I : Longint;decrement : Longint);
|
|
Dec(Var I : Longint);
|
|
Dec(Var I : Byte;decrement : Longint);
|
|
Dec(Var I : Byte);
|
|
...
|
|
\end{verbatim}
|
|
When the compiler encounters a call to the dec function, it will first search
|
|
which function it should use. It therefore checks the parameters in a
|
|
function call, and looks if there is a function definition which matches the
|
|
specified parameter list. If the compiler finds such a function, a call is
|
|
inserted to that function. If no such function is found, a compiler error is
|
|
generated.
|
|
functions that have a \var{cdecl} modifier cannot be overloaded.
|
|
(Technically, because this modifier prevents the mangling of
|
|
the function name by the compiler).
|
|
|
|
Prior to version 1.9 of the compiler, the overloaded functions needed to be
|
|
in the same unit. Now the compiler will continue searching in other units if
|
|
it doesn't find a matching version of an overloaded function in one unit.
|
|
|
|
The compiler accepts the presence of the \var{overload} modifier as in
|
|
Delphi, but it is not required, unless in Delphi mode.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% forward defined functions
|
|
\section{Forward defined functions}
|
|
A function can be declared without having it followed by it's implementation,
|
|
by having it followed by the \var{forward} procedure. The effective
|
|
implementation of that function must follow later in the module.
|
|
The function can be used after a \var{forward} declaration as if it had been
|
|
implemented already.
|
|
The following is an example of a forward declaration.
|
|
\begin{verbatim}
|
|
Program testforward;
|
|
Procedure First (n : longint); forward;
|
|
Procedure Second;
|
|
begin
|
|
WriteLn ('In second. Calling first...');
|
|
First (1);
|
|
end;
|
|
Procedure First (n : longint);
|
|
begin
|
|
WriteLn ('First received : ',n);
|
|
end;
|
|
begin
|
|
Second;
|
|
end.
|
|
\end{verbatim}
|
|
A function can be defined as forward only once.
|
|
Likewise, in units, it is not allowed to have a forward declared function
|
|
of a function that has been declared in the interface part. The interface
|
|
declaration counts as a \var{forward} declaration.
|
|
The following unit will give an error when compiled:
|
|
\begin{verbatim}
|
|
Unit testforward;
|
|
interface
|
|
Procedure First (n : longint);
|
|
Procedure Second;
|
|
implementation
|
|
Procedure First (n : longint); forward;
|
|
Procedure Second;
|
|
begin
|
|
WriteLn ('In second. Calling first...');
|
|
First (1);
|
|
end;
|
|
Procedure First (n : longint);
|
|
begin
|
|
WriteLn ('First received : ',n);
|
|
end;
|
|
end.
|
|
\end{verbatim}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% External functions
|
|
\section{External functions}
|
|
\label{se:external}
|
|
The \var{external} modifier can be used to declare a function that resides in
|
|
an external object file. It allows to use the function in some code, and at
|
|
linking time, the object file containing the implementation of the function
|
|
or procedure must be linked in.
|
|
\input{syntax/external.syn}
|
|
It replaces, in effect, the function or procedure code block.
|
|
As an example:
|
|
\begin{verbatim}
|
|
program CmodDemo;
|
|
{$Linklib c}
|
|
Const P : PChar = 'This is fun !';
|
|
Function strlen (P : PChar) : Longint; cdecl; external;
|
|
begin
|
|
WriteLn ('Length of (',p,') : ',strlen(p))
|
|
end.
|
|
\end{verbatim}
|
|
\begin{remark}
|
|
The parameters in our declaration of the \var{external} function
|
|
should match exactly the ones in the declaration in the object file.
|
|
\end{remark}
|
|
If the \var{external} modifier is followed by a string constant:
|
|
\begin{verbatim}
|
|
external 'lname';
|
|
\end{verbatim}
|
|
Then this tells the compiler that the function resides in library
|
|
'lname'. The compiler will then automatically link this library to
|
|
the program.
|
|
|
|
The name that the function has in the library can also be specified:
|
|
\begin{verbatim}
|
|
external 'lname' name 'Fname';
|
|
\end{verbatim}
|
|
This tells the compiler that the function resides in library 'lname',
|
|
but with name 'Fname'.The compiler will then automatically link this
|
|
library to the program, and use the correct name for the function.
|
|
Under \windows and \ostwo, the following form can also be used:
|
|
\begin{verbatim}
|
|
external 'lname' Index Ind;
|
|
\end{verbatim}
|
|
This tells the compiler that the function resides in library 'lname',
|
|
but with index \var{Ind}. The compiler will then automatically
|
|
link this library to the program, and use the correct index for the
|
|
function.
|
|
|
|
Finally, the external directive can be used to specify the external name
|
|
of the function :
|
|
\begin{verbatim}
|
|
{$L myfunc.o}
|
|
external name 'Fname';
|
|
\end{verbatim}
|
|
This tells the compiler that the function has the name 'Fname'. The
|
|
correct library or object file (in this case myfunc.o) must still be linked.
|
|
so that the function 'Fname' is included in the linking stage.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Assembler functions
|
|
\section{Assembler functions}
|
|
Functions and procedures can be completely implemented in assembly
|
|
language. To indicate this, use the \var{assembler} keyword:
|
|
\input{syntax/asm.syn}
|
|
Contrary to Delphi, the assembler keyword must be present to indicate an
|
|
assembler function.
|
|
For more information about assembler functions, see the chapter on using
|
|
assembler in the \progref.
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Modifiers
|
|
\section{Modifiers}
|
|
A function or procedure declaration can contain modifiers. Here we list the
|
|
various possibilities:
|
|
\input{syntax/modifiers.syn}
|
|
\fpc doesn't support all Turbo Pascal modifiers, but
|
|
does support a number of additional modifiers. They are used mainly for assembler and
|
|
reference to C object files.
|
|
|
|
\subsection{alias}
|
|
The \var{alias} modifier allows the programmer to specify a different name for a
|
|
procedure or function. This is mostly useful for referring to this procedure
|
|
from assembly language constructs or from another object file. As an example,
|
|
consider the following program:
|
|
\begin{verbatim}
|
|
Program Aliases;
|
|
|
|
Procedure Printit;alias : 'DOIT';
|
|
begin
|
|
WriteLn ('In Printit (alias : "DOIT")');
|
|
end;
|
|
begin
|
|
asm
|
|
call DOIT
|
|
end;
|
|
end.
|
|
\end{verbatim}
|
|
\begin{remark} the specified alias is inserted straight into the assembly
|
|
code, thus it is case sensitive.
|
|
\end{remark}
|
|
The \var{alias} modifier does not make the symbol public to other modules,
|
|
unless the routine is also declared in the interface part of a unit, or
|
|
the \var{public} modifier is used to force it as public. Consider the
|
|
following:
|
|
\begin{verbatim}
|
|
|
|
unit testalias;
|
|
|
|
interface
|
|
|
|
procedure testroutine;
|
|
|
|
implementation
|
|
|
|
procedure testroutine;alias:'ARoutine';
|
|
begin
|
|
WriteLn('Hello world');
|
|
end;
|
|
|
|
end.
|
|
\end{verbatim}
|
|
|
|
This will make the routine \var{testroutine} available publicly to
|
|
external object files uunder the label name \var{ARoutine}.
|
|
|
|
\subsection{cdecl}
|
|
\label{se:cdecl}
|
|
The \var{cdecl} modifier can be used to declare a function that uses a C
|
|
type calling convention. This must be used when accessing functions residing in
|
|
an object file generated by standard C compilers. It allows to use the function in
|
|
the code, and at linking time, the object file containing the
|
|
\var{C} implementation of the function or procedure must be linked in.
|
|
As an example:
|
|
\begin{verbatim}
|
|
program CmodDemo;
|
|
{$LINKLIB c}
|
|
Const P : PChar = 'This is fun !';
|
|
Function strlen (P : PChar) : Longint; cdecl; external name 'strlen';
|
|
begin
|
|
WriteLn ('Length of (',p,') : ',strlen(p))
|
|
end.
|
|
\end{verbatim}
|
|
When compiling this, and linking to the C-library, the \var{strlen} function
|
|
can be called throughout the program. The \var{external} directive tells
|
|
the compiler that the function resides in an external object filebrary
|
|
with the 'strlen' name (see \ref{se:external}).
|
|
\begin{remark}
|
|
The parameters in our declaration of the \var{C} function should
|
|
match exactly the ones in the declaration in \var{C}.
|
|
\end{remark}
|
|
|
|
\subsection{export}
|
|
The export modifier is used to export names when creating a shared library
|
|
or an executable program. This means that the symbol will be publicly
|
|
available, and can be imported from other programs. For more information
|
|
on this modifier, consult the section on Programming dynamic libraries
|
|
in the \progref.
|
|
|
|
|
|
\subsection{inline}
|
|
\label{se:inline}
|
|
Procedures that are declared inline are copied to the places where they
|
|
are called. This has the effect that there is no actual procedure call,
|
|
the code of the procedure is just copied to where the procedure is needed,
|
|
this results in faster execution speed if the function or procedure is
|
|
used a lot.
|
|
|
|
By default, \var{inline} procedures are not allowed. Inline code must be enabled
|
|
using the command-line switch \var{-Si} or \var{\{\$inline on\}}
|
|
directive.
|
|
|
|
|
|
\begin{enumerate}
|
|
\item Inline code is NOT exported from a unit. This means that when
|
|
calling an inline procedure from another unit, a normal procedure call will be
|
|
performed. Only inside units, \var{Inline} procedures are really inlined.
|
|
\item Recursive inline functions are not allowed. i.e. an inline function
|
|
that calls itself is not allowed.
|
|
\end{enumerate}
|
|
|
|
\subsection{interrupt}
|
|
\label{se:interrupt}
|
|
The \var{interrupt} keyword is used to declare a routine which will
|
|
be used as an interrupt handler. On entry to this routine, all the registers
|
|
will be saved and on exit, all registers will be restored
|
|
and an interrupt or trap return will be executed (instead of the normal return
|
|
from subroutine instruction).
|
|
|
|
On platforms where a return from interrupt does not exist, the normal exit
|
|
code of routines will be done instead. For more information on the generated
|
|
code, consult the \progref.
|
|
|
|
\subsection{pascal}
|
|
\label{se:pascal}
|
|
The \var{pascal} modifier can be used to declare a function that uses the
|
|
classic pascal type calling convention (passing parameters from left to right).
|
|
For more information on the pascal calling convention, consult the \progref.
|
|
|
|
\subsection{popstack}
|
|
\label{se:popstack}
|
|
Popstack does the same as \var{cdecl}, namely it tells the \fpc compiler
|
|
that a function uses the C calling convention. In difference with the
|
|
\var{cdecl} modifier, it still mangles the name of the function as it would
|
|
for a normal pascal function.
|
|
With \var{popstack}, functions can be called by their pascal names in a
|
|
library.
|
|
|
|
\subsection{public}
|
|
The \var{Public} keyword is used to declare a function globally in a unit.
|
|
This is useful if the function should not be accessible from the unit
|
|
file (i.e. another unit/program using the unit doesn't see the function),
|
|
but must be accessible from the object file. as an example:
|
|
\begin{verbatim}
|
|
Unit someunit;
|
|
interface
|
|
Function First : Real;
|
|
Implementation
|
|
Function First : Real;
|
|
begin
|
|
First := 0;
|
|
end;
|
|
Function Second : Real; [Public];
|
|
begin
|
|
Second := 1;
|
|
end;
|
|
end.
|
|
\end{verbatim}
|
|
If another program or unit uses this unit, it will not be able to use the
|
|
function \var{Second}, since it isn't declared in the interface part.
|
|
However, it will be possible to access the function \var{Second} at the
|
|
assembly-language level, by using it's mangled name (see the \progref).
|
|
|
|
\subsection{register}
|
|
\label{se:register}
|
|
The \var{register} keyword is used for compatibility with Delphi. In
|
|
version 1.0.x of the compiler, this directive has no effect on the
|
|
generated code. As of the 1.9.X versions, this directive is supported. The
|
|
first three arguments are passed in registers EAX,ECX and EDX.
|
|
|
|
\subsection{saveregisters}
|
|
If this modifier is specified after a procedure or function, then the
|
|
\fpc compiler will save all registers on procedure entry, and restore
|
|
them when the procedure exits (except for registers where return values
|
|
are stored).
|
|
|
|
This modifier is not used under normal circumstances, except maybe when
|
|
calling assembler code.
|
|
|
|
\subsection{safecall}
|
|
This modifier ressembles closely the \var{stdcall} modifier. It sends
|
|
parameters from right to left on the stack. The called procedure saves and
|
|
restores all registers.
|
|
|
|
More information about this modifier can be found in the \progref, in the
|
|
section on the calling mechanism and the chapter on linking.
|
|
|
|
\subsection{softfloat}
|
|
This modifier makes sense only on the ARM architecture.
|
|
|
|
\subsection{stdcall}
|
|
This modifier pushes the parameters from right to left on the stack,
|
|
it also aligns all the parameters to a default alignment.
|
|
|
|
More information about this modifier can be found in the \progref, in the
|
|
section on the calling mechanism and the chapter on linking.
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Unsupported Turbo Pascal modifiers
|
|
\section{Unsupported Turbo Pascal modifiers}
|
|
The modifiers that exist in Turbo pascal, but aren't supported by \fpc, are
|
|
listed in \seet{Modifs}.
|
|
\begin{FPCltable}{lr}{Unsupported modifiers}{Modifs}
|
|
Modifier & Why not supported ? \\ \hline
|
|
Near & \fpc is a 32-bit compiler.\\
|
|
Far & \fpc is a 32-bit compiler. \\
|
|
\end{FPCltable}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Operator overloading
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Operator overloading}
|
|
\label{ch:operatoroverloading}
|
|
|
|
\section{Introduction}
|
|
\fpc supports operator overloading. This means that it is possible to
|
|
define the action of some operators on self-defined types, and thus allow
|
|
the use of these types in mathematical expressions.
|
|
|
|
Defining the action of an operator is much like the definition of a
|
|
function or procedure, only there are some restrictions on the possible
|
|
definitions, as will be shown in the subsequent.
|
|
|
|
Operator overloading is, in essence, a powerful notational tool;
|
|
but it is also not more than that, since the same results can be
|
|
obtained with regular function calls. When using operator overloading,
|
|
It is important to keep in mind that some implicit rules may produce
|
|
some unexpected results. This will be indicated.
|
|
|
|
\section{Operator declarations}
|
|
To define the action of an operator is much like defining a function:
|
|
\input{syntax/operator.syn}
|
|
The parameter list for a comparision operator or an arithmetic operator
|
|
must always contain 2 parameters. The result type of the comparision
|
|
operator must be \var{Boolean}.
|
|
|
|
\begin{remark}
|
|
When compiling in \var{Delphi} mode or \var{Objfpc} mode, the result
|
|
identifier may be dropped. The result can then be accessed through
|
|
the standard \var{Result} symbol.
|
|
|
|
If the result identifier is dropped and the compiler is not in one
|
|
of these modes, a syntax error will occur.
|
|
\end{remark}
|
|
|
|
The statement block contains the necessary statements to determine the
|
|
result of the operation. It can contain arbitrary large pieces of code;
|
|
it is executed whenever the operation is encountered in some expression.
|
|
The result of the statement block must always be defined; error conditions
|
|
are not checked by the compiler, and the code must take care of all possible
|
|
cases, throwing a run-time error if some error condition is encountered.
|
|
|
|
In the following, the three types of operator definitions will be examined.
|
|
As an example, throughout this chapter the following type will be used to
|
|
define overloaded operators on :
|
|
\begin{verbatim}
|
|
type
|
|
complex = record
|
|
re : real;
|
|
im : real;
|
|
end;
|
|
\end{verbatim}
|
|
this type will be used in all examples.
|
|
|
|
The sources of the Run-Time Library contain a unit \file{ucomplex},
|
|
which contains a complete calculus for complex numbers, based on
|
|
operator overloading.
|
|
|
|
\section{Assignment operators}
|
|
|
|
The assignment operator defines the action of a assignent of one type of
|
|
variable to another. The result type must match the type of the variable
|
|
at the left of the assignment statement, the single parameter to the
|
|
assignment operator must have the same type as the expression at the
|
|
right of the assignment operator.
|
|
|
|
This system can be used to declare a new type, and define an assignment for
|
|
that type. For instance, to be able to assign a newly defined type 'Complex'
|
|
\begin{verbatim}
|
|
Var
|
|
C,Z : Complex; // New type complex
|
|
|
|
begin
|
|
Z:=C; // assignments between complex types.
|
|
end;
|
|
\end{verbatim}
|
|
The following assignment operator would have to be defined:
|
|
\begin{verbatim}
|
|
Operator := (C : Complex) z : complex;
|
|
\end{verbatim}
|
|
|
|
|
|
To be able to assign a real type to a complex type as follows:
|
|
\begin{verbatim}
|
|
var
|
|
R : real;
|
|
C : complex;
|
|
|
|
begin
|
|
C:=R;
|
|
end;
|
|
\end{verbatim}
|
|
the following assignment operator must be defined:
|
|
\begin{verbatim}
|
|
Operator := (r : real) z : complex;
|
|
\end{verbatim}
|
|
As can be seen from this statement, it defines the action of the operator
|
|
\var{:=} with at the right a real expression, and at the left a complex
|
|
expression.
|
|
|
|
an example implementation of this could be as follows:
|
|
\begin{verbatim}
|
|
operator := (r : real) z : complex;
|
|
|
|
begin
|
|
z.re:=r;
|
|
z.im:=0.0;
|
|
end;
|
|
\end{verbatim}
|
|
As can be seen in the example, the result identifier (\var{z} in this case)
|
|
is used to store the result of the assignment. When compiling in Delphi mode
|
|
or objfpc mode, the use of the special identifier \var{Result} is also
|
|
allowed, and can be substituted for the \var{z}, so the above would be
|
|
equivalent to
|
|
\begin{verbatim}
|
|
operator := (r : real) z : complex;
|
|
|
|
begin
|
|
Result.re:=r;
|
|
Result.im:=0.0;
|
|
end;
|
|
\end{verbatim}
|
|
|
|
The assignment operator is also used to convert types from one type to
|
|
another. The compiler will consider all overloaded assignment operators
|
|
till it finds one that matches the types of the left hand and right hand
|
|
expressions. If no such operator is found, a 'type mismatch' error
|
|
is given.
|
|
|
|
\begin{remark}
|
|
The assignment operator is not commutative; the compiler will never reverse
|
|
the role of the two arguments. in other words, given the above definition of
|
|
the assignment operator, the following is {\em not} possible:
|
|
\begin{verbatim}
|
|
var
|
|
R : real;
|
|
C : complex;
|
|
|
|
begin
|
|
R:=C;
|
|
end;
|
|
\end{verbatim}
|
|
if the reverse assignment should be possible (this is not so for reals and
|
|
complex numbers) then the assigment operator must be defined for that as well.
|
|
\end{remark}
|
|
|
|
\begin{remark}
|
|
The assignment operator is also used in implicit type conversions. This can
|
|
have unwanted effects. Consider the following definitions:
|
|
\begin{verbatim}
|
|
operator := (r : real) z : complex;
|
|
function exp(c : complex) : complex;
|
|
\end{verbatim}
|
|
then the following assignment will give a type mismatch:
|
|
\begin{verbatim}
|
|
Var
|
|
r1,r2 : real;
|
|
|
|
begin
|
|
r1:=exp(r2);
|
|
end;
|
|
\end{verbatim}
|
|
because the compiler will encounter the definition of the \var{exp} function
|
|
with the complex argument. It implicitly converts r2 to a complex, so it can
|
|
use the above \var{exp} function. The result of this function is a complex,
|
|
which cannot be assigned to r1, so the compiler will give a 'type mismatch'
|
|
error. The compiler will not look further for another \var{exp} which has
|
|
the correct arguments.
|
|
|
|
It is possible to avoid this particular problem by specifying
|
|
\begin{verbatim}
|
|
r1:=system.exp(r2);
|
|
\end{verbatim}
|
|
An experimental solution for this problem exists in the compiler, but is
|
|
not enabled by default. Maybe someday it will be.
|
|
\end{remark}
|
|
|
|
\section{Arithmetic operators}
|
|
|
|
Arithmetic operators define the action of a binary operator. Possible
|
|
operations are:
|
|
\begin{description}
|
|
\item[multiplication] to multiply two types, the \var{*} multiplication
|
|
operator must be overloaded.
|
|
\item[division] to divide two types, the \var{/} division
|
|
operator must be overloaded.
|
|
\item[addition] to add two types, the \var{+} addition
|
|
operator must be overloaded.
|
|
\item[substraction] to substract two types, the \var{-} substraction
|
|
operator must be overloaded.
|
|
\item[exponentiation] to exponentiate two types, the \var{**} exponentiation
|
|
operator must be overloaded.
|
|
\end{description}
|
|
|
|
The definition of an arithmetic operator takes two parameters. The first
|
|
parameter must be of the type that occurs at the left of the operator,
|
|
the second parameter must be of the type that is at the right of the
|
|
arithmetic operator. The result type must match the type that results
|
|
after the arithmetic operation.
|
|
|
|
To compile an expression as
|
|
\begin{verbatim}
|
|
var
|
|
R : real;
|
|
C,Z : complex;
|
|
|
|
begin
|
|
C:=R*Z;
|
|
end;
|
|
\end{verbatim}
|
|
one needs a definition of the multiplication operator as:
|
|
\begin{verbatim}
|
|
Operator * (r : real; z1 : complex) z : complex;
|
|
|
|
begin
|
|
z.re := z1.re * r;
|
|
z.im := z1.im * r;
|
|
end;
|
|
\end{verbatim}
|
|
As can be seen, the first operator is a real, and the second is
|
|
a complex. The result type is complex.
|
|
|
|
Multiplication and addition of reals and complexes are commutative
|
|
operations. The compiler, however, has no notion of this fact so even
|
|
if a multiplication between a real and a complex is defined, the
|
|
compiler will not use that definition when it encounters a complex
|
|
and a real (in that order). It is necessary to define both operations.
|
|
|
|
So, given the above definition of the multiplication,
|
|
the compiler will not accept the following statement:
|
|
\begin{verbatim}
|
|
var
|
|
R : real;
|
|
C,Z : complex;
|
|
|
|
begin
|
|
C:=Z*R;
|
|
end;
|
|
\end{verbatim}
|
|
since the types of \var{Z} and \var{R} don't match the types in the
|
|
operator definition.
|
|
|
|
The reason for this behaviour is that it is possible that a multiplication
|
|
is not always commutative. e.g. the multiplication of a \var{(n,m)} with a
|
|
\var{(m,n)} matrix will result in a \var{(n,n)} matrix, while the
|
|
mutiplication of a \var{(m,n)} with a \var{(n,m)} matrix is a \var{(m,m)}
|
|
matrix, which needn't be the same in all cases.
|
|
|
|
\section{Comparision operator}
|
|
The comparision operator can be overloaded to compare two different types
|
|
or to compare two equal types that are not basic types. The result type of
|
|
a comparision operator is always a boolean.
|
|
|
|
The comparision operators that can be overloaded are:
|
|
\begin{description}
|
|
\item[equal to] (=) to determine if two variables are equal.
|
|
\item[less than] ($<$) to determine if one variable is less than another.
|
|
\item[greater than] ($>$) to determine if one variable is greater than another.
|
|
\item[greater than or equal to] ($>=$) to determine if one variable is greater than
|
|
or equal to another.
|
|
\item[less than or equal to] ($<=$) to determine if one variable is greater
|
|
than or equal to another.
|
|
\end{description}
|
|
There is no separate operator for {\em unequal to} ($<>$). To evaluate a
|
|
statement that contans the {\em unequal to} operator, the compiler uses the
|
|
{\em equal to} operator (=), and negates the result.
|
|
|
|
|
|
As an example, the following opetrator allows to compare two complex
|
|
numbers:
|
|
\begin{verbatim}
|
|
operator = (z1, z2 : complex) b : boolean;
|
|
\end{verbatim}
|
|
the above definition allows comparisions of the following form:
|
|
\begin{verbatim}
|
|
Var
|
|
C1,C2 : Complex;
|
|
|
|
begin
|
|
If C1=C2 then
|
|
Writeln('C1 and C2 are equal');
|
|
end;
|
|
\end{verbatim}
|
|
|
|
The comparision operator definition needs 2 parameters, with the types that
|
|
the operator is meant to compare. Here also, the compiler doesn't apply
|
|
commutativity; if the two types are different, then it necessary to
|
|
define 2 comparision operators.
|
|
|
|
In the case of complex numbers, it is, for instance necessary to define
|
|
2 comparsions: one with the complex type first, and one with the real type
|
|
first.
|
|
|
|
Given the definitions
|
|
\begin{verbatim}
|
|
operator = (z1 : complex;r : real) b : boolean;
|
|
operator = (r : real; z1 : complex) b : boolean;
|
|
\end{verbatim}
|
|
the following two comparisions are possible:
|
|
\begin{verbatim}
|
|
Var
|
|
R,S : Real;
|
|
C : Complex;
|
|
|
|
begin
|
|
If (C=R) or (S=C) then
|
|
Writeln ('Ok');
|
|
end;
|
|
\end{verbatim}
|
|
Note that the order of the real and complex type in the two comparisions
|
|
is reversed.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Programs, Units, Blocks
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\chapter{Programs, units, blocks}
|
|
A Pascal program consists of modules called \var{units}. A unit can be used
|
|
to group pieces of code together, or to give someone code without giving
|
|
the sources.
|
|
Both programs and units consist of code blocks, which are mixtures of
|
|
statements, procedures, and variable or type declarations.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Programs
|
|
\section{Programs}
|
|
A pascal program consists of the program header, followed possibly by a
|
|
'uses' clause, and a block.
|
|
\input{syntax/program.syn}
|
|
The program header is provided for backwards compatibility, and is ignored
|
|
by the compiler.
|
|
The uses clause serves to identify all units that are needed by the program.
|
|
The system unit doesn't have to be in this list, since it is always loaded
|
|
by the compiler.
|
|
The order in which the units appear is significant, it determines in
|
|
which order they are initialized. Units are initialized in the same order
|
|
as they appear in the uses clause. Identifiers are searched in the opposite
|
|
order, i.e. when the compiler searches for an identifier, then it looks
|
|
first in the last unit in the uses clause, then the last but one, and so on.
|
|
This is important in case two units declare different types with the same
|
|
identifier.
|
|
When the compiler looks for unit files, it adds the extension \file{.ppu}
|
|
(\file{.ppw} for Win32 platforms) to the name of the unit. On \linux and in
|
|
operating systems where filenames are case sensitive, when looking for a unit,
|
|
the unit name is first looked for in the original case, and when not found,
|
|
converted to all lowercase and searched for.
|
|
|
|
If a unit name is longer than 8 characters, the compiler will first look for
|
|
a unit name with this length, and then it will truncate the name to 8
|
|
characters and look for it again. For compatibility reasons, this is also
|
|
true on platforms that suport long file names.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Units
|
|
\section{Units}
|
|
A unit contains a set of declarations, procedures and functions that can be
|
|
used by a program or another unit.
|
|
The syntax for a unit is as follows:
|
|
\input{syntax/unit.syn}
|
|
The interface part declares all identifiers that must be exported from the
|
|
unit. This can be constant, type or variable identifiers, and also procedure
|
|
or function identifier declarations. Declarations inside the
|
|
implementation part are {\em not} accessible outside the unit. The
|
|
implementation must contain a function declaration for each function or
|
|
procedure that is declared in the interface part. If a function is declared
|
|
in the interface part, but no declaration of that function is present in the
|
|
implementation part, then the compiler will give an error.
|
|
|
|
When a program uses a unit (say \file{unitA}) and this units uses a second
|
|
unit, say \file{unitB}, then the program depends indirectly also on
|
|
\var{unitB}. This means that the compiler must have access to \file{unitB} when
|
|
trying to compile the program. If the unit is not present at compile time,
|
|
an error occurs.
|
|
|
|
Note that the identifiers from a unit on which a program depends indirectly,
|
|
are not accessible to the program. To have access to the identifiers of a
|
|
unit, the unit must be in the uses clause of the program or unit where the
|
|
identifiers are needed.
|
|
|
|
Units can be mutually dependent, that is, they can reference each other in
|
|
their uses clauses. This is allowed, on the condition that at least one of
|
|
the references is in the implementation section of the unit. This also holds
|
|
for indirect mutually dependent units.
|
|
|
|
If it is possible to start from one interface uses clause of a unit, and to return
|
|
there via uses clauses of interfaces only, then there is circular unit
|
|
dependence, and the compiler will generate an error.
|
|
As and example : the following is not allowed:
|
|
\begin{verbatim}
|
|
Unit UnitA;
|
|
interface
|
|
Uses UnitB;
|
|
implementation
|
|
end.
|
|
|
|
Unit UnitB
|
|
interface
|
|
Uses UnitA;
|
|
implementation
|
|
end.
|
|
\end{verbatim}
|
|
But this is allowed :
|
|
\begin{verbatim}
|
|
Unit UnitA;
|
|
interface
|
|
Uses UnitB;
|
|
implementation
|
|
end.
|
|
Unit UnitB
|
|
implementation
|
|
Uses UnitA;
|
|
end.
|
|
\end{verbatim}
|
|
Because \file{UnitB} uses \file{UnitA} only in it's implentation section.
|
|
In general, it is a bad idea to have circular unit dependencies, even if it is
|
|
only in implementation sections.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Blocks
|
|
\section{Blocks}
|
|
Units and programs are made of blocks. A block is made of declarations of
|
|
labels, constants, types variables and functions or procedures. Blocks can
|
|
be nested in certain ways, i.e., a procedure or function declaration can
|
|
have blocks in themselves.
|
|
A block looks like the following:
|
|
\input{syntax/block.syn}
|
|
Labels that can be used to identify statements in a block are declared in
|
|
the label declaration part of that block. Each label can only identify one
|
|
statement.
|
|
Constants that are to be used only in one block should be declared in that
|
|
block's constant declaration part.
|
|
Variables that are to be used only in one block should be declared in that
|
|
block's constant declaration part.
|
|
Types that are to be used only in one block should be declared in that
|
|
block's constant declaration part.
|
|
Lastly, functions and procedures that will be used in that block can be
|
|
declared in the procedure/function declaration part.
|
|
After the different declaration parts comes the statement part. This
|
|
contains any actions that the block should execute.
|
|
All identifiers declared before the statement part can be used in that
|
|
statement part.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Scope
|
|
\section{Scope}
|
|
Identifiers are valid from the point of their declaration until the end of
|
|
the block in which the declaration occurred. The range where the identifier
|
|
is known is the {\em scope} of the identifier. The exact scope of an
|
|
identifier depends on the way it was defined.
|
|
\subsection{Block scope}
|
|
The {\em scope} of a variable declared in the declaration part of a block,
|
|
is valid from the point of declaration until the end of the block.
|
|
If a block contains a second block, in which the identfier is
|
|
redeclared, then inside this block, the second declaration will be valid.
|
|
Upon leaving the inner block, the first declaration is valid again.
|
|
Consider the following example:
|
|
\begin{verbatim}
|
|
Program Demo;
|
|
Var X : Real;
|
|
{ X is real variable }
|
|
Procedure NewDeclaration
|
|
Var X : Integer; { Redeclare X as integer}
|
|
begin
|
|
// X := 1.234; {would give an error when trying to compile}
|
|
X := 10; { Correct assigment}
|
|
end;
|
|
{ From here on, X is Real again}
|
|
begin
|
|
X := 2.468;
|
|
end.
|
|
\end{verbatim}
|
|
In this example, inside the procedure, X denotes an integer variable.
|
|
It has it's own storage space, independent of the variable \var{X} outside
|
|
the procedure.
|
|
\subsection{Record scope}
|
|
The field identifiers inside a record definition are valid in the following
|
|
places:
|
|
\begin{enumerate}
|
|
\item to the end of the record definition.
|
|
\item field designators of a variable of the given record type.
|
|
\item identifiers inside a \var{With} statement that operates on a variable
|
|
of the given record type.
|
|
\end{enumerate}
|
|
\subsection{Class scope}
|
|
A component identifier is valid in the following places:
|
|
\begin{enumerate}
|
|
\item From the point of declaration to the end of the class definition.
|
|
\item In all descendent types of this class, unless it is in the private
|
|
part of the class declaration.
|
|
\item In all method declaration blocks of this class and descendent classes.
|
|
\item In a with statement that operators on a variable of the given class's
|
|
definition.
|
|
\end{enumerate}
|
|
Note that method designators are also considered identifiers.
|
|
\subsection{Unit scope}
|
|
All identifiers in the interface part of a unit are valid from the point of
|
|
declaration, until the end of the unit. Furthermore, the identifiers are
|
|
known in programs or units that have the unit in their uses clause.
|
|
Identifiers from indirectly dependent units are {\em not} available.
|
|
Identifiers declared in the implementation part of a unit are valid from the
|
|
point of declaration to the end of the unit.
|
|
The system unit is automatically used in all units and programs.
|
|
It's identifiers are therefore always known, in each pascal program, library
|
|
or unit.
|
|
The rules of unit scope imply that an identifier of a
|
|
unit can be redefined. To have access to an identifier of another unit that was redeclared in
|
|
the current unit, precede it with that other units name, as in the following
|
|
example:
|
|
\begin{verbatim}
|
|
unit unitA;
|
|
interface
|
|
Type
|
|
MyType = Real;
|
|
implementation
|
|
end.
|
|
Program prog;
|
|
Uses UnitA;
|
|
|
|
{ Redeclaration of MyType}
|
|
Type MyType = Integer;
|
|
Var A : Mytype; { Will be Integer }
|
|
B : UnitA.MyType { Will be real }
|
|
begin
|
|
end.
|
|
\end{verbatim}
|
|
This is especially useful when redeclaring the system unit's identifiers.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Libraries
|
|
\section{Libraries}
|
|
\fpc supports making of dynamic libraries (DLLs under Win32 and \ostwo) trough
|
|
the use of the \var{Library} keyword.
|
|
|
|
A Library is just like a unit or a program:
|
|
\input{syntax/library.syn}
|
|
|
|
By default, functions and procedures that are declared and implemented in
|
|
library are not available to a programmer that wishes to use this library.
|
|
|
|
In order to make functions or procedures available from the library,
|
|
they must be exported in an export clause:
|
|
|
|
\input{syntax/exports.syn}
|
|
|
|
Under Win32, an index clause can be added to an exports entry.
|
|
an index entry must be a positive number larger or equal than 1.
|
|
|
|
Optionally, an exports entry can have a name specifier. If present, the name
|
|
specifier gives the exact name (case sensitive) of the function in the
|
|
library.
|
|
|
|
If neither of these constructs is present, the functions or procedures
|
|
are exported with the exact names as specified in the exports clause.
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Exceptions
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Exceptions}
|
|
\label{ch:Exceptions}
|
|
Exceptions provide a convenient way to program error and error-recovery
|
|
mechanisms, and are closely related to classes.
|
|
Exception support is based on 3 constructs:
|
|
\begin{description}
|
|
\item [Raise\ ] statements. To raise an exeption. This is usually done to signal an
|
|
error condition.
|
|
\item [Try ... Except\ ] blocks. These block serve to catch exceptions
|
|
raised within the scope of the block, and to provide exception-recovery
|
|
code.
|
|
\item [Try ... Finally\ ] blocks. These block serve to force code to be
|
|
executed irrespective of an exception occurrence or not. They generally
|
|
serve to clean up memory or close files in case an exception occurs.
|
|
The compiler generates many implicit \var{Try ... Finally} blocks around
|
|
procedure, to force memory consistence.
|
|
\end{description}
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The raise statement
|
|
\section{The raise statement}
|
|
The \var{raise} statement is as follows:
|
|
\input{syntax/raise.syn}
|
|
This statement will raise an exception. If it is specified, the exception
|
|
instance must be an initialized instance of a class, which is the raise
|
|
type. The address exception is optional. If itis not specified, the compiler
|
|
will provide the address by itself.
|
|
If the exception instance is omitted, then the current exception is
|
|
re-raised. This construct can only be used in an exception handling
|
|
block (see further).
|
|
|
|
\begin{remark} Control {\em never} returns after an exception block. The
|
|
control is transferred to the first \var{try...finally} or
|
|
\var{try...except} statement that is encountered when unwinding the stack.
|
|
If no such statement is found, the \fpc Run-Time Library will generate a
|
|
run-time error 217 (see also \sees{exceptclasses}).
|
|
\end{remark}
|
|
|
|
As an example: The following division checks whether the denominator is
|
|
zero, and if so, raises an exception of type \var{EDivException}
|
|
\begin{verbatim}
|
|
Type EDivException = Class(Exception);
|
|
Function DoDiv (X,Y : Longint) : Integer;
|
|
begin
|
|
If Y=0 then
|
|
Raise EDivException.Create ('Division by Zero would occur');
|
|
Result := X Div Y;
|
|
end;
|
|
\end{verbatim}
|
|
The class \var{Exception} is defined in the \file{Sysutils} unit of the rtl.
|
|
(\sees{exceptclasses})
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The try...except statement
|
|
\section{The try...except statement}
|
|
A \var{try...except} exception handling block is of the following form :
|
|
\input{syntax/try.syn}
|
|
If no exception is raised during the execution of the \var{statement list},
|
|
then all statements in the list will be executed sequentially, and the
|
|
except block will be skipped, transferring program flow to the statement
|
|
after the final \var{end}.
|
|
|
|
If an exception occurs during the execution of the \var{statement list}, the
|
|
program flow will be transferred to the except block. Statements in the
|
|
statement list between the place where the exception was raised and the
|
|
exception block are ignored.
|
|
|
|
In the exception handling block, the type of the exception is checked,
|
|
and if there is an exception handler where the class type matches the
|
|
exception object type, or is a parent type of
|
|
the exception object type, then the statement following the corresponding
|
|
\var{Do} will be executed. The first matching type is used. After the
|
|
\var{Do} block was executed, the program continues after the \var{End}
|
|
statement.
|
|
|
|
The identifier in an exception handling statement is optional, and declares
|
|
an exception object. It can be used to manipulate the exception object in
|
|
the exception handling code. The scope of this declaration is the statement
|
|
block foillowing the \var{Do} keyword.
|
|
|
|
If none of the \var{On} handlers matches the exception object type, then the
|
|
statement list after \var{else} is executed. If no such list is
|
|
found, then the exception is automatically re-raised. This process allows
|
|
to nest \var{try...except} blocks.
|
|
|
|
If, on the other hand, the exception was caught, then the exception object is
|
|
destroyed at the end of the exception handling block, before program flow
|
|
continues. The exception is destroyed through a call to the object's
|
|
\var{Destroy} destructor.
|
|
|
|
As an example, given the previous declaration of the \var{DoDiv} function,
|
|
consider the following
|
|
\begin{verbatim}
|
|
Try
|
|
Z := DoDiv (X,Y);
|
|
Except
|
|
On EDivException do Z := 0;
|
|
end;
|
|
\end{verbatim}
|
|
If \var{Y} happens to be zero, then the DoDiv function code will raise an
|
|
exception. When this happens, program flow is transferred to the except
|
|
statement, where the Exception handler will set the value of \var{Z} to
|
|
zero. If no exception is raised, then program flow continues past the last
|
|
\var{end} statement.
|
|
To allow error recovery, the \var{Try ... Finally} block is supported.
|
|
A \var{Try...Finally} block ensures that the statements following the
|
|
\var{Finally} keyword are guaranteed to be executed, even if an exception
|
|
occurs.
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The try...finally statement
|
|
\section{The try...finally statement}
|
|
A \var{Try..Finally} statement has the following form:
|
|
\input{syntax/finally.syn}
|
|
If no exception occurs inside the \var{statement List}, then the program
|
|
runs as if the \var{Try}, \var{Finally} and \var{End} keywords were not
|
|
present.
|
|
|
|
If, however, an exception occurs, the program flow is immediatly
|
|
transferred from the point where the excepion was raised to the first
|
|
statement of the \var{Finally statements}.
|
|
|
|
All statements after the finally keyword will be executed, and then
|
|
the exception will be automatically re-raised. Any statements between the
|
|
place where the exception was raised and the first statement of the
|
|
\var{Finally Statements} are skipped.
|
|
|
|
As an example consider the following routine:
|
|
\begin{verbatim}
|
|
Procedure Doit (Name : string);
|
|
Var F : Text;
|
|
begin
|
|
Try
|
|
Assign (F,Name);
|
|
Rewrite (name);
|
|
... File handling ...
|
|
Finally
|
|
Close(F);
|
|
end;
|
|
\end{verbatim}
|
|
If during the execution of the file handling an execption occurs, then
|
|
program flow will continue at the \var{close(F)} statement, skipping any
|
|
file operations that might follow between the place where the exception
|
|
was raised, and the \var{Close} statement.
|
|
If no exception occurred, all file operations will be executed, and the file
|
|
will be closed at the end.
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Exception handling nesting
|
|
\section{Exception handling nesting}
|
|
It is possible to nest \var{Try...Except} blocks with \var{Try...Finally}
|
|
blocks. Program flow will be done according to a \var{lifo} (last in, first
|
|
out) principle: The code of the last encountered \var{Try...Except} or
|
|
\var{Try...Finally} block will be executed first. If the exception is not
|
|
caught, or it was a finally statement, program flow will be transferred to
|
|
the last-but-one block, {\em ad infinitum}.
|
|
|
|
If an exception occurs, and there is no exception handler present, then a
|
|
runerror 217 will be generated. When using the \file{sysutils} unit, a default
|
|
handler is installed which will show the exception object message, and the
|
|
address where the exception occurred, after which the program will exit with
|
|
a \var{Halt} instruction.
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Exception classes
|
|
\section{Exception classes}
|
|
\label{se:exceptclasses}
|
|
The \file{sysutils} unit contains a great deal of exception handling.
|
|
It defines the following exception types:
|
|
\begin{verbatim}
|
|
Exception = class(TObject)
|
|
private
|
|
fmessage : string;
|
|
fhelpcontext : longint;
|
|
public
|
|
constructor create(const msg : string);
|
|
constructor createres(indent : longint);
|
|
property helpcontext : longint read fhelpcontext write fhelpcontext;
|
|
property message : string read fmessage write fmessage;
|
|
end;
|
|
ExceptClass = Class of Exception;
|
|
{ mathematical exceptions }
|
|
EIntError = class(Exception);
|
|
EDivByZero = class(EIntError);
|
|
ERangeError = class(EIntError);
|
|
EIntOverflow = class(EIntError);
|
|
EMathError = class(Exception);
|
|
\end{verbatim}
|
|
The sysutils unit also installs an exception handler. If an exception is
|
|
unhandled by any exception handling block, this handler is called by the
|
|
Run-Time library. Basically, it prints the exception address, and it prints
|
|
the message of the Exception object, and exits with a exit code of 217.
|
|
If the exception object is not a descendent object of the \var{Exception}
|
|
object, then the class name is printed instead of the exception message.
|
|
|
|
It is recommended to use the \var{Exception} object or a descendant class for
|
|
all \var{raise} statements, since then the message field of the
|
|
exception object can be used.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Using Assembler
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Using assembler}
|
|
\fpc supports the use of assembler in code, but not inline
|
|
assembler macros. To have more information on the processor
|
|
specific assembler syntax and its limitations, see the \progref.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Assembler statements
|
|
\section{Assembler statements }
|
|
The following is an example of assembler inclusion in pascal code.
|
|
\begin{verbatim}
|
|
...
|
|
Statements;
|
|
...
|
|
Asm
|
|
the asm code here
|
|
...
|
|
end;
|
|
...
|
|
Statements;
|
|
\end{verbatim}
|
|
The assembler instructions between the \var{Asm} and \var{end} keywords will
|
|
be inserted in the assembler generated by the compiler.
|
|
Conditionals can be used ib assembler, the compiler will recognise it,
|
|
and treat it as any other conditionals.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Assembler procedures and functions
|
|
\section{Assembler procedures and functions}
|
|
Assembler procedures and functions are declared using the
|
|
\var{Assembler} directive. This permits the code generator to make a number
|
|
of code generation optimizations.
|
|
|
|
The code generator does not generate any stack frame (entry and exit
|
|
code for the routine) if it contains no local variables and no
|
|
parameters. In the case of functions, ordinal values must be returned
|
|
in the accumulator. In the case of floating point values, these depend
|
|
on the target processor and emulation options.
|
|
|
|
%
|
|
% System unit reference guide.
|
|
%
|
|
|
|
\part{Reference : The System unit}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The system unit
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{The system unit}
|
|
\label{ch:refchapter}
|
|
\FPCexampledir{refex}
|
|
The system unit contains the standard supported functions of \fpc. It is the
|
|
same for all platforms. Basically it is the same as the system unit provided
|
|
with Borland or Turbo Pascal.
|
|
|
|
Functions are listed in alphabetical order. Arguments of functions or
|
|
procedures that are optional are put between square brackets.
|
|
|
|
The pre-defined constants and variables are listed in the first section.
|
|
The second section contains an overview of all functions, grouped by
|
|
functionality, and the last section contains the supported functions
|
|
and procedures.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Types, Constants and Variables
|
|
\section{Types, Constants and Variables}
|
|
|
|
\subsection{Types}
|
|
The following integer types are defined in the System unit:
|
|
\begin{verbatim}
|
|
Shortint = -128..127;
|
|
SmallInt = -32768..32767;
|
|
Longint = $80000000..$7fffffff;
|
|
byte = 0..255;
|
|
word = 0..65535;
|
|
dword = longword;
|
|
cardinal = longword;
|
|
Integer = smallint;
|
|
\end{verbatim}
|
|
The following types are used for the functions that need compiler magic
|
|
such as \seep{Val} or \seep{Str}:
|
|
\begin{verbatim}
|
|
StrLenInt = LongInt;
|
|
ValSInt = Longint;
|
|
ValUInt = Cardinal;
|
|
ValReal = Extended;
|
|
\end{verbatim}
|
|
The \var{Real48} type is defined to emulate the old \tp \var{Real} type:
|
|
\begin{verbatim}
|
|
Real48 = Array[0..5] of byte;
|
|
\end{verbatim}
|
|
The assignment operator has been overloaded so this type can be assigned
|
|
to the \fpc native \var{Double} and \var{Extended} types.
|
|
\seefl{Real2Double}{RealToDouble}.
|
|
|
|
The following character types are defined for Delphi compatibility:
|
|
\begin{verbatim}
|
|
TAnsiChar = Char;
|
|
AnsiChar = TAnsiChar;
|
|
\end{verbatim}
|
|
And the following pointer types as well:
|
|
\begin{verbatim}
|
|
PChar = ^char;
|
|
pPChar = ^PChar;
|
|
PAnsiChar = PChar;
|
|
PQWord = ^QWord;
|
|
PInt64 = ^Int64;
|
|
pshortstring = ^shortstring;
|
|
plongstring = ^longstring;
|
|
pansistring = ^ansistring;
|
|
pwidestring = ^widestring;
|
|
pextended = ^extended;
|
|
ppointer = ^pointer;
|
|
\end{verbatim}
|
|
For the \seef{SetJmp} and \seep{LongJmp} calls, the following jump bufer
|
|
type is defined (for the I386 processor):
|
|
\begin{verbatim}
|
|
jmp_buf = record
|
|
ebx,esi,edi : Longint;
|
|
bp,sp,pc : Pointer;
|
|
end;
|
|
PJmp_buf = ^jmp_buf;
|
|
\end{verbatim}
|
|
The following records and pointers can be used to scan the
|
|
entries in the string message handler tables:
|
|
\begin{verbatim}
|
|
tmsgstrtable = record
|
|
name : pshortstring;
|
|
method : pointer;
|
|
end;
|
|
pmsgstrtable = ^tmsgstrtable;
|
|
|
|
tstringmessagetable = record
|
|
count : dword;
|
|
msgstrtable : array[0..0] of tmsgstrtable;
|
|
end;
|
|
pstringmessagetable = ^tstringmessagetable;
|
|
\end{verbatim}
|
|
|
|
The base class for all classes is defined as:
|
|
\begin{verbatim}
|
|
Type
|
|
TObject = Class
|
|
Public
|
|
constructor create;
|
|
destructor destroy;virtual;
|
|
class function newinstance : tobject;virtual;
|
|
procedure freeinstance;virtual;
|
|
function safecallexception(exceptobject : tobject;
|
|
exceptaddr : pointer) : longint;virtual;
|
|
procedure defaulthandler(var message);virtual;
|
|
procedure free;
|
|
class function initinstance(instance : pointer) : tobject;
|
|
procedure cleanupinstance;
|
|
function classtype : tclass;
|
|
class function classinfo : pointer;
|
|
class function classname : shortstring;
|
|
class function classnameis(const name : string) : boolean;
|
|
class function classparent : tclass;
|
|
class function instancesize : longint;
|
|
class function inheritsfrom(aclass : tclass) : boolean;
|
|
class function inheritsfrom(aclass : tclass) : boolean;
|
|
class function stringmessagetable : pstringmessagetable;
|
|
procedure dispatch(var message);
|
|
procedure dispatchstr(var message);
|
|
class function methodaddress(const name : shortstring) : pointer;
|
|
class function methodname(address : pointer) : shortstring;
|
|
function fieldaddress(const name : shortstring) : pointer;
|
|
procedure AfterConstruction;virtual;
|
|
procedure BeforeDestruction;virtual;
|
|
procedure DefaultHandlerStr(var message);virtual;
|
|
end;
|
|
TClass = Class Of TObject;
|
|
PClass = ^TClass;
|
|
\end{verbatim}
|
|
Unhandled exceptions can be treated using a constant of the
|
|
\var{TExceptProc} type:
|
|
\begin{verbatim}
|
|
TExceptProc = Procedure (Obj : TObject; Addr,Frame: Pointer);
|
|
\end{verbatim}
|
|
\var{Obj} is the exception object that was used to raise the exception,
|
|
\var{Addr} and \var{Frame} contain the exact address and stack frame
|
|
where the exception was raised.
|
|
|
|
The \var{TVarRec} type is used to access the elements passed in a \var{Array
|
|
of Const} argument to a function or procedure:
|
|
\begin{verbatim}
|
|
Type
|
|
PVarRec = ^TVarRec;
|
|
TVarRec = record
|
|
case VType : Longint of
|
|
vtInteger : (VInteger: Longint);
|
|
vtBoolean : (VBoolean: Boolean);
|
|
vtChar : (VChar: Char);
|
|
vtExtended : (VExtended: PExtended);
|
|
vtString : (VString: PShortString);
|
|
vtPointer : (VPointer: Pointer);
|
|
vtPChar : (VPChar: PChar);
|
|
vtObject : (VObject: TObject);
|
|
vtClass : (VClass: TClass);
|
|
vtAnsiString : (VAnsiString: Pointer);
|
|
vtWideString : (VWideString: Pointer);
|
|
vtInt64 : (VInt64: PInt64);
|
|
end;
|
|
\end{verbatim}
|
|
The heap manager uses the \var{TMemoryManager} type:
|
|
\begin{verbatim}
|
|
PMemoryManager = ^TMemoryManager;
|
|
TMemoryManager = record
|
|
Getmem : Function(Size:Longint):Pointer;
|
|
Freemem : Function(var p:pointer):Longint;
|
|
FreememSize : Function(var p:pointer;Size:Longint):Longint;
|
|
AllocMem : Function(Size:longint):Pointer;
|
|
ReAllocMem : Function(var p:pointer;Size:longint):Pointer;
|
|
MemSize : function(p:pointer):Longint;
|
|
MemAvail : Function:Longint;
|
|
MaxAvail : Function:Longint;
|
|
HeapSize : Function:Longint;
|
|
end;
|
|
\end{verbatim}
|
|
More information on using this record can be found in \progref.
|
|
|
|
\subsection{Constants}
|
|
The following constants define the maximum values that can be used with
|
|
various types:
|
|
\begin{verbatim}
|
|
MaxSIntValue = High(ValSInt);
|
|
MaxUIntValue = High(ValUInt);
|
|
maxint = maxsmallint;
|
|
maxLongint = $7fffffff;
|
|
maxSmallint = 32767;
|
|
\end{verbatim}
|
|
The following constants for file-handling are defined in the system unit:
|
|
\begin{verbatim}
|
|
Const
|
|
fmclosed = $D7B0;
|
|
fminput = $D7B1;
|
|
fmoutput = $D7B2;
|
|
fminout = $D7B3;
|
|
fmappend = $D7B4;
|
|
filemode : byte = 2;
|
|
\end{verbatim}
|
|
|
|
The \var{filemode} variable is used when a non-text file is opened using
|
|
\var{Reset}. It indicates how the file will be opened. \var{filemode} can have one of
|
|
the following values:
|
|
\begin{description}
|
|
\item[0] The file is opened for reading.
|
|
\item[1] The file is opened for writing.
|
|
\item[2] The file is opened for reading and writing.
|
|
\end{description}
|
|
The default value is 2. Other values are possible but are operating system specific.
|
|
|
|
Further, the following non processor specific general-purpose constants
|
|
are also defined:
|
|
\begin{verbatim}
|
|
const
|
|
erroraddr : pointer = nil;
|
|
errorcode : word = 0;
|
|
{ max level in dumping on error }
|
|
max_frame_dump : word = 20;
|
|
\end{verbatim}
|
|
\begin{remark}
|
|
Processor specific global constants are named Testxxxx where xxxx
|
|
represents the processor number (such as Test8086, Test68000),
|
|
and are used to determine on what generation of processor the program
|
|
is running on.
|
|
\end{remark}
|
|
The following constants are defined to access VMT entries:
|
|
\begin{verbatim}
|
|
vmtInstanceSize = 0;
|
|
vmtParent = 8;
|
|
vmtClassName = 12;
|
|
vmtDynamicTable = 16;
|
|
vmtMethodTable = 20;
|
|
vmtFieldTable = 24;
|
|
vmtTypeInfo = 28;
|
|
vmtInitTable = 32;
|
|
vmtAutoTable = 36;
|
|
vmtIntfTable = 40;
|
|
vmtMsgStrPtr = 44;
|
|
vmtMethodStart = 48;
|
|
vmtDestroy = vmtMethodStart;
|
|
vmtNewInstance = vmtMethodStart+4;
|
|
vmtFreeInstance = vmtMethodStart+8;
|
|
vmtSafeCallException = vmtMethodStart+12;
|
|
vmtDefaultHandler = vmtMethodStart+16;
|
|
vmtAfterConstruction = vmtMethodStart+20;
|
|
vmtBeforeDestruction = vmtMethodStart+24;
|
|
vmtDefaultHandlerStr = vmtMethodStart+28;
|
|
\end{verbatim}
|
|
The constant names should be used, and never their values, because
|
|
the VMT table can change, breaking code that uses direct values.
|
|
|
|
The following constants will be used for the planned \var{variant} support:
|
|
\begin{verbatim}
|
|
varEmpty = $0000;
|
|
varNull = $0001;
|
|
varSmallint = $0002;
|
|
varInteger = $0003;
|
|
varSingle = $0004;
|
|
varDouble = $0005;
|
|
varCurrency = $0006;
|
|
varDate = $0007;
|
|
varOleStr = $0008;
|
|
varDispatch = $0009;
|
|
varError = $000A;
|
|
varBoolean = $000B;
|
|
varVariant = $000C;
|
|
varUnknown = $000D;
|
|
varByte = $0011;
|
|
varString = $0100;
|
|
varAny = $0101;
|
|
varTypeMask = $0FFF;
|
|
varArray = $2000;
|
|
varByRef = $4000;
|
|
\end{verbatim}
|
|
The following constants are used in the \var{TVarRec} record:
|
|
\begin{verbatim}
|
|
vtInteger = 0;
|
|
vtBoolean = 1;
|
|
vtChar = 2;
|
|
vtExtended = 3;
|
|
vtString = 4;
|
|
vtPointer = 5;
|
|
vtPChar = 6;
|
|
vtObject = 7;
|
|
vtClass = 8;
|
|
vtWideChar = 9;
|
|
vtPWideChar = 10;
|
|
vtAnsiString = 11;
|
|
vtCurrency = 12;
|
|
vtVariant = 13;
|
|
vtInterface = 14;
|
|
vtWideString = 15;
|
|
vtInt64 = 16;
|
|
vtQWord = 17;
|
|
\end{verbatim}
|
|
The \var{ExceptProc} is called when an unhandled exception occurs:
|
|
\begin{verbatim}
|
|
Const
|
|
ExceptProc : TExceptProc = Nil;
|
|
\end{verbatim}
|
|
It is set in the \file{objpas} unit, but it can be set by the programmer
|
|
to change the default exception handling.
|
|
|
|
The following constants are defined to describe the operating system's file
|
|
system:
|
|
\begin{verbatim}
|
|
LineEnding = #10;
|
|
LFNSupport = true;
|
|
DirectorySeparator = '/';
|
|
DriveSeparator = ':';
|
|
PathSeparator = ':';
|
|
FileNameCaseSensitive : Boolean = True;
|
|
\end{verbatim}
|
|
The shown values are for \unix platforms, but will be different on other
|
|
platforms.
|
|
The meaning of the constants is the following:
|
|
\begin{description}
|
|
\item[LineEnding] End of line marker. This constant is used when writing end
|
|
of lines to text files.
|
|
\item[LFNSupport] This is \var{True} if the system supports long file names,
|
|
i.e. filenames that are not restricted to 8.3 characters.
|
|
\item[DirectorySeparator] The character that is used as a directory
|
|
separator, i.e. it appears between various parts of a path to a file.
|
|
\item[DriveSeparator] On systems that support drive letters, this character
|
|
separates the drive indication from the rest of a filename.
|
|
\item[PathSeparator] This character can be found between elements in a
|
|
series of paths (such as the contents of the \var{PATH} environment
|
|
variable.
|
|
\item[FileNameCaseSensitive] Indicates whether filenames are case sensitive.
|
|
\end{description}
|
|
When programming cross-platform, use these constants instead of hard-coded
|
|
characters. This will enhance portability of an application.
|
|
|
|
\subsection{Variables}
|
|
The following variables are defined and initialized in the system unit:
|
|
\begin{verbatim}
|
|
var
|
|
output,input,stderr : text;
|
|
exitproc : pointer;
|
|
exitcode : word;
|
|
stackbottom : Cardinal;
|
|
\end{verbatim}
|
|
The variables \var{ExitProc}, \var{exitcode} are used in the \fpc exit
|
|
scheme. It works similarly to the one in Turbo Pascal:
|
|
|
|
When a program halts (be it through the call of the \var{Halt} function or
|
|
\var{Exit} or through a run-time error), the exit mechanism checks the value
|
|
of \var{ExitProc}. If this one is non-\var{Nil}, it is set to \var{Nil}, and
|
|
the procedure is called. If the exit procedure exits, the value of ExitProc
|
|
is checked again. If it is non-\var{Nil} then the above steps are repeated.
|
|
So when an exit procedure must be installed, the old value of \var{ExitProc}
|
|
should be saved (it may be non-\var{Nil}, since other units could have set
|
|
it). In the exit procedure the value of \var{ExitProc} should be restored to
|
|
the previous value, such that if it was non-\var{Nil} the exit-procedure can be
|
|
called.
|
|
|
|
\FPCexample{ex98}
|
|
|
|
The \var{ErrorAddr} and \var{ExitCode} can be used to check for
|
|
error-conditions. If \var{ErrorAddr} is non-\var{Nil}, a run-time error has
|
|
occurred. If so, \var{ExitCode} contains the error code. If \var{ErrorAddr} is
|
|
\var{Nil}, then {ExitCode} contains the argument to \var{Halt} or 0 if the
|
|
program terminated normally.
|
|
|
|
\var{ExitCode} is always passed to the operating system as the exit-code of
|
|
the current process.
|
|
|
|
\begin{remark}
|
|
The maximum error code under \linux and \unix like operating systems is 127.
|
|
\end{remark}
|
|
|
|
Under \file{GO32}, the following constants are also defined :
|
|
\begin{verbatim}
|
|
const
|
|
seg0040 = $0040;
|
|
segA000 = $A000;
|
|
segB000 = $B000;
|
|
segB800 = $B800;
|
|
\end{verbatim}
|
|
These constants allow easy access to the bios/screen segment via mem/absolute.
|
|
|
|
The randomize function uses a seed stored in the \var{RandSeed} variable:
|
|
\begin{verbatim}
|
|
RandSeed : Cardinal;
|
|
\end{verbatim}
|
|
This variable is initialized in the initialization code of the system unit.
|
|
|
|
Other variables indicate the state of the application.
|
|
\begin{verbatim}
|
|
IsLibrary : boolean;
|
|
IsMultiThread : boolean;
|
|
\end{verbatim}
|
|
The \var{IsLibrary} variable is set to true if this module is a
|
|
shared library instead of an application. The \var{IsMultiThread}
|
|
variable is set to True if the application has spawned other
|
|
threads, otherwise, and by default, it is set to False.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Functions and Procedures by category
|
|
\section{Function list by category}
|
|
What follows is a listing of the available functions, grouped by category.
|
|
For each function there is a reference to the page where the
|
|
function can be found:
|
|
\subsection{File handling}
|
|
Functions concerning input and output from and to file.
|
|
\begin{funclist}
|
|
\procref{Append}{Open a file in append mode}
|
|
\procref{Assign}{Assign a name to a file}
|
|
\procref{Blockread}{Read data from a file into memory}
|
|
\procref{Blockwrite}{Write data from memory to a file}
|
|
\procref{Close}{Close a file}
|
|
\funcref{Eof}{Check for end of file}
|
|
\funcref{Eoln}{Check for end of line}
|
|
\procref{Erase}{Delete file from disk}
|
|
\funcref{Filepos}{Position in file}
|
|
\funcref{Filesize}{Size of file}
|
|
\procref{Flush}{Write file buffers to disk}
|
|
\funcref{IOresult}{Return result of last file IO operation}
|
|
\procref{Read}{Read from file into variable}
|
|
\procref{Readln}{Read from file into variable and goto next line}
|
|
\procref{Rename}{Rename file on disk}
|
|
\procref{Reset}{Open file for reading}
|
|
\procref{Rewrite}{Open file for writing}
|
|
\procref{Seek}{Set file position}
|
|
\funcref{SeekEof}{Set file position to end of file}
|
|
\funcref{SeekEoln}{Set file position to end of line}
|
|
\procref{SetTextBuf}{Set size of file buffer}
|
|
\procref{Truncate}{Truncate the file at position}
|
|
\procref{Write}{Write variable to file}
|
|
\procref{WriteLn}{Write variable to file and append newline}
|
|
\end{funclist}
|
|
|
|
\subsection{Memory management}
|
|
Functions concerning memory issues.
|
|
\begin{funclist}
|
|
\funcref{Addr}{Return address of variable}
|
|
\funcref{Assigned}{Check if a pointer is valid}
|
|
\funcref{CompareByte}{Compare 2 memory buffers byte per byte}
|
|
\funcref{CompareChar}{Compare 2 memory buffers byte per byte}
|
|
\funcref{CompareDWord}{Compare 2 memory buffers byte per byte}
|
|
\funcref{CompareWord}{Compare 2 memory buffers byte per byte}
|
|
\funcref{CSeg}{Return code segment}
|
|
\procref{Dispose}{Free dynamically allocated memory}
|
|
\funcref{DSeg}{Return data segment}
|
|
\procref{FillByte}{Fill memory region with 8-bit pattern}
|
|
\procref{Fillchar}{Fill memory region with certain character}
|
|
\procref{FillDWord}{Fill memory region with 32-bit pattern}
|
|
\procref{Fillword}{Fill memory region with 16-bit pattern}
|
|
\procref{Freemem}{Release allocated memory}
|
|
\procref{Getmem}{Allocate new memory}
|
|
\procref{GetMemoryManager}{Return current memory manager}
|
|
\funcref{High}{Return highest index of open array or enumerated}
|
|
\funcref{IsMemoryManagerSet}{Is the memory manager set}
|
|
\funcref{Low}{Return lowest index of open array or enumerated}
|
|
\procref{Mark}{Mark current memory position}
|
|
\funcref{Maxavail}{Return size of largest free memory block}
|
|
\funcref{Memavail}{Return total available memory}
|
|
\procref{Move}{Move data from one location in memory to another}
|
|
\procrefl{MoveChar0}{MoveCharNull}{Move data till first zero character}
|
|
\procref{New}{Dynamically allocate memory for variable}
|
|
\funcref{Ofs}{Return offset of variable}
|
|
\funcref{Ptr}{Combine segment and offset to pointer}
|
|
\funcref{ReAllocMem}{Resize a memory block on the heap}
|
|
\procref{Release}{Release memory above mark point}
|
|
\funcref{Seg}{Return segment}
|
|
\procref{SetMemoryManager}{Set a memory manager}
|
|
\funcref{Sptr}{Return current stack pointer}
|
|
\funcref{SSeg}{Return stack segment register value}
|
|
\end{funclist}
|
|
|
|
\subsection{Mathematical routines}
|
|
Functions connected to calculating and coverting numbers.
|
|
\begin{funclist}
|
|
\funcref{Abs}{Calculate absolute value}
|
|
\funcref{Arctan}{Calculate inverse tangent}
|
|
\funcref{Cos}{Calculate cosine of angle}
|
|
\procref{Dec}{Decrease value of variable}
|
|
\funcref{Exp}{Exponentiate}
|
|
\funcref{Frac}{Return fractional part of floating point value}
|
|
\funcref{Hi}{Return high byte/word of value}
|
|
\procref{Inc}{Increase value of variable}
|
|
\funcref{Int}{Calculate integer part of floating point value}
|
|
\funcref{Ln}{Calculate logarithm}
|
|
\funcref{Lo}{Return low byte/word of value}
|
|
\funcref{Odd}{Is a value odd or even ? }
|
|
\funcref{Pi}{Return the value of pi}
|
|
\funcref{Power}{Raise float to integer power}
|
|
\funcref{Random}{Generate random number}
|
|
\procref{Randomize}{Initialize random number generator}
|
|
\funcref{Round}{Round floating point value to nearest integer number}
|
|
\funcref{Sin}{Calculate sine of angle}
|
|
\funcref{Sqr}{Calculate the square of a value}
|
|
\funcref{Sqrt}{Calculate the square root of a value}
|
|
\funcref{Swap}{Swap high and low bytes/words of a variable}
|
|
\funcref{Trunc}{Truncate a floating point value}
|
|
\end{funclist}
|
|
|
|
\subsection{String handling}
|
|
All things connected to string handling.
|
|
\begin{funclist}
|
|
\funcref{BinStr}{Construct binary representation of integer}
|
|
\funcref{Chr}{Convert ASCII code to character}
|
|
\funcref{Concat}{Concatenate two strings}
|
|
\funcref{Copy}{Copy part of a string}
|
|
\procref{Delete}{Delete part of a string}
|
|
\funcref{HexStr}{Construct hexadecimal representation of integer}
|
|
\procref{Insert}{Insert one string in another}
|
|
\funcref{Length}{Return length of string}
|
|
\funcref{Lowercase}{Convert string to all-lowercase}
|
|
\funcref{OctStr}{Construct octal representation of integer}
|
|
\funcref{Pos}{Calculate position of one string in another}
|
|
\procref{SetLength}{Set length of a string}
|
|
\procref{SetString}{Set contents and length of a string}
|
|
\procref{Str}{Convert number to string representation}
|
|
\funcref{StringOfChar}{Create string consisting of a number of characters}
|
|
\funcref{Upcase}{Convert string to all-uppercase}
|
|
\procref{Val}{Convert string to number}
|
|
\end{funclist}
|
|
|
|
\subsection{Operating System functions}
|
|
Functions that are connected to the operating system.
|
|
\begin{funclist}
|
|
\procref{Chdir}{Change working directory}
|
|
\procref{Getdir}{Return current working directory}
|
|
\procref{Halt}{Halt program execution}
|
|
\funcref{Paramcount}{Number of parameters with which program was called}
|
|
\funcref{Paramstr}{Retrieve parameters with which program was called}
|
|
\procref{Mkdir}{Make a directory}
|
|
\procref{Rmdir}{Remove a directory}
|
|
\procref{Runerror}{Abort program execution with error condition}
|
|
\end{funclist}
|
|
|
|
\subsection{Miscellaneous functions}
|
|
Functions that do not belong in one of the other categories.
|
|
\begin{funclist}
|
|
\procref{Assert}{Conditionally abort program with error}
|
|
\procref{Break}{Abort current loop}
|
|
\procref{Continue}{Next cycle in current loop}
|
|
\procref{Exclude}{Exclude an element from a set}
|
|
\procref{Exit}{Exit current function or procedure}
|
|
\procref{Include}{Include an element into a set}
|
|
\procref{LongJmp}{Jump to execution point}
|
|
\funcref{Ord}{Return ordinal value of enumerated type}
|
|
\funcref{Pred}{Return previous value of ordinal type}
|
|
\funcref{SetJmp}{Mark execution point for jump}
|
|
\funcref{SizeOf}{Return size of variable or type}
|
|
\funcref{Succ}{Return next value of ordinal type}
|
|
\end{funclist}
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Functions and Procedures
|
|
\section{Functions and Procedures}
|
|
|
|
\begin{function}{Abs}
|
|
\Declaration
|
|
Function Abs (X : Every numerical type) : Every numerical type;
|
|
\Description
|
|
\var{Abs} returns the absolute value of a variable. The result of the
|
|
function has the same type as its argument, which can be any numerical
|
|
type.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Round}
|
|
\end{function}
|
|
|
|
\FPCexample{ex1}
|
|
|
|
\begin{function}{Addr}
|
|
\Declaration
|
|
Function Addr (X : Any type) : Pointer;
|
|
|
|
\Description
|
|
\var{Addr} returns a pointer to its argument, which can be any type, or a
|
|
function or procedure name. The returned pointer isn't typed.
|
|
The same result can be obtained by the \var{@} operator, which can return a
|
|
typed pointer (\progref).
|
|
\Errors
|
|
None
|
|
\SeeAlso
|
|
\seef{SizeOf}
|
|
\end{function}
|
|
|
|
\FPCexample{ex2}
|
|
|
|
\begin{procedure}{Append}
|
|
\Declaration
|
|
Procedure Append (Var F : Text);
|
|
|
|
\Description
|
|
\var{Append} opens an existing file in append mode. Any data written to
|
|
\var{F} will be appended to the file. Only text files can be opened in
|
|
append mode. After a call to \var{Append}, the file \var{F} becomes
|
|
write-only.
|
|
|
|
File sharing is not taken into account when calling \var{Append}.
|
|
|
|
\Errors
|
|
If the file doesn't exist when appending, a run-time error will be generated.
|
|
This behaviour has changed on Windows and Linux platforms, where in versions
|
|
prior to 1.0.6, the file would be created in append mode.
|
|
\SeeAlso
|
|
\seep{Rewrite},\seep{Close}, \seep{Reset}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex3}
|
|
|
|
\begin{function}{Arctan}
|
|
\Declaration
|
|
Function Arctan (X : Real) : Real;
|
|
|
|
\Description
|
|
\var{Arctan} returns the Arctangent of \var{X}, which can be any Real type.
|
|
The resulting angle is in radial units.
|
|
\Errors
|
|
None
|
|
\SeeAlso
|
|
\seef{Sin}, \seef{Cos}
|
|
\end{function}
|
|
|
|
\FPCexample{ex4}
|
|
|
|
\begin{procedure}{Assert}
|
|
\Declaration
|
|
Procedure Assert(expr : Boolean [; const msg: string]);
|
|
|
|
\Description
|
|
With assertions on, \var{Assert} tests if \var{expr} is
|
|
false, and if so, aborts the application with a Runtime error
|
|
227 and an optional error message in \var{msg}.
|
|
If \var{expr} is true, program execution continues normally.
|
|
|
|
If assertions are not enabled at compile time, this routine does
|
|
nothing, and no code is generated for the \var{Assert} call.
|
|
|
|
Enabling and disabling assertions at compile time is done via
|
|
the \var{\$C} or \var{\$ASSERTIONS} compiler switches. These are
|
|
global switches.
|
|
|
|
The default behavior of the assert call can be changed by
|
|
setting a new handler in the \var{AssertErrorProc} variable.
|
|
Sysutils overrides the default handler to raise a \var{EAssertionFailed}
|
|
exception.
|
|
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Halt}, \seep{Runerror}
|
|
\end{procedure}
|
|
|
|
|
|
\begin{procedure}{Assign}
|
|
\Declaration
|
|
Procedure Assign (Var F; Name : String);
|
|
|
|
\Description
|
|
\var{Assign} assigns a name to \var{F}, which can be any file type.
|
|
This call doesn't open the file, it just assigns a name to a file variable,
|
|
and marks the file as closed.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Reset}, \seep{Rewrite}, \seep{Append}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex5}
|
|
|
|
\begin{function}{Assigned}
|
|
\Declaration
|
|
Function Assigned (P : Pointer) : Boolean;
|
|
\Description
|
|
\var{Assigned} returns \var{True} if \var{P} is non-nil
|
|
and retuns \var{False} of \var{P} is nil.
|
|
The main use of Assigned is that Procedural variables, method variables and
|
|
class-type variables also can be passed to \var{Assigned}.
|
|
\Errors
|
|
None
|
|
\SeeAlso
|
|
\seep{New}
|
|
\end{function}
|
|
|
|
\FPCexample{ex96}
|
|
|
|
\begin{function}{BinStr}
|
|
\Declaration
|
|
Function BinStr (Value : longint; cnt : byte) : String;
|
|
|
|
\Description
|
|
\var{BinStr} returns a string with the binary representation
|
|
of \var{Value}. The string has at most \var{cnt} characters.
|
|
(i.e. only the \var{cnt} rightmost bits are taken into account)
|
|
To have a complete representation of any longint-type value, 32
|
|
bits are needed, i.e. \var{cnt=32}
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Str},\seep{Val},\seef{HexStr}, \seef{OctStr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex82}
|
|
|
|
\begin{procedure}{Blockread}
|
|
\Declaration
|
|
Procedure Blockread (Var F : File; Var Buffer; Var Count : Longint [; var
|
|
Result : Longint]);
|
|
|
|
\Description
|
|
\var{Blockread} reads \var{count} or less records from file \var{F}. A
|
|
record is a block of bytes with size specified by the \seep{Rewrite} or
|
|
\seep{Reset} statement.
|
|
|
|
The result is placed in \var{Buffer}, which must contain enough room for
|
|
\var{Count} records. The function cannot read partial records.
|
|
If \var{Result} is specified, it contains the number of records actually
|
|
read. If \var{Result} isn't specified, and less than \var{Count} records were
|
|
read, a run-time error is generated. This behavior can be controlled by the
|
|
\var{\{\$i\}} switch.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Blockwrite}, \seep{Close}, \seep{Reset}, \seep{Assign}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex6}
|
|
|
|
\begin{procedure}{Blockwrite}
|
|
\Declaration
|
|
Procedure Blockwrite (Var F : File; Var Buffer; Var Count : Longint);
|
|
|
|
\Description
|
|
\var{BlockWrite} writes \var{count} records from \var{buffer} to the file
|
|
\var{F}.A record is a block of bytes with size specified by the \seep{Rewrite} or
|
|
\seep{Reset} statement.
|
|
|
|
If the records couldn't be written to disk, a run-time error is generated.
|
|
This behavior can be controlled by the \var{\{\$i\}} switch.
|
|
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Blockread},\seep{Close}, \seep{Rewrite}, \seep{Assign}
|
|
\end{procedure}
|
|
|
|
For the example, see \seep{Blockread}.
|
|
|
|
\begin{procedure}{Break}
|
|
\Declaration
|
|
Procedure Break;
|
|
\Description
|
|
\var{Break} jumps to the statement following the end of the current
|
|
repetitive statement. The code between the \var{Break} call and
|
|
the end of the repetitive statement is skipped.
|
|
The condition of the repetitive statement is NOT evaluated.
|
|
|
|
This can be used with \var{For}, var{repeat} and \var{While} statements.
|
|
|
|
Note that while this is a procedure, \var{Break} is a reserved word
|
|
and hence cannot be redefined.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Continue}, \seep{Exit}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex87}
|
|
|
|
\begin{procedure}{Chdir}
|
|
\Declaration
|
|
Procedure Chdir (const S : string);
|
|
\Description
|
|
\var{Chdir} changes the working directory of the process to \var{S}.
|
|
\Errors
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Mkdir}, \seep{Rmdir}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex7}
|
|
|
|
\begin{function}{Chr}
|
|
\Declaration
|
|
Function Chr (X : byte) : Char;
|
|
\Description
|
|
\var{Chr} returns the character which has ASCII value \var{X}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Ord}, \seep{Str}
|
|
\end{function}
|
|
|
|
\FPCexample{ex8}
|
|
|
|
\begin{procedure}{Close}
|
|
\Declaration
|
|
Procedure Close (Var F : Anyfiletype);
|
|
|
|
\Description
|
|
\var{Close} flushes the buffer of the file \var{F} and closes \var{F}.
|
|
After a call to \var{Close}, data can no longer be read from or written to
|
|
\var{F}.
|
|
To reopen a file closed with \var{Close}, it isn't necessary to assign the
|
|
file again. A call to \seep{Reset} or \seep{Rewrite} is sufficient.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Assign}, \seep{Reset}, \seep{Rewrite}, \seep{Flush}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex9}
|
|
|
|
\begin{function}{CompareByte}
|
|
\Declaration
|
|
function CompareByte(var buf1,buf2;len:longint):longint;
|
|
\Description
|
|
\var{CompareByte} compares two memory regions \var{buf1},\var{buf2} on a
|
|
byte-per-byte basis for a total of \var{len} bytes.
|
|
|
|
The function returns one of the following values:
|
|
\begin{description}
|
|
\item[less than 0] if \var{buf1} and \var{buf2} contain different bytes
|
|
in the first \var{len} bytes, and the first such byte is smaller in \var{buf1}
|
|
than the byte at the same position in \var{buf2}.
|
|
\item[0] if the first \var{len} bytes in \var{buf1} and \var{buf2} are
|
|
equal.
|
|
\item [greater than 0] if \var{buf1} and \var{buf2} contain different bytes
|
|
in the first \var{len} bytes, and the first such byte is larger in \var{buf1}
|
|
than the byte at the same position in \var{buf2}.
|
|
\end{description}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{CompareChar},\seef{CompareWord},\seef{CompareDWord}
|
|
\end{function}
|
|
|
|
\FPCexample{ex99}
|
|
|
|
\begin{function}{CompareChar}
|
|
\Declaration
|
|
function CompareChar(var buf1,buf2;len:longint):longint;
|
|
function CompareChar0(var buf1,buf2;len:longint):longint;
|
|
\Description
|
|
\var{CompareChar} compares two memory regions \var{buf1},\var{buf2} on a
|
|
character-per-character basis for a total of \var{len} characters.
|
|
|
|
The \var{CompareChar0} variant compares \var{len} bytes, or until
|
|
a zero character is found.
|
|
|
|
The function returns one of the following values:
|
|
\begin{description}
|
|
\item[-1] if \var{buf1} and \var{buf2} contain different characters
|
|
in the first \var{len} positions, and the first such character is smaller in \var{buf1}
|
|
than the character at the same position in \var{buf2}.
|
|
\item[0] if the first \var{len} characters in \var{buf1} and \var{buf2} are
|
|
equal.
|
|
\item [1] if \var{buf1} and \var{buf2} contain different characters
|
|
in the first \var{len} positions, and the first such character is larger in
|
|
\var{buf1} than the character at the same position in \var{buf2}.
|
|
\end{description}
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{CompareByte},\seef{CompareWord},\seef{CompareDWord}
|
|
\end{function}
|
|
|
|
\FPCexample{ex100}
|
|
|
|
\begin{function}{CompareDWord}
|
|
\Declaration
|
|
function CompareDWord(var buf1,buf2;len:longint):longint;
|
|
\Description
|
|
\var{CompareDWord} compares two memory regions \var{buf1},\var{buf2} on a
|
|
DWord-per-DWord basis for a total of \var{len} DWords. (A DWord is 4 bytes).
|
|
|
|
The function returns one of the following values:
|
|
\begin{description}
|
|
\item[-1] if \var{buf1} and \var{buf2} contain different DWords
|
|
in the first \var{len} DWords, and the first such DWord is smaller in \var{buf1}
|
|
than the DWord at the same position in \var{buf2}.
|
|
\item[0] if the first \var{len} DWords in \var{buf1} and \var{buf2} are
|
|
equal.
|
|
\item [1] if \var{buf1} and \var{buf2} contain different DWords
|
|
in the first \var{len} DWords, and the first such DWord is larger in \var{buf1}
|
|
than the DWord at the same position in \var{buf2}.
|
|
\end{description}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{CompareChar},\seef{CompareByte},\seef{CompareWord},
|
|
\end{function}
|
|
|
|
\FPCexample{ex101}
|
|
|
|
\begin{function}{CompareWord}
|
|
\Declaration
|
|
function CompareWord(var buf1,buf2;len:longint):longint;
|
|
\Description
|
|
\var{CompareWord} compares two memory regions \var{buf1},\var{buf2} on a
|
|
Word-per-Word basis for a total of \var{len} Words. (A Word is 2 bytes).
|
|
|
|
The function returns one of the following values:
|
|
\begin{description}
|
|
\item[-1] if \var{buf1} and \var{buf2} contain different Words
|
|
in the first \var{len} Words, and the first such Word is smaller in \var{buf1}
|
|
than the Word at the same position in \var{buf2}.
|
|
\item[0] if the first \var{len} Words in \var{buf1} and \var{buf2} are
|
|
equal.
|
|
\item [1] if \var{buf1} and \var{buf2} contain different Words
|
|
in the first \var{len} Words, and the first such Word is larger in \var{buf1}
|
|
than the Word at the same position in \var{buf2}.
|
|
\end{description}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{CompareChar},\seef{CompareByte},\seef{CompareWord},
|
|
\end{function}
|
|
|
|
\FPCexample{ex102}
|
|
|
|
\begin{function}{Concat}
|
|
\Declaration
|
|
Function Concat (S1,S2 [,S3, ... ,Sn]) : String;
|
|
|
|
\Description
|
|
\var{Concat} concatenates the strings \var{S1},\var{S2} etc. to one long
|
|
string. The resulting string is truncated at a length of 255 bytes.
|
|
The same operation can be performed with the \var{+} operation.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Copy}, \seep{Delete}, \seep{Insert}, \seef{Pos}, \seef{Length}
|
|
\end{function}
|
|
|
|
\FPCexample{ex10}
|
|
|
|
\begin{procedure}{Continue}
|
|
\Declaration
|
|
Procedure Continue;
|
|
\Description
|
|
\var{Continue} jumps to the end of the current repetitive statement.
|
|
The code between the \var{Continue} call and the end of the repetitive
|
|
statement is skipped. The condition of the repetitive statement is then
|
|
checked again.
|
|
|
|
This can be used with \var{For}, var{repeat} and \var{While} statements.
|
|
|
|
Note that while this is a procedure, \var{Continue} is a reserved word
|
|
and hence cannot be redefined.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Break}, \seep{Exit}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex86}
|
|
|
|
|
|
\begin{function}{Copy}
|
|
\Declaration
|
|
Function Copy (Const S : String;Index : Integer;Count : Integer) : String;
|
|
|
|
\Description
|
|
\var{Copy} returns a string which is a copy if the \var{Count} characters
|
|
in \var{S}, starting at position \var{Index}. If \var{Count} is larger than
|
|
the length of the string \var{S}, the result is truncated.
|
|
If \var{Index} is larger than the length of the string \var{S}, then an
|
|
empty string is returned.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Delete}, \seep{Insert}, \seef{Pos}
|
|
\end{function}
|
|
|
|
\FPCexample{ex11}
|
|
|
|
\begin{function}{Cos}
|
|
\Declaration
|
|
Function Cos (X : Real) : Real;
|
|
|
|
\Description
|
|
\var{Cos} returns the cosine of \var{X}, where X is an angle, in radians.
|
|
|
|
If the absolute value of the argument is larger than \var{2\^{}63}, then the
|
|
result is undefined.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Arctan}, \seef{Sin}
|
|
\end{function}
|
|
|
|
\FPCexample{ex12}
|
|
|
|
\begin{function}{CSeg}
|
|
\Declaration
|
|
Function CSeg : Word;
|
|
|
|
\Description
|
|
\var{CSeg} returns the Code segment register. In \fpc, it returns always a
|
|
zero, since \fpc is a 32 bit compiler.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{DSeg}, \seef{Seg}, \seef{Ofs}, \seef{Ptr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex13}
|
|
|
|
\begin{procedure}{Dec}
|
|
\Declaration
|
|
Procedure Dec (Var X : Any ordinal type[; Decrement : Any ordinal type]);
|
|
|
|
\Description
|
|
\var{Dec} decreases the value of \var{X} with \var{Decrement}.
|
|
If \var{Decrement} isn't specified, then 1 is taken as a default.
|
|
\Errors
|
|
A range check can occur, or an underflow error, if an attempt it made
|
|
to decrease \var{X} below its minimum value.
|
|
\SeeAlso
|
|
\seep{Inc}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex14}
|
|
|
|
\begin{procedure}{Delete}
|
|
\Declaration
|
|
Procedure Delete (var S : string;Index : Integer;Count : Integer);
|
|
|
|
\Description
|
|
\var{Delete} removes \var{Count} characters from string \var{S}, starting
|
|
at position \var{Index}. All characters after the delected characters are
|
|
shifted \var{Count} positions to the left, and the length of the string is adjusted.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Copy},\seef{Pos},\seep{Insert}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex15}
|
|
|
|
\begin{procedure}{Dispose}
|
|
\Declaration
|
|
Procedure Dispose (P : pointer);\\
|
|
Procedure Dispose (P : Typed Pointer; Des : Procedure);
|
|
\Description
|
|
The first form \var{Dispose} releases the memory allocated with a call to
|
|
\seep{New}. The pointer \var{P} must be typed. The released memory is
|
|
returned to the heap.
|
|
|
|
The second form of \var{Dispose} accepts as a first parameter a pointer
|
|
to an object type, and as a second parameter the name of a destructor
|
|
of this object. The destructor will be called, and the memory allocated
|
|
for the object will be freed.
|
|
\Errors
|
|
An runtime error will occur if the pointer doesn't point to a location in the
|
|
heap.
|
|
\SeeAlso
|
|
\seep{New}, \seep{Getmem}, \seep{Freemem}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex16}
|
|
|
|
\begin{function}{DSeg}
|
|
\Declaration
|
|
Function DSeg : Word;
|
|
|
|
\Description
|
|
\var{DSeg} returns the data segment register. In \fpc, it returns always a
|
|
zero, since \fpc is a 32 bit compiler.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{CSeg}, \seef{Seg}, \seef{Ofs}, \seef{Ptr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex17}
|
|
|
|
\begin{function}{Eof}
|
|
\Declaration
|
|
Function Eof [(F : Any file type)] : Boolean;
|
|
|
|
\Description
|
|
\var{Eof} returns \var{True} if the file-pointer has reached the end of the
|
|
file, or if the file is empty. In all other cases \var{Eof} returns
|
|
\var{False}.
|
|
If no file \var{F} is specified, standard input is assumed.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seef{Eoln}, \seep{Assign}, \seep{Reset}, \seep{Rewrite}
|
|
\end{function}
|
|
|
|
\FPCexample{ex18}
|
|
|
|
\begin{function}{Eoln}
|
|
\Declaration
|
|
Function Eoln [(F : Text)] : Boolean;
|
|
|
|
\Description
|
|
\var{Eof} returns \var{True} if the file pointer has reached the end of a
|
|
line, which is demarcated by a line-feed character (ASCII value 10), or if
|
|
the end of the file is reached.
|
|
In all other cases \var{Eof} returns \var{False}.
|
|
If no file \var{F} is specified, standard input is assumed.
|
|
It can only be used on files of type \var{Text}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Eof}, \seep{Assign}, \seep{Reset}, \seep{Rewrite}
|
|
\end{function}
|
|
|
|
\FPCexample{ex19}
|
|
|
|
\begin{procedure}{Erase}
|
|
\Declaration
|
|
Procedure Erase (Var F : Any file type);
|
|
|
|
\Description
|
|
\var{Erase} removes an unopened file from disk. The file should be
|
|
assigned with \var{Assign}, but not opened with \var{Reset} or \var{Rewrite}
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Assign}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex20}
|
|
|
|
\begin{procedure}{Exclude}
|
|
\Declaration
|
|
Procedure Exclude (Var S : Any set type; E : Set element);
|
|
\Description
|
|
\var{Exclude} removes \var{E} from the set \var{S} if it is
|
|
included inthe set. E should be of the same type as the base type
|
|
of the set \var{S}.
|
|
|
|
Thus, the two following statements do the same thing:
|
|
\begin{verbatim}
|
|
S:=S-[E];
|
|
Exclude(S,E);
|
|
\end{verbatim}
|
|
\Errors
|
|
If the type of the element \var{E} is not equal to the base type of the
|
|
set \var{S}, the compiler will generate an error.
|
|
\SeeAlso
|
|
\seep{Include}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex111}
|
|
|
|
\begin{procedure}{Exit}
|
|
\Declaration
|
|
Procedure Exit ([Var X : return type )];
|
|
|
|
\Description
|
|
\var{Exit} exits the current subroutine, and returns control to the calling
|
|
routine. If invoked in the main program routine, exit stops the program.
|
|
The optional argument \var{X} allows to specify a return value, in the case
|
|
\var{Exit} is invoked in a function. The function result will then be
|
|
equal to \var{X}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Halt}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex21}
|
|
|
|
\begin{function}{Exp}
|
|
\Declaration
|
|
Function Exp (Var X : Real) : Real;
|
|
|
|
\Description
|
|
\var{Exp} returns the exponent of \var{X}, i.e. the number \var{e} to the
|
|
power \var{X}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Ln}, \seef{Power}
|
|
\end{function}
|
|
|
|
\FPCexample{ex22}
|
|
|
|
\begin{function}{Filepos}
|
|
\Declaration
|
|
Function Filepos (Var F : Any file type) : Longint;
|
|
|
|
\Description
|
|
\var{Filepos} returns the current record position of the file-pointer in file
|
|
\var{F}. It cannot be invoked with a file of type \var{Text}. A compiler error
|
|
will be generated if this is attempted.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seef{Filesize}
|
|
\end{function}
|
|
|
|
\FPCexample{ex23}
|
|
|
|
\begin{function}{Filesize}
|
|
\Declaration
|
|
Function Filesize (Var F : Any file type) : Longint;
|
|
\Description
|
|
\var{Filesize} returns the total number of records in file \var{F}.
|
|
It cannot be invoked with a file of type \var{Text}. (under \linux and \unix, this
|
|
also means that it cannot be invoked on pipes).
|
|
If \var{F} is empty, 0 is returned.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seef{Filepos}
|
|
\end{function}
|
|
|
|
\FPCexample{ex24}
|
|
|
|
\begin{procedure}{FillByte}
|
|
\Declaration
|
|
Procedure FillByte(var X;Count:longint;Value:byte);
|
|
\Description
|
|
\var{FillByte} fills the memory starting at \var{X} with \var{Count} bytes
|
|
with value equal to \var{Value}.
|
|
|
|
This is useful for quickly zeroing out a memory location. When the size of
|
|
the memory location to be filled out is a multiple of 2 bytes, it is better
|
|
to use \seep{Fillword}, and if it is a multiple of 4 bytes it is better
|
|
to use \seep{FillDWord}, these routines are optimized for their respective sizes.
|
|
|
|
\Errors
|
|
No checking on the size of \var{X} is done.
|
|
\SeeAlso
|
|
\seep{Fillchar}, \seep{FillDWord}, \seep{Fillword}, \seep{Move}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex102}
|
|
|
|
\begin{procedure}{Fillchar}
|
|
\Declaration
|
|
Procedure Fillchar (Var X;Count : Longint;Value : char or byte);;
|
|
|
|
\Description
|
|
\var{Fillchar} fills the memory starting at \var{X} with \var{Count} bytes
|
|
or characters with value equal to \var{Value}.
|
|
|
|
\Errors
|
|
No checking on the size of \var{X} is done.
|
|
\SeeAlso
|
|
\seep{Fillword}, \seep{Move}, \seep{FillByte}, \seep{FillDWord}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex25}
|
|
|
|
\begin{procedure}{FillDWord}
|
|
\Declaration
|
|
Procedure FillDWord (Var X;Count : Longint;Value : DWord);;
|
|
\Description
|
|
\var{Fillword} fills the memory starting at \var{X} with \var{Count} DWords
|
|
with value equal to \var{Value}. A DWord is 4 bytes in size.
|
|
|
|
\Errors
|
|
No checking on the size of \var{X} is done.
|
|
\SeeAlso
|
|
\seep{FillByte}, \seep{Fillchar}, \seep{Fillword}, \seep{Move}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex103}
|
|
|
|
\begin{procedure}{Fillword}
|
|
\Declaration
|
|
Procedure Fillword (Var X;Count : Longint;Value : Word);;
|
|
\Description
|
|
\var{Fillword} fills the memory starting at \var{X} with \var{Count} words
|
|
with value equal to \var{Value}. A word is 2 bytes in size.
|
|
\Errors
|
|
No checking on the size of \var{X} is done.
|
|
\SeeAlso
|
|
\seep{Fillchar}, \seep{Move}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex76}
|
|
|
|
\begin{procedure}{Flush}
|
|
\Declaration
|
|
Procedure Flush (Var F : Text);
|
|
|
|
\Description
|
|
\var{Flush} empties the internal buffer of an opened file \var{F} and writes the
|
|
contents to disk. The file is \textit{not} closed as a result of this call.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Close}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex26}
|
|
|
|
\begin{function}{Frac}
|
|
\Declaration
|
|
Function Frac (X : Real) : Real;
|
|
|
|
\Description
|
|
\var{Frac} returns the non-integer part of \var{X}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Round}, \seef{Int}
|
|
\end{function}
|
|
|
|
\FPCexample{ex27}
|
|
|
|
\begin{procedure}{Freemem}
|
|
\Declaration
|
|
Procedure Freemem (Var P : pointer; Count : Longint);
|
|
|
|
\Description
|
|
\var{Freemem} releases the memory occupied by the pointer \var{P}, of size
|
|
\var{Count} (in bytes), and returns it to the heap. \var{P} should point to the memory
|
|
allocated to a dynamic variable.
|
|
\Errors
|
|
An error will occur when \var{P} doesn't point to the heap.
|
|
\SeeAlso
|
|
\seep{Getmem}, \seep{New}, \seep{Dispose}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex28}
|
|
|
|
\begin{procedure}{Getdir}
|
|
\Declaration
|
|
Procedure Getdir (drivenr : byte;var dir : string);
|
|
|
|
\Description
|
|
\var{Getdir} returns in \var{dir} the current directory on the drive
|
|
\var{drivenr}, where {drivenr} is 1 for the first floppy drive, 3 for the
|
|
first hard disk etc. A value of 0 returns the directory on the current disk.
|
|
On \linux and \unix systems, \var{drivenr} is ignored, as there is only one
|
|
directory tree.
|
|
\Errors
|
|
An error is returned under \dos, if the drive requested isn't ready.
|
|
\SeeAlso
|
|
\seep{Chdir}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex29}
|
|
|
|
\begin{procedure}{Getmem}
|
|
\Declaration
|
|
Procedure Getmem (var p : pointer;size : Longint);
|
|
|
|
\Description
|
|
\var{Getmem} reserves \var{Size} bytes memory on the heap, and returns a
|
|
pointer to this memory in \var{p}. If no more memory is available, nil is
|
|
returned.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Freemem}, \seep{Dispose}, \seep{New}
|
|
\end{procedure}
|
|
For an example, see \seep{Freemem}.
|
|
|
|
\begin{procedure}{GetMemoryManager}
|
|
\Declaration
|
|
procedure GetMemoryManager(var MemMgr: TMemoryManager);
|
|
\Description
|
|
\var{GetMemoryManager} stores the current Memory Manager record in
|
|
\var{MemMgr}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{SetMemoryManager}, \seef{IsMemoryManagerSet}.
|
|
\end{procedure}
|
|
|
|
For an example, see \progref.
|
|
|
|
\begin{procedure}{Halt}
|
|
\Declaration
|
|
Procedure Halt [(Errnum : byte)];
|
|
\Description
|
|
\var{Halt} stops program execution and returns control to the calling
|
|
program. The optional argument \var{Errnum} specifies an exit value. If
|
|
omitted, zero is returned.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Exit}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex30}
|
|
|
|
\begin{function}{HexStr}
|
|
\Declaration
|
|
Function HexStr (Value : longint; cnt : byte) : String;
|
|
Function HexStr (Value : int64; cnt : byte) : String;
|
|
\Description
|
|
\var{HexStr} returns a string with the hexadecimal representation
|
|
of \var{Value}. The string has exactly \var{cnt} charaters.
|
|
(i.e. only the \var{cnt} rightmost nibbles are taken into account)
|
|
To have a complete representation of a Longint-type value, 8
|
|
nibbles are needed, i.e. \var{cnt=8}.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Str}, \seep{Val}, \seef{BinStr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex81}
|
|
|
|
\begin{function}{Hi}
|
|
\Declaration
|
|
Function Hi (X : Ordinal type) : Word or byte;
|
|
|
|
\Description
|
|
\var{Hi} returns the high byte or word from \var{X}, depending on the size
|
|
of X. If the size of X is 4, then the high word is returned. If the size is
|
|
2 then the high byte is returned.
|
|
\var{Hi} cannot be invoked on types of size 1, such as byte or char.
|
|
\Errors
|
|
None
|
|
\SeeAlso
|
|
\seef{Lo}
|
|
\end{function}
|
|
|
|
\FPCexample{ex31}
|
|
|
|
\begin{function}{High}
|
|
\Declaration
|
|
Function High (Type identifier or variable reference) : Ordinal;
|
|
|
|
\Description
|
|
The return value of \var{High} depends on it's argument:
|
|
\begin{enumerate}
|
|
\item If the argument is an ordinal type, \var{High} returns the highest
|
|
value in the range of the given ordinal type.
|
|
\item If the argument is an array type or an array type variable then
|
|
\var{High} returns the highest possible value of it's index.
|
|
\item If the argument is an open array identifier in a function or
|
|
procedure, then \var{High} returns the highest index of the array, as if the
|
|
array has a zero-based index.
|
|
\end{enumerate}
|
|
The return type is always the same type as the type of the argument
|
|
(This can lead to some nasty surprises !).
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Low}, \seef{Ord}, \seef{Pred}, \seef{Succ}
|
|
\end{function}
|
|
|
|
\FPCexample{ex80}
|
|
|
|
\begin{procedure}{Inc}
|
|
\Declaration
|
|
Procedure Inc (Var X : Any ordinal type[; Increment : Any ordinal type]);
|
|
|
|
\Description
|
|
\var{Inc} increases the value of \var{X} with \var{Increment}.
|
|
If \var{Increment} isn't specified, then 1 is taken as a default.
|
|
\Errors
|
|
If range checking is on, then A range check can occur, or an overflow
|
|
error, when an attempt is made to increase \var{X} over its maximum value.
|
|
\SeeAlso
|
|
\seep{Dec}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex32}
|
|
|
|
\begin{procedure}{Include}
|
|
\Declaration
|
|
Procedure Include (Var S : Any set type; E : Set element);
|
|
\Description
|
|
\var{Include} includes \var{E} in the set \var{S} if it is
|
|
not yet part of the set. E should be of the same type as the base type
|
|
of the set \var{S}.
|
|
|
|
Thus, the two following statements do the same thing:
|
|
\begin{verbatim}
|
|
S:=S+[E];
|
|
Include(S,E);
|
|
\end{verbatim}
|
|
\Errors
|
|
If the type of the element \var{E} is not equal to the base type of the
|
|
set \var{S}, the compiler will generate an error.
|
|
\SeeAlso
|
|
\seep{Exclude}
|
|
\end{procedure}
|
|
|
|
For an example, see \seep{Exclude}
|
|
|
|
\begin{function}{IndexByte}
|
|
\Declaration
|
|
function IndexByte(var buf;len:longint;b:byte):longint;
|
|
\Description
|
|
\var{IndexByte} searches the memory at \var{buf} for maximally \var{len}
|
|
positions for the byte \var{b} and returns it's position if it found one.
|
|
If \var{b} is not found then -1 is returned.
|
|
|
|
The position is zero-based.
|
|
\Errors
|
|
\var{Buf} and \var{Len} are not checked to see if they are valid values.
|
|
\SeeAlso
|
|
\seef{IndexChar}, \seef{IndexDWord}, \seef{IndexWord}, \seef{CompareByte}
|
|
\end{function}
|
|
|
|
\FPCexample{ex105}
|
|
|
|
\begin{function}{IndexChar}
|
|
\Declaration
|
|
function IndexChar(var buf;len:longint;b:char):longint;
|
|
\Declaration
|
|
function IndexChar0(var buf;len:longint;b:char):longint;
|
|
\Description
|
|
\var{IndexChar} searches the memory at \var{buf} for maximally \var{len}
|
|
positions for the character \var{b} and returns it's position if it found one.
|
|
If \var{b} is not found then -1 is returned.
|
|
|
|
The position is zero-based. The \var{IndexChar0} variant stops looking if
|
|
a null character is found, and returns -1 in that case.
|
|
\Errors
|
|
\var{Buf} and \var{Len} are not checked to see if they are valid values.
|
|
\SeeAlso
|
|
\seef{IndexByte}, \seef{IndexDWord}, \seef{IndexWord}, \seef{CompareChar}
|
|
\end{function}
|
|
|
|
\FPCexample{ex108}
|
|
|
|
\begin{function}{IndexDWord}
|
|
\Declaration
|
|
function IndexDWord(var buf;len:longint;DW:DWord):longint;
|
|
\Description
|
|
\var{IndexChar} searches the memory at \var{buf} for maximally \var{len}
|
|
positions for the DWord \var{DW} and returns it's position if it found one.
|
|
If \var{DW} is not found then -1 is returned.
|
|
|
|
The position is zero-based.
|
|
\Errors
|
|
\var{Buf} and \var{Len} are not checked to see if they are valid values.
|
|
\SeeAlso
|
|
\seef{IndexByte}, \seef{IndexChar}, \seef{IndexWord}, \seef{CompareDWord}
|
|
\end{function}
|
|
|
|
\FPCexample{ex106}
|
|
|
|
\begin{function}{IndexWord}
|
|
\Declaration
|
|
function IndexWord(var buf;len:longint;W:word):longint;
|
|
\Description
|
|
\var{IndexChar} searches the memory at \var{buf} for maximally \var{len}
|
|
positions for the Word \var{W} and returns it's position if it found one.
|
|
If \var{W} is not found then -1 is returned.
|
|
\Errors
|
|
\var{Buf} and \var{Len} are not checked to see if they are valid values.
|
|
\SeeAlso
|
|
\seef{IndexByte}, \seef{IndexDWord}, \seef{IndexChar}, \seef{CompareWord}
|
|
\end{function}
|
|
|
|
\FPCexample{ex107}
|
|
|
|
\begin{procedure}{Insert}
|
|
\Declaration
|
|
Procedure Insert (Const Source : String;var S : String;Index : Integer);
|
|
|
|
\Description
|
|
\var{Insert} inserts string \var{Source} in string \var{S}, at position
|
|
\var{Index}, shifting all characters after \var{Index} to the right. The
|
|
resulting string is truncated at 255 characters, if needed. (i.e. for
|
|
shortstrings)
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Delete}, \seef{Copy}, \seef{Pos}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex33}
|
|
|
|
\begin{function}{IsMemoryManagerSet}
|
|
\Declaration
|
|
function IsMemoryManagerSet: Boolean;
|
|
\Description
|
|
\var{IsMemoryManagerSet} will return \var{True} if the memory manager has
|
|
been set to another value than the system heap manager, it will return
|
|
\var{False} otherwise.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{SetMemoryManager}, \seep{GetMemoryManager}
|
|
\end{function}
|
|
|
|
\begin{function}{Int}
|
|
\Declaration
|
|
Function Int (X : Real) : Real;
|
|
|
|
\Description
|
|
\var{Int} returns the integer part of any Real \var{X}, as a Real.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Frac}, \seef{Round}
|
|
\end{function}
|
|
|
|
\FPCexample{ex34}
|
|
|
|
\begin{function}{IOresult}
|
|
\Declaration
|
|
Function IOresult : Word;
|
|
|
|
\Description
|
|
IOresult contains the result of any input/output call, when the
|
|
\var{\{\$i-\}} compiler directive is active, disabling IO checking.
|
|
When the flag is read, it is reset to zero.
|
|
If \var{IOresult} is zero, the operation completed successfully. If
|
|
non-zero, an error occurred. The following errors can occur:
|
|
|
|
\dos errors :
|
|
\begin{description}
|
|
\item [2\ ] File not found.
|
|
\item [3\ ] Path not found.
|
|
\item [4\ ] Too many open files.
|
|
\item [5\ ] Access denied.
|
|
\item [6\ ] Invalid file handle.
|
|
\item [12\ ] Invalid file-access mode.
|
|
\item [15\ ] Invalid disk number.
|
|
\item [16\ ] Cannot remove current directory.
|
|
\item [17\ ] Cannot rename across volumes.
|
|
\end{description}
|
|
I/O errors :
|
|
\begin{description}
|
|
\item [100\ ] Error when reading from disk.
|
|
\item [101\ ] Error when writing to disk.
|
|
\item [102\ ] File not assigned.
|
|
\item [103\ ] File not open.
|
|
\item [104\ ] File not opened for input.
|
|
\item [105\ ] File not opened for output.
|
|
\item [106\ ] Invalid number.
|
|
\end{description}
|
|
Fatal errors :
|
|
\begin{description}
|
|
\item [150\ ] Disk is write protected.
|
|
\item [151\ ] Unknown device.
|
|
\item [152\ ] Drive not ready.
|
|
\item [153\ ] Unknown command.
|
|
\item [154\ ] CRC check failed.
|
|
\item [155\ ] Invalid drive specified..
|
|
\item [156\ ] Seek error on disk.
|
|
\item [157\ ] Invalid media type.
|
|
\item [158\ ] Sector not found.
|
|
\item [159\ ] Printer out of paper.
|
|
\item [160\ ] Error when writing to device.
|
|
\item [161\ ] Error when reading from device.
|
|
\item [162\ ] Hardware failure.
|
|
\end{description}
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
All I/O functions.
|
|
\end{function}
|
|
|
|
\FPCexample{ex35}
|
|
|
|
\begin{function}{Length}
|
|
\Declaration
|
|
Function Length (S : String) : Integer;
|
|
|
|
\Description
|
|
\var{Length} returns the length of the string \var{S}, which is limited
|
|
to 255 for shortstrings. If the strings \var{S} is empty, 0 is returned.
|
|
|
|
{\em Note:} The length of the string \var{S} is stored in \var{S[0]} for
|
|
shortstrings only. The \var{Length} fuction should always be used on
|
|
ansistrings and widestrings.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Pos}
|
|
\end{function}
|
|
|
|
\FPCexample{ex36}
|
|
|
|
\begin{function}{Ln}
|
|
\Declaration
|
|
Function Ln (X : Real) : Real;
|
|
|
|
\Description
|
|
|
|
\var{Ln} returns the natural logarithm of the Real parameter \var{X}.
|
|
\var{X} must be positive.
|
|
|
|
\Errors
|
|
An run-time error will occur when \var{X} is negative.
|
|
\SeeAlso
|
|
\seef{Exp}, \seef{Power}
|
|
\end{function}
|
|
|
|
\FPCexample{ex37}
|
|
|
|
\begin{function}{Lo}
|
|
\Declaration
|
|
Function Lo (O : Word or Longint) : Byte or Word;
|
|
|
|
\Description
|
|
\var{Lo} returns the low byte of its argument if this is of type
|
|
\var{Integer} or
|
|
\var{Word}. It returns the low word of its argument if this is of type
|
|
\var{Longint} or \var{Cardinal}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Ord}, \seef{Chr}, \seef{Hi}
|
|
\end{function}
|
|
|
|
\FPCexample{ex38}
|
|
|
|
\begin{procedure}{LongJmp}
|
|
\Declaration
|
|
Procedure LongJmp (Var env : Jmp\_Buf; Value : Longint);
|
|
|
|
\Description
|
|
|
|
\var{LongJmp} jumps to the adress in the \var{env} \var{jmp\_buf},
|
|
and restores the registers that were stored in it at the corresponding
|
|
\seef{SetJmp} call.
|
|
In effect, program flow will continue at the \var{SetJmp} call, which will
|
|
return \var{value} instead of 0. If a \var{value} equal to zero is passed,
|
|
it will be converted to 1 before passing it on. The call will not return, so it must be
|
|
used with extreme care.
|
|
This can be used for error recovery, for instance when a segmentation fault
|
|
occurred.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{SetJmp}
|
|
\end{procedure}
|
|
For an example, see \seef{SetJmp}
|
|
|
|
\begin{function}{Low}
|
|
\Declaration
|
|
Function Low (Type identifier or variable reference) : Longint;
|
|
|
|
\Description
|
|
The return value of \var{Low} depends on it's argument:
|
|
\begin{enumerate}
|
|
\item If the argument is an ordinal type, \var{Low} returns the lowest
|
|
value in the range of the given ordinal type.
|
|
\item If the argument is an array type or an array type variable then
|
|
\var{Low} returns the lowest possible value of it's index.
|
|
\end{enumerate}
|
|
The return type is always the same type as the type of the argument
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{High}, \seef{Ord}, \seef{Pred}, \seef{Succ}
|
|
\end{function}
|
|
for an example, see \seef{High}.
|
|
\begin{function}{Lowercase}
|
|
\Declaration
|
|
Function Lowercase (C : Char or String) : Char or String;
|
|
|
|
\Description
|
|
\var{Lowercase} returns the lowercase version of its argument \var{C}.
|
|
If its argument is a string, then the complete string is converted to
|
|
lowercase. The type of the returned value is the same as the type of the
|
|
argument.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Upcase}
|
|
\end{function}
|
|
|
|
\FPCexample{ex73}
|
|
|
|
\begin{procedure}{Mark}
|
|
\Declaration
|
|
Procedure Mark (Var P : Pointer);
|
|
|
|
\Description
|
|
This routine is here for compatibility with Turbo Pascal, but
|
|
it is not implemented and currently does nothing.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Getmem}, \seep{Freemem}, \seep{New}, \seep{Dispose}, \seef{Maxavail}
|
|
\end{procedure}
|
|
|
|
\begin{function}{Maxavail}
|
|
\Declaration
|
|
Function Maxavail : Longint;
|
|
|
|
\Description
|
|
\var{Maxavail} returns the size, in bytes, of the biggest free memory block in
|
|
the heap.
|
|
\begin{remark}
|
|
The heap grows dynamically if more memory is needed than is available.
|
|
\end{remark}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Release}, \seef{Memavail},\seep{Freemem}, \seep{Getmem}
|
|
\end{function}
|
|
|
|
\FPCexample{ex40}
|
|
|
|
\begin{function}{Memavail}
|
|
\Declaration
|
|
Function Memavail : Longint;
|
|
|
|
\Description
|
|
\var{Memavail} returns the size, in bytes, of the free heap memory.
|
|
\begin{remark}
|
|
The heap grows dynamically if more memory is needed than is available. The
|
|
heap size is not equal to the size of the memory available to the
|
|
operating system, it is internal to the programs created by \fpc.
|
|
\end{remark}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Maxavail},\seep{Freemem}, \seep{Getmem}
|
|
\end{function}
|
|
|
|
\FPCexample{ex41}
|
|
|
|
\begin{procedure}{Mkdir}
|
|
\Declaration
|
|
Procedure Mkdir (const S : string);
|
|
|
|
\Description
|
|
\var{Mkdir} creates a new directory \var{S}.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Chdir}, \seep{Rmdir}
|
|
\end{procedure}
|
|
For an example, see \seep{Rmdir}.
|
|
\begin{procedure}{Move}
|
|
\Declaration
|
|
Procedure Move (var Source,Dest;Count : Longint);
|
|
\Description
|
|
\var{Move} moves \var{Count} bytes from \var{Source} to \var{Dest}.
|
|
\Errors
|
|
If either \var{Dest} or \var{Source} is outside the accessible memory for
|
|
the process, then a run-time error will be generated.
|
|
\SeeAlso
|
|
\seep{Fillword}, \seep{Fillchar}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex42}
|
|
|
|
\begin{procedurel}{MoveChar0}{MoveCharNull}
|
|
\Declaration
|
|
procedure MoveChar0(var Src,Dest;Count:longint);
|
|
\Description
|
|
\var{MoveChar0} moves \var{Count} bytes from \var{Src} to \var{Dest}, and
|
|
stops moving if a zero character is found.
|
|
\Errors
|
|
No checking is done to see if \var{Count} stays within the memory allocated
|
|
to the process.
|
|
\SeeAlso
|
|
\seep{Move}
|
|
\end{procedurel}
|
|
|
|
\FPCexample{ex109}
|
|
|
|
\begin{procedure}{New}
|
|
\Declaration
|
|
Procedure New (Var P : Pointer[, Constructor]);
|
|
|
|
\Description
|
|
\var{New} allocates a new instance of the type pointed to by \var{P}, and
|
|
puts the address in \var{P}.
|
|
If P is an object, then it is possible to
|
|
specify the name of the constructor with which the instance will be created.
|
|
\Errors
|
|
If not enough memory is available, \var{Nil} will be returned.
|
|
\SeeAlso
|
|
\seep{Dispose}, \seep{Freemem}, \seep{Getmem}, \seef{Memavail},
|
|
\seef{Maxavail}
|
|
\end{procedure}
|
|
For an example, see \seep{Dispose}.
|
|
\begin{function}{Odd}
|
|
\Declaration
|
|
Function Odd (X : Longint) : Boolean;
|
|
|
|
\Description
|
|
\var{Odd} returns \var{True} if \var{X} is odd, or \var{False} otherwise.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Abs}, \seef{Ord}
|
|
\end{function}
|
|
|
|
\FPCexample{ex43}
|
|
|
|
\begin{function}{OctStr}
|
|
\Declaration
|
|
Function OctStr (Value : longint; cnt : byte) : String;
|
|
Function OctStr (Value : int64; cnt : byte) : String;
|
|
\Description
|
|
\var{OctStr} returns a string with the octal representation
|
|
of \var{Value}. The string has exactly \var{cnt} charaters.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Str}, \seep{Val}, \seef{BinStr}, \seef{HexStr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex112}
|
|
|
|
\begin{function}{Ofs}
|
|
\Declaration
|
|
Function Ofs (Var X) : Longint;
|
|
|
|
\Description
|
|
\var{Ofs} returns the offset of the address of a variable.
|
|
This function is only supported for compatibility. In \fpc, it
|
|
returns always the complete address of the variable, since \fpc is a 32 bit
|
|
compiler.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{DSeg}, \seef{CSeg}, \seef{Seg}, \seef{Ptr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex44}
|
|
|
|
\begin{function}{Ord}
|
|
\Declaration
|
|
Function Ord (X : Any ordinal type) : Longint;
|
|
|
|
\Description
|
|
\var{Ord} returns the Ordinal value of a ordinal-type variable \var{X}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Chr}, \seef{Succ}, \seef{Pred}, \seef{High}, \seef{Low}
|
|
\end{function}
|
|
|
|
\FPCexample{ex45}
|
|
|
|
\begin{function}{Paramcount}
|
|
\Declaration
|
|
Function Paramcount : Longint;
|
|
|
|
\Description
|
|
\var{Paramcount} returns the number of command-line arguments. If no
|
|
arguments were given to the running program, \var{0} is returned.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Paramstr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex46}
|
|
|
|
\begin{function}{Paramstr}
|
|
\Declaration
|
|
Function Paramstr (L : Longint) : String;
|
|
|
|
\Description
|
|
\var{Paramstr} returns the \var{L}-th command-line argument. \var{L} must
|
|
be between \var{0} and \var{Paramcount}, these values included.
|
|
The zeroth argument is the path and file name with which the program was
|
|
started.
|
|
|
|
The command-line parameters will be truncated to a length of 255,
|
|
even though the operating system may support bigger command-lines.
|
|
The \var{Objpas} unit (used in \var{objfpc} or \var{delphi} mode) define versions
|
|
of \var{Paramstr} which return the full-length command-line arguments.
|
|
|
|
When the complete command-line must be accessed, the \var{argv} pointer
|
|
should be used to retrieve the real values of the command-line parameters.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Paramcount}
|
|
\end{function}
|
|
For an example, see \seef{Paramcount}.
|
|
\begin{function}{Pi}
|
|
\Declaration
|
|
Function Pi : Real;
|
|
|
|
\Description
|
|
\var{Pi} returns the value of Pi (3.1415926535897932385).
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Cos}, \seef{Sin}
|
|
\end{function}
|
|
|
|
\FPCexample{ex47}
|
|
|
|
\begin{function}{Pos}
|
|
\Declaration
|
|
Function Pos (Const Substr : String;Const S : String) : Integer;
|
|
\Description
|
|
\var{Pos} returns the index of \var{Substr} in \var{S}, if \var{S} contains
|
|
\var{Substr}. In case \var{Substr} isn't found, \var{0} is returned.
|
|
The search is case-sensitive.
|
|
\Errors
|
|
None
|
|
\SeeAlso
|
|
\seef{Length}, \seef{Copy}, \seep{Delete}, \seep{Insert}
|
|
\end{function}
|
|
|
|
\FPCexample{ex48}
|
|
|
|
\begin{function}{Power}
|
|
\Declaration
|
|
Function Power (base,expon : Real) : Real;
|
|
\Description
|
|
|
|
\var{Power} returns the value of \var{base} to the power \var{expon}.
|
|
\var{Base} and \var{expon} can be of type Longint, in which case the
|
|
result will also be a Longint.
|
|
|
|
The function actually returns \var{Exp(expon*Ln(base))}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Exp}, \seef{Ln}
|
|
\end{function}
|
|
|
|
\FPCexample{ex78}
|
|
|
|
\begin{function}{Pred}
|
|
\Declaration
|
|
Function Pred (X : Any ordinal type) : Same type;
|
|
\Description
|
|
\var{Pred} returns the element that precedes the element that was passed
|
|
to it. If it is applied to the first value of the ordinal type, and the
|
|
program was compiled with range checking on (\var{\{\$R+\}}, then a run-time
|
|
error will be generated.
|
|
\Errors
|
|
Run-time error 201 is generated when the result is out of
|
|
range.
|
|
\SeeAlso
|
|
\seef{Ord}, \seef{Pred}, \seef{High}, \seef{Low}
|
|
\end{function}
|
|
|
|
for an example, see \seef{Ord}
|
|
|
|
\begin{function}{Ptr}
|
|
\Declaration
|
|
Function Ptr (Sel,Off : Longint) : Pointer;
|
|
\Description
|
|
\var{Ptr} returns a pointer, pointing to the address specified by
|
|
segment \var{Sel} and offset \var{Off}.
|
|
|
|
\begin{remark}
|
|
\begin{enumerate}
|
|
\item In the 32-bit flat-memory model supported by \fpc, this
|
|
function is obsolete.
|
|
\item The returned address is simply the offset.
|
|
\end{enumerate}
|
|
\end{remark}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Addr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex59}
|
|
|
|
\begin{function}{Random}
|
|
\Declaration
|
|
Function Random [(L : Longint)] : Longint or Real;
|
|
|
|
\Description
|
|
\var{Random} returns a random number larger or equal to \var{0} and
|
|
strictly less than \var{L}.
|
|
If the argument \var{L} is omitted, a Real number between 0 and 1 is returned.
|
|
(0 included, 1 excluded)
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Randomize}
|
|
\end{function}
|
|
|
|
\FPCexample{ex49}
|
|
|
|
\begin{procedure}{Randomize}
|
|
\Declaration
|
|
Procedure Randomize ;
|
|
|
|
\Description
|
|
\var{Randomize} initializes the random number generator of \fpc, by giving
|
|
a value to \var{Randseed}, calculated with the system clock.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Random}
|
|
\end{procedure}
|
|
For an example, see \seef{Random}.
|
|
\begin{procedure}{Read}
|
|
\Declaration
|
|
Procedure Read ([Var F : Any file type], V1 [, V2, ... , Vn]);
|
|
|
|
\Description
|
|
\var{Read} reads one or more values from a file \var{F}, and stores the
|
|
result in \var{V1}, \var{V2}, etc.; If no file \var{F} is specified, then
|
|
standard input is read.
|
|
If \var{F} is of type \var{Text}, then the variables \var{V1, V2} etc. must be
|
|
of type \var{Char}, \var{Integer}, \var{Real}, \var{String} or \var{PChar}.
|
|
If \var{F} is a typed file, then each of the variables must be of the type
|
|
specified in the declaration of \var{F}. Untyped files are not allowed as an
|
|
argument.
|
|
\Errors
|
|
If no data is available, a run-time error is generated. This behavior can
|
|
be controlled with the \var{\{\$i\}} compiler switch.
|
|
\SeeAlso
|
|
\seep{Readln}, \seep{Blockread}, \seep{Write}, \seep{Blockwrite}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex50}
|
|
|
|
\begin{procedure}{Readln}
|
|
\Declaration
|
|
Procedure Readln [Var F : Text], V1 [, V2, ... , Vn]);
|
|
|
|
\Description
|
|
\var{Read} reads one or more values from a file \var{F}, and stores the
|
|
result in \var{V1}, \var{V2}, etc. After that it goes to the next line in
|
|
the file. The end of the line is marked by the \var{LineEnding}
|
|
character sequence (which is platform dependent). The end-of-line marker is
|
|
not considered part of the line and is ignored.
|
|
|
|
If no file \var{F} is specified, then standard input is read.
|
|
The variables \var{V1, V2} etc. must be of type \var{Char}, \var{Integer},
|
|
\var{Real}, \var{String} or \var{PChar}.
|
|
|
|
\Errors
|
|
If no data is available, a run-time error is generated. This behavior can
|
|
be controlled with the \var{\{\$i\}} compiler switch.
|
|
\SeeAlso
|
|
\seep{Read}, \seep{Blockread}, \seep{Write}, \seep{Blockwrite}
|
|
\end{procedure}
|
|
|
|
For an example, see \seep{Read}.
|
|
|
|
\begin{functionl}{Real2Double}{RealToDouble}
|
|
\Declaration
|
|
Function Real2Double(r : real48) : double;
|
|
\Description
|
|
The \var{Real2Double} function converts a \tp style real (6 bytes long) to
|
|
a native \fpc double type. It can be used e.g. to read old binary TP files with
|
|
FPC and convert them to Free Pacal binary files.
|
|
|
|
Note that the assignment operator has been overloaded so a \var{Real48} type
|
|
can be assigned directly to a double or extended.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\end{functionl}
|
|
|
|
\FPCexample{ex110}
|
|
|
|
\begin{procedure}{Release}
|
|
\Declaration
|
|
Procedure Release (Var P : pointer);
|
|
|
|
\Description
|
|
This routine is here for compatibility with Turbo Pascal, but
|
|
it is not implemented and currently does nothing.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Mark}, \seef{Memavail}, \seef{Maxavail}, \seep{Getmem}, \seep{Freemem}
|
|
\seep{New}, \seep{Dispose}
|
|
\end{procedure}
|
|
|
|
\begin{procedure}{Rename}
|
|
\Declaration
|
|
Procedure Rename (Var F : Any Filetype; Const S : String);
|
|
\Description
|
|
\var{Rename} changes the name of the assigned file \var{F} to \var{S}.
|
|
\var{F}
|
|
must be assigned, but not opened.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Erase}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex77}
|
|
|
|
\begin{procedure}{Reset}
|
|
\Declaration
|
|
Procedure Reset (Var F : Any File Type[; L : Longint]);
|
|
\Description
|
|
\var{Reset} opens a file \var{F} for reading. \var{F} can be any file type.
|
|
If \var{F} is a text file, or refers to standard I/O (e.g : '') then it is
|
|
opened read-only, otherwise it is opened using the mode specified in
|
|
\var{filemode}.
|
|
|
|
If \var{F} is an untyped file, the record size can be specified in
|
|
the optional parameter \var{L}. A default value of 128 is used.
|
|
|
|
File sharing is not taken into account when calling \var{Reset}.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Rewrite}, \seep{Assign}, \seep{Close}, \seep{Append}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex51}
|
|
|
|
\begin{procedure}{Rewrite}
|
|
\Declaration
|
|
Procedure Rewrite (Var F : Any File Type[; L : Longint]);
|
|
\Description
|
|
\var{Rewrite} opens a file \var{F} for writing. \var{F} can be any file type.
|
|
If \var{F} is an untyped or typed file, then it is opened for reading and
|
|
writing. If \var{F} is an untyped file, the record size can be specified in
|
|
the optional parameter \var{L}. Default a value of 128 is used.
|
|
if \var{Rewrite} finds a file with the same name as \var{F}, this file is
|
|
truncated to length \var{0}. If it doesn't find such a file, a new file is
|
|
created.
|
|
|
|
Contrary to \tp, \fpc opens the file with mode \var{fmoutput}. If it should
|
|
be opened in \var{fminout} mode, an extra call to \seep{Reset} is needed.
|
|
|
|
File sharing is not taken into account when calling \var{Rewrite}.
|
|
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Reset}, \seep{Assign}, \seep{Close}, \seep{Flush}, \seep{Append}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex52}
|
|
|
|
\begin{procedure}{Rmdir}
|
|
\Declaration
|
|
Procedure Rmdir (const S : string);
|
|
|
|
\Description
|
|
\var{Rmdir} removes the directory \var{S}.
|
|
\Errors
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Chdir}, \seep{Mkdir}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex53}
|
|
|
|
\begin{function}{Round}
|
|
\Declaration
|
|
Function Round (X : Real) : Longint;
|
|
|
|
\Description
|
|
\var{Round} rounds \var{X} to the closest integer, which may be bigger or
|
|
smaller than \var{X}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Frac}, \seef{Int}, \seef{Trunc}
|
|
\end{function}
|
|
|
|
\FPCexample{ex54}
|
|
|
|
\begin{procedure}{Runerror}
|
|
\Declaration
|
|
Procedure Runerror (ErrorCode : Word);
|
|
|
|
\Description
|
|
\var{Runerror} stops the execution of the program, and generates a
|
|
run-time error \var{ErrorCode}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Exit}, \seep{Halt}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex55}
|
|
|
|
\begin{procedure}{Seek}
|
|
\Declaration
|
|
Procedure Seek (Var F; Count : Longint);
|
|
|
|
\Description
|
|
\var{Seek} sets the file-pointer for file \var{F} to record Nr. \var{Count}.
|
|
The first record in a file has \var{Count=0}. F can be any file type, except
|
|
\var{Text}. If \var{F} is an untyped file, with no record size specified in
|
|
\seep{Reset} or \seep{Rewrite}, 128 is assumed.
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seef{Eof}, \seef{SeekEof}, \seef{SeekEoln}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex56}
|
|
|
|
\begin{function}{SeekEof}
|
|
\Declaration
|
|
Function SeekEof [(Var F : text)] : Boolean;
|
|
|
|
\Description
|
|
\var{SeekEof} returns \var{True} is the file-pointer is at the end of the
|
|
file. It ignores all whitespace.
|
|
Calling this function has the effect that the file-position is advanced
|
|
until the first non-whitespace character or the end-of-file marker is
|
|
reached.
|
|
If the end-of-file marker is reached, \var{True} is returned. Otherwise,
|
|
False is returned.
|
|
If the parameter \var{F} is omitted, standard \var{Input} is assumed.
|
|
|
|
\Errors
|
|
A run-time error is generated if the file \var{F} isn't opened.
|
|
\SeeAlso
|
|
\seef{Eof}, \seef{SeekEoln}, \seep{Seek}
|
|
\end{function}
|
|
|
|
\FPCexample{ex57}
|
|
|
|
\begin{function}{SeekEoln}
|
|
\Declaration
|
|
Function SeekEoln [(Var F : text)] : Boolean;
|
|
|
|
\Description
|
|
\var{SeekEoln} returns \var{True} is the file-pointer is at the end of the
|
|
current line. It ignores all whitespace.
|
|
Calling this function has the effect that the file-position is advanced
|
|
until the first non-whitespace character or the end-of-line marker is
|
|
reached.
|
|
If the end-of-line marker is reached, \var{True} is returned. Otherwise,
|
|
False is returned.
|
|
The end-of-line marker is defined as \var{\#10}, the LineFeed character.
|
|
If the parameter \var{F} is omitted, standard \var{Input} is assumed.
|
|
\Errors
|
|
A run-time error is generated if the file \var{F} isn't opened.
|
|
\SeeAlso
|
|
\seef{Eof}, \seef{SeekEof}, \seep{Seek}
|
|
\end{function}
|
|
|
|
\FPCexample{ex58}
|
|
|
|
\begin{function}{Seg}
|
|
\Declaration
|
|
Function Seg (Var X) : Longint;
|
|
|
|
\Description
|
|
\var{Seg} returns the segment of the address of a variable.
|
|
This function is only supported for compatibility. In \fpc, it
|
|
returns always 0, since \fpc is a 32 bit compiler, segments have no meaning.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{DSeg}, \seef{CSeg}, \seef{Ofs}, \seef{Ptr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex60}
|
|
|
|
\begin{procedure}{SetMemoryManager}
|
|
\Declaration
|
|
procedure SetMemoryManager(const MemMgr: TMemoryManager);
|
|
\Description
|
|
\var{SetMemoryManager} sets the current memory manager record to
|
|
\var{MemMgr}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{GetMemoryManager}, \seef{IsMemoryManagerSet}
|
|
\end{procedure}
|
|
|
|
For an example, see \progref.
|
|
|
|
\begin{function}{SetJmp}
|
|
\Declaration
|
|
Function SetJmp (Var Env : Jmp\_Buf) : Longint;
|
|
|
|
\Description
|
|
|
|
\var{SetJmp} fills \var{env} with the necessary data for a jump back to the
|
|
point where it was called. It returns zero if called in this way.
|
|
If the function returns nonzero, then it means that a call to \seep{LongJmp}
|
|
with \var{env} as an argument was made somewhere in the program.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{LongJmp}
|
|
\end{function}
|
|
|
|
\FPCexample{ex79}
|
|
|
|
|
|
\begin{procedure}{SetLength}
|
|
\Declaration
|
|
Procedure SetLength(var S : String; Len : Longint);
|
|
\Description
|
|
\var{SetLength} sets the length of the string \var{S} to \var{Len}. \var{S}
|
|
can be an ansistring, a short string or a widestring.
|
|
For \var{ShortStrings}, \var{Len} can maximally be 255. For \var{AnsiStrings}
|
|
it can have any value. For \var{AnsiString} strings, \var{SetLength} {\em
|
|
must} be used to set the length of the string.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Length}
|
|
\end{procedure}
|
|
|
|
|
|
\FPCexample{ex85}
|
|
|
|
\begin{procedure}{SetString}
|
|
\Declaration
|
|
Procedure SetString(var S : String; Buf : PChar; Len : Longint);
|
|
\Description
|
|
\var{SetString} sets the length of the string \var{S} to \var{Len} and
|
|
if \var{Buf} is non-nil, copies \var{Len} characters from \var{Buf}
|
|
into \var{S}. \var{S} can be an ansistring, a short string or a widestring.
|
|
For \var{ShortStrings}, \var{Len} can maximally be 255.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{SetLength}
|
|
\end{procedure}
|
|
|
|
|
|
|
|
\begin{procedure}{SetTextBuf}
|
|
\Declaration
|
|
Procedure SetTextBuf (Var f : Text; Var Buf[; Size : Word]);
|
|
|
|
\Description
|
|
\var{SetTextBuf} assigns an I/O buffer to a text file. The new buffer is
|
|
located at \var{Buf} and is \var{Size} bytes long. If \var{Size} is omitted,
|
|
then \var{SizeOf(Buf)} is assumed.
|
|
The standard buffer of any text file is 128 bytes long. For heavy I/O
|
|
operations this may prove too slow. The \var{SetTextBuf} procedure allows
|
|
to set a bigger buffer for the IO of the application, thus reducing the number of
|
|
system calls, and thus reducing the load on the system resources.
|
|
The maximum size of the newly assigned buffer is 65355 bytes.
|
|
\begin{remark}
|
|
\begin{itemize}
|
|
\item Never assign a new buffer to an opened file. A
|
|
new buffer can be assigned immediately after a call to \seep{Rewrite}, \seep{Reset} or
|
|
\var{Append}, but not after the file was read from/written to. This may cause
|
|
loss of data. If a new buffer must be assigned after read/write
|
|
operations have been performed, the file should be flushed first.
|
|
This will ensure that the current buffer is emptied.
|
|
\item Take care that the assigned buffer is always valid. If a local variable is
|
|
assigned as a buffer, then after the program exits the local program block,
|
|
the buffer will no longer be valid, and stack problems may occur.
|
|
\end{itemize}
|
|
\end{remark}
|
|
\Errors
|
|
No checking on \var{Size} is done.
|
|
\SeeAlso
|
|
\seep{Assign}, \seep{Reset}, \seep{Rewrite}, \seep{Append}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex61}
|
|
|
|
\begin{function}{Sin}
|
|
\Declaration
|
|
Function Sin (X : Real) : Real;
|
|
|
|
\Description
|
|
\var{Sin} returns the sine of its argument \var{X}, where \var{X} is an
|
|
angle in radians.
|
|
|
|
If the absolute value of the argument is larger than \var{2\^{}63}, then the
|
|
result is undefined.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Cos}, \seef{Pi}, \seef{Exp}, \seef{Ln}
|
|
\end{function}
|
|
|
|
\FPCexample{ex62}
|
|
|
|
\begin{function}{SizeOf}
|
|
\Declaration
|
|
Function SizeOf (X : Any Type) : Longint;
|
|
|
|
\Description
|
|
\var{SizeOf} returns the size, in bytes, of any variable or type-identifier.
|
|
\begin{remark}
|
|
This isn't really a RTL function. Its result is calculated at
|
|
compile-time, and hard-coded in the executable.
|
|
\end{remark}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Addr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex63}
|
|
|
|
\begin{function}{Sptr}
|
|
\Declaration
|
|
Function Sptr : Pointer;
|
|
|
|
\Description
|
|
\var{Sptr} returns the current stack pointer.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{SSeg}
|
|
\end{function}
|
|
|
|
\FPCexample{ex64}
|
|
|
|
\begin{function}{Sqr}
|
|
\Declaration
|
|
Function Sqr (X : Real) : Real;
|
|
|
|
\Description
|
|
\var{Sqr} returns the square of its argument \var{X}.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Sqrt}, \seef{Ln}, \seef{Exp}
|
|
\end{function}
|
|
|
|
\FPCexample{ex65}
|
|
|
|
\begin{function}{Sqrt}
|
|
\Declaration
|
|
Function Sqrt (X : Real) : Real;
|
|
|
|
\Description
|
|
\var{Sqrt} returns the square root of its argument \var{X}, which must be
|
|
positive.
|
|
\Errors
|
|
If \var{X} is negative, then a run-time error is generated.
|
|
\SeeAlso
|
|
\seef{Sqr}, \seef{Ln}, \seef{Exp}
|
|
\end{function}
|
|
|
|
\FPCexample{ex66}
|
|
|
|
\begin{function}{SSeg}
|
|
\Declaration
|
|
Function SSeg : Longint;
|
|
|
|
\Description
|
|
\var{SSeg} returns the Stack Segment. This function is only
|
|
supported for compatibility reasons, as \var{Sptr} returns the
|
|
correct contents of the stackpointer.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Sptr}
|
|
\end{function}
|
|
|
|
\FPCexample{ex67}
|
|
|
|
\begin{procedure}{Str}
|
|
\Declaration
|
|
Procedure Str (Var X[:NumPlaces[:Decimals]]; Var S : String);
|
|
|
|
\Description
|
|
\var{Str} returns a string which represents the value of X. X can be any
|
|
numerical type.
|
|
The optional \var{NumPLaces} and \var{Decimals} specifiers control the
|
|
formatting of the string.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Val}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex68}
|
|
|
|
\begin{function}{StringOfChar}
|
|
\Declaration
|
|
Function StringOfChar(c : char;l : Integer) : String;
|
|
\Description
|
|
\var{StringOfChar} creates a new String of length \var{l} and fills
|
|
it with the character \var{c}.
|
|
|
|
It is equivalent to the following calls:
|
|
\begin{verbatim}
|
|
SetLength(StringOfChar,l);
|
|
FillChar(Pointer(StringOfChar)^,Length(StringOfChar),c);
|
|
\end{verbatim}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{SetLength}
|
|
\end{function}
|
|
|
|
\FPCexample{ex97}
|
|
|
|
\begin{function}{Succ}
|
|
\Declaration
|
|
Function Succ (X : Any ordinal type) : Same type;
|
|
|
|
\Description
|
|
\var{Succ} returns the element that succeeds the element that was passed
|
|
to it. If it is applied to the last value of the ordinal type, and the
|
|
program was compiled with range checking on (\var{\{\$R+\}}), then a run-time
|
|
error will be generated.
|
|
|
|
\Errors
|
|
Run-time error 201 is generated when the result is out of
|
|
range.
|
|
\SeeAlso
|
|
\seef{Ord}, \seef{Pred}, \seef{High}, \seef{Low}
|
|
\end{function}
|
|
for an example, see \seef{Ord}.
|
|
\begin{function}{Swap}
|
|
\Declaration
|
|
Function Swap (X) : Type of X;
|
|
|
|
\Description
|
|
\var{Swap} swaps the high and low order bytes of \var{X} if \var{X} is of
|
|
type \var{Word} or \var{Integer}, or swaps the high and low order words of
|
|
\var{X} if \var{X} is of type \var{Longint} or \var{Cardinal}.
|
|
The return type is the type of \var{X}
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Lo}, \seef{Hi}
|
|
\end{function}
|
|
|
|
\FPCexample{ex69}
|
|
|
|
\begin{function}{Trunc}
|
|
\Declaration
|
|
Function Trunc (X : Real) : Longint;
|
|
|
|
\Description
|
|
\var{Trunc} returns the integer part of \var{X},
|
|
which is always smaller than (or equal to) \var{X} in absolute value.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Frac}, \seef{Int}, \seef{Round}
|
|
\end{function}
|
|
|
|
\FPCexample{ex70}
|
|
|
|
\begin{procedure}{Truncate}
|
|
\Declaration
|
|
Procedure Truncate (Var F : file);
|
|
|
|
\Description
|
|
\var{Truncate} truncates the (opened) file \var{F} at the current file
|
|
position.
|
|
|
|
\Errors
|
|
Depending on the state of the \var{\{\$I\}} switch, a runtime error can be
|
|
generated if there is an error. In the \var{\{\$I-\}} state, use \var{IOResult}
|
|
to check for errors.
|
|
\SeeAlso
|
|
\seep{Append}, \seef{Filepos},
|
|
\seep{Seek}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex71}
|
|
|
|
\begin{function}{Upcase}
|
|
\Declaration
|
|
Function Upcase (C : Char or string) : Char or String;
|
|
|
|
\Description
|
|
\var{Upcase} returns the uppercase version of its argument \var{C}.
|
|
If its argument is a string, then the complete string is converted to
|
|
uppercase. The type of the returned value is the same as the type of the
|
|
argument.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{Lowercase}
|
|
\end{function}
|
|
|
|
\FPCexample{ex72}
|
|
|
|
\begin{procedure}{Val}
|
|
\Declaration
|
|
Procedure Val (const S : string;var V;var Code : word);
|
|
|
|
\Description
|
|
\var{Val} converts the value represented in the string \var{S} to a numerical
|
|
value, and stores this value in the variable \var{V}, which
|
|
can be of type \var{Longint}, \var{Real} and \var{Byte}.
|
|
If the conversion isn't succesfull, then the parameter \var{Code} contains
|
|
the index of the character in \var{S} which prevented the conversion.
|
|
The string \var{S} is allowed to contain spaces in the beginning.
|
|
|
|
The string \var{S} can contain a number in decimal, hexadecimal, binary
|
|
or octal format, as described in the language reference.
|
|
|
|
\Errors
|
|
If the conversion doesn't succeed, the value of \var{Code} indicates the
|
|
position where the conversion went wrong.
|
|
\SeeAlso
|
|
\seep{Str}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex74}
|
|
|
|
\begin{procedure}{Write}
|
|
\Declaration
|
|
Procedure Write ([Var F : Any filetype;] V1 [; V2; ... , Vn)];
|
|
|
|
\Description
|
|
\var{Write} writes the contents of the variables \var{V1}, \var{V2} etc. to
|
|
the file \var{F}. \var{F} can be a typed file, or a \var{Text} file.
|
|
If \var{F} is a typed file, then the variables \var{V1}, \var{V2} etc. must
|
|
be of the same type as the type in the declaration of \var{F}. Untyped files
|
|
are not allowed.
|
|
If the parameter \var{F} is omitted, standard output is assumed.
|
|
If \var{F} is of type \var{Text}, then the necessary conversions are done
|
|
such that the output of the variables is in human-readable format.
|
|
This conversion is done for all numerical types. Strings are printed exactly
|
|
as they are in memory, as well as \var{PChar} types.
|
|
The format of the numerical conversions can be influenced through
|
|
the following modifiers:
|
|
\var{ OutputVariable : NumChars [: Decimals ] }
|
|
This will print the value of \var{OutputVariable} with a minimum of
|
|
\var{NumChars} characters, from which \var{Decimals} are reserved for the
|
|
decimals. If the number cannot be represented with \var{NumChars} characters,
|
|
\var{NumChars} will be increased, until the representation fits. If the
|
|
representation requires less than \var{NumChars} characters then the output
|
|
is filled up with spaces, to the left of the generated string, thus
|
|
resulting in a right-aligned representation.
|
|
If no formatting is specified, then the number is written using its natural
|
|
length, with nothing in front of it if it's positive, and a minus sign if
|
|
it's negative.
|
|
Real numbers are, by default, written in scientific notation.
|
|
|
|
\Errors
|
|
If an error occurs, a run-time error is generated. This behavior can be
|
|
controlled with the \var{\{\$i\}} switch.
|
|
\SeeAlso
|
|
\seep{WriteLn}, \seep{Read}, \seep{Readln}, \seep{Blockwrite}
|
|
\end{procedure}
|
|
\begin{procedure}{WriteLn}
|
|
\Declaration
|
|
Procedure WriteLn [([Var F : Text;] [V1 [; V2; ... , Vn)]];
|
|
|
|
\Description
|
|
\var{WriteLn} does the same as \seep{Write} for text files, and emits a
|
|
Carriage Return - LineFeed character pair after that.
|
|
If the parameter \var{F} is omitted, standard output is assumed.
|
|
If no variables are specified, a Carriage Return - LineFeed character pair
|
|
is emitted, resulting in a new line in the file \var{F}.
|
|
\begin{remark}
|
|
Under \linux and \unix, the Carriage Return character is omitted, as
|
|
customary in Unix environments.
|
|
\end{remark}
|
|
|
|
\Errors
|
|
If an error occurs, a run-time error is generated. This behavior can be
|
|
controlled with the \var{\{\$i\}} switch.
|
|
\SeeAlso
|
|
\seep{Write}, \seep{Read}, \seep{Readln}, \seep{Blockwrite}
|
|
\end{procedure}
|
|
\FPCexample{ex75}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% The objpas unit
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{The OBJPAS unit}
|
|
The \file{objpas} unit is meant for compatibility with Object Pascal as
|
|
implemented by Delphi. The unit is loaded automatically by the \fpc compiler
|
|
whenever the \var{Delphi} or \var{objfpc} more is entered, either through
|
|
the command line switches \var{-Sd} or \var{-Sh} or with the \var{\{\$MODE
|
|
DELPHI\}} or \var{\{\$MODE OBJFPC\}} directives.
|
|
|
|
It redefines some basic pascal types, introduces some functions for
|
|
compatibility with Delphi's system unit, and introduces some methods for the
|
|
management of the resource string tables.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Tytpes
|
|
\section{Types}
|
|
The \file{objpas} unit redefines two integer types, for compatibity with
|
|
Delphi:
|
|
\begin{verbatim}
|
|
type
|
|
smallint = system.integer;
|
|
integer = system.longint;
|
|
\end{verbatim}
|
|
The resource string tables can be managed with a callback function which the
|
|
user must provide: \var{TResourceIterator}.
|
|
\begin{verbatim}
|
|
Type
|
|
TResourceIterator =
|
|
Function (Name,Value : AnsiString;Hash : Longint):AnsiString;
|
|
\end{verbatim}
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Functions and procedures
|
|
\section{Functions and Procedures}
|
|
|
|
\begin{procedure}{AssignFile}
|
|
\Declaration
|
|
Procedure AssignFile(Var f: FileType;Name: Character type);
|
|
\Description
|
|
\var{AssignFile} is completely equivalent to the system unit's \seep{Assign}
|
|
function: It assigns \var{Name} to a function of any type (\var{FileType}
|
|
can be \var{Text} or a typed or untyped \var{File} variable). \var{Name} can
|
|
be a string, a single character or a \var{PChar}.
|
|
|
|
It is most likely introduced to avoid confusion between the regular
|
|
\seep{Assign} function and the \var{Assign} method of \var{TPersistent}
|
|
in the Delphi VCL.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{CloseFile}, \seep{Assign}, \seep{Reset}, \seep{Rewrite}, \seep{Append}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex88}
|
|
|
|
\begin{procedure}{CloseFile}
|
|
\Declaration
|
|
Procedure CloseFile(Var F: FileType);
|
|
\Description
|
|
\var{CloseFile} flushes and closes a file \var{F} of any file type.
|
|
\var{F} can be \var{Text} or a typed or untyped \var{File} variable.
|
|
After a call to \var{CloseFile}, any attempt to write to the file \var{F}
|
|
will result in an error.
|
|
|
|
It is most likely introduced to avoid confusion between the regular
|
|
\seep{Close} function and the \var{Close} method of \var{TForm}
|
|
in the Delphi VCL.
|
|
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Close}, \seep{AssignFile}, \seep{Reset}, \seep{Rewrite}, \seep{Append}
|
|
\end{procedure}
|
|
|
|
for an example, see \seep{AssignFile}.
|
|
|
|
\begin{procedurel}{Freemem}{objpasfreemem}
|
|
\Declaration
|
|
Procedure FreeMem(Var p:pointer[;Size:Longint]);
|
|
\Description
|
|
\var{FreeMem} releases the memory reserved by a call to
|
|
\seepl{GetMem}{objpasgetmem}. The (optional) \var{Size} parameter is
|
|
ignored, since the object pascal version of \var{GetMem} stores the amount
|
|
of memory that was requested.
|
|
|
|
Be sure not to release memory that was not obtained with the \var{Getmem}
|
|
call in \file{Objpas}. Normally, this should not happen, since objpas
|
|
changes the default memory manager to it's own memory manager.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{Freemem}, \seepl{GetMem}{objpasgetmem}, \seep{Getmem}
|
|
\end{procedurel}
|
|
|
|
\FPCexample{ex89}
|
|
|
|
\begin{procedurel}{Getmem}{objpasgetmem}
|
|
\Declaration
|
|
Procedure Getmem(Var P:pointer;Size:Longint);
|
|
\Description
|
|
\var{GetMem} reserves \var{Size} bytes of memory on the heap and returns
|
|
a pointer to it in \var{P}. \var{Size} is stored at offset -4 of the
|
|
result, and is used to release the memory again. \var{P} can be a typed or
|
|
untyped pointer.
|
|
|
|
Be sure to release this memory with the \seepl{FreeMem}{objpasfreemem} call
|
|
defined in the \file{objpas} unit.
|
|
\Errors
|
|
In case no more memory is available, and no more memory could be obtained
|
|
from the system a run-time error is triggered.
|
|
\SeeAlso
|
|
\seepl{FreeMem}{objpasfreemem}, \seep{Getmem}.
|
|
\end{procedurel}
|
|
|
|
For an example, see \seepl{FreeMem}{objpasfreemem}.
|
|
|
|
\begin{function}{GetResourceStringCurrentValue}
|
|
\Declaration
|
|
Function GetResourceStringCurrentValue(TableIndex,StringIndex : Longint) : AnsiString;
|
|
\Description
|
|
\var{GetResourceStringCurrentValue} returns the current value of the
|
|
resourcestring in table \var{TableIndex} with index \var{StringIndex}.
|
|
|
|
The current value depends on the system of internationalization that was
|
|
used, and which language is selected when the program is executed.
|
|
\Errors
|
|
If either \var{TableIndex} or \var{StringIndex} are out of range, then
|
|
a empty string is returned.
|
|
\SeeAlso
|
|
\seep{SetResourceStrings},
|
|
\seef{GetResourceStringDefaultValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringTableCount},
|
|
\seef{ResourceStringCount}
|
|
\end{function}
|
|
|
|
\FPCexample{ex90}
|
|
|
|
\begin{function}{GetResourceStringDefaultValue}
|
|
\Declaration
|
|
Function GetResourceStringDefaultValue(TableIndex,StringIndex : Longint) : AnsiString
|
|
\Description
|
|
\var{GetResourceStringDefaultValue} returns the default value of the
|
|
resourcestring in table \var{TableIndex} with index \var{StringIndex}.
|
|
|
|
The default value is the value of the string that appears in the source code
|
|
of the programmer, and is compiled into the program.
|
|
\Errors
|
|
If either \var{TableIndex} or \var{StringIndex} are out of range, then
|
|
a empty string is returned.
|
|
\Errors
|
|
\SeeAlso
|
|
\seep{SetResourceStrings},
|
|
\seef{GetResourceStringCurrentValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringTableCount},
|
|
\seef{ResourceStringCount}
|
|
\end{function}
|
|
|
|
\FPCexample{ex91}
|
|
|
|
\begin{function}{GetResourceStringHash}
|
|
\Declaration
|
|
Function GetResourceStringHash(TableIndex,StringIndex : Longint) : Longint;
|
|
\Description
|
|
\var{GetResourceStringHash} returns the hash value associated with the
|
|
resource string in table \var{TableIndex}, with index \var{StringIndex}.
|
|
|
|
The hash value is calculated from the default value of the resource string
|
|
in a manner that gives the same result as the GNU \file{gettext} mechanism.
|
|
It is stored in the resourcestring tables, so retrieval is faster than
|
|
actually calculating the hash for each string.
|
|
\Errors
|
|
If either \var{TableIndex} or \var{StringIndex} is zero, 0 is returned.
|
|
\SeeAlso
|
|
\seef{Hash}
|
|
\seep{SetResourceStrings},
|
|
\seef{GetResourceStringDefaultValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringTableCount},
|
|
\seef{ResourceStringCount}
|
|
\end{function}
|
|
|
|
For an example, see \seef{Hash}.
|
|
|
|
\begin{function}{GetResourceStringName}
|
|
\Declaration
|
|
Function GetResourceStringName(TableIndex,StringIndex : Longint) : Ansistring;
|
|
\Description
|
|
\var{GetResourceStringName} returns the name of the resourcestring in table
|
|
\var{TableIndex} with index \var{StringIndex}. The name of the string is
|
|
always the unit name in which the string was declared, followed by a period
|
|
and the name of the constant, all in lowercase.
|
|
|
|
If a unit \file{MyUnit} declares a resourcestring \var{MyTitle} then the
|
|
name returned will be \var{myunit.mytitle}. A resourcestring in the program file
|
|
will have the name of the program prepended.
|
|
|
|
The name returned by this function is also the name that is stored in the
|
|
resourcestring file generated by the compiler.
|
|
|
|
Strictly speaking, this information isn't necessary for the functioning
|
|
of the program, it is provided only as a means to easier translation of
|
|
strings.
|
|
\Errors
|
|
If either \var{TableIndex} or \var{StringIndex} is zero, an empty string
|
|
is returned.
|
|
\SeeAlso
|
|
\seep{SetResourceStrings},
|
|
\seef{GetResourceStringDefaultValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringTableCount},
|
|
\seef{ResourceStringCount}
|
|
\end{function}
|
|
|
|
\FPCexample{ex92}
|
|
|
|
|
|
\begin{function}{Hash}
|
|
\Declaration
|
|
Function Hash(S : AnsiString) : longint;
|
|
\Description
|
|
\var{Hash} calculates the hash value of the string \var{S} in a manner that
|
|
is compatible with the GNU gettext hash value for the string. It is the same
|
|
value that is stored in the Resource string tables, and which can be
|
|
retrieved with the \seef{GetResourceStringHash} function call.
|
|
\Errors
|
|
None. In case the calculated hash value should be 0, the returned result
|
|
will be -1.
|
|
\SeeAlso
|
|
\seef{GetResourceStringHash},
|
|
\end{function}
|
|
|
|
\FPCexample{ex93}
|
|
|
|
\begin{functionl}{Paramstr}{objpasparamstr}
|
|
\Declaration
|
|
Function ParamStr(Param : Integer) : Ansistring;
|
|
\Description
|
|
\var{ParamStr} returns the \var{Param}-th command-line parameter as an
|
|
AnsiString. The system unit \seef{Paramstr} function limits the result to
|
|
255 characters.
|
|
|
|
The zeroeth command-line parameter contains the path of the executable,
|
|
except on \linux, where it is the command as typed on the command-line.
|
|
\Errors
|
|
In case \var{Param} is an invalid value, an empty string is returned.
|
|
\SeeAlso
|
|
\seef{Paramstr}
|
|
\end{functionl}
|
|
|
|
For an example, see \seef{Paramstr}.
|
|
|
|
\begin{function}{ReAllocMem}
|
|
\Declaration
|
|
function ReAllocMem(var p:pointer;Size:Longint):pointer;
|
|
\Description
|
|
\var{ReAllocMem} resizes the memory pointed to by \var{P} so it has size
|
|
\var{Size}. The value of \var{P} may change during this operation.
|
|
The contents of the memory pointed to by \var{P} (if any) will be copied to
|
|
the new location, but may be truncated if the newly allocated memory block
|
|
is smaller in size. If a larger block is allocated, only the used memory is
|
|
initialized, extra memory will not be zeroed out.
|
|
|
|
Note that \var{P} may be nil, in that case the behaviour of \var{ReAllocMem}
|
|
is equivalent to \seep{Getmem}.
|
|
\Errors
|
|
If no memory is available then a run-time error will occur.
|
|
\SeeAlso
|
|
\seep{Getmem}, \seep{Freemem}
|
|
\end{function}
|
|
|
|
\begin{procedure}{ResetResourceTables}
|
|
\Declaration
|
|
Procedure ResetResourceTables;
|
|
\Description
|
|
\var{ResetResourceTables} resets all resource strings to their default
|
|
(i.e. as in the source code) values.
|
|
|
|
Normally, this should never be called from a user's program. It is called
|
|
in the initialization code of the \file{objpas} unit. However, if the
|
|
resourcetables get messed up for some reason, this procedure will fix them
|
|
again.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seep{SetResourceStrings},
|
|
\seef{GetResourceStringDefaultValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringTableCount},
|
|
\seef{ResourceStringCount}
|
|
\end{procedure}
|
|
|
|
\begin{function}{ResourceStringCount}
|
|
\Declaration
|
|
Function ResourceStringCount(TableIndex : longint) : longint;
|
|
\Description
|
|
\var{ResourceStringCount} returns the number of resourcestrings in
|
|
the table with index \var{TableIndex}. The strings in a particular table
|
|
are numbered from \var{0} to \var{ResourceStringCount-1}, i.e. they're zero
|
|
based.
|
|
\Errors
|
|
If an invalid \var{TableIndex} is given, \var{-1} is returned.
|
|
\SeeAlso
|
|
\seep{SetResourceStrings},
|
|
\seef{GetResourceStringCurrentValue},
|
|
\seef{GetResourceStringDefaultValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringTableCount},
|
|
\end{function}
|
|
|
|
For an example, see \seef{GetResourceStringDefaultValue}
|
|
|
|
\begin{function}{ResourceStringTableCount}
|
|
\Declaration
|
|
Function ResourceStringTableCount : Longint;
|
|
\Description
|
|
\var{ResourceStringTableCount} returns the number of resource string tables;
|
|
this may be zero if no resource strings are used in a program.
|
|
|
|
The tables are numbered from 0 to \var{ResourceStringTableCount-1}, i.e.
|
|
they're zero based.
|
|
\Errors
|
|
\SeeAlso
|
|
\seep{SetResourceStrings},
|
|
\seef{GetResourceStringDefaultValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringCount}
|
|
\end{function}
|
|
|
|
For an example, see \seef{GetResourceStringDefaultValue}
|
|
|
|
\begin{procedure}{SetResourceStrings}
|
|
\Declaration
|
|
TResourceIterator = Function (Name,Value : AnsiString;Hash : Longint):AnsiString;
|
|
|
|
Procedure SetResourceStrings (SetFunction : TResourceIterator);
|
|
\Description
|
|
\var{SetResourceStrings} calls \var{SetFunction} for all resourcestrings
|
|
in the resourcestring tables and sets the resourcestring's current value
|
|
to the value returned by \var{SetFunction}.
|
|
|
|
The \var{Name},\var{Value} and \var{Hash} parameters passed to the iterator
|
|
function are the values stored in the tables.
|
|
\Errors
|
|
None.
|
|
\SeeAlso
|
|
\seef{GetResourceStringCurrentValue},
|
|
\seef{GetResourceStringDefaultValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringTableCount},
|
|
\seef{ResourceStringCount}
|
|
\end{procedure}
|
|
|
|
\FPCexample{ex95}
|
|
|
|
\begin{function}{SetResourceStringValue}
|
|
\Declaration
|
|
Function SetResourceStringValue(TableIndex,StringIndex : longint; Value : Ansistring) : Boolean;
|
|
\Description
|
|
\var{SetResourceStringValue} assigns \var{Value} to the resource string in
|
|
table \var{TableIndex} with index \var{StringIndex}.
|
|
\Errors
|
|
\SeeAlso
|
|
\seep{SetResourceStrings},
|
|
\seef{GetResourceStringCurrentValue},
|
|
\seef{GetResourceStringDefaultValue},
|
|
\seef{GetResourceStringHash},
|
|
\seef{GetResourceStringName},
|
|
\seef{ResourceStringTableCount},
|
|
\seef{ResourceStringCount}
|
|
\end{function}
|
|
|
|
\FPCexample{ex94}
|
|
|
|
|
|
%
|
|
% The index.
|
|
%
|
|
\printindex
|
|
\end{document} |