Browse Source

Finished all syntax elements

michael 27 years ago
parent
commit
a3b235565a
1 changed files with 232 additions and 110 deletions
  1. 232 110
      docs/ref.tex

+ 232 - 110
docs/ref.tex

@@ -34,7 +34,7 @@
 \latex{\usepackage{fpc}}
 \latex{\usepackage{listings}\blankstringtrue%
 \selectlisting{tp}\stringstyle{\ttfamily}\keywordstyle{\bfseries}
-\prelisting{\sffamily}}
+\prelisting{\sffamily\sloppy}}
 \html{\input{fpc-html.tex}}
 \usepackage{fancyheadings}
 \pagestyle{fancy}
@@ -128,6 +128,8 @@ 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
 %
@@ -1132,7 +1134,7 @@ Var p : array[0..Infinity] of Longint;
 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 \seef{Getmem} function.
+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:
@@ -1271,7 +1273,7 @@ An object is declared just as you would declare a record; except that you
 can now declare procedures and fuctions 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 the were included in the
+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}
@@ -1372,7 +1374,7 @@ It is also possible to use the \var{with} statement with an object instance:
 \begin{listing}
 With AnObject do
   begin
-  Afield := 12
+  Afield := 12;
   AMethod;
   end;
 \end{listing}
@@ -1385,19 +1387,24 @@ identifiers. More about this in \sees{With}
 
 As can be seen in the syntax diagram for an object declaration, \fpc supports
 constructors and destructors. You are responsible for calling the 
-destructor and constructor explicitly when using objects.
+constructor and the destructor explicitly when using objects.
 
 The declaration of a constructor or destructor is as follows:
 
 \input{syntax/construct.syn}
 
-A constructor is {\em required} if you use virtual methods.
+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 varible of an object
+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. Given the following declarations :
+instantiated object. Consider the following declarations:
 \begin{listing}
 Type
   TObj = object;
@@ -1408,7 +1415,7 @@ Type
 
 Var PP : Pobj;
 \end{listing}
-Then the following 3 calls are equivalent :
+Then the following 3 calls are equivalent:
 \begin{listing}
  pp := new (Pobj,Init);
 \end{listing}
@@ -1444,11 +1451,10 @@ given.
 
 \section{Method invocation}
 Methods are called just as normal procedures are called, only they have a 
-object instance identifier prepended to them
-\seec{Statements}.
+object instance identifier prepended to them (see also \seec{Statements}).
 
 To determine which method is called, it is necessary to know the type of
-method:
+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}
@@ -1460,19 +1466,19 @@ For example, consider the following declarations:
 Type
   TParent = Object 
     ...
-    procedure Method;
+    procedure Doit;
     ...
     end;
-  PPArent = ^TParent;
+  PParent = ^TParent;
   TChild = Object(TParent) 
     ...
-    procedure Method;
+    procedure Doit;
     ...
     end;
   PChild = ^TChild;  
 \end{listing}
 As it is visible, both the parent and child objects have a method called
-\var{Draw}. Consider now the following declarations and calls :
+\var{Doit}. Consider now the following declarations and calls:
 \begin{listing}
 Var ParentA,ParentB : PParent;
     Child           : PChild;
@@ -1481,16 +1487,16 @@ Var ParentA,ParentB : PParent;
    ParentB := New(PChild,Init);
    Child := New(PChild,Init);
 
-   ParentA^.Method;
-   ParentB^.Method;
-   Child^.Method;
+   ParentA^.Doit;
+   ParentB^.Doit;
+   Child^.Doit;
 \end{listing}
-Of the three invocations of \var{Method}, only the last one will call
-\var{TChild.Method}, the other two calls will call \var{TParent.Method} 
+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.Method}, even though it will be created as a \var{TChild}.
+\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
@@ -1502,18 +1508,19 @@ 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 provious example, consider the following alterbative
+Going back to the previous example, consider the following alternative
 declaration:
 \begin{listing}
 Type
   TParent = Object 
     ...
-    procedure Method;virtual;
+    procedure Doit;virtual;
     ...
     end;
+  PParent = ^TParent;
   TChild = Object(TParent) 
     ...
-    procedure Method;virtual;
+    procedure Doit;virtual;
     ...
     end;
   PChild = ^TChild;  
@@ -1528,46 +1535,46 @@ Var ParentA,ParentB : PParent;
    ParentB := New(PChild,Init);
    Child := New(PChild,Init);
 
-   ParentA^.Method;
-   ParentB^.Method;
-   Child^.Method;
+   ParentA^.Doit;
+   ParentB^.Doit;
+   Child^.Doit;
 \end{listing}
 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
+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 the \var{Method}, the program
+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.Method} will be called.
+\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.Method} is said to {\em override} the \var{TParent.Method}.
-It is possible to acces the \var{TPArent.Method} from within the
-var{TChild.Method}, with the \var{inherited} keyword:
+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{listing}
-TChild.Method;
+Procedure TChild.Doit;
 
 begin
-  inherited Method; 
+  inherited Doit; 
   ...
 end;
 \end{listing}
-In the above example, when var{TChild.Method} is called, the first thing it
-does is call \var{TPArent.Method}. You cannot use the inherited keyword on 
+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. 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 !
+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 
@@ -1576,13 +1583,13 @@ method. Continuing our example, take a look at this:
 Type
   TParent = Object 
     ...
-    procedure Method;virtual;
+    procedure Doit;virtual;abstract;
     ...
     end;
   PParent=^TParent;
   TChild = Object(TParent) 
     ...
-    procedure Method;virtual;
+    procedure Doit;virtual;
     ...
     end;
   PChild = ^TChild;  
@@ -1597,9 +1604,9 @@ Var ParentA,ParentB : PParent;
    ParentB := New(PChild,Init);
    Child := New(PChild,Init);
 
-   ParentA^.Method;
-   ParentB^.Method;
-   Child^.Method;
+   ParentA^.Doit;
+   ParentB^.Doit;
+   Child^.Doit;
 \end{listing}
 First of all, Line 4 will generate a compiler error, stating that you cannot
 generate instances of objects with abstract methods: The compiler has
@@ -1622,7 +1629,7 @@ 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
+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}
@@ -1652,8 +1659,9 @@ The prototype declaration of a class is as follows :
 
 \input{syntax/typeclas.syn}
 
-Again, You can repeat as many \var{private} and \var{public} blocks as you 
-want. Methods are normal function or procedure declarations. 
+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
@@ -1720,14 +1728,14 @@ begin
   ANobject.AMethod;
 \end{listing}
 
-\subsection{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 assiciate 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 constuct the
+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:
@@ -1871,7 +1879,7 @@ As an example, see the following declaration:
 \begin{listing}
 Type TIntList = Class
       Private
-      Function GetInt (I : Longint);
+      Function GetInt (I : Longint) : longint;
       Function GetAsString (A : String) : String;
       Procedure SetInt (I : Longint; Value : Longint;);
       Procedure SetAsString (A : String; Value : String);
@@ -1900,7 +1908,7 @@ AIntList.StrItems[26] := 'zero';
 Because the index types are wrong.
 
 Array properties can be declared as \var{default} properties. This means that
-it is not necessary to specifiy the property name when assigning or readin
+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{listing}
@@ -1924,7 +1932,7 @@ cannot redeclare the default property.
 Expressions occur in assignments or in tests. Expressions produce a value,
 of a certain type. 
 
-Expressions are built with two ocmponents: Operators and their Operands.
+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
@@ -1991,7 +1999,7 @@ Factors are all other constructions:
 
 \input{syntax/expfact.syn}
 
-\section{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:
@@ -2062,7 +2070,7 @@ How then, should one compare whether \var{F} points to the function
 If F = @AddOne Then
   WriteLn ('Functions are equal');
 \end{listing}
-The left hand side of the boolean expression is an address. The right and
+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
@@ -2096,7 +2104,7 @@ The following are valid set constructors:
 
 \begin{listing}
 [today,tomorrow]
-[Monfay..Friday,Sunday]
+[Monday..Friday,Sunday]
 [ 2, 3*2, 6*2, 9*2 ]
 ['A'..'Z','a'..'z','0'..'9']
 \end{listing}
@@ -2131,14 +2139,14 @@ Word(@Buffer)
 
 \section{The @ operator}
 
-The address operator \var{@} returns the address of a variable or function.
-It is used as follows:
+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 assignent compatible with all pointer types. The type of
+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.
 
@@ -2201,7 +2209,7 @@ 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.
+As an exception : division (\var{/}) results always in real values.
 
 \begin{FPCltable}{ll}{Unary arithmetic operators}{unaroperators}
 Operator & Operation \\ \hline
@@ -2209,7 +2217,7 @@ Operator & Operation \\ \hline
 \var{-} & Sign inversion \\ \hline
 \end{FPCltable}
 
-For unary operators, the result type is always equal to th expression type.
+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.
@@ -2293,7 +2301,7 @@ The following are valid string operations:
   'This is ' + 'VERY ' + 'easy !'
   Dirname+'\' 
 \end{listing}
-The folowwing is not:
+The following is not:
 \begin{listing}
 Var Dirname = Pchar;
 ...
@@ -2301,7 +2309,7 @@ Var Dirname = Pchar;
 \end{listing}
 Because \var{Dirname} is a null-terminated string.
 
-\subsection{Set operations}
+\subsection{Set operators}
 
 The following operations on sets can be performed with operators: 
 Union, difference and intersection. The operators needed for this are listed
@@ -2313,7 +2321,7 @@ Operator & Action \\ \hline
 \var{*} & Intersection \\ \hline
 \end{FPCltable}
 
-The set typed of the operands must be the same, or an error will be
+The set type of the operands must be the same, or an error will be
 generated by the compiler.
 
 \subsection{Relational operators}
@@ -2336,7 +2344,7 @@ 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 troe for \var{PChar} type pointers. If you want to compare the
+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.
 
@@ -2349,7 +2357,7 @@ operand, otherwise it returns \var{False}
 
 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, and jump to them (within certain limits) with \var{Goto}
 statements.
 
 This can be seen in the following syntax diagram:
@@ -2361,10 +2369,13 @@ A label can be an identifier or an integer digit.
 \section{Simple statements}
 
 A simple statement cannot be decomposed in separate statements. There are
-basically 3 kinds of simple statements:
+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
@@ -3616,20 +3627,30 @@ serve to clean up memory or close files in case an exception occurs.
 code.
 \end{description}
 
+\subsection{The raise statement}
+
 The \var{raise} statement is as follows:
-\begin{listing}
-  Raise [ExceptionInstance [at Address]];
-\end{listing}
-This statement will raise an exception. If specified, \var{ExceptionInstance} 
-must be an initialized instance of a class, which is the raise type. If
-specified, \var{Address} must be an expression that returns an address.
 
-If \var{ExceptionInstance} is omitted, then the Current exception is
+\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.
+block (see further).
+
+Remark that 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}).
 
 As an example: The following division checks whether the denominator is
 zero, and if so, raises an exception of type \var{EDivException}
+
 \begin{listing}
 Type EDivException = Class(Exception);
 
@@ -3642,35 +3663,48 @@ begin
 end;
 \end{listing}
 The class \var{Exception} is defined in the \file{Sysutils} unit of the rtl.
+(\sees{exceptclasses})
+
+\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}.
 
-An exception handling block is of the following form :
-\begin{listing}
-  Try
-    ...Statement List...
-  Except
-    [On [E:] ExceptionClass do CompoundStatement;] 
-    [ Default exception handler]
-  end;
-\end{listing}
 If an exception occurs during the execution of the \var{statement list}, the
-program flow fill be transferred to the except block. There, the type of the
-exception is checked, and if there is a \var{On ExcType} statement where
-\var{ExcType} matches the exception object type, or is a parent type of
-the exception object type, then the statements follwing the corresponding 
+program flow fill 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 \var{E} 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.
+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
 \var{Default exception handler} is executed. If no such default handler 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{listing}
@@ -3691,22 +3725,20 @@ A \var{Try...Finally} block ensures that the statements following the
 \var{Finally} keyword are guaranteed to be executed, even if an exception
 occurs.
 
-A \var{Try..Finally} block has the following form:
+\section{The try...finally statement}
 
-\begin{listing}
-  Try
-    ...Statement List...
-  Finally
-    [ Finally Statements ]
-  end;
-\end{listing}
-If no exception occurs inside the \var{Statement List}, then the program
+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 to the first statement of the \var{Finally statements}. 
-All statements of the \var{Finally Statements} will be executed, and then
+transferred from the point where the excepion was raised to the first 
+statement  of the \var{Finally statements}. 
+All statements after the finally kayword 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.
@@ -3737,6 +3769,8 @@ 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.
 
+\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
@@ -3750,6 +3784,44 @@ handler is installed which ioll show the exception object message, and the
 address where the exception occurred, after which the program will exit with
 a \var{Halt} instruction.
 
+\section{Exception classes}
+\label{se:exceptclasses}
+
+The \file{sysutils} unit contains a great deal of exception handling.
+It defines the following exception types:
+\begin{listing}
+       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{listing}
+
+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 Exception object or a descendant class for 
+all raise statemnts, since then you can use the message field of the
+exception object.
+
 \chapter{Using assembler}
 
 \fpc supports the use of assembler in your code, but not inline
@@ -3811,7 +3883,8 @@ behaviour as Turbo Pascal.
 % System unit reference guide.
 %
 %\end{document}
-\chapter{Reference : The system unit}
+\part{Reference : The System unit}
+\chapter{The system unit}
 \label{ch:refchapter}
 
 The system unit contains the standard supported functions of \fpc. It is the
@@ -4283,6 +4356,22 @@ of X. If the size of X is 4, then the high word is returned. If the size is
 \latex{\inputlisting{refex/ex31.pp}}
 \html{\input{refex/ex31.tex}}
 
+\function{High}{(Type identifier or variable reference)}{Longint}
+{ 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 when it gets.
+\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}
+}{None.}{\seef{High}, \seef{Ord}, \seef{Pred}, \seef{Succ}}
+
+\latex{\inputlisting{refex/ex80.pp}}
+\html{\input{refex/ex80.tex}}
+
 \procedure{Inc}{(Var X : Any ordinal type[; Increment : Longint])}
 {\var{Inc} increases the value of \var{X} with \var{Increment}.
 If \var{Increment} isn't specified, then 1 is taken as a default.}
@@ -4419,6 +4508,18 @@ occurred.}{None.}{\seef{SetJmp}}
 
 For an example, see \seef{SetJmp}
 
+\function{Low}{(Type identifier or variable reference)}{Longint}
+{ 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 when it gets.
+\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}
+}{None.}{\seef{High}, \seef{Ord}, \seef{Pred}, \seef{Succ}}
+
+for an example, see \seef{High}.
+
 \function{Lowercase}{(C : Char or String)}{Char or String}
 {\var{Lowercase} returns the lowercase version of its argument \var{C}.
 If its argument is a string, then the complete string is converted to
@@ -4515,11 +4616,10 @@ compiler.
 \html{\input{refex/ex44.tex}}
 
 
-\function{Ord}{(X : Ordinal type)}{Byte}
+\function{Ord}{(X : Any ordinal type)}{Longint}
 {\var{Ord} returns the Ordinal value of a ordinal-type variable \var{X}.}
 {None.}
-{\seef{Chr}}
-
+{\seef{Chr}, \seef{Ord}, \seef{Pred}, \seef{High}, \seef{Low}}
 
 \latex{\inputlisting{refex/ex45.pp}}
 \html{\input{refex/ex45.tex}}
@@ -4582,6 +4682,18 @@ The function actually returns \var{Exp(expon*Ln(base))}
 \latex{\inputlisting{refex/ex78.pp}}
 \html{\input{refex/ex78.tex}}
 
+\function{Pred}{(X : Any ordinal type)}{Same type}
+{ \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.
+}{Run-time error 201 is generated when the result is out of
+range.}{\seef{Ord}, \seef{Pred}, \seef{High}, \seef{Low}}
+
+for an example, see \seef{Ord}
+\latex{\inputlisting{refex/ex80.pp}}
+\html{\input{refex/ex80.tex}}
+
 \function{Ptr}{(Sel,Off : Longint)}{Pointer}
 {
 \var{Ptr} returns a pointer, pointing to the address specified by
@@ -4906,6 +5018,16 @@ formatting of the string.}
 \latex{\inputlisting{refex/ex68.pp}}
 \html{\input{refex/ex68.tex}}
 
+\function{Succ}{(X : Any ordinal type)}{Same type}
+{ \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.
+}{Run-time error 201 is generated when the result is out of
+range.}{\seef{Ord}, \seef{Pred}, \seef{High}, \seef{Low}}
+
+for an example, see \seef{Ord}.
+
 \function{Swap}{(X)}{Type of X}
 {\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