mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 14:31:38 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			7306 lines
		
	
	
		
			244 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			7306 lines
		
	
	
		
			244 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.
 | |
| % Uncomment the one you need here. The book version is for the published
 | |
| % book version.
 | |
| %\documentclass{report}
 | |
| \documentclass{book}
 | |
| %
 | |
| % Preamble
 | |
| %
 | |
| \ifx\pdfoutput\undefined
 | |
|   \usepackage{html}
 | |
|   \usepackage{htmllist}
 | |
|   \latex{\usepackage{fpc}}
 | |
|   \html{\input{fpc-html.tex}}
 | |
| \else
 | |
| % Uncomment the fpc or fpcbook version, depending on the output format
 | |
| % you want.
 | |
|   \usepackage{fpc}
 | |
| %  \usepackage{fpcbook}
 | |
| \fi
 | |
| \latex{%
 | |
|   \ifpdf
 | |
|   \pdfinfo{/Author(Michael Van Canneyt)
 | |
|            /Title(Standard units Reference Guide)
 | |
|            /Subject(Free Pascal Reference guide)
 | |
|            /Keywords(Free Pascal, Language, System Unit)
 | |
|            }
 | |
| \fi}
 | |
| %
 | |
| % Settings
 | |
| %
 | |
| \makeindex
 | |
| %
 | |
| % Syntax style
 | |
| %
 | |
| \usepackage{syntax}
 | |
| \input{syntax/diagram.tex}
 | |
| %
 | |
| % Start of document.
 | |
| %
 | |
| \begin{document}
 | |
| \title{Free Pascal :\\ Reference guide.}
 | |
| \docdescription{Reference guide for Free Pascal, version \fpcversion}
 | |
| \docversion{1.8}
 | |
| \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, on
 | |
| which you can click to jump to the declaration.
 | |
| \item References to Unix manual pages. (For linux 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 that
 | |
| you must get from the left side to the right side, following the arrows.
 | |
| When you are at the right of a syntax diagram, 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 you must type exactly as in the diagram:
 | |
| \begin{mysyntdiag}
 | |
| \lit*{keywords\ are\ like\ this}
 | |
| \end{mysyntdiag}
 | |
| When you can repeat something there is an arrow around it:
 | |
| \begin{mysyntdiag}
 | |
| \<[b] \synt{this\ can\ be\ repeated} \\ \>
 | |
| \end{mysyntdiag}
 | |
| When there are different possibilities, they are listed in columns:
 | |
| \begin{mysyntdiag}
 | |
| \(
 | |
| \synt{First\ possibility} \\
 | |
| \synt{Second\ possibility}
 | |
| \)
 | |
| \end{mysyntdiag}
 | |
| Note, that one of the possibilities can be empty:
 | |
| \begin{mysyntdiag}
 | |
| \[
 | |
| \synt{First\ possibility} \\
 | |
| \synt{Second\ possibility}
 | |
| \]
 | |
| \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
 | |
| 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. Contrary to Delphi, \fpc doesn't
 | |
| allow you to redefine these modifiers.
 | |
| \begin{multicols}{4}
 | |
| \begin{verbatim}
 | |
| absolute
 | |
| abstract
 | |
| alias
 | |
| assembler
 | |
| cdecl
 | |
| default
 | |
| export
 | |
| external
 | |
| far
 | |
| forward
 | |
| index
 | |
| name
 | |
| near
 | |
| override
 | |
| pascal
 | |
| popstack
 | |
| private
 | |
| protected
 | |
| public
 | |
| published
 | |
| read
 | |
| register
 | |
| saveregisters
 | |
| 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 you can redefine
 | |
| these types. You are, 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 you define 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 denoted in decimal notation. Real (or decimal) numbers are
 | |
| written using engeneering notation (e.g. \var{0.314E1}).
 | |
| \fpc supports hexadecimal format 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.
 | |
| In addition to the support for hexadecimal notation, \fpc also supports
 | |
| binary notation. You can specify a binary number by preceding it with a
 | |
| percent sign (\var{\%}). Thus, \var{255} can be specified in binary notation
 | |
| as \var{\%11111111}.
 | |
| The following diagrams show the syntax for numbers.
 | |
| \input{syntax/numbers.syn}
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % Labels
 | |
| \section{Labels}
 | |
| Labels can be digit sequences or identifiers.
 | |
| \input{syntax/label.syn}
 | |
| \begin{remark}
 | |
| Note that you must specify the \var{-Sg} switch before you can use labels.
 | |
| 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} can be used, however. For more information on expressions, see
 | |
| \seec{Expressions}.
 | |
| You can only declare constants of the following types: \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}
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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 also allow you 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, you should specify each element of the record, 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 you'll get a compile-time error.
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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; you cannot assign values to
 | |
| them, except through the special mechanisms in the objpas unit. However,
 | |
| you can use them 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.
 | |
| You can declare your own types, which is in essence defining an identifier
 | |
| that can be used to denote your 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 gives you a way to make types platform independent, by
 | |
| only using your own types, and then defining these types for each platform
 | |
| individually. The programmer that uses your units doesn't have to worry
 | |
| about type size and so on. It also allows you to use shortcut names for
 | |
| fully qualified type names. You can 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 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 ordinal types is presented in \seet{ordinals}
 | |
| \begin{FPCltable}{l}{Predefined ordinal types}{ordinals}
 | |
| Name\\ \hline
 | |
| Integer \\
 | |
| Shortint \\
 | |
| SmallInt \\
 | |
| Longint \\
 | |
| Int64 \\
 | |
| Byte \\
 | |
| Word \\
 | |
| Cardinal \\
 | |
| QWord \\
 | |
| Boolean \\
 | |
| ByteBool \\
 | |
| LongBool \\
 | |
| Char \\ \hline
 | |
| \end{FPCltable}
 | |
| The integer types, and their ranges and sizes, that are predefined in
 | |
| \fpc are listed in \seet{integers}.
 | |
| \begin{FPCltable}{lcr}{Predefined integer types}{integers}
 | |
| Type & Range & Size in bytes \\ \hline
 | |
| Byte & 0 .. 255 & 1 \\
 | |
| Shortint & -128 .. 127 & 1\\
 | |
| Integer & -32768 .. 32767 & 2\footnote{The integer type is redefined as
 | |
| longint if you are in Delphi or ObjFPC mode, and then has size 4} \\
 | |
| Word & 0 .. 65535 & 2 \\
 | |
| Longint & -2147483648 .. 2147483647 & 4\\
 | |
| Cardinal & 0..4294967295 & 4 \\
 | |
| Int64 & -9223372036854775808 .. 9223372036854775807 & 8 \\
 | |
| QWord & 0 .. 18446744073709551615 & 8 \\ \hline
 | |
| \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}
 | |
| 
 | |
| \begin{remark} The \var{WordBool}, \var{LongBool} and \var{ByteBool} types
 | |
| were not supported by \fpc until version 0.99.6.
 | |
| \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 you should keep the enumerated elements 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 You cannot use the \var{Pred} and \var{Succ} functions on
 | |
| this kind of enumeration types. If you try to do that, you'll get a compiler
 | |
| error.
 | |
| \item Enumeration types are by default stored in 4 bytes. You can change
 | |
| this behaviour 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
 | |
|   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}
 | |
| But you can also define subrange types of enumeration types:
 | |
| \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 an 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\footnote{In Turbo Pascal.} \\ \hline
 | |
| Single & 1.5E-45 .. 3.4E38 & 7-8 & 4 \\
 | |
| Real & 5.0E-324 .. 1.7E308 & 15-16 & 8 \\
 | |
| 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}
 | |
| Until version 0.9.1 of the compiler, all the \var{Real} types were mapped to
 | |
| type \var{Double}, meaning that they all have size 8. The \seef{SizeOf} function
 | |
| is your friend here. The \var{Real} type of turbo pascal is automatically
 | |
| mapped to Double. The \var{Comp} type is, in effect, a 64-bit integer.
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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.
 | |
| You can specify a character constant by enclosing the character in single
 | |
| quotes, as follows : 'a' or 'A' are both character constants.
 | |
| You can also specify a character by their 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.)
 | |
| If you want to represent the single quote character, type it 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 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
 | |
| coversions. 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}
 | |
| 
 | |
| For short strings \fpc reserves \var{Size+1} bytes for the string \var{S},
 | |
| and in the zeroeth element of the string (\var{S[0]}) it will store the
 | |
| length of the variable.
 | |
| If you don't specify the size of the string, \var{255} is taken as a
 | |
| default.
 | |
| For example in
 | |
| \begin{verbatim}
 | |
| {$H-}
 | |
| 
 | |
| Type
 | |
|    NameString = String[10];
 | |
|    StreetString = String;
 | |
| \end{verbatim}
 | |
| \var{NameString} can contain maximum 10 characters. While
 | |
| \var{StreetString} can contain 255 characters. The sizes of these variables
 | |
| are, respectively, 11 and 256 bytes.
 | |
| 
 | |
| \subsection{Ansistrings}
 | |
| 
 | |
| If the \var{\{\$H\}} switch is on, then a string definition that doesn't
 | |
| contain a length specifier, will be regarded as an ansistring.
 | |
| 
 | |
| Ansistrings are strings that have no length limit. They are reference
 | |
| counted. Internally, an ansistring is treated as a pointer.
 | |
| 
 | |
| If the string is empty (\var{''}), then the pointer is nil.
 | |
| If the string is not empty, then the pointer points to a structure in
 | |
| heap memory that looks as in \seet{ansistrings}.
 | |
| 
 | |
| \begin{FPCltable}{rl}{AnsiString memory structure}{ansistrings}
 | |
| Offset & Contains \\ \hline
 | |
| -12  & Longint with maximum string size. \\
 | |
| -8   & Longint with actual string size.\\
 | |
| -4   & Longint with reference count.\\
 | |
| 0    & Actual string, null-terminated. \\ \hline
 | |
| \end{FPCltable}
 | |
| 
 | |
| Because of this structure, it is 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.
 | |
| 
 | |
| AnsiStrings can be unlimited in length. Since the length is stored,
 | |
| the length of an ansistring is available immediatly, providing for fast
 | |
| access.
 | |
| 
 | |
| 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
 | |
| your code.
 | |
| 
 | |
| If a 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, global or 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 100,000 strings will be dereferenced one by one. 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 it is automatically dereferenced.
 | |
| 
 | |
| If you assign a value 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.
 | |
| 
 | |
| It is impossible to access the length of an ansistring by referring to
 | |
| the zeroeth character. The following statement will generate a compiler
 | |
| error if S is an ansistring:
 | |
| \begin{verbatim}
 | |
|   Len:=S[0];
 | |
| \end{verbatim}
 | |
| Instead, you must use the \seef{Length} function to get the length of a
 | |
| string.
 | |
| 
 | |
| To set the length of an ansistring, you can use the \seep{SetLength}
 | |
| function.
 | |
| 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 you can mix the use of ansistrings and short strings
 | |
| without problems.
 | |
| 
 | |
| You can typecast ansistrings 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. If you typecast an empty
 | |
| ansistring to a pointer, the pointer wil be \var{Nil}. If you typecast an
 | |
| empty ansistring 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 if you want to ensure a string has reference count 1)
 | |
| \end{enumerate}
 | |
| \subsection{Constant strings}
 | |
| 
 | |
| To specify a constant string, you enclose the string in single-quotes, just
 | |
| as a \var{Char} type, only now you can have more than one character.
 | |
| 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 you can see, 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 you can add two strings. 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.
 | |
| 
 | |
| 
 | |
| \subsection{PChar}
 | |
| \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 you can do it in C.
 | |
| 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.
 | |
| You cannot add null-terminated strings as you can do with normal Pascal
 | |
| strings. If you want to concatenate two \var{PChar} strings, you will need
 | |
| to use the unit \seestrings.
 | |
| However, it is possible to do some pointer arithmetic. You can use the
 | |
| operators \var{+} and \var{-} 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:
 | |
| \input{syntax/typearr.syn}
 | |
| The following is a valid array declaration:
 | |
| \begin{verbatim}
 | |
| Type
 | |
|   RealArray = Array [1..100] of Real;
 | |
| \end{verbatim}
 | |
| 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.
 | |
| \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 you want to read a typed file with records, produced by
 | |
| a Turbo Pascal program, then chances are that you will not succeed in
 | |
| reading that file correctly.
 | |
| 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
 | |
| you're working on (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.
 | |
| As from version 0.9.3, \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}
 | |
| You can compare two sets with the \var{<>} and \var{=} operators, but not
 | |
| (yet) with the \var{<} and \var{>} operators.
 | |
| As of compiler version 0.9.5, 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 stops you,
 | |
| 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 you can treat a pointer to some type 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 you use the former, you must allocate memory
 | |
| yourself, 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 descrease 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.
 | |
| You can also use normal arithmetic operators on pointers, 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 is {\em not} multiplied by the
 | |
| size of the type the pointer points to.
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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;
 | |
| ...
 | |
| P := @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 you use the \var{-So} switch, in which case you can drop the address
 | |
| operator.)
 | |
| \begin{remark} The modifiers concerning the calling conventions (\var{cdecl},
 | |
| \var{pascal}, \var{stdcall} and \var{popstack} stick to 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
 | |
| P := @printit;
 | |
| end.
 | |
| \end{verbatim}
 | |
| Because the \var{TOneArgCcall} type is a procedure that uses the cdecl
 | |
| calling convention.
 | |
| \end{remark}
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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 you would declare a record; except that you
 | |
| can now declare procedures and functions as if they were part of the record.
 | |
| Objects can ''inherit'' fields and methods from ''parent'' objects. This means
 | |
| that you can use these fields and methods as if they were included in the
 | |
| objects you declared as a ''child'' object.
 | |
| 
 | |
| Furthermore, you can declare fields, procedures and functions 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 you can see, you can repeat as many \var{private} and \var{public}
 | |
| blocks as you want.
 | |
| \var{Method definitions} are normal function or procedure declarations.
 | |
| You cannot put fields 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
 | |
| you would access a record field : 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}
 | |
| You cannot access fields that are in a private section of an object from
 | |
| outside the objects' methods. If you do, 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. You are 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 you use virtual methods.
 | |
| In the declaration of the object type, you should use a simple identifier
 | |
| for the name of the constuctor or destructor. When you implement the
 | |
| constructor or destructor, you should use a qulified method identifier,
 | |
| 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 you want to allocate a dynamic variable of an object
 | |
| type, you can specify the constructor's name 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 you should use the
 | |
| extended syntax of \var{new} and \var{dispose} to generate instances of an
 | |
| object. You can 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 you want the method that is actually called to
 | |
| 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}. You cannot use the inherited keyword on
 | |
| 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).
 | |
| You cannot create an instance of an object that has an abstract method.
 | |
| 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 you 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 you override an abstract method, you cannot call the parent
 | |
| method 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, only 2 visibility specifiers exist : \var{private} and
 | |
| \var{public}. If you don't specify a visibility specifier, \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 [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 your 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 if you specify the \var{-S2} or \var{-Sd} options.
 | |
| \end{remark}
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % Class definitions
 | |
| \section{Class definitions}
 | |
| The prototype declaration of a class is as follows :
 | |
| \input{syntax/typeclas.syn}
 | |
| Again, You can repeat as many \var{private}, \var{protected}, \var{published}
 | |
| and \var{public} blocks as you want.
 | |
| Methods are normal function or procedure declarations.
 | |
| As you can see, 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}
 | |
| 
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % Class instantiation
 | |
| \section{Class instantiation}
 | |
| Classes must be created using their constructor. Remember that a class is a
 | |
| pointer to an object, so when you declare a variable of some class, 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, you would do the following :
 | |
| \begin{verbatim}
 | |
|   ClassVar := ClassType.ConstructorName;
 | |
| \end{verbatim}
 | |
| You cannot use the extended syntax of \var{new} and \var{dispose} 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, you can declare a packed class.
 | |
| 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 invocaticn 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: you {\em must}
 | |
| override virtual methods 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 you should not do this. Instead use the \var{TObject.Dispatch} method.
 | |
| 
 | |
| 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 you might
 | |
| need. \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 messae 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 you might
 | |
| need. \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 you define the method for.
 | |
| \end{remark}
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % Properties
 | |
| \section{Properties}
 | |
| Classes can contain properties as part of their fields list. A property
 | |
| acts like a normal field, i.e. you can get or set it's value, but
 | |
| 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] 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.
 | |
| You can also have array properties. 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, you 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}
 | |
| You can have only one default property per class, and descendent classes
 | |
| cannot redeclare the default property.
 | |
| 
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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 Operators with equal precedence are executed from left to right.
 | |
| \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 epression, their contents is evaluated
 | |
| first. Thus, \var {5*(3+7)} would result in 50.
 | |
| \end{enumerate}
 | |
| 
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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.
 | |
| \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 you are 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 you want to enter a set-type constant in an expression, you must give a
 | |
| set constructor. In essence this is the same thing as when you define a set
 | |
| type, only you have 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, you must use the address operator if you want to assign a value
 | |
| 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.
 | |
| You 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. You can only mix integer
 | |
| and real types 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. If you want to compare the
 | |
| strings the \var{Pchar} points to, you must use the \var{StrComp} function
 | |
| from the \file{strings} unit.
 | |
| The \var{in} returns \var{True} if the left operand (which must have the same
 | |
| ordinal type as the set type) 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 your program or unit. You can label your
 | |
| statements, and jump to them (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, you should specify the \var{-Sc}
 | |
| command-line switch.
 | |
| 
 | |
| \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, you must keep the following 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, you need to specify the
 | |
| \var{-Sg} compiler switch.
 | |
| \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 Delhpi 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 you want, you must explicitly put the
 | |
| \var{begin} and \var{end} keywords. When in doubt, add them, they don't
 | |
| hurt.
 | |
| 
 | |
| 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\footnote{
 | |
| The \var{with} statement does not work correctly when used with
 | |
| objects or classes until version 0.99.6}
 | |
| 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}
 | |
| If you use 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 illiustrates
 | |
| 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}
 | |
| As of version 0.99.7, \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 you to insert assembler code right in your
 | |
| 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 your code. The compiler stores certain results in the
 | |
| registers. If you modify the registers 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. You can change the default assembler style with the
 | |
| \var{\{\$asmmode xxx\}} switch in your 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 you need to pass arguments 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.
 | |
| \subsection{Value parameters}
 | |
| Value parameters are declared as follows:
 | |
| \input{syntax/paramval.syn}
 | |
| When you declare parameters 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)
 | |
| 
 | |
| Take care that using value parameters makes heavy use of the stack,
 | |
| especially if you pass 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).
 | |
| 
 | |
| You can pass open arrays as value parameters. See \sees{openarray} for
 | |
| more information on using open arrays.
 | |
| \subsection{Variable parameters}
 | |
| \label{se:varparams}
 | |
| Variable parameters are declared as follows:
 | |
| \input{syntax/paramvar.syn}
 | |
| When you declare parameters 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 that you make to the parameter, will
 | |
| proagate 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 parameters can be untyped. In that case the variable has no type,
 | |
| and hence is incompatible with all other types. However, you can use the
 | |
| address operator on it, or you can pass it to a function that has also an
 | |
| untyped parameter. If you want to use an untyped parameter in an assigment,
 | |
| or you want to assign to it, you must use a typecast.
 | |
| 
 | |
| File type variables must always be passed as variable parameters.
 | |
| 
 | |
| You can pass open arrays as variable parameters. See \sees{openarray} for
 | |
| more information on using open arrays.
 | |
| \subsection{Constant parameters}
 | |
| In addition to variable parameters and value parameters \fpc also supports
 | |
| Constant parameters. You can specify a constant parameter as follows:
 | |
| \input{syntax/paramcon.syn}
 | |
| A constant argument is passed by reference if it's size is larger than a
 | |
| longint. It is passed by value if the size equals 4 or less.
 | |
| This means that the function or procedure receives a pointer to the passed
 | |
| argument, but you are not allowed to assign to it, this will result in a
 | |
| compiler error. Likewise, you cannot pass a const parameter 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.
 | |
| 
 | |
| You can pass open arrays 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. you can declare a procedure
 | |
| 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, you can pass open arrays only 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 you
 | |
| are 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 your 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 varable 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 you can define the same function 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 if you want to define the same function for different
 | |
| types. For example, in the RTL, the  \var{Dec} procedure is
 | |
| is 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 your
 | |
| 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.
 | |
| You cannot have overloaded functions that have a \var{cdecl} or \var{export}
 | |
| modifier (Technically, because these two modifiers prevent the mangling of
 | |
| the function name by the compiler).
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % forward defined functions
 | |
| \section{Forward defined functions}
 | |
| You can define a function 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}
 | |
| You cannot define a function twice as forward (nor is there any reason why
 | |
| you would want to do that).
 | |
| Likewise, in units, you cannot 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 you to use the function in
 | |
| your code, and at linking time, you must link the object file containing the
 | |
| implementation of the function or procedure.
 | |
| \input{syntax/external.syn}
 | |
| It replaces, in effect, the function or procedure code block. As such, it
 | |
| can be present only in an implementation block of a unit, or in a program.
 | |
| 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
 | |
| your program.
 | |
| 
 | |
| You can also specify the name that the function has in the library:
 | |
| \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 your program, and use the correct name for the function.
 | |
| Under \windows and \ostwo, you can also use the following form:
 | |
| \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 your program, and use the correct index for the
 | |
| function.
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % Assembler functions
 | |
| \section{Assembler functions}
 | |
| Functions and procedures can be completely implemented in assembly
 | |
| language. To indicate this, you 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. More on the use of modifiers can be found in
 | |
| the \progref.
 | |
| 
 | |
| \subsection{Public}
 | |
| The \var{Public} keyword is used to declare a function globally in a unit.
 | |
| This is useful if you don't want a function to be accessible from the unit
 | |
| file, but you do want the function to 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{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 if you wish to acces functions in
 | |
| an object file generated by a C compiler. It allows you to use the function in
 | |
| your code, and at linking time, you must link the object file containing the
 | |
| \var{C} implementation of the function or procedure.
 | |
| 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}
 | |
| When compiling this, and linking to the C-library, you will be able to call
 | |
| the \var{strlen} function throughout your program. The \var{external}
 | |
| directive tells the compiler that the function resides in an external
 | |
| object filebrary (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}. Since \var{C} is case
 | |
| sensitive, this means also that the name of the
 | |
| function must be exactly the same. the \fpc compiler will use the name {\em
 | |
| exactly} as it is typed in the declaration.
 | |
| \end{remark}
 | |
| 
 | |
| \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} you could access functions by their pascal names in a
 | |
| library.
 | |
| 
 | |
| \subsection{Export}
 | |
| Sometimes you must provide a callback function for a C library, or you want
 | |
| your routines to be callable from a C program. Since \fpc and C use
 | |
| different calling schemes for functions and procedures\footnote{More
 | |
| techically: In C the calling procedure must clear the stack. In \fpc, the
 | |
| subroutine clears the stack.}, the compiler must be told to generate code
 | |
| that can be called from a C routine. This is where the \var{Export} modifier
 | |
| comes in. Contrary to the other modifiers, it must be specified separately,
 | |
| as follows:
 | |
| \begin{verbatim}
 | |
| function DoSquare (X : Longint) : Longint; export;
 | |
| begin
 | |
| ...
 | |
| end;
 | |
| \end{verbatim}
 | |
| The square brackets around the modifier are not allowed in this case.
 | |
| \begin{remark}
 | |
| as of version 0.9.8, \fpc supports the Delphi \var{cdecl} modifier.
 | |
| This modifier works in the same way as the \var{export} modifier.
 | |
| More information about these modifiers can be found in the \progref, in the
 | |
| section on the calling mechanism and the chapter on linking.
 | |
| \end{remark}
 | |
| 
 | |
| \subsection{StdCall}
 | |
| As of version 0.9.8, \fpc supports the Delphi \var{stdcall} modifier.
 | |
| This modifier does actually nothing, since the \fpc compiler by default
 | |
| pushes parameters from right to left on the stack, which is what the
 | |
| modifier does under Delphi (which pushes parameters on the stack from left to
 | |
| right).
 | |
| More information about this modifier can be found in the \progref, in the
 | |
| section on the calling mechanism and the chapter on linking.
 | |
| 
 | |
| \subsection{saveregisters}
 | |
| As of version 0.99.15, \fpc has the \var{saveregisters} modifier. 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).
 | |
| 
 | |
| You should not need this modifier, except maybe when calling assembler code.
 | |
| 
 | |
| \subsection{Alias}
 | |
| The \var{Alias} modifier allows you to specify a different name for a
 | |
| procedure or function. This is mostly useful for referring to this procedure
 | |
| from assembly language constructs. 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, combined with the \var{Public} modifier, make a
 | |
| powerful tool for making externally accessible object files.
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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. \\
 | |
| %External & Replaced by \var{C} modifier. \\ \hline
 | |
| \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}.
 | |
| 
 | |
| 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 bythe 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}
 | |
| You would have to define the following assignment operator:
 | |
| \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, unit names
 | |
| are converted to all lowercase when looking for a unit.
 | |
| 
 | |
| 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, you must put that unit in the uses clause of the program or unit where
 | |
| you want to yuse the identifier.
 | |
| 
 | |
| 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 program or unit
 | |
| you make.
 | |
| The rules of unit scope implie that you can redefine an identifier of a
 | |
| unit. 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 if you redeclare 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 your library.
 | |
| 
 | |
| In order to make functions or procedures available from the library,
 | |
| you must export them 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.
 | |
| It is best to use low index values, although nothing forces you to
 | |
| do this.
 | |
| 
 | |
| 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}
 | |
| As of version 0.99.7, \fpc supports 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. If you use 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 you can use the message field of the
 | |
| exception object.
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % Using Assembler
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| \chapter{Using assembler}
 | |
| \fpc supports the use of assembler in your 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 your code.
 | |
| \begin{verbatim}
 | |
|  ...
 | |
|  Statements;
 | |
|  ...
 | |
|  Asm
 | |
|    your 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.
 | |
| You can still use conditionals in your assembler, the compiler will
 | |
| recognise it, and treat it as any other conditionals.
 | |
| 
 | |
| \begin{remark}
 | |
| Before version 0.99.1, \fpc did not support reference to variables by
 | |
| their names in the assembler parts of your code.
 | |
| \end{remark}
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % Assembler procedures and functions
 | |
| \section{Assembler procedures and functions}
 | |
| Assembler procedures and functions are declared using the
 | |
| \var{Assembler} directive. The \var{Assembler} keyword is supported
 | |
| as of version 0.9.7. 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.
 | |
| 
 | |
| \begin{remark} From version 0.99.1 to 0.99.5 (\emph{excluding}
 | |
| FPC 0.99.5a), the \var{Assembler} directive did not have the
 | |
| same effect as in Turbo Pascal, so beware! The stack frame would be
 | |
| omitted if there were no local variables, in this case if the assembly
 | |
| routine had any parameters, they would be referenced directly via the stack
 | |
| pointer. This was \emph{ NOT} like Turbo Pascal where the stack frame is only
 | |
| omitted if there are no parameters \emph{ and } no local variables. As
 | |
| stated earlier, starting from version 0.99.5a, \fpc now has the same
 | |
| behaviour as Turbo Pascal.
 | |
| \end{remark}
 | |
| 
 | |
| %
 | |
| % 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    = cardinal;
 | |
| longword = cardinal;
 | |
| 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 following character types are defined for Delphi compatibility:
 | |
| \begin{verbatim}
 | |
| TAnsiChar   = Char;
 | |
| AnsiChar    = TAnsiChar;
 | |
| \end{verbatim}
 | |
| And the following pointer types:
 | |
| \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 if you want 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}
 | |
| 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}
 | |
| You should always use the constant names, and never their values, because
 | |
| the VMT table can change, breaking your code.
 | |
| 
 | |
| 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 you can set it yourself to change
 | |
| the default exception handling.
 | |
| 
 | |
| \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 : Longint;
 | |
|   loweststack : Longint;
 | |
| \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 if you want to install your exit procedure, you should save the old value
 | |
| of \var{ExitProc} (may be non-\var{Nil}, since other units could have set it before
 | |
| you did). In your exit procedure you then restore the value of
 | |
| \var{ExitProc}, 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
 | |
| your process.
 | |
| 
 | |
| \begin{remark}
 | |
| The maximum error code under \linux 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.
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| % 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 you can find the
 | |
| function.
 | |
| \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 segmant and offset to pointer}
 | |
| \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 ESS 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{Pos}{Calculate position of one string in another}
 | |
| \procref{SetLength}{Set 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{Break}{Abort current loop}
 | |
| \procref{Continue}{Next cycle in current loop}
 | |
| \procref{Exit}{Exit current function or procedure}
 | |
| \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. If the file didn't exist, it will be
 | |
| created, contrary to the Turbo Pascal implementation of \var{Append}, where
 | |
| a file needed to exist in order to be opened by
 | |
| \var{Append}.
 | |
| Only text files can be opened in append mode.
 | |
| 
 | |
| \Errors
 | |
| If the file can't be created, a run-time error will be generated.
 | |
| \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}{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, you need 32
 | |
| bits, i.e. \var{cnt=32}
 | |
| 
 | |
| \Errors
 | |
| None.
 | |
| \SeeAlso
 | |
| \seep{Str},\seep{Val},\seef{HexStr}
 | |
| \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
 | |
| If \var{Result} isn't specified, then a run-time error is generated if less
 | |
| than \var{count} records were read.
 | |
| \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
 | |
| A run-time error is generated if, for some reason, the records couldn't be
 | |
| written to disk.
 | |
| \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
 | |
| If the directory \var{S} doesn't exist, a run-time error is generated.
 | |
| \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
 | |
| None.
 | |
| \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[-1] 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 [1] 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 : Byte) : 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 : Longint]);
 | |
| 
 | |
| \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 you try 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 Dispiose (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 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
 | |
| None.
 | |
| \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
 | |
| A run-time error will be generated if the specified file doesn't exist, or
 | |
| is opened by the program.
 | |
| \SeeAlso
 | |
| \seep{Assign}
 | |
| \end{procedure}
 | |
| 
 | |
| \FPCexample{ex20}
 | |
| 
 | |
| \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}. If you try to
 | |
| do this, a compiler error will be generated.
 | |
| \Errors
 | |
| None.
 | |
| \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, this
 | |
| also means that it cannot be invoked on pipes.)
 | |
| If \var{F} is empty, 0 is returned.
 | |
| \Errors
 | |
| None.
 | |
| \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. If you know
 | |
| that 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's 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
 | |
| If the disk is full, a run-time error will be generated.
 | |
| \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 dynamical 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, \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;
 | |
| \Description
 | |
| \var{HexStr} returns a string with the hexadecimal representation
 | |
| of \var{Value}. The string has at most \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, you need 8
 | |
| nibbles, 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 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{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 : Longint]);
 | |
| 
 | |
| \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, if you try to increase \var{X} over its maximum value.
 | |
| \SeeAlso
 | |
| \seep{Dec}
 | |
| \end{procedure}
 | |
| 
 | |
| \FPCexample{ex32}
 | |
| 
 | |
| \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;
 | |
| 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;
 | |
| \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;
 | |
| \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 : Longint);
 | |
| 
 | |
| \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) : Byte;
 | |
| 
 | |
| \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. Ansistrings have their length stored elsewhere,
 | |
| the \var{Length} fuction should always be used on ansistrings.
 | |
| 
 | |
| \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 resores 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 you pas a \var{value} equal to zero, 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
 | |
| \var{Mark} copies the current heap-pointer to \var{P}.
 | |
| \Errors
 | |
| None.
 | |
| \SeeAlso
 | |
| \seep{Getmem}, \seep{Freemem}, \seep{New}, \seep{Dispose}, \seef{Maxavail}
 | |
| \end{procedure}
 | |
| 
 | |
| \FPCexample{ex39}
 | |
| 
 | |
| \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.
 | |
| \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
 | |
| If a parent-directory of directory \var{S} doesn't exist, a run-time error is generated.
 | |
| \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. With older versions of
 | |
| the compiler, a segmentation-fault will occur.
 | |
| \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}{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 name with which the program was started.
 | |
| 
 | |
| In all cases, the command-line will be truncated to a length of 255,
 | |
| even though the operating system may support bigger command-lines. If you
 | |
| want to access the complete command-line, you must use the \var{argv} pointer
 | |
| to access 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) : Byte;
 | |
| \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. If you recompile
 | |
| the RTL with \var{-dDoMapping} defined, then the compiler returns the
 | |
| following : \var{ptr := pointer(\$e0000000+sel shl 4+off)} under \dos, or
 | |
| \var{ptr := pointer(sel shl 4+off)} on other OSes.
 | |
| \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 (defined by the \var{LineFeed (\#10)} character).
 | |
| 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{procedure}{Release}
 | |
| \Declaration
 | |
| Procedure Release (Var P : pointer);
 | |
| 
 | |
| \Description
 | |
| \var{Release} sets the top of the Heap to the location pointed to by
 | |
| \var{P}. All memory at a location higher than \var{P} is marked empty.
 | |
| \Errors
 | |
| A run-time error will be generated if \var{P} points to memory outside the
 | |
| heap.
 | |
| \SeeAlso
 | |
| \seep{Mark}, \seef{Memavail}, \seef{Maxavail}, \seep{Getmem}, \seep{Freemem}
 | |
| \seep{New}, \seep{Dispose}
 | |
| \end{procedure}
 | |
| For an example, see \seep{Mark}.
 | |
| \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
 | |
| A run-time error will be generated if \var{F} isn't assigned,
 | |
| or doesn't exist.
 | |
| \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 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.
 | |
| \Errors
 | |
| If the file cannot be opened for reading, then a run-time error is
 | |
| generated. This behavior can be changed by the \var{\{\$i\} } compiler switch.
 | |
| \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 you want
 | |
| to get it in \var{fminout} mode, you'll need to do an extra call to
 | |
| \seep{Reset}.
 | |
| 
 | |
| \Errors
 | |
| If the file cannot be opened for writing, then a run-time error is
 | |
| generated. This behavior can be changed by the \var{\{\$i\} } compiler switch.
 | |
| \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
 | |
| If \var{S} doesn't exist, or isn't empty, a run-time error is generated.
 | |
| 
 | |
| \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
 | |
| A run-time error is generated if \var{Count} points to a position outside
 | |
| the file, or the file isn't opened.
 | |
| \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 or a short string.
 | |
| 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}{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/0
 | |
| operations this may prove too slow. The \var{SetTextBuf} procedure allows
 | |
| you to set a bigger buffer for your 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. You can assign a
 | |
| new buffer immediately after a call to \seep{Rewrite}, \seep{Reset} or
 | |
| \var{Append}, but not after you read from/wrote to the file. This may cause
 | |
| loss of data. If you still want to assign a new buffer after read/write
 | |
| operations have been performed, flush the file first. This will ensure that
 | |
| the current buffer is emptied.
 | |
| \item Take care that the buffer you assign is always valid. If you
 | |
| assign a local variable as a buffer, then after your 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. It's result is calculated at
 | |
| compile-time, and hard-coded in your 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 : longint) : AnsiString;
 | |
| \Description
 | |
| \var{StringOfChar} creates a new Ansistring 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
 | |
| Errors are reported by IOresult.
 | |
| \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} isn't allowed to contain spaces.
 | |
| \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, 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{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
 | |
| \seep{SetResourceStrings},
 | |
| \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} | 
